入门篇
对于一个优质第三库最好的入门学习方式就是去读官方文档。
- 速查
Array, matrix and vector types
简介
Eigen是C++中可以用来调用并进行矩阵计算的一个库,简单了说它就是一个c++版本的matlab包。
Eigen是一个开源库,从3.1.1版本开始遵从MPL2许可。
-
快速参考页面(quick reference pages)
以非常简洁的格式提供非常完整的 API 描述,目前只有两个功能集:
-
有关扩展特征特征和支持自定义标量类型的讨论和示例
-
例如预处理器指令、控制断言、多线程、MKL 支持、一些Eigen的内部见解等等…
-
如何安装
下载解压缩,
项目的包含路径
添加Eigen源代码根目录,代码中包含Eigen头文件即可。但是往往还会用到Eigen的unsupported 模块,因此最好的做法的是将
Eigen-3.X
和Eigen-3.X\unsupported
均放在include:项目include:
"..\Eigen\Eigen-3.X" "..\Eigen\Eigen-3.X\unsupported"
这样是为了在导入
unsupported
时会不知道来源,直接用Eigen
反而比较省事,引用时:
//Eigen #include <Eigen/Dense> #include <Eigen/NonLinearOptimization>
实际上,
Eigen
子目录中的头文件是使用Eigen编译程序所需的唯一文件。所有平台的头文件都相同。没有必要使用 CMake 或安装任何东西。
模块和头文件
Eigen库被分为一个Core模块和其他一些模块,每个模块有一些相应的头文件。 为了便于引用,Dense模块整合了一系列模块;Eigen模块整合了所有模块。一般情况下,include<Eigen/Dense>
就够了。
Hello Eigen
-
头文件
使用Eigen添加以下头文件即可
#include <Eigen/Dense>
using namespace Eigen;
- 快速写一个Eigen代码让你第一次接触Eigen
void Eigen_introduction_started_001()
{
MatrixXd m(2, 2); // MatrixXd 表示的是动态数组,初始化的时候指定数组的行数和列数
cout << m << endl; // eigen重载了<<运算符,可以直接输出eigen矩阵的值
m(0, 0) = 3;
m(1, 0) = 2.5;
m(0, 1) = -1;
m(1, 1) = m(1, 0) + m(0, 1);
std::cout << m << std::endl;
}
输出
-6.27744e+66 -6.27744e+66
-6.27744e+66 -6.27744e+66
3 -1
2.5 1.5
解释一下上述程序
-
Eigen头文件定义了多种类型,但对于简单的应用,可能足以只使用
MatrixXd
类型。 -
矩阵是任意大小,因此是
X in MatrixXd
-
其中每个条目都是一个
double
,因此是d in MatrixXd
Matrices and vectors
现在结合矩阵和向量进行练习
- example 1
void Eigen_introduction_started_002()
{
//初始化动态矩阵m,使用Random函数,初始化的值在[-1,1]区间内,矩阵大小3X3
MatrixXd m = MatrixXd::Random(3, 3);
cout << m << endl;
//MatrixXd::Constant(3, 3, 1.2)初始化3X3矩阵,矩阵里面的数值为常量,全部为1.2
// Eigen重载了 + 运算符,两个矩阵有相同的行数和列数即可相加,对应位置上的值相加
m = (m + MatrixXd::Constant(3, 3, 1.2));
//矩阵 乘 常数
m *= 100;
cout << "m =" << endl << m << endl;
//定义一个向量 v len = 3;
VectorXd v(3); //只是定义了尺寸
// 和 STL 不同,没有初始化,而是未初始化内存空间,可以访问
cout << v[0] << endl;
//逗号初始化,英文:comma-initializer,Eigen未提供c++11 的{}初始化方式
v << 1, 2, 3;
// eigen重载了<<运算符,可以直接输出Eigen向量的值
// 并且Eigen的一维向量默认为列向量
cout << "v = " << endl << v << endl;
//矩阵与向量的乘法
cout << "m * v =" << endl << m * v << endl;
}
- example 2
void Eigen_introduction_started_003()
{
//MatrixXd m = MatrixXd::Random(3, 3);
//m = (m + MatrixXd::Constant(3, 3, 1.2)) * 50;
//cout << "m =" << endl << m << endl;
//VectorXd v(3);
//v << 1, 2, 3;
//cout << "m * v =" << endl << m * v << endl;
//一下代码实现的功能与上述完全一致
//但是实现方式略有不同,相比上一个例子,以下代码更多的采用了方阵实现
Matrix3d m = Matrix3d::Random();
m = (m + Matrix3d::Constant(1.2)) * 50;
cout << "m =" << endl << m << endl;
Vector3d v(1, 2, 3);
cout << "m * v =" << endl << m * v << endl;
}
-
总结
使用固定大小的矩阵和向量有两个优点。编译器生成更好(更快)的代码,因为它知道矩阵和向量的大小。在类型中指定大小还允许在编译时进行更严格的检查。例如,如果您尝试将 a
Matrix4d
(4×4 矩阵)与 aVector3d
(大小为 3 的向量)相乘,编译器会报错。但是,使用多种类型会增加编译时间和可执行文件的大小。在编译时也可能不知道矩阵的大小。经验上是对 4×4 或更小的大小使用固定大小的矩阵。