How to perform tensor summation without using "for" loop

6 Ansichten (letzte 30 Tage)
Davoud
Davoud am 14 Jan. 2019
Bearbeitet: Guillaume am 15 Jan. 2019
Hi. I have a matrix A with n*4 dimentions, I want to sum each element of the first row with all the elements of the 2nd row to obtain a matrix B with 4.^2 elements and then, to sum each element of the 3rd row of matrix A with all the elements of matrix B to obtain a matrix C with 4.^3 elements. The process should continue until we have a matrix with 4.^n elements. I want to do this without for loop to increase the speed.
For example A=[1 2 3 4; 5 6 7 8; 9 10 11 12]
then B is:
B=[6 7 8 9; 7 8 9 10; 8 9 10 11; 9 10 11 12]
and C=C_0' is:
C_0=[15 16 17 18 16 17 18 19 17 18 19 20 18 19 20 21; 16 17 18 19 17 18 19 20 18 19 20 21 19 20 21 22; 17 18 19 20 18 19 20 21 19 20 21 22 20 21 22 23; 18 19 20 21 19 20 21 22 20 21 22 23 21 22 23 24]
Thank you in advance

Akzeptierte Antwort

Guillaume
Guillaume am 14 Jan. 2019
A = [1 2 3 4; 5 6 7 8; 9 10 11 12];
rows = num2cell(A, 2); %split A, keeping columns together
[rows{:}] = ndgrid(rows{:}); %calculate cartesian product of all the rows
result = reshape(sum(cat(numel(rows) + 1, rows{:}), numel(rows) + 1), [], size(A, 2))' %sum the cartesian product and reshape into desired output format
Note that the above iterates over the elements of row1, then row2, ... then rown. If you want the reverse, then change the second line to:
[rows{:}] = ndgrid(rows{end:-1:1});
Your example is ambiguous in that respect.
  2 Kommentare
Davoud
Davoud am 15 Jan. 2019
Thank you for your answer. I have checked the result of your code with that of a code written using "for" loops for
A = [0.1 0.2 0.4 0.6; 1 2 3 4; 0.4 0.6 0.8 1; 10 11 12 13]
It seems the results are not the same. The "for" loop code is :
B=zeros(4,4);
for i=1:4
B(i,1:4)=A(1,i)+A(2,:);
end
B=reshape(B, [],1);
C=zeros(4,16);
for i=1:4
C(i,1:16)=A(3,i)+B(1:16,1);
end
C=reshape(C, [],1);
D=zeros(4,64);
for i=1:4
D(i,1:64)=A(4,i)+C(1:64,1);
end
D
Would you please modify your code.
Thank you
Guillaume
Guillaume am 15 Jan. 2019
Bearbeitet: Guillaume am 15 Jan. 2019
It seems the results are not the same
That's because the order of iteration in your loop approah is not very logical. In your result,
D(1, 1) = A(1, 1) + A(2, 1) + A(3, 1) + A(4, 1)
D(1, 2) = A(1, 1) + A(2, 1) + A(3, 2) + A(4, 1) %notice that you're iterating over row 3 first
D(1, 3) = A(1, 1) + A(2, 1) + A(3, 3) + A(4, 1)
D(1, 4) = A(1, 1) + A(2, 1) + A(3, 4) + A(4, 1)
D(1, 5) = A(1, 2) + A(2, 1) + A(3, 1) + A(4, 1) %then over row 1
D(1, 6) = A(1, 2) + A(2, 1) + A(3, 2) + A(4, 1)
...
D(1, 17) = A(1, 1) + A(2, 2) + A(3, 1) + A(4, 1) %then over row 2
...
So the iteration order in your loop is row 3, 1, 2, 4. As I said, the iteration order in my solution is 1, 2, 3, 4 (with [rows{:}] = ndgrid(rows{:});) or 4, 3, 2, 1 (with [rows{:}] = ndgrid(rows{end:-1:1});) which is a lot more logical, and easily extends to inputs with more rows.
If you're bent on using that illogical order, then
[rows{:}] = ndgrid(rows{[3, 1, 2, 4]});
will give you the same output. However, the code is no longer generic so you'll have to decide what order you want to use for matrices with more rows.

Melden Sie sich an, um zu kommentieren.

Weitere Antworten (0)

Kategorien

Mehr zu Loops and Conditional Statements finden Sie in Help Center und File Exchange

Community Treasure Hunt

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

Start Hunting!

Translated by