我有一个二维特征数组,其中数组中的每一项都是一个三元素特征向量(例如,表面上的速度场)。
我想将2D数组的每个元素与一个3元素的特征向量相乘,有效地取点积。
Eigen::Array<Eigen::Vector3d, Eigen::Dynamic, Eigen::Dynamic> velField(5, 5);
Eigen::Vector3d n;
// ... initialisation of n and velField not shown
Eigen::Array<double, Eigen::Dynamic, Eigen::Dynamic> result(5, 5);
result = n.transpose() * velField;
如果你混合了不同的数字类型,会产生编译错误。但是,如果我不分配结果,而只是计算它:
n.transpose() * velField;
它编译。什么是"结果"的正确返回类型-或者我如何解决这个问题?
编辑
同样的问题可以在这个更简单的情况下观察到(乘以一个double):
Eigen::Array<Eigen::Vector3d, Eigen::Dynamic, Eigen::Dynamic> velField(5, 5);
// ... initialisation of velField not shown
Eigen::Array<Eigen::Vector3d, Eigen::Dynamic, Eigen::Dynamic> result(5, 5);
result = 3.0 * velField;
然而,当使用std::complex<double>
而不是Eigen::Vector3d
时,相同的代码可以工作:
Eigen::Array<std::complex<double>, Eigen::Dynamic, Eigen::Dynamic> velField(5, 5);
// ... initialisation of velField not shown
Eigen::Array<std::complex<double>, Eigen::Dynamic, Eigen::Dynamic> result(5, 5);
result = 3.0 * velField;
我想知道为什么它适用于std::complex
而不是Eigen::Vector3d
。这两种类型都用double
定义操作符*
。
经过进一步的阅读,我找到了答案:
根据矩阵类的参考文档,第一个模板参数_Scalar
为:
_Scalar: matrix_tparam_scalar Numeric type, e.g. float, double, int or std::complex<float>.
User defined sclar types are supported as well.
链接到本页。它列出了"自定义标量类型"的需求。在上面的示例中,缺少<Vector3d>
对应的Eigen::NumTraits
。它不能在Vector3d
中正确实现,所以应该只在Eigen::Matrix
/Eigen::Array
中存储表示标量的类型。
更新:
没有赋值n.transpose() * velField;
的行因为延迟求值而工作。当这样做时(在c++ 11中):
auto result = n.transpose() * velField;
但是此时它没有做任何计算(检查调试器中result
的类型)。一旦您使用result
,它将以与第一个示例相同的方式失败。
不允许。我建议将velField存储为矩阵,即3D向量的1D数组,然后使用标准线性代数运算符。