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 件のコメント

Rik
Rik 2023 年 1 月 20 日
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.

サインインしてコメントする。

 採用された回答

Matt J
Matt J 2023 年 1 月 20 日
編集済み: Matt J 2023 年 1 月 20 日

0 投票

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 件のコメント

Hylke Dijkstra
Hylke Dijkstra 2023 年 1 月 20 日
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.

サインインしてコメントする。

その他の回答 (0 件)

カテゴリ

ヘルプ センター および File Exchange で Operating on Diagonal Matrices についてさらに検索

製品

リリース

R2022b

Community Treasure Hunt

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

Start Hunting!

Translated by