打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
矩阵库Eigen的MatrixXd中预定义的类型
在使用Eigen编程时,到处是Curiously recurring template pattern,那么,我们如何知道一个矩阵中存的是double型变量还是float型的变量呢?
有人会说, MatrixXd中存的就是double型变量MatrixXf中存的是float型变量啊!


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

可是,如果一个泛型函数是如下定义的,我们如何知道X中存的是什么类型的变量呢?
C++代码  
  1. template <typename Derived> void cov(const MatrixBase<Derived>& X){}  


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


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


使用的时候,用如下语句可以声明一个变量s:

C++代码  
  1. typename Derived::Scalar s;  


好了,最后来膜拜一下PlainObject的定义:
C++代码  
  1. 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  


还有些简单的:
C++代码  
  1. typedef typename internal::traits<Derived>::Index Index;  
  2. typedef typename internal::traits<Derived>::Scalar Scalar;  
  3. typedef typename NumTraits<Scalar>::Real RealScalar;  


可能有些人还会有疑问,为何是internal::traits<Derived>::Scalar  而不是Derived::Scalar(事实上我们用的时候可以这么用,但是在写Eigen库的过程中不行)!!原因是在编写Eigen库的过程中,类型相互引用,会产生类型未定义的问题(大致如此,描述可能不准确),这样的问题,我们作为库的使用者是不会遇到的
摘录Eigen官方文档如下:

引用
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".




Matrix类官方文档:
http://eigen.tuxfamily.org/dox/classEigen_1_1Matrix.html

MatrixBase类官方文档:
http://eigen.tuxfamily.org/dox/classEigen_1_1MatrixBase.html#ac33495a0e3788e5951670c392b44d9ad

编写Eigen的泛型函数:
http://eigen.tuxfamily.org/dox/TopicFunctionTakingEigenTypes.html

关于internal::traits的,这篇对理解Eigen架构很有帮助:
http://eigen.tuxfamily.org/dox/TopicInsideEigenExample.html
     
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
Kalman滤波器的C++实现
eigen测试程序
Eigen教程7
vins_mono-预积分代码实现详解
VINS-Mono阅读先导篇
Writing Maintainable SIMD Intrinsics Using C++ Templates
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服