c++矩阵运算库Eigen简介
C++矩阵运算库Eigen介绍
C++中的矩阵运算库常用的有Armadillo,Eigen,OpenCV,ViennaCL,PETSc等。我自己在网上搜了一下不同运算库的特点,最后选择了Eigen。主要原因是Eigen体积较小,不用安装也不用编译,库是以头文件的形式给出,直接将它扔到我们自己的工程文件中即可,移植起来也无压力。我们可以在Eigen官网下载源文件。
Eigen的HelloWorld
我这里使用的Eigen的版本为Eigen 3.3.3,源文件目录如下:
可以直接用记事本打开INSTALL文件,里面有编译和不编译时分别怎么使用。我这里使用的方法是不对文件进行编译。
- 找个地方新建一个工程目录,这里我在桌面上新建一个MatrixTest文件夹。
- 将Eigen目录中的Eigen文件夹拷贝到我们的MatrixTest目录中。
- 在MatrixTest中再建立一个main.cpp文件写入如下代码:
#include <iostream>
#include "Eigen\Core"//import most common Eigen types
using namespace Eigen;int main(int,char*[])
{Matrix3f m3;m3<<1,2,3,4,5,6,7,8,9;Matrix4f m4 = Matrix4f::Identity();Vector4i v4(1,2,3,4);std::cout<<"m3\n"<<m3<<"\nm4:\n"<<m4<<"\nv4:\n"<<v4<<std::endl;
}
- 在MatrixTest目录的地址栏中输入cmd,然后用
g++ main.cpp
对文件进行编译,再运行命令a
。可以看到我们已经输出了我们的矩阵了。
Eigen常规矩阵定义
Eigen的使用在官网上有详细的介绍,这里对我学习过程中用到的基本操作进行介绍。首先是矩阵的定义。
在矩阵类的模板参数共有6个。一般情况下我们只需要关注前三个参数即可。前三个模板参数如下所示:
Matrix<typename Scalar,int RowsAtCompileTime,int ColsAtCompileTime>
- Scalar参数为矩阵元素的类型,该参数可以是int,float,double等。
- RowsAtCompileTime和ColsAtCompileTime是矩阵的行数和列数。
如Matrix<float,4,4> M44
是定义一个4×4的矩阵,矩阵元素以float类型存储。直接使用矩阵模板定义一个矩阵往往会觉得麻烦,Eigen提供了一些基本矩阵的别名定义,如typedef Matrix<float,4,4> Matrix4f
.下面是一些内置的别名定义.来源于官方手册:
typedef Matrix< std::complex<double> , 2 , 2 > Matrix2cd
typedef Matrix< std::complex<float> , 2 , 2 > Matrix2cf
typedef Matrix< double , 2 , 2 > Matrix2d
typedef Matrix< float , 2 , 2 > Matrix2f
typedef Matrix< int , 2 , 2 > Matrix2i
typedef Matrix< std::complex<double> , 3 , 3 > Matrix3cd
typedef Matrix< std::complex<float> , 3 , 3 > Matrix3cf
typedef Matrix< double , 3 , 3 > Matrix3d
typedef Matrix< float , 3 , 3 > Matrix3f
typedef Matrix< int , 3 , 3 > Matrix3i
typedef Matrix< std::complex<double> , 4 , 4 > Matrix4cd
typedef Matrix< std::complex<float> , 4 , 4 > Matrix4cf
typedef Matrix< double , 4 , 4 > Matrix4d
typedef Matrix< float , 4 , 4 > Matrix4f
typedef Matrix< int , 4 , 4 > Matrix4i
typedef Matrix< std::complex<double> , Dynamic , Dynamic > MatrixXcd
typedef Matrix< std::complex<float> , Dynamic , Dynamic > MatrixXcf
typedef Matrix< double , Dynamic , Dynamic > MatrixXd
typedef Matrix< float , Dynamic , Dynamic > MatrixXf
typedef Matrix< int , Dynamic , Dynamic > MatrixXi
typedef Matrix< std::complex<double> , 1, 2 > RowVector2cd
typedef Matrix< std::complex<float> , 1, 2 > RowVector2cf
typedef Matrix< double , 1, 2 > RowVector2d
typedef Matrix< float , 1, 2 > RowVector2f
typedef Matrix< int , 1, 2 > RowVector2i
typedef Matrix< std::complex<double> , 1, 3 > RowVector3cd
typedef Matrix< std::complex<float> , 1, 3 > RowVector3cf
typedef Matrix< double , 1, 3 > RowVector3d
typedef Matrix< float , 1, 3 > RowVector3f
typedef Matrix< int , 1, 3 > RowVector3i
typedef Matrix< std::complex<double> , 1, 4 > RowVector4cd
typedef Matrix< std::complex<float> , 1, 4 > RowVector4cf
typedef Matrix< double , 1, 4 > RowVector4d
typedef Matrix< float , 1, 4 > RowVector4f
typedef Matrix< int , 1, 4 > RowVector4i
typedef Matrix< std::complex<double> , 1, Dynamic > RowVectorXcd
typedef Matrix< std::complex<float> , 1, Dynamic > RowVectorXcf
typedef Matrix< double , 1, Dynamic > RowVectorXd
typedef Matrix< float , 1, Dynamic > RowVectorXf
typedef Matrix< int , 1, Dynamic > RowVectorXi
typedef Matrix< std::complex<double> , 2 , 1> Vector2cd
typedef Matrix< std::complex<float> , 2 , 1> Vector2cf
typedef Matrix< double , 2 , 1> Vector2d
typedef Matrix< float , 2 , 1> Vector2f
typedef Matrix< int , 2 , 1> Vector2i
typedef Matrix< std::complex<double> , 3 , 1> Vector3cd
typedef Matrix< std::complex<float> , 3 , 1> Vector3cf
typedef Matrix< double , 3 , 1> Vector3d
typedef Matrix< float , 3 , 1> Vector3f
typedef Matrix< int , 3 , 1> Vector3i
typedef Matrix< std::complex<double> , 4 , 1> Vector4cd
typedef Matrix< std::complex<float> , 4 , 1> Vector4cf
typedef Matrix< double , 4 , 1> Vector4d
typedef Matrix< float , 4 , 1> Vector4f
typedef Matrix< int , 4 , 1> Vector4i
typedef Matrix< std::complex<double> , Dynamic , 1> VectorXcd
typedef Matrix< std::complex<float> , Dynamic , 1> VectorXcf
typedef Matrix< double , Dynamic , 1> VectorXd
typedef Matrix< float , Dynamic , 1> VectorXf
typedef Matrix< int , Dynamic , 1> VectorXi
2 向量
向量被作为一种特殊的矩阵进行处理,即要么行为一要么列为一。除非显式的说明为行向量,否则这里将向量默认为列向量。请看下面两个别名定义:
typedef Matrix<float,3,1> Vector3f;
typedef Matrix<int,1,2> RowVector2i;
3 矩阵的动态空间分配
很多时候在程序的编译阶段也许我们并不知道矩阵具体的行列数,这时候使用动态控件分配就显得很必要了。当我们给矩阵模板中参数RowsAtCompileTime或者ColsAtCompileTime参数指定为Dynamic时,表示该矩阵对应行或列为一个动态分配的值。下面是两个动态矩阵的别名定义:
typedef Matrix<double,Dynamic,Dynamic> MatrixXd;
typedef Matrix<int,Dynamic,1> VectorXi;
4 矩阵的构建
经过上面的介绍以后,我们应该能定义一些基本的矩阵了。如:
Matrix3f a; //定义一个float类型3×3固定矩阵a
MatrixXf b; //定义一个float类型动态矩阵b(0×0)
Matrix<int,Dynamic,3> b; //定义一个int类型动态矩阵(0×3)
对应动态矩阵,我们也可以在构造的时候给出矩阵所占用的空间,比如:
MatrixXf a(10,15); //定义float类型10×15动态矩阵
VectorXf b(30); //定义float类型30×1动态矩阵(列向量)
为了保持一致性,我们也可以使用上面构造函数的形式定义一个固定的矩阵,即Matrix3f a(3,3)
也是允许的。
上面矩阵在构造的过程中并没有初始化,Eigen还为一些小的(列)向量提供了可以初始化的构造函数。如:
Vector2d a(5.0,6.0);
Vector3d b(5.0,6.0,7.0);
Vector4d c(5.0,6.0,7.0,8.0);
5 矩阵元素的访问
Eigen提供了矩阵元素的访问形式和matlab中矩阵的访问形式非常相似,最大的不同是matlab中元素从1开始,而Eigen的矩阵中元素是从0开始访问。对于矩阵,第一个参数为行索引,第二个参数为列索引。而对于向量只需要给出一个索引即可。
#include <iostream>
#include "Eigen\Core"//import most common Eigen types
using namespace Eigen;int main()
{MatrixXd m(2,2);m(0,0) = 3;m(1,0) = 2.5;m(0,1) = -1;m(1,1) = m(1,0) + m(0,1);std::cout<<"Hear is the matrix m:\n"<<m<<std::endl;VectorXd v(2);v(0) = 4;v(1) = v(0) - 1;std::cout<<"Here is the vector v:\n"<<v<<std::endl;
}
输出结果如下:
Hear is the matrix m:3 -1
2.5 1.5
Here is the vector v:
4
3
像m(index)
这种访问形式并不仅限于向量之中,对于矩阵也可以这样访问。这一点和matlab相同,我们知道在matlab中定义一个矩阵a(3,4),如果我访问a(5)相当于访问a(2,2),这是因为在matlab中矩阵是按列存储的。这里比较灵活,默认矩阵元素也是按列存储的,但是我们也可以通过矩阵模板构造参数Options=RowMajor改变存储方式(这个参数是我们还没有提到的矩阵构造参数的第4个参数)。
6 一般初始化方法
对于矩阵的初始化,我们可以采用下面的方法方便且直观的进行:
Matrix3f m;
m<<1,2,3,4,5,6,7,8,9;
std:cout<<m;
7 矩阵的大小
Eigen提供了rows()
,cols()
,size()
方法来获取矩阵的大小,同时也同了resize()
方法从新改变动态数组的大小。
#include <iostream>
#include "Eigen\Core"using namespace Eigen;int main()
{MatrixXd m(2,5);m<<1,2,3,4,5,6,7,8,9,10;m.resize(4,3);std::cout<<"The matrix m is:\n"<<m<<std::endl;std::cout<<"The matrix m is of size "<<m.rows()<<"x"<<m.cols()<<std::endl;std::cout<<"It has "<<m.size()<<" coefficients"<<std::endl;VectorXd v(2);v<<1,2;v.resize(5);std::cout<<"The vector v is:\n"<<v<<std::endl;std::cout<<"The vector v is of size "<<v.size()<<std::endl;std::cout<<"As a matrix,v is of size "<<v.rows()<<"x"<<v.cols()<<std::endl;
}
输出结果如下:
The matrix m is:1 3 56 8 102 4 9.58787e-3157 9 1.17493e-309
The matrix m is of size 4x3
It has 12 coefficients
The vector v is:12
1.17477e-3097.0868e-3040
The vector v is of size 5
As a matrix,v is of size 5x1
可以看到我们可以把矩阵任意的resize,但是resize后矩阵的元素会改变,如果resize后的矩阵比之前的大会出现一些未初始化的元素。如果被resize的矩阵按列存储(默认),那么resize命令和matlab中的reshape执行结果相同,只是matlab要求reshape的矩阵前后元素必须相同,也就是不允许resize后不能出现未初始化的元素。
对于固定大小的矩阵虽然也支持resize命令,但是resize后的大小只能是它本身的大小,否则就会报错。因为resize前后如果矩阵大小一样,就不会执行resize。如果我们不想在resize后改变矩阵的对应元素,那么可以使用conservativeResize()
方法。对应上面程序中的m矩阵我们调用m.conservativeResize(4,3)
后得到结果如下。其中因为行数增加了,增加的行会以未初始化的形式出现。
The matrix m is:1 2 36 7 8
9.58787e-315 2.122e-314 1.52909e+2490 0 2.47039e+249
http://eigen.tuxfamily.org/dox/group__TutorialMatrixClass.html
8 赋值和大小变换
在Eigen中使用=可以直接将一个矩阵复制给另外一个矩阵,如果被复制的和赋值矩阵大小不一致,会自动对被复制矩阵执行resize函数。当然如果被复制的矩阵为固定矩阵当然就不会执行resize函数。当然也可以通过一些设置取消这个自动resize的过程。
using namespace Eigen;int main()
{MatrixXf a(2,2);MatrixXf b(3,3);b<<1,2,3,4,5,6,7,8,9;a = b;std::cout<<a<<std::endl;
}
输出结果:
1 2 3
4 5 6
7 8 9
9 固定矩阵和动态矩阵
什么时候使用固定矩阵什么时候使用动态矩阵呢?简单的说:当矩阵尺寸比较小时使用固定矩阵(一般小于16),当矩阵尺寸较大时使用动态矩阵(一般大于32)。使用固定矩阵有更好的表现,它可以避免重复的动态内存分配,固定矩阵实际上是一个array。即Matrix4f mymatrix;
事实上是float mymatrix[16];
。所以这个是真的不花费任何运行时间。相反动态矩阵的建立需要在
heap中分配空间。即MatrixXf mymatrix(rows,colums);
实际上是float *mymatrix = new float[rows*colums];
.此外动态矩阵还要保存行和列的值。
当然固定矩阵也存在着显而易见的弊端。当数组的大小过大时,固定数组的速度优势就不那么明显了,相反过大的固定数组有可能造成stack的溢出。这时候动态矩阵的灵活性就显得十分重要了。
10 其他模板参数
最开始我们已经提到了建立一个矩阵一共有6个模板参数,其中有3个我们还没有提到(其实第三个参数已经提到过了)。
Matrix<typename Scalar,int RowsAtCompileTime,int ColsAtCompileTime,int Options=0,int MaxRowsAtCompileTime = RowsAtCompileTime,int MaxColsAtCompileTime = ColsAtCompileTime>
- Options:这个参数决定了矩阵在存储过程中实际是按行还是按列存储。这个存储方式在前面我们提到的矩阵变换时必须要注意。默认是按列存储,我们可以显示的使用
Options=RowMajor
让矩阵实际按行存储。如Matrix<float,2,3,RowMajor> a;
. - MaxRowsAtCompileTime和MaxColsAtCompileTime:这两个值是设定动态矩阵在分配空间时最大的行数和列数。如
Matrix<float,Dynamic,Dynamic,0,3,4>;
.
11 常规的矩阵typedef
我们前面给出了一些常用的矩阵typedef.其实可以总结如下:
- MatrixNt对应的是Matrix<type,N,N>.比如MatrixXi对应的是Matrix<int,Dynamic,Dynamic>.
- VectorNt对应的是Matrix<type,N,1>.比如Vector2f对应的是Matrix<float,2,1>.
- RowVectorNt对应的是Matrix<type,1,N>.比如RowVector3d对应的是Matrix<double,1,3>.
其中:
- N可以是2,3,4或者X(表示Dynamic).
- t可以是i(int),f(float),d(double),cf(complex),cd(complex).只定义了这些类型的typedef并不表示只支持这些数据类型的运算。比如所有的整形类型的运算都支持(长的,短的,有符号的,无符号的)。
转载于:https://www.cnblogs.com/yabin/p/6435901.html
c++矩阵运算库Eigen简介相关推荐
- Eigen矩阵运算库快速上手
目录 1. 配置 2. 初始化 2.1 Array类 2.2 Vector类 2.3 Matrix类 2.4 Vector赋值 2.5 高级初始化 3. 矩阵计算 3.1 矩阵基本计算 3.2 线性求 ...
- Eigen 矩阵运算库在实际项目中的使用
Eigen 矩阵运算库在实际项目中的使用情况如何? 心血来潮,试了试纯模板技术写的 Eigen 并作了简单的性能测试,三个 1000 阶的方阵连乘运算 Eigen 比 MATLAB 快了一倍,比 Op ...
- 三阶矩阵的lu分解详细步骤_快速入门矩阵运算——开源库Eigen
矩阵是数学中一个重要的工具,广泛应用于各种场景下的数值分析,例如,数字信号处理,图像处理等.我们如何在程序中使用矩阵进行运算呢?本文将为大家介绍一个开源的矩阵运算工具--Eigen. Eigen is ...
- eigen 列向量转矩阵_快速入门矩阵运算——开源库Eigen
矩阵是数学中一个重要的工具,广泛应用于各种场景下的数值分析,例如,数字信号处理,图像处理等.我们如何在程序中使用矩阵进行运算呢?本文将为大家介绍一个开源的矩阵运算工具--Eigen. Eigen is ...
- C++矩阵运算库推荐
Armadillo:C++下的Matlab替代品 Eigen3:强大且只需头文件 OpenCV:方便的计算机视觉计算库 ViennaCL:并行矩阵计算 PETSc:大规模并行科学计算 其他的矩阵计算库 ...
- apache madlib 教程_Apache顶级开源项目——机器学习库MADlib简介与应用实例
原标题:Apache顶级开源项目--机器学习库MADlib简介与应用实例 Apache MADlib是Pivotal与UCBerkeley合作的一个开源机器学习库,提供了精确的数据并行实现.统计和机器 ...
- C语言矩阵运算库大起底
GSL GNU Scientific Library自带的矩阵运算,据说速度一般. Blitz++ Blitz++ 与 MTL 都是基于 C++ template 高效数值计算程序库,不过他们专注于不 ...
- 超好用的纯C语言矩阵运算库
超好用的纯C语言矩阵运算库 easyMatrix 最近开发基于异构传感器的异步定位数据的卡尔曼滤波,因为最终要用在一个老爷DSP上,已有代码都是C写的,不想研究这种老爷设备下的C++调用,Eigen这 ...
- Cuda矩阵运算库cuBLAS介绍
文章目录 简介 cuBLAS库新特性 cuBLAS代码热身 cublasSetMatrix() cudaMalloc() cublasSscal() 源代码 cuBLAS 辅助函数 上下文管理 复制矩 ...
最新文章
- python的下载和安装步骤-下载及安装Python详细步骤
- tomcat 不支持put 高版本_「MG6_DCT280」湿式七档双离合版本-性价比并不高
- 应用市场中包名(package name)的唯一性
- aptitude 命令_C-命令行参数Aptitude问题与解答
- java selenium ie_Selenium webdriver Java 操作IE浏览器
- Go:Unresolved dependency
- EGE绘图之四 Gif动图播放
- 通过VBA在excel中实现多只股票基金实时交易数据查询(完整的excel原件可以在我的资源中下载)
- 数值分析Guass分解——错误讨论
- 收藏!常用的档案馆(室)检索工具及编制方法
- HTML5+CSS3笔记 (黑马pink老师)
- ionic学习(十一):页面下拉刷新(Refresher)
- Caffeine使用篇 - Cleanup
- html拖拽手势,h5实现手势操作放大缩小拖动等
- jQuery实现点击文本框弹出热门标签的提示示例
- 【C语言程序设计】实验 10
- 一个生成密保卡的程序
- es6 javascript的字符串对象新增团员方法
- 预算内资金 budgetary funds
- JS escape()和unescape()函数的介绍