矩阵库Eigen的MatrixXd中预定义的类型

[size=large]在使用Eigen编程时,到处是Curiously recurring template pattern,那么,我们如何知道一个矩阵中存的是double型变量还是float型的变量呢?
有人会说, MatrixXd中存的就是double型变量MatrixXf中存的是float型变量啊![/size]

我是无耻的插队者:不了解Curiously recurring template pattern的可以看我之前的文章:[url]http://cherishlc.iteye.com/blog/1994276[/url]

[size=large]可是,如果一个泛型函数是如下定义的,我们如何知道X中存的是什么类型的变量呢?[/size]
template <typename Derived> void cov(const MatrixBase<Derived>& X){}


[size=large]先说一下这样写的[color=red]好处[/color]:
[list]
[*]1、通用性强,X既可以是[color=blue]MatrixXd[/color]类型的,也可以是MatrixXf类型的,甚至是矩阵的一个[color=blue]子块[/color]m1.block(0,0,10,10)的 或者[color=blue]表达式[/color] m1+m2 (假设m1,m2为MatrixXd类型的)
[*]2、速度快(表达式类型不用先进行运算,存为Matrix了)
[/list]

但是,事物都有其两面性。。。
[color=red]问题[/color]来了:如果再写函数的过程中,我们需要声明一个临时变量,与X中存储的元素类型相同,该如何声明?
答案很简单,Eigen在MatrixBase类(事实上是近乎所有类)中为我们定义了这些类型,
[color=red]类型列表[/color]如下:
[list]
[*][color=blue]Scalar[/color]: 矩阵中存储的类型
[*][color=blue]Index[/color]: 矩阵下标的类型,貌似为unsigned int型的
[*][color=blue]PlainObject[/color]: 表达式对应的矩阵类型, 比如m1+m2对应的PlainObject为 m1的类型,即decltype(m1)
[/list]

[color=red]使用[/color]的时候,用如下语句可以声明一个变量s:[/size]
typename Derived::Scalar s;


[size=large]好了,最后来膜拜一下PlainObject的定义:[/size]
typedef Matrix<typename internal::traits<Derived>::Scalar, internal::traits<Derived>::RowsAtCompileTime, internal::traits<Derived>::ColsAtCompileTime, AutoAlign | (internal::traits<Derived>::Flags&RowMajorBit ? RowMajor : ColMajor), internal::traits<Derived>::MaxRowsAtCompileTime, internal::traits<Derived>::MaxColsAtCompileTime > PlainObject


[size=large]还有些简单的:[/size]
typedef typename internal::traits<Derived>::Index Index;
typedef typename internal::traits<Derived>::Scalar Scalar;
typedef typename NumTraits<Scalar>::Real RealScalar;


[size=large]可能有些人还会有疑问,为何是[color=blue]internal::traits<Derived>::Scalar[/color] 而不是Derived::Scalar(事实上我们用的时候可以这么用,但是在写Eigen库的过程中不行)!!原因是在编写Eigen库的过程中,类型相互引用,会产生类型未定义的问题(大致如此,描述可能不准确),这样的问题,我们作为库的使用者是不会遇到的
摘录Eigen官方文档如下:[/size]
[quote]Let us now explain the internal::traits here. The internal::scalar_sum_op class takes one template parameter: the type of the numbers to handle. Here of course we want to pass the scalar type (a.k.a. numeric type) of VectorXf, which is float. How do we determine which is the scalar type of Derived ? Throughout Eigen, all matrix and expression types define a typedef Scalar which gives its scalar type. For example, VectorXf::Scalar is a typedef for float. So here, if life was easy, we could find the numeric type of Derived as just

typename Derived::Scalar
Unfortunately, we can't do that here, as the compiler would complain that the type Derived hasn't yet been defined. So we use a workaround: in src/Core/util/ForwardDeclarations.h, we declared (not defined!) all our subclasses, like Matrix, and we also declared the following class template:

template<typename T> struct internal::traits;
In src/Core/Matrix.h, right before the definition of class Matrix, we define a partial specialization of internal::traits for T=Matrix<any template parameters>. In this specialization of internal::traits, we define the Scalar typedef. So when we actually define Matrix, it is legal to refer to "typename internal::traits\<Matrix\>::Scalar".[/quote]


[color=blue][size=large]Matrix类官方文档:[/size][/color]
[url]http://eigen.tuxfamily.org/dox/classEigen_1_1Matrix.html[/url]

[color=blue][size=large]MatrixBase类官方文档:[/size][/color]
[url]http://eigen.tuxfamily.org/dox/classEigen_1_1MatrixBase.html#ac33495a0e3788e5951670c392b44d9ad[/url]

[color=blue][size=large]编写Eigen的泛型函数:[/size][/color]
[url]http://eigen.tuxfamily.org/dox/TopicFunctionTakingEigenTypes.html[/url]

[color=blue][size=large]关于internal::traits的,这篇对理解Eigen架构很有帮助:[/size][/color]
[url]http://eigen.tuxfamily.org/dox/TopicInsideEigenExample.html[/url]
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值