这是我在做项目时,给下一届接手的人写的一个关于Eigen库的快速上手手册,主要是针对于项目的应用来写的。当时使用Eigen库的目的是,将Matlab写的,LPCC和MFCC两种声音识别算法,十字形声阵列的MUSIC定位算法,和SVM分类器算法,转换成C++然后移植到到ARM处理器上(操作系统级上的并不是裸机)。而使用Eigen库的原因就是,其能够在编译时进一步优化,而且只需导入头文件即可进行调用,而不像其他的一些库需要安装那么麻烦。这篇使用说明是在2016年7月14日完成的。
由于我是第一次写这个博客,很多地方的图片我不知道怎么调整大小。原来的写的说明手册是在word上写的,已经上传到了优快云上。
下面就是关于Eigen矩阵库的使用说明。
准备工作
http://blog.youkuaiyun.com/augusdi/article/details/12907341
建议先把这个网页上的东西看完,边看边输入里面的程序来看,撑死3个小时就完成了
下面以这个快速指导手册为准来讲解:
http://eigen.tuxfamily.org/dox/group__QuickRefPage.html
一、Modules and Header files
#include <Eigen/Dense>
这里一般就包括了我们所需要的所有函数,如果还需要稀疏部分的话,那就使用
#include <Eigen/Eigen>
二、Array, matrix and vector types
1. Eigen提供了两种稠密矩阵:数学上的矩阵和向量,这两种通过使用模板Matrix类来实现;通常对于1维或者2维的数组通过模板Array类来实现。这两种类的不同点是主要在于API上:Array类提供了简单的数据操作的接口。而Matrix类提供了线性代数操作的接口。一般来说我们转算法只用Matrix好了,以后是不是需要优化这里先不管
两个类的定义
Matrix
Array
因为我们主要需要用的是Matrix类,这一类中有很多的成员函数,可以参考
http://eigen.tuxfamily.org/dox/classEigen_1_1Matrix.html
继续讲:
l Scalar是类型,可以使float, double, bool, int, std::complex<float>
l RowsAtCompileTime和ColsAtCompileTime是行数和列数,可以使动态的也可以是静态的
l Option是按列排列还是按行排列,默认是按列排列(这个参数就不用设了,这样就跟Matlab一样都是按列排列)。
2. 行数和列数是动态的还是静态的还是一个动态一个静态都随便,下面给几个例子:
这里,Dynamic表示动态的意思。
3. 在大多数的情况下,我们可以用简单的方式来定义Matrix变量(通过typedef)
这里需要注意一下,向量一般都是指的是列向量(数学里也差不多,没发现所有的书上都喜欢定义列向量,然后转置成行向量嘛 -_-)。
上面只是一部分的例子,下面我会列举一下比较常用的例子:
4. 矩阵和数组之间的转换:
1) array()的定义如下
就是将矩阵表示转换成数组表示
2) matrix()的定义如下
就是将数组表示转换成矩阵表示
5. Basicmatrix manipulation
下面每栏按照下图的格式(总共4栏)
1) 构造函数
默认情况下,系数是未初始化的。1D objects表示1维的数组或者向量。2D objects表示2维的矩阵(就是有行和列),数组其实也是可以有二维的,上面没有列出来(实际上对于我们来说也不需要)
2) 初始化
这里要使用<<这个重载的运算符来进行赋值,在准备工作里的也说过了。这里需要说明的是,前面讲过,矩阵是按列存储的,所以在内存中的存储形式应该是1,4,7,2,5,8,3,6,9.但是这并不意味着我们通过<<来进行赋值时,也要按照列来输入,具体为什么需要看一下<<的重载定义。而我们同样可以跟Matlab一样,通过m1(0),m1(1)……(注意下标要从0开始)来一个一个的取出元素,我们可以发现,确实是按照列来存储的。具体的可以见http://eigen.tuxfamily.org/dox/group__TopicStorageOrders.html
3) 初始化
这里,Identity是单位矩阵的意思。
4) Runtimeinfo
这里,rows()和cols()是获取矩阵的行数和列数,size()是获取矩阵的大小(也就是有多少个数据)。
l innerSize()的定义如下
就是说,
向量的话(这里用的是ve