简介
一句话介绍Eigen:
Eigen is a C++ template library for linear algebra: matrices, vectors, numerical solvers, and related algorithms.
Eigen是用于线性代数的C++模板库:用于矩阵,向量,数值求解器和相关算法运算。
特点:
- 功能完善:支持所有大小的矩阵、支持所有标准数据类型等
- 速度极快:表达式模板允许在适当的情况下智能地删除临时文件并启用延迟计算
- 高可靠性
- 高灵活性
机器学习框架TensorFlow底层用于矩阵计算的库就是使用的Eigen。
安装
Eigen库是header-only的,只需安装头文件即可。
可以直接使用命令安装:sudo apt-get install libeigen3-dev
。默认的安装路径为:/usr/include/eigen3
。
也可以下载代码,然后把头文件目录放在项目目录下,这样不需要使用root权限。
Eigen模块及头文件
数值运算的需求是多种多样的。Eigen为这些不同的需求进行分类,并以头文件的形式进行区分。
这样用户只需要包含应用需要的头文件即可。
总结如下:
简单矩阵的建立
直接上代码:
#include "Eigen/Core"
#include <iostream>
using std::cout;
using std::endl;
int main()
{
Eigen::Matrix<double, 2, 2> m; # 创建double类型的2X2维矩阵
m << 1, 2, 3, 4; # 为每个元素赋值
Eigen::MatrixXf m1(2, 3); # 创建动态矩阵,并初始化为2X3矩阵,类型为float
m1 << 1, 2, 3, 4, 5, 6;
Eigen::Matrix3d m2 = Eigen::Matrix3d::Identity(); # 3维double类型的单位矩阵
Eigen::Matrix3d m3 = Eigen::Matrix3d::Random(); # 3维double类型的随机矩阵
Eigen::Vector3f v1 = Eigen::Vector3f::Zero(); # 3维float类型的零向量(默认为列向量,除非显式指定)
Eigen::Vector3d v2(1.0, 2.0, 3.0); # 3维double类型的向量,并赋值
Eigen::VectorXf v3(3); # 动态列向量,指定为3维
v3 << 1.0, 2.0, 3.0;
Eigen::RowVector2d rv1(1, 2); # 2维行向量,并赋值
Eigen::RowVectorXd rv2(5); # 动态行向量,初始化为5维
rv2 << 1, 2, 3, 4, 5;
cout << m1(1, 1) << endl; # 输出指定位置的值
cout << v1(1) << endl;
return 0;
}
上述代码中,已经使用注释说明了它们的用途。关于底层的一些东西:
- 所有矩阵和向量均为Matrix模板类的对象
- 向量是矩阵的行(或列)为1是的特殊情况
- 矩阵的三参数模板:
/* 强制性的三参数模板的原型 (三个参数分别表示:标量的类型,编译时的行,编译时的列) */
Matrix<typename Scalar, int RowsAtCompileTime, int ColsAtCompileTime>
/* 用typedef定义了很多模板,例如:Matrix4f 表示 4×4 的floats 矩阵 */
typedef Matrix<float, 4, 4> Matrix4f;
- 向量也是用矩阵定义的:
typedef Matrix<float, 3, 1> Vector3f; # 默认的是列向量,即矩阵的列恒为1
typedef Matrix<int, 1, 2> RowVector2i; # 指定行向量,即矩阵的行恒为1
- 动态矩阵,是编译时不确定大小,在运行时才确定大小的矩阵:
typedef Matrix<double, Dynamic, Dynamic> MatrixXd;
typedef Matrix<int, Dynamic, 1> VectorXi;
/* 也可使用行固定列动态的矩阵 */
Matrix<float, 3, Dynamic>
- 矩阵的下标是从0开始访问
矩阵运算
直接上代码:
int main()
{
Matrix2d a;
a << 1, 2, 3, 4;
cout << a << endl;
MatrixXd b(2,2);
b << 2, 3, 1, 4;
cout << b << endl;
cout << "a + b =\n" << a + b << endl; //矩阵加法
cout << "a - b =\n" << a - b << endl; //矩阵减法
Vector3d v(1,2,3);
Vector3d w(1,0,0);
cout << "-v + w - v =\n" << -v + w - v << endl; //向量加减法
cout << "2.5 * a =" << 2.5 * a << endl;
MatrixXcf c = MatrixXcf::Random(2, 2);
cout << "c: " << c << endl;
cout << "c^T: " << c.transpose() << endl; // 转置
cout << "c^H: " << c.conjugate() << endl; // 共轭
// cout << "c^(-1): " << c.inverse() << endl; // 矩阵的逆
cout << "a * b: " << a * b << endl;
cout << "b * a: " << b * a << endl;
Vector2d u(1, 3);
cout << "a * u: " << a * u << endl;
cout << "u^T * a : " << u.transpose() * a << endl;
cout << "v dot w: " << v.dot(w) << endl; // 点积
// cout << "v cross w: " << v.cross(w) << endl; // 叉积
}
这部分内容就不多解释了,看代码都能看懂。