Eigen线性代数c++模板库入门(macos端)
一、什么是Eigen?
Eigen 是一个用于线性代数的 c + + 模板库: 矩阵、向量、数值求解器和相关算法
- Eigen功能强大
它支持所有的矩阵尺寸,从小的固定尺寸矩阵到任意大的稠密矩阵,甚至稀疏矩阵
它支持所有标准的数值类型,包括 std: : complex、 integers,并且很容易扩展到自定义数字类型 - Eigen速度超快
- Eigen是可靠地
二、安装Eigen使用步骤
1.Homebrew
- 简介:
Homebrew 是 Mac 上管理软件包的最实用工具之一。Homebrew是一款Mac
OS平台下的软件包管理工具,拥有安装、卸载、更新、查看、搜索等很多实用的功能。简单的一条指令,就可以实现包管理,而不用你关心各种依赖和文件路径的情况,十分方便快捷。 - 安装: 终端运行如下
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
官方安装有时会出现无法连接服务器的情况,如下图:
可以运行下面自动脚本(已经全部替换为国内地址),然后选择 1 (中科大的)
/bin/zsh -c "$(curl -fsSL https://gitee.com/cunkai/HomebrewCN/raw/master/Homebrew.sh)"
2.安装Eigen
- 终端运行: brew install eigen
- 默认安装路径为:
/usr/local/Cellar/eigen/3.3.9
- 代码如下(示例):
三、Clion编程环境
-
Clion简介
CLion是一款专为开发C及C++所设计的跨平台IDE。它是以IntelliJ为基础设计的,包含了许多智能功能来提高开发人员的生产力,提高开发人员的工作效率。 这种强大的IDE帮助开发人员在Linux、OS X和Windows上来开发C/C++,同时它还使用智能编辑器来提高代码质量、自动代码重构并且深度整合CMake编译系统,从而提高开发人员的开发效率。 -
学生免费
Clion官方提供学生免费使用政策,只要你有校园邮箱就可以
四、Eigen使用
使用clion新建项目eigenMatrix
项目引入Eigen库
打开项目的cmakelists.txt文件,向其中添加以下代码
include_directories("/usr/local/include/eigen3")
加入Eigen库头文件
打开main.cpp文件 加入以下代码
#include<Eigen/Core>
#include<Eigen/Dense>
矩阵的声明
//Eigen 中所有向量和矩阵都是Eigen::Matrix,它是一个模板类。它的前三个参为:数据类型,行,列
// 声明一个2*3的float矩阵
Matrix<float, 2, 3> matrix_23;
//声明一个3维向量
Vector3d v_3d;
Matrix<float, 3, 1> vd_3d;
// Matrix3d 实质上是 Eigen::Matrix<double, 3, 3>
Matrix3d matrix_33 = Matrix3d::Zero(); //初始化为零
// 如果不确定矩阵大小,可以使用动态大小的矩阵
Matrix<double, Dynamic, Dynamic> matrix_dynamic;
// 更简单的
MatrixXd matrix_x;
矩阵的基本使用
//基本参数
Eigen::Matrix<double, 3, 3> A;
Eigen::Matrix<double, 3, Eigen::Dynamic> B;
cout<<A.size()<<endl;
cout<<A.rows()<<endl;
cout<<A.cols()<<
运行结果:
9
3
3
-改变大小 只能改变带有Dynamic的维
cout<<endl;
//改变大小 只能改变带有Dynamic的维
cout<<B.size()<<endl;
B.resize(3,100);
cout<<B.size()<<endl;
B.resize(3,50);
cout<<B.size()<<endl;
运行结果:
0
300
150
矩阵的输入输出
//矩阵的输入输出
A << 1, 2, 3,
4, 5, 6,
7, 8, 9;
cout<<"A:"<<endl;
cout<<A<<endl;
//使用下标访问特定数据
cout<<A(2,1)<<endl;
B.resize(3,9); //输入的维度必须和设定的维度一致
B<< A,A,A; //用三个A赋值
cout<<"B:"<<endl;
cout<<B<<endl;
A.fill(100);
cout<<"A:"<<endl;
cout<<A<<endl;
运行结果:
A:
1 2 3
4 5 6
7 8 9
8
B:
1 2 3 1 2 3 1 2 3
4 5 6 4 5 6 4 5 6
7 8 9 7 8 9 7 8 9
A:
100 100 100
100 100 100
100 100 100
矩阵的基本运算
cout<<endl;
//矩阵的基本运算
Eigen::Matrix3d m1 = Eigen::Matrix3d::Random(); // 随机数矩阵
Eigen::Matrix3d m2 = Eigen::Matrix3d::Random(); // 随机数矩阵
cout << "random matrix m1: \n" << m1 << endl;
cout << "transpose: \n" << m1.transpose() << endl; // 转置
cout << "sum: " << m1.sum() << endl; // 各元素和
cout << "trace: " << m1.trace() << endl; // 迹
cout << "times 10: \n" << 10 * m1 << endl; // 数乘
cout << "inverse: \n" << m1.inverse() << endl; // 逆
cout << "det: " << m1.determinant() << endl; // 行列式
cout << "m1*m2:"<<endl<<m1*m2<<endl; //矩阵相乘 一定要保证维度合法性!
运行结果:
random matrix m1:
-0.999984 -0.0826997 -0.905911
-0.736924 0.0655345 0.357729
0.511211 -0.562082 0.358593
transpose:
-0.999984 -0.736924 0.511211
-0.0826997 0.0655345 -0.562082
-0.905911 0.357729 0.358593
sum:
-1.99453
trace:
-0.575857
times 10:
-9.99984 -0.826997 -9.05911
-7.36924 0.655345 3.57729
5.11211 -5.62082 3.58593
inverse:
-0.370316 -0.888554 -0.0491136
-0.737309 -0.172358 -1.69072
-0.627782 0.996559 0.208558
det: -0.606436
m1*m2:
-0.885282 0.224109 0.804256
-0.642049 -0.868276 -0.373563
0.589327 0.541352 -0.515106
-求矩阵特征值和特征向量
cout<<endl;
//求矩阵特征值和特征向量
A<<3,2,-1,-2,-2,2,3,6,-1;
cout<<"A:"<<endl<<A<<endl<<endl;
cout<<"特征值:\n"<<A.eigenvalues()<<endl<<endl;
Eigen::EigenSolver<Eigen::Matrix3d> eig(A);
cout<<"特征值:\n"<<eig.eigenvalues()<<endl<<endl;
cout<<"特征向量:\n"<<eig.eigenvectors()<<endl;
运行结果:
A:
3 2 -1
-2 -2 2
3 6 -1特征值: (2,0) (-4,0) (2,0)
特征值: (2,0) (-4,0) (2,0)
特征向量:
(0.889001,0) (0.267261,0) (-0.746408,0)
(-0.254,0) (-0.534522,0) (0.556032,0)
(0.381,0) (0.801784,0) (0.365655,0)
这里的所有计算结果都是用复数表示的,所以第二维都是零,观察特征向量时应竖向观察,一列为一个特征向量。
cout<<endl;
// 解方程
// 我们求解 matrix3d * x = v_3d 这个方程
// 直接求逆自然是最直接的,但是求逆运算量大
Eigen::Matrix<double, 3, 3> matrix_33= Eigen::Matrix3d::Random(3,3)*10;
matrix_33 = matrix_33 * matrix_33.transpose(); // 保证半正定
Eigen::Matrix<double, 3, 1> v_3d = Eigen::MatrixXd::Random(3, 1);
clock_t time_stt = clock(); // 计时
// 直接求逆
Eigen::Matrix<double,3, 1> x = matrix_33.inverse() * v_3d;
cout << "计算时间: "
<< 1000 * (clock() - time_stt) / (double) CLOCKS_PER_SEC << "ms" << endl;
cout << "x = " << x.transpose() << endl;
输出结果:
计算时间: 0.021ms
x = 0.00977934 -0.00773583 0.00556298
计算时间:0.16ms
x = 0.00977934 -0.00773583 0.00556298