Eigen库的学习使用

环境准备

在虚拟机上安装Eigen
sudo apt-get install libeigen3-dev
下载好视觉SLAM十四讲对应的代码后,下载KDevelop,KDevelop位于Ubuntu系统的软件仓库,可以使用apt-get来安装。

1.打开project,选择对应目录下的CMakeLists.txt。

在这里插入图片描述
会生成build目录:
在这里插入图片描述

2.build该工程

在这里插入图片描述
报错1: By not providing “FindPangolin.cmake” in CMAKE_MODULE_PATH this project has asked CMake to find a package configuration file provided by “Pangolin”, but CMake did not find one.
没有Pangolin导致(Pangolin是对OpenGL进行封装的轻量级的OpenGL输入/输出和视频显示的库。可以用于3D视觉和3D导航的视觉图,可以输入各种类型的视频、并且可以保留视频和输入数据用于debug。)之前复现ORB_SLAM2的时候因为版本的问题安装这个库搞了很久,所以这次之前复用之前的方法。
step1:安装依赖项

sudo apt-get install libglew-dev libpython2.7-dev

step2:到github官网上下载0.5版本的Pangolin,解压后到该目录下。

cd Pangolin
mkdir build
cd build
cmake ..
make -j16
sudo make install

报错2:
在这里插入图片描述
添加头文件#include <Eigen/Geometry>

编译成功:
在这里插入图片描述

3.执行程序

1.在run-——>Current Launch Configuration中配置选择要执行的文件。
在这里插入图片描述
Executable中选择build目录下生成的可执行文件,最后在Launch Configurations选择要执行的文件,点击界面中的"Execute"即可。
在这里插入图片描述
执行结果:
在这里插入图片描述

编程学习

KDevelop常用的快捷键,可以在setting中的configure shortcuts设置。
win+left 上次访问的上下文
win+right 下次访问的上下文
Ctrl+d 注释
Ctrl+Shift+d 解注释
F9运行程序

使用Eigen的头文件

//Eigen的核心部分
#include<Eigen/Core>
//稠密矩阵的代数运算(逆、特征值等)
#include<Eigen/Dense>
//Eigen的几何模块,提供各种旋转和平移的表示
#include<Eigen/Geometry>

1.动态矩阵和静态矩阵的定义和初始化

//定义并初始化一个2*3的矩阵
Matrix<float,2,3> matrix_23;
matrix_23 << 1,2,3,4,5,6;

//定义一个动态矩阵
MatrixXd matrixXd;
Matrix<double,Dynamic,Dynamic> matrix_dynamic;

//向量的定义,Vector3d实质是Matrix<double,3,1>
Vector3d v_3d;
v_3d<<3,2,1;
Vector4d v_4d;

2.如何访问并操作矩阵中的元素

//访问第2行第1列的元素
cout<<matrix_23(2,1);
//假设m是一个3*3的矩阵并已经初始化,对里面的元素进行操作
m(0, 0) = 1;
m(0, 1) = 2;
m(1, 0) = m(0, 0) + 3;
m(1, 1) = m(0, 0) * m(0, 1);

3.如何使元素类型不同的矩阵相乘(float和double)

//用cast()显示转换
Matrix<double,2,1> result = matrix_23.cast<double>()*v_3d;

4.求矩阵的转置、和、迹、逆、行列式等基本操作

Matrix3d matrix_33 = Matrix3d::Random();//随机数矩阵
Matrix3d matrix_33_other = Matrix3d::Random();//随机数矩阵
cout << "random matrix: \n" << matrix_33 << endl;
cout << "transpose: \n" << matrix_33.transpose() << endl;      // 转置
cout << "sum: " << matrix_33.sum() << endl;            // 各元素和
cout << "trace: " << matrix_33.trace() << endl;          // 迹
cout << "times 10: \n" << 10 * matrix_33 << endl;               // 数乘
cout << "inverse: \n" << matrix_33.inverse() << endl;        // 逆
cout << "det: " << matrix_33.determinant() << endl;    // 行列式
cout << "det: " << matrix_33.conjugate() << endl;    // 共轭矩阵
cout << "det: " << matrix_33.adjoint() << endl;    // 伴随矩阵
cout << "det: " << matrix_33.mincoeff() << endl;    // 最小值
cout << "det: " << matrix_33.maxcoeff() << endl;    // 最大值
cout << "det: " << matrix_33.mean() << endl;    // 平均值
cout << "det: " << matrix_33.prod() << endl;    // 所有元素求积
cout << "det: " << matrix_33.dot(matrix_33_other ) << endl;    // 点乘
cout << "det: " << matrix_33.cross(matrix_33_other ) << endl;    // 叉乘

5.求矩阵的特征值和特征向量

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 << endl;

6.解方程

  // 解方程
  // 我们求解 matrix_NN * x = v_Nd 这个方程
  // N的大小在前边的宏里定义,它由随机数生成
  // 直接求逆自然是最直接的,但是求逆运算量大
  Matrix<double, MATRIX_SIZE, MATRIX_SIZE> matrix_NN = MatrixXd::Random(MATRIX_SIZE, MATRIX_SIZE);
  matrix_NN = matrix_NN * matrix_NN.transpose();  // 保证半正定
  Matrix<double, MATRIX_SIZE, 1> v_Nd = MatrixXd::Random(MATRIX_SIZE, 1);
  // 直接求逆
  Matrix<double, MATRIX_SIZE, 1> x = matrix_NN.inverse() * v_Nd;
  cout << "x = " << x.transpose() << endl;
  // 通常用矩阵分解来求,例如QR分解,速度会快很多
  x = matrix_NN.colPivHouseholderQr().solve(v_Nd);
  cout << "x = " << x.transpose() << endl;
  // 对于正定矩阵,还可以用cholesky分解来解方程
  x = matrix_NN.ldlt().solve(v_Nd);
  cout << "x = " << x.transpose() << endl;

7.旋转矩阵、旋转向量、四元数、欧拉角的定义和之间的转换

//1.定义旋转矩阵和旋转向量,将旋转向量转为旋转矩阵
Matrix3d rotation_matrix = Matrix3d::Identity();
AngleAxisd rotation_vector =(M_PI/4,Vector3d(0,0,1));
//.matrix()将旋转向量转为旋转矩阵
cout<<rotation_vector.matrix()<<endl;
//.toRotationMatrix()也可以将旋转向量转为旋转矩阵
rotation_matrix = rotation_vector.toRotationMatrix();

//现在有一个三维向量,利用旋转矩阵、旋转向量、欧式变换矩阵分别对其进行坐标变换
Vector3d v(1,0,0);
//旋转向量进行坐标变换
Vector3d v_rotated = rotation_vector*v;
//旋转矩阵进行坐标变换
v_rotated = rotation_matrix*v;
//用欧式变换矩阵进行坐标变换
Isometry3d T = Isometry3d::Identity();
T.rotate(rotation_vector);
T.pretanslate(Vector3d(1,3,4));
//相当于Rv+t
Vector3d v_tranformed = T*v

//将旋转矩阵转为欧拉角 按ZYX顺序 roll pitch yow
Vector3d enlur_angle = rotation_matrix.enlurAngles(2,1,0);

//把旋转矩阵或旋转向量赋值给四元数
Quaterniond q = Quaterniond(rotation_vector);
q = Quaterniond(rotation_matrix);
//使用四元数旋转一个向量
v_rotated = q*v;
//用四元数和平移向量表示两个坐标系的变换关系,怎么进行坐标转换
Quaterniond q1(0.35, 0.2,0.3,0.1),q2(-0.5,0.4,-0.1,0.2);
q1.normalize();
q2.normalize();
Vector3d t1(0.3,0.1,0.1),t2(-0.1,0.5,0.3);
Vector3d p1(0.5,0,0.2);
//得到机器人坐标系1、2到世界坐标系的变换矩阵
Isometry3d T1w(q1),T2w(q2);
T1w.pretranslate(t1);
T2w.pretranslate(t2);
//将机器人坐标系p1转到机器人坐标系p2
Vector3d p2 = T2w * T1w.inverse() * p1;
cout<<p2.transpose()<<endl;




  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: Eigen是一个C++模板,用于线性代数计算。通过学习Eigen的源码,可以深入了解其内部实现原理,从而更好地利用该进行编程。 首先,学习Eigen的源码可以帮助我们理解它是如何实现矩阵和向量的表示和运算的。Eigen采用模板编程的方式,可以适应不同的矩阵和向量类型,包括动态大小和静态大小,以及不同的数据类型,如浮点数、整数等。通过查看源码,我们可以了解Eigen是如何使用模板来实现通用的矩阵和向量类型,并提供相应的运算功能。 其次,学习Eigen的源码还可以帮助我们了解其高效的实现方式。Eigen在设计和实现时,考虑了性能和内存使用效率。它采用矩阵和向量的表达形式,可以有效地进行运算,并尽量减少内存的分配和拷贝。通过分析源码,我们可以学习Eigen是如何通过优化算法和数据结构来提高计算性能的。 此外,学习Eigen的源码还有助于我们了解其丰富的功能和用法。Eigen提供了大量的线性代数计算功能,包括矩阵乘法、矩阵分解、特征值分解、线性方程求解等。通过深入学习Eigen的源码,我们可以理解每个功能的实现细节,进而更好地应用于实际问题中。 综上所述,通过学习Eigen的源码,我们可以深入了解其内部实现原理,掌握其高效的计算方式,同时了解其丰富的功能和用法。这将有助于我们更好地利用Eigen进行线性代数计算。 ### 回答2: Eigen是一个用于线性代数的C++模板,包含了各种矩阵运算、向量运算和线性方程求解等功能。通过学习Eigen的源码,可以深入理解矩阵运算的原理和实现细节,提高代码效率和准确性。 首先,Eigen源码使用模板实现了矩阵和向量的各种运算操作,这意味着可以使用不同的数据类型和维度来进行运算,使得代码更加灵活和通用。学习源码可以了解到模板元编程的技巧和实现方式,提高代码设计的灵活性。 其次,Eigen的源码包含了矩阵和向量的基本运算方法,如加减乘除、转置、求逆等,可以通过源码学习到这些运算方法的具体实现原理和优化技巧。了解这些细节可以帮助我们更好地理解算法的本质和性能优化的方法,提高代码的效率。 此外,Eigen的源码还包含了线性方程求解的方法,如LU分解、QR分解和特征值分解等。学习源码可以了解到这些求解方法的具体实现过程和数学原理,加深对数学建模和求解问题的理解。 最后,学习Eigen源码还可以帮助我们理解矩阵和向量的内存布局和访问方式。Eigen使用列优先的内存布局方式,了解源码可以了解到这种布局方式的原理和优势,避免内存访问的冗余和低效。 总之,通过学习Eigen的源码,可以深入理解线性代数的各种运算方法和数学原理,提高代码效率和准确性。同时,还可以学习到模板元编程的技巧和实现方式,提高代码设计的灵活性。 ### 回答3: Eigen是一个用于线性代数运算的C++模板,由于其高性能和易用性,被广泛应用于科学计算、机器学习等领域。学习Eigen的源码可以帮助我们深入理解其内部实现原理,进而更好地使用进行开发。 在学习Eigen源码时,首先我们可以从它的模板结构和设计思想入手。Eigen使用了大量模板元编程的技术,利用C++的模板特性实现了高度的灵活性和通用性。通过阅读Eigen的模板实现,我们可以学习到如何利用模板编程来实现复杂的数学运算和算法,以及如何提高程序性能和可维护性。 其次,我们可以关注Eigen的矩阵和向量运算部分的源码。Eigen提供了丰富的矩阵和向量运算接口,包括基本的加减乘除运算、转置、求逆、特征值分解等等。通过深入研究其源码,我们可以了解到这些运算是如何实现的,了解它们的算法和优化方法,从而更好地掌握Eigen使用技巧。 此外,学习Eigen源码还可以让我们了解到一些底层的计算优化技术。Eigen使用了一些特殊的技巧和优化策略,如内存对齐、向量化指令、并行计算等等,以提高运算性能。通过学习这些优化技术,我们可以将其应用到自己的程序中,提高程序的执行效率。 总之,学习Eigen的源码可以帮助我们更好地理解其内部实现原理,并且提高我们对线性代数的理解和运用能力。通过深入研究Eigen的源码,我们可以获得更多关于高性能计算和模板编程的经验,为我们日后的程序开发和科学计算提供有益的借鉴。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值