3

假设c是一个 d 维向量。我想计算以下三阶张量 在此处输入图像描述

其中e_i代表i欧几里得空间的第 th 个标准基。有没有一种有效的方法来计算这个?我正在使用以下 for 循环和 Kruskal-tensor使用Sandia National Labs 管理的张量工具箱ktensor来计算它:

x=ktensor({c,c,c});
I=eye(d);

for i=1:d
    x=x+2*c(i)*ktensor({I(:,i),I(:,i),I(:,i)}
end

for i=1:d
    for j=1:d

         x=x- c(i)*c(j)*(ktensor({I(:,i),I(:,i),I(:,j)})+ktensor({I(:,i),I(:,j),I(:,i)})+ktensor({I(:,i),I(:,j),I(:,j)}))


    end
end
4

2 回答 2

2

这是一种可能性。

  • 我对第二项使用了优化,因为它c沿着张量的“对角线”放置 的值。
  • 对于第一项,优化空间不大,因为它是密集乘法,所以bsxfun看起来很合适。
  • 对于第三项,我坚持使用bsxfun,但由于结果有些稀疏,如果矩阵的大小很大,您可能会受益于“手动”填充它。

这是代码:

dim = 10;
c = [1:dim]';
e = eye(dim);

x = zeros([dim, dim, dim]);
% initialize with second term
x(1:dim*(dim+1)+1:end) = 2 * c;
% add first term
x = x + bsxfun(@times, bsxfun(@times, c, shiftdim(c, -1)), shiftdim(c, -2));
% add third term
x = x - sum(sum(bsxfun(@times, shiftdim(c*c',-3), ...
   bsxfun(@times, bsxfun(@times, permute(e, [1, 3, 4, 2, 5]), permute(e, [3, 1, 4, 2, 5])), permute(e, [3, 4, 1, 5, 2])) +...
   bsxfun(@times, bsxfun(@times, permute(e, [1, 3, 4, 2, 5]), permute(e, [3, 1, 4, 5, 2])), permute(e, [3, 4, 1, 2, 5])) +...
   bsxfun(@times, bsxfun(@times, permute(e, [1, 3, 4, 5, 2]), permute(e, [3, 1, 4, 2, 5])), permute(e, [3, 4, 1, 2, 5]))), 5), 4);

编辑

第三项的更有效(尤其是内存)计算:

ec = bsxfun(@times, e, c);
x  = x - ...
  bsxfun(@times, ec, shiftdim(c, -2)) -...
  bsxfun(@times, c', reshape(ec, [dim, 1, dim])) -....
  bsxfun(@times, c, reshape(ec, [1, dim, dim]));
于 2017-06-29T19:08:30.360 回答
0

您可以尝试并行计算工具箱,即parfor循环。

x=ktensor({c,c,c});
I=eye(d);

y = zeros(d,d,d, d);
parfor i=1:d
    y(:,:,:, i) = 2*c(i)*ktensor({I(:,i),I(:,i),I(:,i)};
end
x = x + sum(y, 4);

z = zeros(d,d,d, d,d);
parfor i=1:d
    for j=1:d % only one layer of parallelization is allowed
         z(:,:,:, i,j) = c(i)*c(j)*(ktensor({I(:,i),I(:,i),I(:,j)})+ktensor({I(:,i),I(:,j),I(:,i)})+ktensor({I(:,i),I(:,j),I(:,j)}));
    end
end
x = x - sum(sum(z, 5), 4);
x % is your result

它只是在单独的线程中运行未触及的ktensor命令,因此工具箱负责并行运行代码。

由于每次迭代的独立性,例如c_{i+1, j+1}不依赖c_{i, j},这是可能的。

根据系统的核心(和超线程)数量,可能会有高达 #-of-cores-times 的加速。

于 2017-06-29T20:17:36.607 回答