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


  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值