Clear Filters
Clear Filters

Question about matrix manipulation

2 views (last 30 days)
Dear all,
So I have the following problem:
A = magic(9);
%% this is a 9x9 matrix, which can be divided into 9 3x3 matrices %%
%% I want the 3x3 matrices on the "main" diagonal to be the same %%
%% And I want to sum over the remaining matrices (by column) %%
%% So the end product should be six 3x3 matrices %%
B = zeros(6,9);
B(1:3,1:3) = A(1:3,1:3);
B(1:3,4:6) = A(4:6,4:6);
B(1:3,7:9) = A(7:9,7:9);
RS21 = A(4:6,1:3);
RS23 = A(4:6,7:9);
RS12 = A(1:3,4:6);
RS13 = A(1:3,7:9);
RS31 = A(7:9,1:3);
RS32 = A(7:9,4:6);
RS1 = RS21 + RS31;
RS2 = RS12 + RS32;
RS3 = RS13 + RS23;
B(4:6,1:3) = RS1;
B(4:6,4:6) = RS2;
B(4:6,7:9) = RS3;
%% If I did everything right the column totals should still be the same: %%
ACT = ones(1,9)*A;
BCT = ones(1,6)*B;
%% Which they are! Great %%
%% But now comes the catch. My matrix that I want to do this for is a 1435x1435 matrix, %%
%% With 41 countries and 31 industries. In that case, I the end result should be a 62x1435 matrix %%
%% Where I sum over all countries that are not on the "main" diagonal (I use "main" here as the actual %%
%% diagonal consists of elements, while in this case it consists of 41 35x35 matrices) %%
Are there any tricks in Matlab that I can use to get my desired result more easily? In my example it is quite easily tracktable since the matrix only has a few dimensions, but for my large matrix it takes a lot of work. I guess the permute and reshape commands should be useful but I don't know how to apply them in this particular case.
Thanks for any help!
  1 Comment
Rik
Rik on 20 Jan 2023
Indexing is your friend here. You numbered your variables with indices, so the only thing you need to do is to calculate the indices of A from the indices into RS. A nested loop and a cell array is probably all you need to get the basic structure.
Once you have working code you can start to worry about performance, but I don't think a loop will be particularly slow in this case.

Sign in to comment.

Accepted Answer

Matt J
Matt J on 20 Jan 2023
Edited: Matt J on 20 Jan 2023
Using this FEX download, it's fairly easy:
A=rand(1435);
sz=[35,35];
N=blkLength(A,sz);
B=blkReshape(A,sz,1,1,[]);
B(:,:,1:N+1:end)=0; %set diagonal blocks to zero
B=sum( blkReshape(B,sz,1,1,N,[]) ,3); %sum blocks
result=blkReshape(B,sz,1,1,[]); %final result
whos result
Name Size Bytes Class Attributes
result 35x35x41 401800 double
  1 Comment
Hylke Dijkstra
Hylke Dijkstra on 20 Jan 2023
A = rand(1435);
sz = [35,35];
N = blkLength(A,sz);
B = blkReshape(A,sz,1,1,[]);
B = B(:,:,1:N+1:end);
B = reshape(B,35,[]);
C = blkReshape(A,sz,1,1,[]);
C(:,:,1:N+1:end) = 0;
C = sum( blkReshape(C,sz,1,1,N,[]) ,3);
C = blkReshape(C,sz,1,1,[]);
C = reshape(C,35,[]);
result = [B; C];
So I modified your code a bit and I think this should be what I need. Perhaps you have an even easier way of doing it!
Thanks for your help so far.

Sign in to comment.

More Answers (0)

Products


Release

R2022b

Community Treasure Hunt

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

Start Hunting!