How to perform tensor summation without using "for" loop
4 visualizzazioni (ultimi 30 giorni)
Mostra commenti meno recenti
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
0 Commenti
Risposta accettata
Guillaume
il 14 Gen 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 Commenti
Guillaume
il 15 Gen 2019
Modificato: Guillaume
il 15 Gen 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.
Più risposte (0)
Vedere anche
Categorie
Scopri di più su Loops and Conditional Statements in Help Center e File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!