1. Eigen库的安装

安装:sudo apt-get install libeigen3-dev;

位置:/usr/include  (查询指令:sudo updatedb; locate eigen3);

说明:Eigen库仅有头文件,因此没有.so 库文件,是一个c++库。Eigen库提供了大量的矩阵运算,比如行列式、转置、逆、迹、输出、行列式求和、特征值和特征向量等。除此之外,Eigen库还提供了旋转矩阵、旋转向量、四元素之间的变换运算。

2. Eigen库的使用

本部分讲述Eigen库的简单使用,实践基础基于前篇博文https://mp-new.csdn.net/mp_blog/creation/editor/117987682

  • c_cpp_properties.json 加入 Eigen头文件路径
"includePath": [
                "${workspaceFolder}/include",
                "/usr/include/eigen3"
               ],
  • launch.json 修改可执行文件路径
"program": "${workspaceFolder}/bin/Eigen",
  • CMakeLists.txt 加入以下内容
include_directories(/usr/include/eigen3)    
add_executable(Eigen src/Eigen.cpp)
  • Eigen.cpp内容如下
/*****b
功能:演示Eigen库的基本使用,包括
作者:ybin
时间:17,06,2021
*****/

#include<iostream>
#include<Eigen/Core>
#include<Eigen/Dense>             //稠密矩阵的逆运算、行列式运算等
#include<ctime>                   //用于计时
#include<Eigen/Geometry>          //用于旋转、平移
#define MAX_SIZE 50

using namespace std;

int main(int argc, char** argv)
{
    /*****1. 矩阵、向量的定义、赋值、打印与访问*****/
    Eigen::Matrix<float,2,3> matrix_23;  //定义一个float类型,2×3矩阵
    matrix_23 << 1,2,3,4,5,6;            //矩阵赋值
    cout<< "matrix_23=\n" << matrix_23 << endl;

    Eigen::MatrixXd matrix_x;            //动态方阵
    matrix_x = Eigen::Matrix3d::Ones();  //初始化为1
    cout<< "matrix_x=\n" << matrix_x << endl;

    Eigen::Vector3d v_3d;                //定义一个3×1向量
    v_3d << 1,2,3;                       //赋值
    cout<< "v_3d=\n" << v_3d << endl;

    //访问元素
    for (int i = 0; i < 3; i++)          
    {
        for (int j = 0; j < 3; j++)
        {
            matrix_x(i,j)=8;
        }
        
    }
    cout<< "matrix_x=\n" << matrix_x << endl;

    /*****2. 矩阵的运算:相乘、转置、逆、迹、行列式、求和*****/
    //Eigen::Vector2d v_2d = matrix_23 * v_3d 会出现错误,因为matrix_23为float类型,v_3d为double类型
    Eigen::Vector2d v_2d = matrix_23.cast<double> ()* v_3d;  //相乘
    cout<< "v_2d=\n"<<v_2d << endl;
    Eigen::Matrix3d matrix_33 = Eigen::Matrix3d::Identity();
    cout<<"\n"<< matrix_33.transpose()<<endl;        //转置
    cout<<"\n"<< matrix_33.inverse()<<endl;          //逆
    cout<<"\n"<< matrix_33.trace()<<endl;            //迹
    cout<<"\n"<< matrix_33.determinant()<<endl;      //行列式
    cout<<"\n"<< matrix_33.sum()<<endl;              //转置

    /*****3. 解方程组 *****/
    Eigen::MatrixXd matrix_NN = Eigen::MatrixXd::Random(MAX_SIZE, MAX_SIZE);
    Eigen::VectorXd v_nd = Eigen::MatrixXd::Random(MAX_SIZE,1);

    // 法1:直接求逆
    clock_t t1 = clock();
    Eigen::Matrix<double,MAX_SIZE,1> x = matrix_NN.inverse()*v_nd;
    cout<<"time when using nomal inverse = "<< (clock() -t1)/(double)CLOCKS_PER_SEC << "s" << endl;
    
    // 法2:QR分解法 (速度教快)
    t1 = clock();
    x = matrix_NN.colPivHouseholderQr().solve(v_nd);
    cout<<"time when using Qr = "<< (clock() -t1)/(double)CLOCKS_PER_SEC << "s" << endl;

    /*****4.求特征值和特征向量*****/
    Eigen::SelfAdjointEigenSolver<Eigen::Matrix3d> Eigen_solve (matrix_33);
    cout<<"Eigen_value"<<Eigen_solve.eigenvalues()<<endl;
    cout<<"Eigen_vector"<<Eigen_solve.eigenvectors()<<endl;
    

    /*****5. Eigen 几何模块,包括旋转矩阵、旋转向量、四元素之间的相互转换*****/
    Eigen::Matrix3d rotate_matrix = Eigen::Matrix3d::Identity();               //定义旋转矩阵,初始化为单位矩阵 
    Eigen::AngleAxis<double> rotate_vector (0, Eigen::Vector3d(0,0,1));        //定义旋转向量,初始化
    Eigen::Quaterniond q (rotate_matrix);                                      //定义四元素                                     
    cout<<"rotate_matrix = " <<rotate_matrix<<endl;                              //显示旋转矩阵
    cout<<"q.coeffs = "<< q.coeffs() <<endl;                                     //显示四元素,coeffs顺序,前面为虚部,后面为实部
    cout<<"rotate_vector to matrix" <<rotate_vector.toRotationMatrix()<<endl;    //旋转向量到旋转矩阵
    cout<<"q to matrix" <<q.toRotationMatrix()<<endl;                            //四元素到旋转矩阵

    Eigen::Vector3d v (1,0,0);                                                   //定义待旋转向量
    cout<<"v_rotate from rotate_matrix = "<<rotate_matrix*v<<endl;                //通过旋转矩阵
    cout<<"v_rotate from rotate_vector = "<<rotate_vector*v<<endl;                //通过旋转向量
    cout<<"v_rotate from q = "<<q*v<<endl;                                        //通过四元素

    /*****6. 变换矩阵的定义,赋值,与坐标变换*****/
    Eigen::Isometry3d T = Eigen::Isometry3d::Identity();
    T.rotate (rotate_vector);
    T.pretranslate (Eigen::Vector3d (1,0,0));
    cout<<"tranform matrix ="<<T.matrix()<<endl;
    cout<<"v_transform from T="<<T*v<<endl;
    return 0;
}

 3. QR 分解(housedolder 待补充)

Logo

聚焦RDK与具身智能,汇集机器人开发教程、开源案例和技术交流

更多推荐