Combining individual matrices diagonally into bigger matrix with overlapping elements added
6 views (last 30 days)
Show older comments
![](https://www.mathworks.com/matlabcentral/answers/uploaded_files/147133/image.jpeg)
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!
1 Comment
Accepted Answer
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.
0 Comments
More Answers (2)
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
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.
Eduardo Márquez
on 13 Feb 2015
Thanks for watching, sorry, it is customary. I'll take it into consideration from now.
See Also
Categories
Find more on Loops and Conditional Statements 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!