如何在matlab中一次取两个以上矩阵的外积?

Posted

技术标签:

【中文标题】如何在matlab中一次取两个以上矩阵的外积?【英文标题】:How to take outer product of more than two matrices in one shot, in matlab? 【发布时间】:2012-12-30 15:00:05 【问题描述】:

我想计算y = a⊗a⊗a,其中a 是一个n×1 向量, 是outer product operator。在这种情况下,y 应该是一个 n×n×n 张量。

如果y = a⊗a,那就简单了。我只是这样做:

y = a * a' 

但是在第一种情况下该怎么办?如果有两个以上的向量,我如何在 MATLAB 中有效地计算这个外积?

【问题讨论】:

我不明白你想计算什么。是y = a x a x a吗?如果是这样,当其中一个操作数是矩阵时,外积是如何定义的? 是的,我想计算 y = a x a x a。或者更高阶的,例如 y = a x a x a x a x a。 【参考方案1】:

y = u⊗v 的多维(张量)情况下,我认为您需要像这样移动第二个操作数的维度:

v_t = permute(v, circshift(1:(ndims(u) + ndims(v)), [0, ndims(u)]));

然后将它们与bsxfun相乘:

y = bsxfun(@times, u, v_t);

正则矩阵乘法只针对向量和二维矩阵定义,所以我们不能在一般情况下使用它。

另外请注意,如果第二个操作数是一维向量,此计算仍然会失败,因为 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 = varargink;
        v_t = permute(v, circshift(1:(my_ndims(y) + my_ndims(v)),[0, my_ndims(y)]));
        y = bsxfun(@times, y, v_t);
    end

我希望我算对了!

【讨论】:

【参考方案2】:

您也可以使用kron 函数:

kron(a * a', a)

或者当需要四个外(克罗内克张量)产品时:

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 张量。

【讨论】:

【参考方案3】:

在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 是数据立方体:

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

使用克罗内克乘积法

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 的另一个优点是它很容易泛化到更高阶。

【讨论】:

以上是关于如何在matlab中一次取两个以上矩阵的外积?的主要内容,如果未能解决你的问题,请参考以下文章

数理知识向量数乘,内积,外积,matlab代码实现

2D 数组每列的外积形成 3D 数组 - NumPy

如何用Mathmatica求矩阵外积?

为什么两个numpy (n,)向量的矩阵@乘积是点积,而不是外积?

R语言中两个数组(或向量)的外积怎样计算

计算任意维度数组的外积