Eigen中的表达模板

Ale*_*eph 6 eigen eigen3

我想了解表达模板在Eigen中是如何工作的.我明白两个动态双向量的总和是由看起来像这样的东西执行的:

CwiseBinaryOp< internal::scalar_sum_op<double>, VectorXd const, VectorXd const > operator+(VectorXd const & lhs, VectorXd const & rhs);
Run Code Online (Sandbox Code Playgroud)

我也理解了如何实现两个向量的差异.

我有两个问题.

1.标量的矢量乘积如何工作?

我注意到

CwiseBinaryOp< internal::scalar_product_op<double>, VectorXd const, VectorXd const > 
Run Code Online (Sandbox Code Playgroud)

但我觉得它只是为了在两个向量之间执行分量运算而设计的.这是否意味着标量向量的乘积对应于一元运算符

CwiseUnaryOp< internal::scalar_product_op<double>, VectorXd const, VectorXd const > ?
Run Code Online (Sandbox Code Playgroud)

2.模板表达式可以通过混合操作构建吗?

例如,在表达式中

x = u + (2*v + (v-w))
Run Code Online (Sandbox Code Playgroud)

这些操作是否以这样的嵌套方式执行?

  • v-w 导致构建E1实例
  • 2*v 导致构建E2的实例
  • 2*v + (v-w) 导致构建E3实例
  • u + (2*v + (u-w)) 导致构建E4实例
  • x = u + (2*v + (v-w)) 电话

构造函数

VectorXd(E4 const &);
Run Code Online (Sandbox Code Playgroud)

或超载

VectorXd & operator=(E4 const &);
Run Code Online (Sandbox Code Playgroud)

它使用以下别名评估从前面的步骤构建的树:

using diff = internal::scalar_difference_op<double>;
using prod = internal::scalar_product_op<double>;
using sum = internal::scalar_sum_op<double>;

using E1 = CwiseBinaryOp< diff, VectorXd const, VectorXd const >;
using E2 = CwiseUnaryOp< prod, VectorXd const >;
using E3 = CwiseBinaryOp< sum, E1 const, E2 const >;
Run Code Online (Sandbox Code Playgroud)

gga*_*ael 6

1.标量的矢量乘积如何工作?

在Eigen 3.2中,它实现为一元运算符,带有存储标量因子值的函子.在Eigen 3.3中,它现在被实现为给定矩阵表达式和常量表达式之间的二元运算符,如:

CwiseBinaryOp<scalar_product_op<double,double>,
              VectorXd,
              CwiseNullaryOp<scalar_constant_op<double>, VectorXd> >
Run Code Online (Sandbox Code Playgroud)

该方法允许清楚地区分s*vec和vec*s,并且返回类型例如vec*s等同于其中之一vec*VectorxD::Constant(vec.size(),s).

2.模板表达式可以通过混合操作构建吗?

您的理解是正确的:首先创建表达式E1到E4,然后评估从重载operator=生成代码开始,如:

for(i=0;i<x.size();++i)
  x[i] = E4.coeff(i);
Run Code Online (Sandbox Code Playgroud)