欢迎您访问 最编程 本站为您分享编程语言代码,编程技术文章!
您现在的位置是: 首页

轻松上手C++矩阵运算:Eigen矩阵库详解

最编程 2024-02-13 20:51:36
...

最近和一些朋友讨论到了C++中数学工具的问题,以前总是很2地自己写矩阵运算,或者有时候在matlab里计算了一些数据再往C程序里倒,唉~想想那些年,我们白写的代码啊……人家早已封装好了!首先推荐几个可以在C++中调用的数学平台:eigen、bias、lapack、svd、CMatrix,本文着重eigen做以讲解,希望对各位有所帮助。

一、什么是Eigen库

 

 

 

 

Eigen是可以用来进行线性代数、矩阵、向量操作等运算的C++矩阵库,它里面包含了很多算法。它的License是MPL2。它支持多平台。使用类似Matlab的方式操作矩阵,单纯讲和Matlab的对应的话,可能不如Armadillo(http://arma.sourceforge.net/)对应的好,但功能绝对强大。
Eigen包含了绝大部分你能用到的矩阵算法,同时提供许多第三方的接口。Eigen一个重要特点是采用源码的方式提供给用户使用,在使用时只需要包含Eigen的头文件即可进行使用。之所以采用这种方式,是因为Eigen采用模板方式实现,由于模板函数不支持分离编译,所以只能提供源码而不是动态库的方式供用户使用,因此非常轻量而易于跨平台。你要做的就是把用到的头文件和你的代码放在一起就可以了。

Eigen的一些特性:

  • 支持整数、浮点数、复数,使用模板编程,可以为特殊的数据结构提供矩阵操作。比如在用ceres-solver进行做优化问题(比如bundle adjustment)的时候,有时候需要用模板编程写一个目标函数,ceres可以将模板自动替换为内部的一个可以自动求微分的特殊的double类型。而如果要在这个模板函数中进行矩阵计算,使用Eigen就会非常方便。
  • 支持逐元素、分块、和整体的矩阵操作。
  • 内含大量矩阵分解算法包括LU,LDLt,QR、SVD等等。
  • 支持使用Intel MKL加速
  • 部分功能支持多线程
  • 稀疏矩阵支持良好,到今年新出的Eigen3.3,已经自带了SparseLU、SparseQR、共轭梯度(ConjugateGradient solver)、bi conjugate gradient stabilized solver等解稀疏矩阵的功能。同时提供SPQR、UmfPack等外部稀疏矩阵库的接口。
  • 支持常用几何运算,包括旋转矩阵、四元数、矩阵变换、AngleAxis(欧拉角与Rodrigues变换)等等。
  • 更新活跃,用户众多(Google、WilliowGarage也在用),使用Eigen的比较著名的开源项目有ROS(机器人操作系统)、PCL(点云处理库)、Google Ceres(优化算法)。OpenCV自带到Eigen的接口。
    总体来讲,如果经常做一些比较复杂的矩阵计算的话,或者想要跨平台的话,非常值得一用。
  • Eigen中的矩阵类型一般都是用类似MatrixXXX来表示,可以根据该名字来判断其数据类型,比如说’d’代表double并不是用来表示整数的,;‘f’代表float; ‘i’代表整数;‘c’代表complex,即复数;’d’表示dynamic,即表示矩阵中有些维数是不确定的,动态的……举例子比如说:Matrix2cd,表示的是2*2维的,其每个元素都是复数,复数的实部和虚部都为double类型。 

    Eigen中需要非常注意其数据类型,比如2个向量相乘如果得到一个矩阵,则向量中元素的类型和矩阵中元素的类型必须都相同,否则会出现错误。

二、Eigen的下载、帮助文档等网址

Eigen的下载与在VS中的配置,可参考下面两个博客:(下载得到的是个code包,不用安装。)

http://blog.****.net/hjx_1000/article/details/8477522

或者:http://blog.****.net/abcjennifer/article/details/7781936

Eigen帮助文档的地址http://eigen.tuxfamily.org/dox/pages.html,本文中很多例子也是直接摘自这些帮助文档, 

另外关于Eigen的论坛可以访问http://forum.kde.org/viewforum.php?f=74

三、Eigen的简单应用

看了一下官方文档,Eigen库除了能实现各种矩阵操作外,貌似还提供《数学分析》中的各种矩阵操作(包括L矩阵U矩阵)。目前我使用到的还是简单的矩阵操作,如加减乘除,求行列式,转置,逆,这些基本操作只要:​​​​​​​

#include "Eigen/Eigen"
using namespace Eigen;