文章目录
1 什么是线性代数库
简答地说,就是用来 实现 矩阵的运算,向量的运算 等线性代数操作的第三方库。
2 Eigen简介
Eigen是什么?
- Eigen 是一个线性算术的C++模板库,包括:vectors, matrices, 以及相关算法。功能强大、快速、优雅以及支持多平台。
- Eigen是一个开源库,从3.1.1版本开始遵从MPL2许可。除了C++标准库以外,不需要任何其他的依赖包。Eigen使用的CMake建立配置文件和单元测试,并自动安装。如果使用Eigen库,只需包特定模块的的头文件即可。
Eigen的功能与特点
- Eigen是全能的
- 支持各种各样的矩阵,包括固定大小的矩阵,动态矩阵,还有稀疏矩阵。
- 支持所有标准数学类型,包括复数、整数,并且可以自定义数字类型。
- 支持各种矩阵分解和几何特征。
- 还提供了许多功能,如非线性优化、矩阵函数、多项式求解器、快速傅里叶变换FFT等。
- 快
Eigen做了大量的优化,代码运行速度快。 - 可靠
Eigen的算法做了精心挑选,而且经过了大量的测试,包括Eigen自己的测试套件、标准BLAS测试套件,以及LAPACK测试套件等。 - 优雅
Eigen库是使用模板编写的,接口设计简洁优雅,方便使用,C++程序员倍感亲切。
3 安装
Eigen的安装十分地简单,只需要下载源码即可。
目前最新稳定版本3.3.7下载链接
下载后,将下载的压缩包解压,得到的文件目录如下图1所示:
图1
我们真正需要的文件,在该目录下的 Eigen/src目录下,里面有各个模块对应的文件夹,每个文件夹里是头文件 h文件,我们使用的时候,包含这个头文件就可以了。如下图所示:
到此,安装完毕!
4 在vs 上使用
我用的vs2017,使用其实超级简单,原理就是只用告诉vs,Eigen的头文件能在哪里找到即可。
- 新建一个c++项目
这个大家随便建,我这里是一个多元线性回归的项目,打架建一个空白项目就可以了。
- 在包含目录中添加Eigen解压得到的文件路径
step1:
step2:
step3:
step4:
在此添加Eigen库的路径即可,注意,这个路径应该是下图对应的路径
5 测试是否安装成功
直接执行一个程序即可验证是否安装成功
#include <iostream>
#include <Eigen/Dense>
using namespace Eigen;
using namespace std;
void test3() {
Matrix<int,3,3> mat;
mat << 1, 1, 1,
2, 2, 2,
3, 3, 3;
cout << mat << endl;;
}
int main(){
test3();
}
控制台输出:
这样就说明安装成功了!
6 Eigen入门学习
Matrix
在eigen中,所有的矩阵和向量都是Matrix模板类的对象。向量是特殊的矩阵,一行或一列
Matrix 有6个参数,先看前三个参数
Matrix<typename Scalar, int RowsAtCompileTime, int ColsAtCompileTime>
Scalar 是数据类型
RowsAtCompileTime 是行数(编译时知道的)
ColsAtCompileTime 是列数(编译时知道的)
Vectors
向量,一般是列向量
typedef Matrix<float,3,1> Vector3f;
3个float的列向量
Dynamic Matrix
如果编译时并不知道矩阵维度,可以使用动态矩阵
typedef Matrix<double, Dynamic, Dynamic> MatrixXd;
构造
不需要使用new 来构造,直接用
// 未初始化的3 x 3的float矩阵
Matrix3f a;
// 0 x 0 的动态矩阵
MatrixXf b;
矩阵元素操作
MatrixXd m(2,2);
m(0,0)=3
初始化
Matrix3f m;
m << 1, 2, 3,
4, 5, 6,
7, 8, 9;
std::cout << m;
结果:
重新分配矩阵大小
#include <iostream>
#include <Eigen/Dense>
using namespace Eigen;
int main()
{
MatrixXd m(2,5);
m.resize(4,3);
std::cout << "The matrix m is of size "
<< m.rows() << "x" << m.cols() << std::endl;
std::cout << "It has " << m.size() << " coefficients" << std::endl;
VectorXd v(2);
v.resize(5);
std::cout << "The vector v is of size " << v.size() << std::endl;
std::cout << "As a matrix, v is of size "
<< v.rows() << "x" << v.cols() << std::endl;
}
赋值
MatrixXf a(2,2);
std::cout << "a is of size " << a.rows() << "x" << a.cols() << std::endl;
MatrixXf b(3,3);
a = b;
std::cout << "a is now of size " << a.rows() << "x" << a.cols() << std::endl;
7 使用线性代数库写算法的好处
会大大简化编码,让你只用关注算法的推导,简化实现的难度。拿我自己来说,这次写多元线性回归,
可以看到,线性代数实现版本的编码比for循环的简单了很多。