averaging each diagonal line in a matrix

Hi,

I have a tridiagonal matrix and I would like to compute the average of each line of nonzero entries in this matrix. I have run the code, unfortunately, it only works for the main diagonal line but not for others.

Once the average is computed, I want to replace each element in the diagonal line with the averaged value. For example, I have a matrix:

1. Z=[1 2 3 4; 4 3 4 5; 2 3 2 1; 3 4 5 2].
2. Then, extract Z to be a tridiagonal matrix W
W= [1 2 0 0; 4 3 4 0; 0 3 2 1; 0 0 5 2].
3. Next, I compute the average of each diagonal line, and replace each element in each line with its averaged value:
Y = [ 2 2.33 0 0; 4 2 2.33 0; 0 4 2 2.33; 0 0 4 2].

This is my code:
#include <iostream>
#include <complex>
using namespace std;


const int order = 4;


void print(complex<double> M[order][order])
{
for (int i = 0; i < order; i++)
{
for (int j = 0; j < order; j++)
cout << M[i][j] << '\t';
cout << '\n';
}
}


int main()
{
complex<double> Z[order][order] = { { 1, 2, 3, 4 },{ 4, 3, 4, 5 },{ 2, 3, 2, 1 }, { 3, 4, 5, 2 } };
complex<double> W[order][order] = { 0 }, Y[order][order] = { 0 };
complex<double> d1sum = 0, d2sum = 0, d3sum = 0;
complex<double> ave1diag = 0, ave2diag = 0, ave3diag = 0;


//tridiagonal matrix
for (int i = 0; i < order; i++)
{
// main diagonal line
W[i][i] = Z[i][i];
d1sum = d1sum + W[i][i] ;
ave1diag = d1sum / (double)order;


//1-step behind the main diagonal
if (i > 0)
W[i][i - 1] = Z[i][i - 1];
d2sum = d2sum + W[i][i-1];
ave2diag = d2sum / (double)(order-1);

//1-step after the main diagonal
if (i < order - 1)
W[i][i + 1] = Z[i][i + 1];
d3sum = d3sum + W[i][i + 1];
ave3diag = d3sum / (double)(order - 1);

}


for (int i = 0; i < order; i++)
{

// main diagonal line
Y[i][i] =ave1diag;


//1-step behind the main diagonal
if (i > 0)
Y[i][i - 1] = ave2diag;

//1-step after the main diagonal
if (i < order - 1)
Y[i][i + 1] = ave3diag;


}
cout << "Original matrix, Z:\n";
print(Z);

cout << "\nReduced matrix, W:\n";
print(W);

cout << "\nNew averaged matrix, Y:\n";
print(Y);

cout << "\nSum of 1st diagonal is " << d1sum;
cout << "\nAverage of main diagonal line " << ave1diag << "\n";
cout << "\nSum of 1-step before the main diagonal is " << d2sum;
cout << "\nAverage of 1-step before the main diagonal line " << ave2diag << "\n";
cout << "\nSum of 1-step after the main diagonal is " << d3sum;
cout << "\nAverage of 1-step after the main diagonal line " << ave3diag << "\n";
system("pause");
return 0;
}

25 posts.
Still no code tags.
That's just sad.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
#include <iostream>
#include <iomanip>
#include <complex>
using namespace std;


const int order = 4;


void print( complex<double> M[order][order], int width = 12 )
{
   for ( int i = 0; i < order; i++ )
   {
      for ( int j = 0; j < order; j++ ) cout << setw( width) << M[i][j] << " ";
      cout << '\n';
   }
}


int main()
{
   complex<double> Z[order][order] = { { 1, 2, 3, 4 },{ 4, 3, 4, 5 },{ 2, 3, 2, 1 }, { 3, 4, 5, 2 } };
   complex<double> W[order][order] = { 0 }, Y[order][order] = { 0 };
   complex<double> sumLower = 0, sumDiag = 0, sumUpper = 0;

   // Sum diagonal elements; note that W[][] is NOT REALLY NECESSARY
   for ( int i = 0; i < order; i++ )
   {
      W[i][i] = Z[i][i];
      sumDiag += Z[i][i];

      if ( i > 0         ) 
      {
         W[i][i-1] = Z[i][i-1];
         sumLower += Z[i][i-1];
      }

      if ( i < order - 1 ) 
      {
         W[i][i+1] = Z[i][i+1];
         sumUpper += Z[i][i+1];
      }
   }


   // Average the diagonals
   complex<double> aveLower = sumLower / ( order - 1.0 );
   complex<double> aveDiag  = sumDiag  / (double) order;
   complex<double> aveUpper = sumUpper / ( order - 1.0 );


   // Replace three diagonals by their averages
   for ( int i = 0; i < order; i++ )
   {
      Y[i][i] = aveDiag;
      if ( i > 0         ) Y[i][i-1] = aveLower;
      if ( i < order - 1 ) Y[i][i+1] = aveUpper;
   }


   cout << "Original matrix:\n";
   print( Z );

   cout << "\nIntermediate matrix:\n";
   print( W );

   cout << "\nDiagonal-averaged matrix:\n";
   print( Y, 16 );
}


Original matrix:
       (1,0)        (2,0)        (3,0)        (4,0) 
       (4,0)        (3,0)        (4,0)        (5,0) 
       (2,0)        (3,0)        (2,0)        (1,0) 
       (3,0)        (4,0)        (5,0)        (2,0) 

Intermediate matrix:
       (1,0)        (2,0)        (0,0)        (0,0) 
       (4,0)        (3,0)        (4,0)        (0,0) 
       (0,0)        (3,0)        (2,0)        (1,0) 
       (0,0)        (0,0)        (5,0)        (2,0) 

Diagonal-averaged matrix:
           (2,0)      (2.33333,0)            (0,0)            (0,0) 
           (4,0)            (2,0)      (2.33333,0)            (0,0) 
           (0,0)            (4,0)            (2,0)      (2.33333,0) 
           (0,0)            (0,0)            (4,0)            (2,0) 



@nurulhudaismail, I'm a bit mystified by what you are intending to do with this. Also, I'm sure that there are plenty of people at the University of Sheffield who could help you, even if they are ... ahem ... on the wrong side of the Pennines.


For [code] tags and other formatting see
http://www.cplusplus.com/forum/lounge/253680/

Last edited on
Registered users can post here. Sign in or register to post.