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

6 visualizzazioni (ultimi 30 giorni)
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.

Risposta accettata

Bruno Luong
Bruno Luong il 7 Dic 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 Commenti
Mark Stone
Mark Stone il 7 Dic 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,.

Accedi per commentare.

Più risposte (1)

James Tursa
James Tursa il 7 Dic 2020
Modificato: James Tursa il 7 Dic 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 Commenti
Mark Stone
Mark Stone il 7 Dic 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 il 7 Dic 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.

Accedi per commentare.

Categorie

Scopri di più su Linear Algebra 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!

Translated by