Eigen 中的表达式模板
Expression templates in Eigen
我想了解表达式模板在 Eigen 中的工作原理。
我知道两个动态双向量的总和是由这样的东西执行的:
CwiseBinaryOp< internal::scalar_sum_op<double>, VectorXd const, VectorXd const > operator+(VectorXd const & lhs, VectorXd const & rhs);
我也明白了两个向量的差值是如何实现的
我有两个问题。
1.向量与标量的乘积如何计算?
我注意到
CwiseBinaryOp< internal::scalar_product_op<double>, VectorXd const, VectorXd const >
存在,但我感觉它只是设计用于在两个向量之间执行分量运算。这是否意味着向量与标量的乘积对应于一元运算符,比如
CwiseUnaryOp< internal::scalar_product_op<double>, VectorXd const, VectorXd const > ?
2。模板表达式可以从混合运算中构建吗?
例如,在像
这样的表达式中
x = u + (2*v + (v-w))
这些操作真的是这样嵌套执行的吗?
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 &);
或重载
VectorXd & operator=(E4 const &);
它评估从前面的步骤构建的树,别名如下:
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 >;
1.向量与标量的乘积如何计算?
在 Eigen 3.2 中,它被实现为一个一元运算符,一个函子存储标量因子的值。在 Eigen 3.3 中,它现在被实现为给定矩阵表达式和常量表达式之间的二元运算符,类似于:
CwiseBinaryOp<scalar_product_op<double,double>,
VectorXd,
CwiseNullaryOp<scalar_constant_op<double>, VectorXd> >
这种方法可以清楚地区分 s*vec
和 vec*s
,return 类型,例如 vec*s
等同于 [=15] =].
2。模板表达式可以从混合运算中构建吗?
您的理解是正确的:首先创建表达式 E1 到 E4,然后计算从重载 operator=
开始,生成如下代码:
for(i=0;i<x.size();++i)
x[i] = E4.coeff(i);
我想了解表达式模板在 Eigen 中的工作原理。 我知道两个动态双向量的总和是由这样的东西执行的:
CwiseBinaryOp< internal::scalar_sum_op<double>, VectorXd const, VectorXd const > operator+(VectorXd const & lhs, VectorXd const & rhs);
我也明白了两个向量的差值是如何实现的
我有两个问题。
1.向量与标量的乘积如何计算?
我注意到
CwiseBinaryOp< internal::scalar_product_op<double>, VectorXd const, VectorXd const >
存在,但我感觉它只是设计用于在两个向量之间执行分量运算。这是否意味着向量与标量的乘积对应于一元运算符,比如
CwiseUnaryOp< internal::scalar_product_op<double>, VectorXd const, VectorXd const > ?
2。模板表达式可以从混合运算中构建吗?
例如,在像
这样的表达式中x = u + (2*v + (v-w))
这些操作真的是这样嵌套执行的吗?
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 &);
或重载
VectorXd & operator=(E4 const &);
它评估从前面的步骤构建的树,别名如下:
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 >;
1.向量与标量的乘积如何计算?
在 Eigen 3.2 中,它被实现为一个一元运算符,一个函子存储标量因子的值。在 Eigen 3.3 中,它现在被实现为给定矩阵表达式和常量表达式之间的二元运算符,类似于:
CwiseBinaryOp<scalar_product_op<double,double>,
VectorXd,
CwiseNullaryOp<scalar_constant_op<double>, VectorXd> >
这种方法可以清楚地区分 s*vec
和 vec*s
,return 类型,例如 vec*s
等同于 [=15] =].
2。模板表达式可以从混合运算中构建吗?
您的理解是正确的:首先创建表达式 E1 到 E4,然后计算从重载 operator=
开始,生成如下代码:
for(i=0;i<x.size();++i)
x[i] = E4.coeff(i);