使用Eigen3的Tensor和TensorSymmetry计算所有差分矢量对

问题描述 投票:0回答:1

我有一个Nx3张量C。 N在编译时未知(正在从用户提供的数据文件中读取N个3坐标)。我想创建一个NxNx3张量(称为D),并具有所有坐标的矢量差。因此,D的元素看起来像D(i, j) = C(i) - C(j)。尽管签署了这些差异,但我只需要它们朝一个方向发展(不要紧,只要保持一致即可)。我正在寻找一种方法,仅评估唯一元素,而不必编写双重for循环。我找到的关于Eigen TensorSymmetry模块的文档并未完全清楚如何执行此操作,甚至无法做到。值得一说的是,我能够使用以下方法为一维写一个numpy式的差异差:

Eigen::array<int, 2> flip({1,0});
Eigen::array<int, 2> bc({1,N});
d = c.broadcast(bc) - c.broadcast(bc).shuffle(flip);

这里c是等级1的N长度张量,d是等级2的NxN尺寸张量。

我已经尝试对NxNx3张量进行各种排列,以排列或扩展Nx3输入数据,但似乎找不到合适的东西。我现在正在使用的表达式是:

Eigen::array<int, 3> expand({N, N, 3});
Eigen::array<int, 3> trans({1,0,2});
Tensor<double, 2> C(N, 3);
Tensor<double, 3> D(N, N, 3);

// fill up C from file-object like thing foo not relevant to this problem
for (auto i = 0; i < N; i++)
  for (auto j = 0; j < 3; j++)
    C(i, j) = foo.getCoords()[j];

D = C.broadcast(expand) - C.broadcast(expand).shuffle(trans);

上面的内容会编译,但是会产生明显错误的结果(甚至没有预期的尺寸,这是奇怪的...)。我尝试了扩展选项的各种排列,例如expand({N,3,1})expand({1,N,3}),以及trans,但显然这里缺少一些内容;尚无任何工作。

如上所述,我也看不到如何或是否可以利用D的反对称性来避免一些多余的减法。

任何建议将不胜感激。

c++ eigen tensor eigen3
1个回答
0
投票

我对自己的问题的解决方案有些不尽人意,是编写了一个for循环。这没有利用任何对称性,也没有进行延迟评估,但确实提供了预期的结果。

Eigen::array<int, 2> bcChip({N, 3});
for (auto i = 0; i < N; i++){
  D.chip(i, 0) = C - C.chip(i, 0).eval().broadcast(bcChip);
}

[请注意,如果有人能够使用Eigen Tensor的功能提供更好的/更好的实现,我会接受他们的回答。

© www.soinside.com 2019 - 2024. All rights reserved.