How to create N+1 dimensional array by taking exterior product of 1st dimension of two N dimensional arrays?
8 ビュー (過去 30 日間)
古いコメントを表示
I would like to efficiently create an N+1 dimensional array C, whose first 2 dimensions are the exterior product of the 1st dimension of the N dimensional arrays A and B. The exterior product of m by 1 column vectors x and y is the m by m matrix x*y'.
As an example, given the 2 by 3 by 5 arrays A and B, I would like to create the 2 by 2 by 3 by 5 array C such that C(i,j,k,l) = A(i,k,l)*B(j,k,l).
For efficiency pruposes, I would like to do this without for loops, to the extent possible (I know how to do this with slow, ugly, brute force for loops). Given that I will apply this to YALMIP sdpvar arrays, implicit expansion can't be used. The following (non-exhaustive list) can be used in any combination:
reshape
repmat
vec'ing (i.e., A(:))
.*
kron
bsxfun (if needed)
Thanks.
0 件のコメント
採用された回答
Bruno Luong
2020 年 12 月 7 日
Solution without expansion as requested
sizeA = size(A);
reshapeB = reshape(B,[1 size(B)]);
reshapeA = reshape(A,[sizeA(1) 1 sizeA(2:end)]);
rA = ones(size(size(A))); rA(2)=size(B,1);
rB = ones(size(size(B))); rB(1)=size(A,1);
C = repmat(reshapeA,rA) .* repmat(reshapeB,rB) ;
4 件のコメント
Bruno Luong
2020 年 12 月 7 日
I believe James's answer deserves the acceptation. My contribution is next to nothing.
その他の回答 (1 件)
James Tursa
2020 年 12 月 7 日
編集済み: James Tursa
2020 年 12 月 7 日
Maybe try this:
sizeB = size(B);
reshapeA = reshape(A,[1 size(A)]);
reshapeB = reshape(B,[sizeB(1) 1 sizeB(2:end)]);
C = reshapeA .* reshapeB; % would do this if implicit expansion works for your case
C = bsxfun(@times,reshapeA,reshapeB); % try this if implicit expansion doesn't work for your case
Or you can swap where the 1's go in A and B if you want the 2D transpose in those first two dimensions.
EDIT
Corrected last lines above to use reshapeA and reshapeB.
Also my comment about the 1's was intended to steer you towards this solution if it was more appropriate:
sizeA = size(A);
reshapeA = reshape(A,[sizeA(1) 1 sizeA(2:end)]);
reshapeB = reshape(B,[1 size(B)]);
etc.
7 件のコメント
James Tursa
2020 年 12 月 7 日
Sorry I apparently misunderstood. But according to your post, using bsxfun was acceptable so that is what I gave you with this line, which doesn't use implicit expansion:
C = bsxfun(@times,reshapeA,reshapeB);
However, as long as you have a solution that works for you from Bruno, all is good.
参考
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!