【问题标题】:Getting the N-dimensional product of vectors获取向量的 N 维乘积
【发布时间】:2013-07-19 03:38:21
【问题描述】:

我正在尝试编写代码来获得向量的“N 维积”。因此,例如,如果我有 2 个长度为 L、x 和 y 的向量,那么“二维乘积”就是正则向量乘积,R=x*y',因此 R、R(i, j) 是 x 的第 i 个元素和 y 的第 j 个元素的乘积,即 R(i,j)=x(i)*y(j)。

问题是如何在 matlab 中针对任意维度优雅地概括这一点。这是我有 3 个向量 x,y,z,我想要 3 维数组 R,使得 R(i,j,k)=x(i)*y(j)*z(k)。

对于 4 个向量 x1,x2,x3,x4 也是如此:R(i1,i2,i3,i4)=x1(i1)*x2(i2)*x3(i3)*x4(i4) 等。 ..

另外,我事先不知道维度的数量。代码必须能够处理任意数量的输入向量,输入向量的数量对应于最终答案的维度。

是否有任何简单的 matlab 技巧可以做到这一点并避免专门检查 R 的每个元素?

谢谢!

【问题讨论】:

  • 啊,我现在看到您关于不知道维数的编辑。我会更新我的答案。

标签: matlab nested-loops matrix-multiplication discrete-mathematics


【解决方案1】:

内置函数bsxfun 是一个快速实用程序,应该能够提供帮助。它被设计为在每个元素的基础上为两个尺寸不匹配的输入执行 2 个输入功能。 Singletons维度被扩展,非singleton维度需要匹配。 (这听起来令人困惑,但一旦发现它在很多方面都很有用。)

据我了解您的问题,您可以调整每个向量的维度形状以定义它应该被定义的维度。然后使用嵌套的bsxfun 调用来执行乘法。

示例代码如下:

%Some inputs, N-by-1 vectors
x = [1; 3; 9];
y = [1; 2; 4];
z = [1; 5];

%The computation you describe, using nested BSXFUN calls
bsxfun(@times, bsxfun(@times, ...  %Nested BSX fun calls, 1 per dimension
    x, ...                         %    First argument, in dimension 1
    permute(y,2:-1:1) ) , ...      %    Second argument, permuited to dimension 2
    permute(z,3:-1:1) )            %    Third argument, permuted to dimension 3

%Result
% ans(:,:,1) =
%      1     2     4
%      3     6    12
%      9    18    36
% ans(:,:,2) =
%      5    10    20
%     15    30    60
%     45    90   180

要处理任意数量的维度,可以使用递归或循环构造对其进行扩展。循环看起来像这样:

allInputs = {[1; 3; 9], [1; 2; 4], [1; 5]};

accumulatedResult = allInputs {1};
for ix = 2:length(allInputs)
    accumulatedResult = bsxfun(@times, ...
        accumulatedResult, ...
        permute(allInputs{ix},ix:-1:1));
end

【讨论】:

  • 谢谢你的追求。这很有帮助,但还不是全部。我事先不知道维度的数量(它是一个参数),那么我该如何修改这个代码为任意N维度?
  • 查看循环实现的编辑。这让我想起了一个类似(但有点离题)的问题:stackoverflow.com/a/9337114/931379
【解决方案2】:

我认为“正则向量积”是指外积。

无论如何,您都可以使用ndgrid 函数。比起使用bsxfun,我更喜欢它,因为它更简单。

% make some vectors
w = 1:10;
x = w+1;
y = x+1;
z = y+1;

vecs = {w,x,y,z};

nvecs = length(vecs);

[grids{1:nvecs}] = ndgrid(vecs{:});

R = grids{1};
for i=2:nvecs
    R = R .* grids{i};
end;

% Check results
for i=1:10
    for j=1:10
        for k=1:10
            for l=1:10
                V(i,j,k,l) = R(i,j,k,l) == w(i)*x(j)*y(k)*z(l);
            end;
        end;
    end;
end;

all(V(:))

    ans = 1

【讨论】:

  • 嗨奈杰尔。谢谢!我实际上事先不知道尺寸(只是编辑了问题)。
  • 我编辑了一个更通用的版本。只要您有一个带有向量的元胞数组,它就可以工作。
猜你喜欢
  • 1970-01-01
  • 2017-03-11
  • 1970-01-01
  • 2013-07-19
  • 2016-01-09
  • 2022-08-17
  • 2021-06-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多