MATLAB Answers

Outer product of two rectangular matrices

383 ビュー (過去 30 日間)
Dario Cortese
Dario Cortese 2019 年 2 月 19 日
編集済み: Jan 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
Matt J 2019 年 2 月 19 日
編集済み: Matt J 2019 年 2 月 19 日
outer = r(:)*r(:).'

Jan
Jan 2019 年 2 月 19 日
編集済み: 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