Eigen的简单应用

Eigen是一个C++开源线性代数库,它提供了快速的矩阵相关的线性代数运算,还包括求解方程组,求特征值,特征向量等功能,许多上层的软件库也使用Eigen进行矩阵运算

与其他库相比,Eigen的特殊之处在于,它是一个纯用头文件搭建起来的库,这意味着你只能找到它的头文件,而没有文件后缀名为.so或.a的二进制文件的库,因此在使用的时候,只需引入Eigen的头文件即可,不需要链接库文件,接下来进行一些关于Eigen的简单使用

首先在工作目录下建立源文件eigenMatrix.cpp

#include<iostream>
using namespace std;
#include<ctime>
//Eigen的核心部分
#include<Eigen/Core>
//稠密矩阵的代数运算(逆,特征值等)
#include<Eigen/Dense>
using namespace Eigen;
#define Matrix_size 50

/*接下来演示其基本类型的使用*/
int main(int argc,char **argv)
{
	//Eigen中所有向量和矩阵都是Eigen::Matrix,他是一个模板类,前三个参数为数据类型、行、列
	//声明一个2*3的float矩阵
	Matrix<float,2,3> matrix_23;
	//同时,Eigen通过typedef提供了许多内置类型,不过底层仍是Eigen::Matrix
	//例如,Vector3d实质上是Eigen::Matrix<double,3,1>,即三维向量
	Vector3d v_3d;
	//这是一样的
	Matrix<float,3,1> vd_3d;
	//Matrix3d实质上是Eigen::Matrix<double,3.3>
	Matrix3d matrix_33 = Matrix3d::Zero();//初始化为0
	//如果不确定矩阵大小,可以使用动态大小的矩阵
	Matrix<double,Dynamic,Dynamic> matrix_dynamic;
	//更简单
	MatrixXd matrix_x;

	//.....依次类推
	//接下来是对Eigen阵的操作
	//输入数据(初始化)
	matrix_23<<1,2,3,4,5,6;
	cout<<"matrix_23输出为:\n"<<matrix_23<<endl;
	//用()访问矩阵中的元素
	cout<<"print matrix 2*3"<<endl;
	for(int i=0;i<2;i++)
	{
		for(int j=0;j<3;j++)
		{
		cout<<matrix_23(i,j)<<"\t";
		}
		cout<<endl;
	}
	//矩阵和向量相乘(实际上仍是矩阵和矩阵)
	v_3d<< 3,2,1;
	vd_3d<<4,5,6;
	//在eigen里面。不同数据类型的矩阵不能混合,应该显示转换
	//同时也要遵守矩阵的乘法法则
	//result.transpose()矩阵转置
	Matrix<double,2,1> result = matrix_23.cast<double>()*v_3d;
	cout<<"[1,2,3;4,5,6]*[3,2,1]:\n"<<result.transpose()<<endl;
	Matrix<float,2,1> result2 = matrix_23*vd_3d;
	cout<<"[1,2,3;4,5,6]*[4,5,6]:\n"<<result2.transpose()<<endl;

	//其他类型的矩阵运算如下
	matrix_33 = Matrix3d::Random();//随机数矩阵
	cout<<"random matrix:\n"<<matrix_33<<endl;	
	cout<<"transpose:\n"<<matrix_33.transpose()<<endl;//转置
	cout<<"各元素和sum:\t"<<matrix_33.sum()<<endl;//各元素求和
	cout<<"trace:\t"<<matrix_33.trace()<<endl;//迹
	cout<<"times 10:\n"<<10*matrix_33<<endl;//数乘
	cout<<"inverse:\n"<<matrix_33.inverse()<<endl;//逆
	cout<<"det:\t"<<matrix_33.determinant()<<endl;//行列式

	//特征值
	//实对称矩阵可以进行相似对角化
	SelfAdjointEigenSolver<Matrix3d> eigen_solver(matrix_33.transpose()*matrix_33);
	cout<<"Eigen values = \n"<<eigen_solver.eigenvalues()<<endl;//特征值
	cout<<"Eigen vectors = \n"<<eigen_solver.eigenvectors()<<endl;//特征向量
	
	//解方程
	//求解matrix_NN*x = v_Nd方程
	//N的大小在前面的宏里定义,它是由随机数生成
	//直接求逆较直接,但是运算量较大
	Matrix<double,Matrix_size,Matrix_size> matrix_NN = MatrixXd::Random(Matrix_size,Matrix_size);
	matrix_NN = matrix_NN * matrix_NN.transpose();//保证半正定
	Matrix<double,Matrix_size,1> v_Nd = MatrixXd::Random(Matrix_size,1);
	clock_t time_stt = clock();//计时
	//直接求逆
	Matrix<double,Matrix_size,1> x = matrix_NN.inverse()*v_Nd;
	cout<<"time of normal inverse is:"<<1000*(clock() - time_stt)/(double) CLOCKS_PER_SEC<<"ms"<<endl;
	cout<<"x = "<<x.transpose()<<endl;
	//通常用矩阵分解来求,比如QR分解,速度快很多
	time_stt = clock();
	x = matrix_NN.colPivHouseholderQr().solve(v_Nd);
	cout<< "time of QR is:"<<1000*(clock() - time_stt)/(double) CLOCKS_PER_SEC<<"ms"<<endl;
	cout<<"x = "<<x.transpose()<<endl;
	//对于正定矩阵,还可以用cholesky分解来解方程
	time_stt = clock();
	x = matrix_NN.ldlt().solve(v_Nd);
	cout<< "time of ldlt decomposition is:"<<1000*(clock() - time_stt)/(double) CLOCKS_PER_SEC<<"ms"<<endl;
	cout<<"x = "<<x.transpose()<<endl;

	
	system("pause");
	return 0;

}

上述程序历程演示了Eigen的一些基本运算,接下来要进行编译,在CMakeLists.txt中要指定Eigen的头文件目录:

#因为eigen库只有头文件,所以不需要再用target_link_libraries语句将程序链接到库上
include_directories("/usr/include/eigen3")

最后终端输入命令编译运行:

cd build
cmake ..
make
./eigenMatrix.cpp

运行结果为:

matrix_23输出为:
1 2 3
4 5 6
print matrix 2*3
1	2	3	
4	5	6	
[1,2,3;4,5,6]*[3,2,1]:
10 28
[1,2,3;4,5,6]*[4,5,6]:
32 77
random matrix:
 0.680375   0.59688 -0.329554
-0.211234  0.823295  0.536459
 0.566198 -0.604897 -0.444451
transpose:
 0.680375 -0.211234  0.566198
  0.59688  0.823295 -0.604897
-0.329554  0.536459 -0.444451
各元素和sum:	1.61307
trace:	1.05922
times 10:
 6.80375   5.9688 -3.29554
-2.11234  8.23295  5.36459
 5.66198 -6.04897 -4.44451
inverse:
-0.198521   2.22739    2.8357
  1.00605 -0.555135  -1.41603
 -1.62213   3.59308   3.28973
det:	0.208598
Eigen values = 
0.0242899
 0.992154
  1.80558
Eigen vectors = 
-0.549013 -0.735943  0.396198
 0.253452 -0.598296 -0.760134
-0.796459  0.316906 -0.514998

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值