如何在C ++中将本征张量与另一个本征张量的标量和相乘?

时间:2018-09-18 18:17:19

标签: c++ tensorflow eigen blas tensor

我正在使用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))

1 个答案:

答案 0 :(得分:1)

根据this exchange,您应该可以通过分配减少的结果来强制执行评估:

Eigen::Tensor<float, 0> vSum = v.sum();

这应该适合您的线路:

ans = u * u.constant(vSum);

其原因是,如果尝试直接使用constant调用模板方法v.sum(),它将尝试使用声明的返回类型为Scalar,这是行不通的。 Eigen使用了很多复杂的,本质上是不透明的类型,以最大程度地减少不必要的计算和复制,但同时也进行了大量的模板处理,因此在这种情况下显式地强制进行类型转换并不少见。