我正在使用C ++中Eigen库的Tensor方面,想计算一个Eigen Tensor的按元素乘积乘以第二个Eigen Tensor中元素的标量总和。像这样:
['Date', 'Index']
但是不支持*运算符。
README建议使用与Tensor对象关联的#include <Eigen/Dense>
Eigen::Tensor<float,2>u(5,5);
Eigen::Tensor<float,2>v(5,5);
u.setConstant(1.f);
v.setConstant(2.f);
Eigen::Tensor<float,2>ans(5,5);
ans = u*v.sum();
方法。而
.constant()
正确编译并运行
ans = u*u.constant(5.);
auto ans2 = u.sum();
没有。
ans = u*u.constant(v.sum());
从进一步的阅读看来,这是因为error: no matching function for call to ‘Eigen::Tensor<float, 2>::constant(const Eigen::TensorReductionOp<Eigen::internal::SumReducer<float>, const Eigen::DimensionList<long int, 2ul>, const Eigen::Tensor<float, 2>, Eigen::MakePointer>)’
ans = u*u.constant(v.sum());
^
希望将标量值传递给它,而u.constant()
返回一个“未求值的表达式”(请参见张量运算和C ++ README中的“自动” )。进一步建议可以使用v.sum()
来强制对v.sum()
进行评估,尽管这似乎返回了另一种“未评估的表达式”类型,尽管在末尾标记了.eval()
。 / p>
ForcedEvalOp
README的TODO部分提到:
“ 标量值的表示形式: 标量值通常由大小为1且秩为1的张量表示。改为使用秩为0的张量会更合乎逻辑,并且对用户更友好。例如Tensor :: maximum()当前返回一个Tensor。同样,2个1d张量(通过收缩)的内积返回1d张量。将来,这些操作可能会更新为返回0d张量。”
这暗示error: no matching function for call to ‘Eigen::Tensor<float, 2>::constant(const Eigen::TensorForcedEvalOp<const Eigen::TensorReductionOp<Eigen::internal::SumReducer<float>, const Eigen::DimensionList<long int, 2ul>, const Eigen::Tensor<float, 2>, Eigen::MakePointer> >)’
ans = u*u.constant(v.sum().eval());
^
应该返回长度为1的秩1张量。但是通常用于索引的v.sum()
运算符似乎无法以可用的形式访问()
的值和:
u.constant()
也无法编译。
ans = u*u.constant(v.sum()(0))
error: no match for call to ‘(const Eigen::TensorReductionOp<Eigen::internal::SumReducer<float>, const Eigen::DimensionList<long int, 2ul>, const Eigen::Tensor<float, 2>, Eigen::MakePointer>) (int)’
ans = u*u.constant(v.sum()(0));
^
。
ans = u*u.constant(v.sum().eval()(0))
答案 0 :(得分:1)
根据this exchange,您应该可以通过分配减少的结果来强制执行评估:
Eigen::Tensor<float, 0> vSum = v.sum();
这应该适合您的线路:
ans = u * u.constant(vSum);
其原因是,如果尝试直接使用constant
调用模板方法v.sum()
,它将尝试使用声明的返回类型为Scalar
,这是行不通的。 Eigen使用了很多复杂的,本质上是不透明的类型,以最大程度地减少不必要的计算和复制,但同时也进行了大量的模板处理,因此在这种情况下显式地强制进行类型转换并不少见。