Banded Matrices


dinaharchery
04-29-2010, 12:36 PM
Hello,

I have a compacted, banded, matrix of dimensions N*BW (where bandwidth, BW, is 5) that I would like to be able to convert back to its full, original matrix (i.e. sparse matrix). Can anyone help?

The reason is I would like to apply a conjugate gradient solver to the matrix and for this I need the original sparse matrix. Also, just the general utility to convert matrices back and forth would be great.

Thank you.:D

davekw7x
04-30-2010, 11:53 AM
I have a compacted, banded, matrix of dimensions N*BW (where bandwidth, BW, is 5)Where did it come from?

With pencil and paper, write out the original matrix. Look at the relationship between the original index values and the compacted form.

Don't know how to go from compacted form to full form with pencil and paper? Then start with a full-sized pentadiagonal matrix and write the compacted form. Look at the relationship between the index values of of the compacted form and the original.

Etc.


Try something like the following on your original matrix:

cout << "Original pentadiagonal banded matrix:" << endl;
for (int i = 0; i < nrows; i++) {
for (int j = 0; j < ncols; j++) {
cout << setw(7) << original[i][j];
}
cout << endl;
}
cout << endl;

for (int i = 0; i < nrows; i++) {
for (int j = 0; j < bandwidth; j++) {
int idx = i + j - 2; // 2 = bandwidth/2;
if ((idx >= 0) && (idx < nrows)) {
banded5[i][j] = original[i][idx];
}
else {
banded5[i][j] = 0.0;
}
}
}

cout << "Compacted storage form of banded matrix:" << endl;
for (int i = 0; i < nrows; i++) {
for (int j = 0; j < bandwidth; j++) {
cout << setw(7) << banded5[i][j];
}
cout << endl;
}
cout << endl;

for (int i = 0; i < nrows; i++) {
for (int j = 0; j < ncols; j++) {
int idx = j - i + 2; // 2 = bandwidth/2;
//cout << "[" << i << "][" << j << "] = " << idx << endl;
if ((idx >= 0) && (idx < bandwidth)) {
expanded[i][j] = banded5[i][idx];
}
else {
expanded[i][j] = 0.0;
}
}
}

cout << "Expanded back to full-sized form:" << endl;
for (int i = 0; i < nrows; i++) {
for (int j = 0; j < ncols; j++) {
cout << setw(7) << expanded[i][j];
}
cout << endl;
}
cout << endl;


With nrows = ncols = 8 and bandwitth = 5, the output can be something like:

Original pentadiagonal banded matrix:
10 11 12 0 0 0 0 0
13 14 15 16 0 0 0 0
17 18 19 20 21 0 0 0
0 22 23 24 25 26 0 0
0 0 27 28 29 30 31 0
0 0 0 32 33 34 35 36
0 0 0 0 37 38 39 40
0 0 0 0 0 41 42 43

Compacted storage form of banded matrix:
0 0 10 11 12
0 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 0
41 42 43 0 0

Expanded back to full-sized form:
10 11 12 0 0 0 0 0
13 14 15 16 0 0 0 0
17 18 19 20 21 0 0 0
0 22 23 24 25 26 0 0
0 0 27 28 29 30 31 0
0 0 0 32 33 34 35 36
0 0 0 0 37 38 39 40
0 0 0 0 0 41 42 43


If your matrix doesn't have the same size and shape, and you can't figure it out, then post some more details of what you are really working with.


Regards,

Dave