最近再算矩阵运算的时候,接触了一些Eigen库,自己算了一些相关的矩阵算法,相关代码如下:
tips:代码是在windows进行的,需要手动的自己下载eigen库然后还有相关的链接
#include <iostream>
//Eigen部分
#include <Eigen/Dense>
//稠密矩阵的代数运算 (逆,特征值等)
#include<Eigen/Core>
using namespace Eigen;
using namespace std;
/*int main()
{
Vector3d v(1, 2, 3);
Vector3d w(0, 1, 2);
cout << "Dot product: " << v.dot(w) << endl;
double dp = v.adjoint() * w; // automatic conversion of the inner product to a scalar
cout << "Dot product via a matrix product: " << dp << endl;
cout << "Cross product:\n" << v.cross(w) << endl;
}*/
#define MATRIX_SIZE 50
int main(int argc, char** argv)
{
//Eigen 以矩阵为基本数据单元。他是一个模板类,他的前三个参数为:数据类型,行,列
//声明一个2*3的float矩阵
Eigen::Matrix<float, 2, 3> matrix_23;
//Eigen 通过typedef 提供了许多内置类型,不过底层仍是 Eigen::Matrix
//例如 Vector3d 实质上是Eigen::Matrix<double,3,1>
Eigen::Vector3d v_3d;
//Matrix3d实质上是Eigen::Matrix<double,3,3>
Eigen::Matrix3d matrix_33 = Eigen::Matrix3d::Zero();//初始化为零
//如果不确定矩阵大小,可以使用动态大小的矩阵
Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic>matrix_dynamic;
//更简单的
Eigen::MatrixXd matrix_x;
//下面演示对矩阵的操作
//输入数据
matrix_23 << 1, 2, 3, 4, 5, 6;
//输出
cout << matrix_23 << endl;
/* for (int i = 0; i < 1; i++) {
for (int j = 0; j < 2; j++){
cout << matrix_23(i, j) << endl;
}
}*/
for (int i = 0; i < 1; i++)
for (int j = 0; j < 2; j++)
std::cout << matrix_23(i, j) << std::endl;
v_3d << 3, 2, 1;
//矩阵和向量相乘(实际上仍是矩阵和矩阵)
//不同类型的矩阵,不能进行混合运算
//错误示范:
// Eigen::Matrix<double, 2, 1>result_wrong_type = matrix_23 * v_3d;
//为什么会出错呢,我们来分析以下原因 在这里我们首先定义 result是一个2*1的矩阵,类型是double的
// matrix_23 类型是float的2*3矩阵,他们在形式上是可以相乘的,但是由于里面的元素类型不同,所以是不可以的
// 应该做显示转换
// cout << result_wrong_type << endl;
//这里面.cast<duuble>是Eigen库里面一种提供显示转换的方式,毕竟方便快捷
Eigen::Matrix<double, 2, 1>result = matrix_23.cast<double>() * v_3d;
cout << result << endl;
matrix_33 = Eigen::Matrix3d::Random();//使用Eigen库来生成一个3×3的双精度浮点数矩阵,其中的元素是随机值
cout << matrix_33 << endl;
cout <<"转置运算"<< matrix_33.transpose() << endl;
cout <<"各元素和"<< matrix_33.sum() << endl;//
cout << "矩阵的迹" << matrix_33.trace() << endl; //矩阵的迹表示是矩阵主对角线之和
cout << "数乘" << 10 * matrix_33 << endl;
cout << "矩阵的逆" << matrix_33.inverse() << endl;
cout << "计算矩阵的行列式" << matrix_33.determinant() << endl;
//计算特征值 利用eigen的库可以计算矩阵的特征值以及特征向量
//实对称矩阵可以保证对角化成功
Eigen::SelfAdjointEigenSolver<Eigen::Matrix3d> eigen_solver (matrix_33.transpose() * matrix_33);
cout << "Eigen value =" << eigen_solver.eigenvalues() << endl;//特征值
cout << "Eigen vectors =" << eigen_solver.eigenvectors() << endl;//特征向量
//解方程
//我们求解matrix_NN * x = v_Nd 这个方程
//N的大小在前边的宏里定义,矩阵由随机数生成
//直接求逆自然之最直接的,但是求逆运算量大
Eigen::Matrix<double, MATRIX_SIZE, MATRIX_SIZE> matrix_NN;
matrix_NN = Eigen::MatrixXd::Random(MATRIX_SIZE, MATRIX_SIZE);
Eigen::Matrix<double,MATRIX_SIZE, 1>v_Nd;
v_Nd = Eigen::MatrixXd::Random(MATRIX_SIZE, 1);
clock_t time_stt = clock();//
//直接求逆
Eigen::Matrix<double, MATRIX_SIZE, 1> x = matrix_NN.inverse() * v_Nd;
//求时间的思路是 获取当前时间已经在程序执行前的时间,进行做差得到时钟数,时间差以时钟周期为单位
//之后除以LOCKS_PER_SEC,就可以将这个时间差转换为秒数
cout << "time use in normal invers is " <<" "<<1000 * (clock() - time_stt) / (double)CLOCKS_PER_SEC << "ms" << endl;
//矩阵求逆的另一种方式 例如用QR分解,速度会快很多
time_stt = clock();
x = matrix_NN.colPivHouseholderQr().solve(v_Nd);
cout << "time use in Qr compsition is " << 1000 * (clock() - time_stt) / (double)CLOCKS_PER_SEC << "ms" << endl;
return 0;
}