How to perform tensor summation without using "for" loop
10 次查看(过去 30 天)
显示 更早的评论
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 个评论
采纳的回答
Guillaume
2019-1-14
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 个评论
Guillaume
2019-1-15
编辑:Guillaume
2019-1-15
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.
更多回答(0 个)
另请参阅
类别
在 Help Center 和 File Exchange 中查找有关 Loops and Conditional Statements 的更多信息
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!