Matrix multiplication with three level loops
이전 댓글 표시
Hi everybody,
I have a problem with multiplying following two matrices. In first matrix (A), which is 62x2108 I have some coefficients in first row and columns 1:34 for country #1, all other column elements in 1st row are zeros, then in second row and column 35:68 for country #2, elsewhere in 2nd row are zeros etc. In matrix EXP, which is 2108x62 I have data for exports from 62 countries and 34 industries in rows, to 62 countries in columns. I would like to multiply matrix A as such with matrix EXP but with all entries equal to zero except the one corresponding to industry let's say k (for each country, this implies repetition of 34 multiplications). The result should be a matrix of size 2108x62.
My code is following, but I just can't get to include the third level of loop, which is that multiplication for each industry, zeros for all other industries.
B=zeros(2108,62);
help=zeros(34);
for i=1:62
for j=1:62
for k=1:34
B(((i-1)*34+1):(i*34),j)=A(i,((j-1)*34+1):(j*34))*((help(k,k)==1)*EXP(((i-1)*34+1):(i*34),j));
end
end
end
If enyone has an idea, let me know.
Best,
Miroslav
댓글 수: 2
It would help if you could produce a condensed example, with numbers, of what you want to obtain.
However, as I hinted in your previous question I'm not sure the way you're storing your data is a good idea. My feeling is that a better storage format would make all your calculations much easier.
Miroslav Josic
2017년 2월 8일
답변 (1개)
Guillaume
2017년 2월 8일
You do have a choice about the storage, it was your choice to rearrange your A matrix with all these 0.
The problem is at the moment you're conflating countries and industries in the same dimension (columns in A, rows in B), which makes it a lot more difficult to manipulate. If you separate this into different dimensions, it makes it all easier.
So, let's have A as a ncountries x nindustries matrix:
%to get there with your original 1x2108 vector:
%A = reshape(A, 34, 62)'
%example with 3 countries x 4 industries
A = [1 2 3 4
5 6 7 8
9 10 11 12];
Similarly, your EXP matrix should be an ncountries x nindustries x ncountries 3D matrix
EXP = [10 20 30
11 21 31
12 22 32
13 23 33
14 24 34
15 25 35
16 26 36
17 27 37
18 28 38
19 29 39
20 30 40
21 31 41]; %the not so useful (ncountries x nindustries) x ncountries matrix
EXP = permute(reshape(EXP, 4, 3, 3), [2 1 3]) %much more useful 3D matrix
Then to get the result you want, it's simply
M = A .* EXP %in R2016b, prior to that: M = bsxfun(@times, A, EXP)
댓글 수: 5
Miroslav Josic
2017년 2월 10일
편집: Miroslav Josic
2017년 2월 10일
Guillaume
2017년 2월 10일
If the M matrix is really the one you written above, then I don't understand the logic. If it is, using valid matlab notation:
M=[[1 2 3 4]*[10 0 0 0]' [1 2 3 4]*[20 0 0 0]' [1 2 3 4]*[30 0 0 0]'
[1 2 3 4]*[0 11 0 0]' [1 2 3 4]*[0 21 0 0]' [1 2 3 4]*[0 31 0 0]'
[1 2 3 4]*[0 0 12 0]' [1 2 3 4]*[0 0 22 0]' [1 2 3 4]*[0 0 32 0]'
[1 2 3 4]*[0 0 0 13]' [1 2 3 4]*[0 0 0 23]' [1 2 3 4]*[0 0 0 33]'
[5 6 7 8]*[14 0 0 0]' [5 6 7 8]*[24 0 0 0]' [5 6 7 8]*[34 0 0 0]'
[5 6 7 8]*[0 15 0 0]' [5 6 7 8]*[0 25 0 0]' [5 6 7 8]*[0 35 0 0]'
[5 6 7 8]*[0 0 16 0]' [5 6 7 8]*[0 0 26 0]' [5 6 7 8]*[0 0 36 0]'
[5 6 7 8]*[0 0 0 17]' [5 6 7 8]*[0 0 0 27]' [5 6 7 8]*[0 0 0 37]'
[9 10 11 12]*[18 0 0 0]' [9 10 11 12]*[28 0 0 0]' [9 10 11 12]*[38 0 0 0]'
[9 10 11 12]*[0 19 0 0]' [9 10 11 12]*[0 29 0 0]' [9 10 11 12]*[0 39 0 0]'
[9 10 11 12]*[0 0 20 0]' [9 10 11 12]*[0 0 30 0]' [9 10 11 12]*[0 0 40 0]'
[9 10 11 12]*[0 0 0 21]' [9 10 11 12]*[0 0 0 31]' [9 10 11 12]*[0 0 0 41]'];
instead (that is rows 5-8 are [5 6 7 8]*... and rows 9-12 are [9 10 11 12]*...), then the code I've given does exactly what you want:
A=[1 2 3 4
5 6 7 8
9 10 11 12];
EXP = [10 20 30
11 21 31
12 22 32
13 23 33
14 24 34
15 25 35
16 26 36
17 27 37
18 28 38
19 29 39
20 30 40
21 31 41];
EXP = permute(reshape(EXP, 4, 3, 3), [2 1 3]); %4 industries x 3 countries x 3 countries
M2 = EXP .* A; %bsxfun(@times, EXP, A) prior to R2016b
The rows of M2 correspond to countries, the columns to industries, and the pages to the countries again. You can reshape / permute M2 to a form that makes it easier for you to visualise, maybe:
permute(M2, [2 3 1])
looks more similar to your M, or even
reshape(permute(M2, [2 1 3]), [], 3)
which I would not recommend since once again, you're mixing countries and industries in the rows but it does contain the exact same values as your M:
>>isequal(M, reshape(permute(M2, [2 1 3]), [], 3))
ans =
1
Miroslav Josic
2017년 2월 17일
편집: Miroslav Josic
2017년 2월 17일
Guillaume
2017년 2월 20일
I'm very confused. As shown above, the code gives the exact answer you asked for.
Please, give examples with numbers so I can actually test code. With your value example, it looks like a reshape or permute is not right. But as I said, I don't think this form of M is useful as it uses rows to store two orthogonal concepts.
Miroslav Josic
2017년 2월 20일
카테고리
도움말 센터 및 File Exchange에서 Matrices and Arrays에 대해 자세히 알아보기
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!