Combining individual matrices diagonally into bigger matrix with overlapping elements added

17 views (last 30 days)
Hello all,
I'm throwing in the towel after struggling to come up with any elegant way to do a problem. I've uploaded the input and desired output as an image.
In words, basically I have 4qty 2x2 matrices that need to go into a bigger 5x5 matrix such that the overlapping elements are added. The bigger matrix size is a square matrix, always 1 plus the size of the smaller matrices. All the smaller matrices are the same size, in this case 2x2.
The issue is that the code needs to work for other cases too , in the sense that if I have 6qty of 2x2 matrices, the bigger 7x7 matrix also needs to have the sums of overlapping elements. So I'm looking for a general code.
Thanks really for helping!

Accepted Answer

John D'Errico
John D'Errico on 13 Feb 2015
Learn to use sparse. This is the kind of thing sparse does very well, AND it creates a sparse matrix, so the array will be stored efficiently when you start needing to solve bigger problems.
You can find my blktridiag on the File Exchange, which would actually do exactly what you need, at least in this specific case. Perhaps better might be to look at how it is coded, so you would learn to use sparse.
Or, if you wanted to solve this particular case simply and trivially, it could be done using spdiags, where you would pass it the three sets of diagonal elements. Again, one call to spdiags sill suffice, and the result will be a sparse matrix.
So for example, if a,b,c,d are row vectors, each of length n, lets see how you might build the result with one call to spdiags.
n = 4;
a = [1 2 3 4];
b = [5 6 7 8];
c = [1 3 5 7];
d = [2 4 6 8];
MATRIX = spdiags([0,b;[a,0]+[0,d];[c,0]]',[1 0 -1],5,5)
MATRIX =
(1,1) 1
(2,1) 1
(1,2) 5
(2,2) 4
(3,2) 3
(2,3) 6
(3,3) 7
(4,3) 5
(3,4) 7
(4,4) 10
(5,4) 7
(4,5) 8
(5,5) 8
full(MATRIX)
ans =
1 5 0 0 0
1 4 6 0 0
0 3 7 7 0
0 0 5 10 8
0 0 0 7 8
Finally, you can create this matrix simply enough using three calls to diag. Again, if you have ROW vectors of length n as a,b,c,d, then in one line, with no loops, we have:
MATRIX = diag([a,0] + [0,d]) + diag(b,1) + diag(c,-1);
MATRIX =
1 5 0 0 0
1 4 6 0 0
0 3 7 7 0
0 0 5 10 8
0 0 0 7 8
Again, see that the result is as expected, this time asa full matrix. That result from diag will be a full matrix, unless your vectors were stored in sparse form originally. In that case, the final matrix will also be sparse.
As I said, for more complicated problems, sparse itself is a trivial solution. Learn to use it, and your code will be the better for it. Best of all, no more need to throw in the towel.

More Answers (2)

Eduardo Márquez
Eduardo Márquez on 13 Feb 2015
Edited: Eduardo Márquez on 13 Feb 2015
Maybe this:
Matrixs = ones(2,2,4);
d = size(Matrixs);
final = zeros(d(1)*d(3) - (d(3)-1),d(2)*d(3) - (d(3)-1));
for k = 1:d(3)
final(1+((k-1)*(d(1)-1)):1+((k-1)*(d(1)-1))+d(1) - 1,1+((k-1)*(d(2)-1)):1+((k-1)*(d(2)-1))+d(2) -1)=Matrixs(:,:,k)+...
final(1+((k-1)*(d(1)-1)):1+((k-1)*(d(1)-1))+d(1) - 1,1+((k-1)*(d(2)-1)):1+((k-1)*(d(2)-1))+d(2) -1) %;
end
If change dims of Matrixs works, include if matrix are rectangular.
  2 Comments
Guillaume
Guillaume on 13 Feb 2015
Eduardo,
I would avoid writing clear all; close all; clc in answers. Leave my workspace, figures and command window alone. Your answer should work regardless of their state.

Sign in to comment.


RG_85
RG_85 on 16 Feb 2015
Thanks guys. I hear you John on the significance of spare matrices. I can see how this helps as the matrices get bigger since storing zeros is inefficient. However for a small problem like mine, its still nice to be able to see the matrices in full.

Categories

Find more on Operating on Diagonal Matrices in Help Center and File Exchange

Products

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!