我想计算y = a⊗a⊗a
,其中a
是n-by-1向量,⊗
是outer product operator。在这种情况下,y
应该是n-by-n-by-n张量。
如果y = a⊗a
,这很容易。我只是这样做:
y = a * a'
但是在第一种情况下该怎么办?如果有两个以上的向量,如何在MATLAB中有效地计算这个外积?
答案 0 :(得分:6)
在y = u⊗v
的多维(张量)情况下,我认为您需要移动第二个操作数的维度,如下所示:
v_t = permute(v, circshift(1:(ndims(u) + ndims(v)), [0, ndims(u)]));
然后将它们与bsxfun
:
y = bsxfun(@times, u, v_t);
常规矩阵乘法仅针对向量和二维矩阵定义,因此我们不能在一般情况下使用它。
另请注意,如果第二个操作数是1-D向量,则此计算仍然失败,因为ndims
对于向量返回2而不是1。为此,我们定义我们自己的计算维度的函数:
my_ndims = @(x)(isvector(x) + ~isvector(x) * ndims(x));
要完成答案,您可以定义一个新函数(例如。匿名函数),如下所示:
outprod = @(u, v)bsxfun(@times, u, permute(v, circshift(1:(my_ndims(u) + my_ndims(v)), [0, my_ndims(u)])));
然后根据需要多次使用它。例如,y = a×a×a
将按如下方式计算:
y = outprod(outprod(a, a), a);
当然,您可以编写一个更好的函数,它可以使用可变数量的参数来为您节省一些输入。这些方面的东西:
function y = outprod(u, varargin)
my_ndims = @(x)(isvector(x) + ~isvector(x) * ndims(x));
y = u;
for k = 1:numel(varargin)
v = varargin{k};
v_t = permute(v, circshift(1:(my_ndims(y) + my_ndims(v)),[0, my_ndims(y)]));
y = bsxfun(@times, y, v_t);
end
我希望我的数学合适!
答案 1 :(得分:3)
您也可以使用kron
功能:
kron(a * a', a)
或当需要四种外部(kronecker张量)产品时:
kron(kron(a * a', a), a)
等等。最后一个给出了 m x n 矩阵,其中m = n * n * n。
如果需要在产品上添加尺寸,您可以使用reshape
功能:
reshape(kron(a * a', a), [n, n, n])
或
reshape(kron(kron(a * a', a), a), [n, n, n, n])
等等。最后一个给你一个 n x n x n x n 张量。
答案 2 :(得分:2)
在a previous solution中使用kron
的问题在于它抛弃了外部产品的规范索引。
相反,ndgrid
非常适合这种情况:
a = [1; 2; 3];
b = [4; 5];
c = [6; 7; 8; 9];
[xx, yy, zz] = ndgrid(1:length(a), 1:length(b), 1:length(c));
% desired outerproduct
M = a(xx) .* b(yy) .* c(zz);
在纸面上,我们可以检查所需的解决方案M
是否为datacube:
M(:,:,1) = | M(:,:,2) = | M(:,:,3) = | M(:,:,4) =
| | |
24 30 | 28 35 | 32 40 | 36 45
48 60 | 56 70 | 64 80 | 72 90
72 90 | 84 105 | 96 120 | 108 135
使用Kronecker产品方法
M2 = reshape(kron(a * b', c), [length(a), length(b), length(c)]);
我们会得到:
M2(:,:,1) = | M2(:,:,2) = | M2(:,:,3) = | M2(:,:,4) =
| | |
24 36 | 64 84 | 30 45 | 80 105
28 48 | 72 96 | 35 60 | 90 120
32 56 | 72 108 | 40 70 | 90 135
Datacube M2
与M
具有相同的元素,但这些元素重新排列。这是因为kron(a * b', c)
在连续块中不包含M
的切片,以便于直接应用reshape
函数。要以这种方式计算外部产品,我们需要对kron(a * b', c)
的元素应用重新排列操作/函数(可确定,但是非常费时且耗时)。
使用ndgrid
的另一个好处是它可以轻松地推广到更高的订单。