Eigen 是一个 C++ 开源线性代数库
它提供了快速的有关矩阵的线性代数运算,还包括解方程等功能。
Eigen 它是一个纯用头文件搭建起来的库,只能找到它的头文件,没有.so 或.a 那样的二进制文件
在使用时,只需引入 Eigen 的头文件即可,不需要链接它的库文件
下面总结下 其 使用 方法 ,方便忘记时翻阅
声明矩阵和向量
Eigen 以矩阵为基本数据单元。它是一个模板类。它的前三个参数为:数据类型,行,列
=============================================
声明一个基本的矩阵
声明一个 2*3 的 float 矩阵
//声明一个 2*3 的 float 矩阵
Eigen::Matrix<float, 2, 3> matrix_23;
=============================================
声明一个基本的向量
同时,Eigen 通过 typedef 提供了许多内置类型,不过底层仍是 Eigen::Matrix
Vector3d 实质上是 Eigen::Matrix<double, 3, 1>
//声明一个 三维向量
Eigen::Vector3d v_3d;
=============================================
矩阵初始化为零
还有 Matrix3d 实质上是 Eigen::Matrix<double, 3, 3>
Eigen::Matrix3d matrix_33 = Eigen::Matrix3d::Zero(); //初始化为零
=============================================
矩阵赋值随机数
matrix_33 = Eigen::Matrix3d::Random();//矩阵取随机数
=============================================
声明动态大小的矩阵
如果不确定矩阵大小,可以使用动态大小的矩阵
Eigen::Matrix< double, Eigen::Dynamic, Eigen::Dynamic > matrix_dynamic;
Eigen::MatrixXd matrix_x;//相当于上面一行
=============================================
对矩阵操作
输入数据
matrix_23 << 1, 2, 3, 4, 5, 6;//矩阵输入
v_3d << 3, 2, 1;//向量输入
=============================================
输出数据
cout << matrix_23 << endl;
打印的结果
=============================================
访问矩阵中的元素
通过()访问矩阵中的元素
for (int i=0; i<1; i++)
for (int j=0; j<2; j++)
cout<<matrix_23(i,j)<<endl;
=============================================
改变矩阵数据类型
matrix_23.cast< double >() 将 float 转换成了 double
matrix_23.cast<double>()
=============================================
矩阵相乘
Eigen::Matrix<double, 2, 1> result = matrix_23.cast<double>() * v_3d;
注意 两矩阵的类型要一致 ,矩阵的维度有匹配 ,否则会报错
matrix_23.cast< double >() 将 float 转换成了 double
Eigen::Matrix<double, 2, 1> result_wrong_type = matrix_23 * v_3d; // 这样不对 类型不匹配
报错如下:
error: no type named ‘ReturnType’ in ‘struct Eigen::ScalarBinaryOpTraits<float, double, Eigen::internal::scalar_product_op<float, double> >’
typedef typename ScalarBinaryOpTraits::Scalar, typename traits::Scalar>::ReturnType Scalar;
Eigen::Matrix<double, 2, 3> result_wrong_dimension = matrix_23.cast<double>() * v_3d;// 这样不对 维度不匹配
报错如下
/usr/local/include/eigen3/Eigen/src/Core/PlainObjectBase.h:732:41: required from ‘Derived& Eigen::PlainObjectBase::_set_noalias(const Eigen::DenseBase&) [with OtherDerived = Eigen::Product<Eigen::CwiseUnaryOp<Eigen::internal::scalar_cast_op<float, double>, const Eigen::Matrix<float, 2, 3> >, Eigen::Matrix<double, 3, 1>, 0>; Derived = Eigen::Matrix<double, 2, 3, 0, 2, 3>]’
/usr/local/include/eigen3/Eigen/src/Core/PlainObjectBase.h:537:19: required from ‘Eigen::PlainObjectBase::PlainObjectBase(const Eigen::DenseBase&) [with OtherDerived = Eigen::Product<Eigen::CwiseUnaryOp<Eigen::internal::scalar_cast_op<float, double>, const Eigen::Matrix<float, 2, 3> >, Eigen::Matrix<double, 3, 1>, 0>; Derived = Eigen::Matrix<double, 2, 3, 0, 2, 3>]’
/usr/local/include/eigen3/Eigen/src/Core/Matrix.h:377:29: required from ‘Eigen::Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>::Matrix(const Eigen::EigenBase&) [with OtherDerived = Eigen::Product<Eigen::CwiseUnaryOp<Eigen::internal::scalar_cast_op<float, double>, const Eigen::Matrix<float, 2, 3> >, Eigen::Matrix<double, 3, 1>, 0>; _Scalar = double; int _Rows = 2; int _Cols = 3; int _Options = 0; int _MaxRows = 2; int _MaxCols = 3]’
/home/jone/slam_learn/eigneMatrix_lianxi/eigenMatrix.cpp:68:84: required from here
/usr/local/include/eigen3/Eigen/src/Core/util/StaticAssert.h:33:40: error: static assertion failed: YOU_MIXED_MATRICES_OF_DIFFERENT_SIZES
#define EIGEN_STATIC_ASSERT(X,MSG) static_assert(X,#MSG);
矩阵转置
转置
matrix_33.transpose()
=============================================
各元素和
各元素和
matrix_33.sum()
=============================================
迹
迹
matrix_33.trace()
数乘
数乘
10*matrix_33
逆
逆
matrix_33.inverse()
=============================================
行列式
行列式
matrix_33.determinant()
=============================================
求特征值
求特征值
对角化 A(T)*A
Eigen::SelfAdjointEigenSolver<Eigen::Matrix3d> eigen_solver ( matrix_33.transpose()*matrix_33 );
cout << "Eigen values = " << eigen_solver.eigenvalues() << endl;
cout << "Eigen vectors = " << eigen_solver.eigenvectors() << endl;
===============================================
利用矩阵解方程
直接求逆解方程
求解方程
求解 matrix_NN * x = v_Nd 这个方程
直接求逆自然是最直接的,但是求逆运算量大
#define MATRIX_SIZE 50
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 );
// 直接求逆
Eigen::Matrix<double,MATRIX_SIZE,1> x = matrix_NN.inverse()*v_Nd;
矩阵分解(QR) 解方程
// 通常用矩阵分解来求,例如 QR 分解,速度会快很多
x = matrix_NN.colPivHouseholderQr().solve(v_Nd);