3

我有两个张量:A一个是二阶张量,B一个是四阶张量。我知道在计算两个张量的双点积 (:)时,结果张量的秩会减少 2,所以在我的示例中,结果应该是二阶张量。

但是,当我在 MATLAB 中编写此代码时,会出现以下错误:

矩阵尺寸必须一致。

我怎么解决这个问题?

4

2 回答 2

3

MATLAB 中的冒号运算符没有达到您的预期,因为它提供了另一个功能。事实上,MATLAB 中没有内置的双内积实现。您需要自己实现它,例如:

idx = max(0, ndims(A) - 1); %// Index of first common dimension
B_t = permute(B, circshift(1:ndims(A) + ndims(B), [0, idx - 1]));
double_dot_prod = squeeze(sum(squeeze(sum(bsxfun(@times, A, B_t), idx)), idx));

您的张量在哪里(A即多维矩阵)。向量化这是一个难以破解的难题,所以我希望我的数学是正确的!B

如果您愿意,可以将此代码放在一个函数中以方便使用。为了良好的实践,还要验证两个张量都是二阶或更高的。这是一个友好的复制粘贴版本:

function C = double_dot(A, B)
    assert(~isvector(A) && ~isvector(B))
    idx = max(0, ndims(A) - 1);
    B_t = permute(B, circshift(1:ndims(A) + ndims(B), [0, idx - 1]));
    C = squeeze(sum(squeeze(sum(bsxfun(@times, A, B_t), idx)), idx));

忠告:我建议您阅读在线教程以熟悉 MATLAB 语言的基础知识。

于 2013-07-08T12:25:16.830 回答
1

这是非常不幸的,但据我所知,MATLAB 并没有在他们的标准库中实现张量的内积。要生成内积的标量版本,您需要低效地遍历每个条目,例如:

function C = double_dot(A,B)
    for i=1:1:3
        for j=1:1:3
            C = C + A(i,j)*B(i,j);
        end
    end

或者,您可以对 Eitan 的矢量化代码(上图)稍加修改。他的代码产生一个向量。两个张量的内积应该是一个标量。因此,您需要对他的代码生成的最终数组求和。

function C = double_dot(A, B)
    assert(~isvector(A) && ~isvector(B))
    idx = max(0, ndims(A) - 1);
    B_t = permute(B, circshift(1:ndims(A) + ndims(B), [0, idx - 1]));
    C = sum(squeeze(sum(squeeze(sum(bsxfun(@times, A, B_t), idx)), idx)));

Eitan 的代码是该dot函数在 matlab 中的实现(参见https://www.mathworks.com/help/matlab/ref/dot.html)。请注意关于矩阵点积的部分。相反,您应该更简单地使用:

function C = double_dot(A,B)
    C = sum(dot(A,B));
于 2017-06-07T14:33:20.173 回答