[TOC]
概述
文章参考:https://zhuanlan.zhihu.com/p/462494086
Eigen是一个C++语言中的开源的模板库,支持线性代数的运算,包括向量运算,矩阵运算,数值分析等相关算法。因为eigen只包含头文件,所以使用的话不需要进行编译,只需要在cpp文件开头写#include <Eigen>
就好。
Eigen是C++中可以用来调用并进行矩阵计算的一个库,简单了说它就是一个c++版本的matlab包。
开源库安装
直接安装
apt-get方式(假设默认安装到/usr/local/include里(可在终端中输入locate eigen3查看位置),若实际中默认安装到了/usr/include的话,可以对应替换下面命令的相应部分)
1 2
| sudo apt install libeigen3-dev
|
这种安装方式有一个缺点,因为apt包更新比较慢,安装的版本可能不是最新版,那么之后的一些依赖于eigen的库可能没有办法使用(如Sophus库要求必须选用3.3以上版本的eigen包),可以使用指令来查看apt包中eigen的版本
上述安装的问题,会将上面的依赖库安装到/usr/local/include。我们可以执行复制命令。将Eigen文件夹及其内容放在/usr/include
1
| sudo cp -r /usr/local/include/eigen3 /usr/include
|
源码编译安装
下载地址:http://eigen.tuxfamily.org/index.php?title=Main_Page#Download
克隆下载:
1
| git clone https://gitlab.com/libeigen/eigen.git
|
编译步骤:
1 2 3 4 5 6 7 8
| #编译 cd eigen-3.3.9 mkdir build cd build cmake ..
#安装 make install
|
安装完成之后,安装的头文件和静态库
1 2
| 头文件在:/usr/local/include/eigen3 静态库:/usr/local/lib/engines-3
|
上述安装的问题,会将上面的依赖库安装到/usr/local/include。我们可以执行复制命令。将Eigen文件夹及其内容放在/usr/include
1
| sudo cp -r /usr/local/include/eigen3 /usr/include
|
框架集成
eigen库采用模板编程技术,仅由一些头文件组成,运行速度快。用cmake管理项目的时候,只需要在CMakeLists.txt里面头文件的路径即可:
CMakeList里面添加:
1 2
| find_package(Eigen3 REQUIRED) include_directories(${EIGEN3_INCLUDE_DIR})
|
模块与头文件
模块 |
头文件 |
内容 |
Core |
#include <Eigen/Core> |
矩阵和数组 (向量) 类 (Matrix, Array),基于线性代数还有数组操作 |
Geometry |
#include <Eigen/Geometry> |
变换,平移,缩放,2D 旋转和 3D 旋转 (包括四元数和角轴) |
LU |
#include <Eigen/LU> |
使用求解器进行求逆,行列式,LU 分解操作 |
Cholesky |
#include <Eigen/Cholesky> |
使用求解器进行 LLT, LT, Cholesky 分解 |
Householder |
#include <Eigen/Householder> |
Householder 变换;被用作几个线性代数模块 |
SVD |
#include <Eigen/SVD> |
SVD 分解与最小二乘求解器 |
QR |
#include <Eigen/QR> |
QR 分解 |
Eigenvalues |
#include <EIgen/Eigenvalues> |
特征值,特征向量分解 |
Sparse |
#include <Eigen/Sparse> |
稀疏矩阵存储以及相关的基本线性代数 |
Dense |
#include <Eigen/Dense> |
包括 Core, Geometry, LU, Cholesky, SVD, QR, Eigenvalues 的头文件 |
Eigen |
#include <Eigen/Eigen> |
包括 Dense 和 Sparse 的头文件 |
工程集成
如果依赖库是直接安装到系统里面的
1 2 3 4 5 6 7 8
| set(EIGEN_LIBRARIES "/usr/local/lib/engines-3") set(EIGEN_INCLUDES "/usr/local/include/eigen3/Eigen")
find_package(Eigen3 REQUIRED) include_directories("${EIGEN_INCLUDES}") link_directories("${EIGEN_LIBRARIES}")
|
代码示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96
| #include <iostream> #include <ctime> #include <Eigen/Dense> using namespace std; #define MATRIX_SIZE 100 int main() { Eigen::Matrix<float, 2, 3> matrix_23; Eigen::Vector3d v_3d; Eigen::Matrix<float, 3, 1> vd_3d; Eigen::Matrix3d matrix_33 = Eigen::Matrix3d::Zero(); Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic> matrix_dynamic; Eigen::MatrixXd matrix_x; matrix_23 << 1, 2, 3, 4, 5, 6; cout << matrix_23 << endl; for (int i = 0; i < 2; i++) for (int j = 0; j < 3; j++) cout << matrix_23(i, j) << "\t"; cout << endl; v_3d << 3, 2, 1; vd_3d << 4, 5, 6; Eigen::Matrix<double, 2, 1> result = matrix_23.cast<double>() * v_3d; cout << result << endl; Eigen::Matrix<float, 2, 1> result2 = matrix_23 * vd_3d; cout << result2 << endl; matrix_33 = Eigen::Matrix3d::Random(); cout << matrix_33 << endl; cout << "-------------------------" << endl; cout << matrix_33.transpose() << endl; cout << "-------------------------" << endl; cout << matrix_33.sum() << endl; cout << "-------------------------" << endl; cout << matrix_33.trace() << endl; cout << "-------------------------" << endl; cout << 10 * matrix_33 << endl; cout << "-------------------------" << endl; cout << matrix_33.inverse() << endl; cout << "-------------------------" << endl; cout << matrix_33.determinant() << endl; Eigen::SelfAdjointEigenSolver<Eigen::Matrix3d> eigen_solver(matrix_33.transpose()*matrix_33); cout << "Eigen values = \n" << eigen_solver.eigenvalues() << endl; cout << "Eigen vectors = \n" << eigen_solver.eigenvectors() << endl; Eigen::Matrix< double, MATRIX_SIZE, MATRIX_SIZE > matrix_NN; matrix_NN = Eigen::MatrixXd::Random(MATRIX_SIZE, MATRIX_SIZE); Eigen::Matrix< double, MATRIX_SIZE, 1> v_Nd; v_Nd = Eigen::MatrixXd::Random(MATRIX_SIZE, 1); clock_t time_stt = clock(); Eigen::Matrix<double, MATRIX_SIZE, 1> x = matrix_NN.inverse()*v_Nd; cout << "time use in normal inverse is " << 1000 * (clock() - time_stt) / (double)CLOCKS_PER_SEC << "ms" << endl; time_stt = clock(); x = matrix_NN.colPivHouseholderQr().solve(v_Nd); cout << "time use in Qr decomposition is " << 1000 * (clock() - time_stt) / (double)CLOCKS_PER_SEC << "ms" << endl; return 0; }
|