两个张量的双点积

时间:2013-07-04 13:39:19

标签: matlab linear-algebra

我有两个张量:A是二阶张量,B是四阶张量。我知道在计算两个张量的double dot product (:)时,得到的张量的等级将减少2,所以在我的例子中,结果应该是二阶张量。

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

  

矩阵尺寸必须达成一致。

我该如何解决这个问题?

2 个答案:

答案 0 :(得分:3)

MATLAB中的colon运算符不能满足您的期望,因为它提供了另一种功能。事实上,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));

其中AB是你的张量(多维矩阵)。矢量化这是一个难以破解的难题,所以我希望我的数学正确!

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

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语言的基础知识。

答案 1 :(得分: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的代码是matlab中dot函数的一个实现(参见https://www.mathworks.com/help/matlab/ref/dot.html)。请注意关于matricies的点积的部分。相反,你应该更简单地使用:

function C = double_dot(A,B)
    C = sum(dot(A,B));