Eigen的使用总结

518 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 16 天,点击查看活动详情

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<typename traits::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::SelfAdjointEigenSolverEigen::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);

在这里插入图片描述