# Outer product of two rectangular matrices

383 ビュー (過去 30 日間)
Dario Cortese 2019 年 2 月 19 日

If I have a vector r , I can easily calculate its inner product
r=[1 2 3];
inner = r*r'
inner =
14
Same goes for the outer product (please see here for complete definition)
outer=r'*r
outer =
1 2 3
2 4 6
3 6 9
outer, as it should be, has components (where N is the total number of components, here 3). inner, on the other hand has components (where m is the number of rows, here 1).
I want to be able to do this standard thing to rectangular matrices too. The inner product of rectangular matrices is easy enough:
r =
1 2 3
1 1 1
inner=r*r'
inner =
14 6
6 3
inner has components (2x2=4) and this is what I expect from the matrix multiplication of r with its transponse.
Clearly, though, it is not clear how I should calculate the outer product of r with itself, because now the definition of "inner product with transponse" and "outer product with itself" have the same syntax in matlab. Indeed, if I try to repeat what I have done for the vector r, I obtain:
outer=r'*r
outer =
2 3 4
3 5 7
4 7 10
which is not the outer product of r with itself, as it's evident from the fact that it does not have =36, but only components (where n is the number of column). What matlab has interpreted my calculation to be is the inner product of r transponse and r.
How do I obtain the proper outer product, whose components are all the combinations of products between components of r?

サインインしてコメントする。

### 回答 (2 件)

Matt J 2019 年 2 月 19 日

outer = r(:)*r(:).'
##### 0 件のコメント表示非表示 -1 件の古いコメント

サインインしてコメントする。

Jan 2019 年 2 月 19 日

If you have a [N x M] array and a [R x S x T] array, the output product becomes [N x M x R x S x T]. This can be done with nested for loops:
function C = OuterProduct(A, B) % version 1
sizeA = size(A);
sizeB = size(B);
C = zeros([sizeA, sizeB]);
if ndims(A) == 2 && ndims(B) == 2
for b2 = 1:sizeB(2)
for b1 = 1:sizeB(1)
for a2 = 1:sizeA(2)
for a1 = 1:sizeA(1)
C(a1, a2, b1, b2) = A(a1, a2) * B(b1, b2);
end
end
end
end
else
error('Not implemented yet.');
end
end
Is this correct so far? This is a primitive approach and it can be improved with respect to run-time. But this is a proof of concept yet. Now an improvement:
function C = OuterProduct(A, B) % version 2
sizeA = size(A);
sizeB = size(B);
C = zeros([sizeA, sizeB]);
if ndims(A) == 2 && ndims(B) == 2
for b2 = 1:sizeB(2)
for b1 = 1:sizeB(1)
%for a2 = 1:sizeA(2)
% for a1 = 1:sizeA(1)
C(:, :, b1, b2) = A * B(b1, b2);
% end
%end
end
end
else
error('Not implemented yet.');
end
end
A general solution is still ugly:
function C = OuterProduct(A, B) % version 3
C = zeros([size(A), size(B)]);
q = ndims(A) + 1;
index = cell(1, q);
index(1:q-1) = {':'}; % A cell as index vector of dynamic length
for k = 1:numel(B)
index{q} = k; % Linear index for elements of B
C(index{:}) = A * B(k);
end
end
Nicer and faster with bsxfun or the modern automatic expanding and the elementwise product:
function C = OuterProduct(A, B) % version 4
C = A .* reshape(B, [ones(1, ndims(A)), size(B)]);
% Matlab < R2016b:
% C = bsxfun(@times, A, reshape(B, [ones(1, ndims(A)), size(B)]))
end
Note: There is no reason to reshape A also:
AA = reshape(A, [size(A), ones(1, ndims(B))])
size(A)
size(AA) % Has still the same size!
Trailing dimensions of length 1 are ignored in Matlab.
Alternatively (see Matt J's solution):
function C = OuterProduct(A, B) % version 5
C = reshape(A(:) * B(:).', [size(A), size(B)]);
end
I love Matlab for the last two versions.

サインインしてコメントする。

R2018b

### Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by