How to create N+1 dimensional array by taking exterior product of 1st dimension of two N dimensional arrays?

6 Ansichten (letzte 30 Tage)
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.

Akzeptierte Antwort

Bruno Luong
Bruno Luong am 7 Dez. 2020
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 Kommentare
Bruno Luong
Bruno Luong am 7 Dez. 2020
I believe James's answer deserves the acceptation. My contribution is next to nothing.
Mark Stone
Mark Stone am 7 Dez. 2020
@Bruno Luong Perhaps you built on the answer by @James Tursa, but your answer fulfills my criteria, and his, evren after editing does not. Thanks to you both,.

Melden Sie sich an, um zu kommentieren.

Weitere Antworten (1)

James Tursa
James Tursa am 7 Dez. 2020
Bearbeitet: James Tursa am 7 Dez. 2020
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 Kommentare
Mark Stone
Mark Stone am 7 Dez. 2020
Yes, the edit by @James Tursa does fix the transposition issue, but I believe does still rely on implicit expansion, and therefore does not handle my situation. The answer by @Bruno Luong does not use implicit expansion and meets my needs. Thansk to you botj.
James Tursa
James Tursa am 7 Dez. 2020
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.

Melden Sie sich an, um zu kommentieren.

Kategorien

Mehr zu Linear Algebra 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