两个张量的双点积

3
我有两个张量: A 是一个二阶张量,B 是一个四阶张量。 我知道当计算两个张量的双点积(:)时,结果张量的秩将降低两个,因此在我的例子中结果应该是一个二阶张量。
然而,当我在MATLAB中编写这段代码时,它会出现以下错误:

矩阵维度必须相同。

我该如何解决这个问题?

1
  1. 提供一些代码展示张量是如何表示以及你是如何进行乘法运算的。
  2. 通过双点积,你是否指的是MATLAB中的(:)运算符,比如A(:)
- Mohsen Nosratinia
你没有提供任何代码。我们怎么知道你做错了什么? - user85109
@ISarasky 你看了我的回答了吗? - Eitan T
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));

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


2
感谢Eitan的指导。 - ISara sky
1
哇,你是怎么把那个野兽向量化的?!干得好! - Cramer

2
很不幸,据我所知,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)。请注意矩阵点积部分。更简单的方法是使用:

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接