Eigen
简介
Eigen 是一个C++线性代数模板库,包括矩阵,向量,数值求解及相关的算法。
其是开源的,并以源代码的方式提供给用户。使用仅需要下载源代码,不需要任何其他依赖项。项目中使用,仅需要包含Eigen头文件即可。
第一个程序
第一个相对简单的程序可以帮助入门。
#include <iostream>
#include <Eigen/Dense>
using Eigen::MatrixXd;
int main()
{
MatrixXd m(2,2);
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;
}
第一个程序说明
Eigen 的头文件定义了多种类型,对于简单的程序来说,使用 MatrixXd 类型足够了。MatrixX d中的 “X” 代表了这是任意大小的矩阵,而 “d” 代表了其中每个元素均是 double 类型。类似的还有 MatrixXf,代表 float 类型。有关详情可参阅数组,矩阵与向量类型。
Eigen/Dense 头文件中定义了 MatrixXd 及相关类型的所有成员函数。该头文件中的所有类及函数均在 Eigen 命名空间中。
主程序的第一行声明了 MatrixXd 类型的变量,并且指定了其大小,即 2 * 2 的矩阵。下面的索引与 C++ 二维数组方括号类似,只是变成了圆括号索引,中间加逗号。
最后一行将整个矩阵输出,之所以能直接输出,是因为 Eigen 库重载了 << 运算符。
第二个程序 矩阵与向量
1. 先看一个在运行时指定矩阵大小的例子。
#include <iostream>
#include <Eigen/Dense>
using namespace Eigen;
using namespace std;
int main()
{
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;
}
逐行解释如下:
- 声明了一个 MatrixXd 变量,并通过 Random() 函数将其初始化为 3 * 3 大小的随机矩阵,随机值在-1和1之间。
- MatrixXd::Constant(3, 3, 1.2) 是产生一个 3 * 3 大小,值全部为 1.2 的矩阵。由于重载了 + 运算符,所以这里的加号是将矩阵对应位置的值相加,与数学上的矩阵相加一致。后面的乘号,是将矩阵里的每一个值均乘以50,再将整个矩阵赋值给m矩阵。
- VectorXd 是定义一个动态向量声明,v(3),是指定v是一个三维向量,此时内存已经分配,但是不会初始化元素。
- v << 1, 2, 3; 是对v赋值,看 << 的流指向。 v = [ 1 2 3 ] T v = [1\quad2 \quad3]^T v=[123]T。
- 最后的 m × \times × v 是矩阵乘以向量的体现,与数学一致。3 × \times × 3的矩阵乘以3*1的向量,得到3 × \times × 1的向量。
看结果,当然每个人运行可能不一样,因为是随机值。
m =
10.1251 90.8741 45.0291
66.3585 68.5009 99.5962
29.3304 57.9873 92.284
m * v =
326.961
502.149
422.157
2. 再看一个在编译时指定矩阵大小的例子。
#include <iostream>
#include <Eigen/Dense>
using namespace Eigen;
using namespace std;
int main()
{
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;
}
对比上述动态的实现,静态版本:
- 由于指定了矩阵Matrix3d的大小为3*3,所以后面的Random()函数即不需要指定行列大小了,下面的Constant类似。
- 同理,Vector3d也是这样,指定了其为3维向量。并且注意到,v的值在构造时已经指定,即v(1,2,3)。
小结
使用指定大小的矩阵和向量有如下两个优点。
- 编译更快
- 方便编译时更严格的检查