【发布时间】:2019-02-22 20:06:19
【问题描述】:
我在 C++ 中使用 Eigen 库的张量方面,并希望计算一个本征张量乘以第二个本征张量中元素的标量和的逐元素乘积。比如:
#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();
但是这种方式不支持 * 运算符。
README 建议使用与张量对象关联的.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() 期望将一个标量值传递给它,而v.sum() 返回一个“非求值表达式”(参见 张量运算和 C++“自动” 在README)。还有进一步的建议,可以使用.eval() 强制对v.sum() 进行评估,尽管这似乎返回了另一个“未评估的表达式”类型,尽管最后标记了ForcedEvalOp。
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());
^
README 的 TODO 部分提到:
"标量值的表示: 标量值通常由大小为 1 且等级为 1 的张量表示。使用等级为 0 的张量会更合乎逻辑且用户友好。例如 Tensor::maximum() 当前返回一个张量。类似地,2 个一维张量的内积(通过收缩)返回一个一维张量。将来这些操作可能会更新为返回 0d 张量。”
这意味着v.sum() 应该返回一个长度为 1 的等级 1 张量。但通常用于索引的 () 运算符似乎无法以可用的形式访问其值 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))
.
error: no match for call to ‘(const Eigen::TensorForcedEvalOp<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().eval()(0));
【问题讨论】:
标签: c++ tensorflow eigen blas tensor