How to perform tensor summation without using "for" loop
4 vues (au cours des 30 derniers jours)
Afficher commentaires plus anciens
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 commentaires
Réponse acceptée
Guillaume
le 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 commentaires
Guillaume
le 15 Jan 2019
Modifié(e) : Guillaume
le 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.
Plus de réponses (0)
Voir également
Catégories
En savoir plus sur Loops and Conditional Statements dans Help Center et File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!