预备工作
1.环境
博主最近在整理知识点,发现之前整理的Eigen笔记有不少地方存在错误,现重新整理。
此次开发环境为Windows10+CLion,首先前往Eigen官网下载源文件:Eigen官网地址
此处安装3.2版本的Eigen。下载压缩包后解压至某一地方存放。使用Ubuntu进行开发时,可使用如下指令安装Eigen3:
1
2sudo apt-get install -y libeigen3-dev
安装的默认位置一般为:/usr/include/eigen3,可以使用如下指令查看库文件的具体安装位置。
1
2
3sudo update locate eigen3
2.新建工程
打开Clion,新建工程study
,在该工程下新建子目录include
和src
,并在src
内新建源文件及CMakeLists.txt
文件,整体结构如下:
3.CMakeLists.txt配置
根目录下的CMakeLists.txt
填写内容如下:
1
2
3
4
5
6
7
8
9# Cmake最低版本 cmake_minimum_required(VERSION 3.20) # 工程名 project(study) # CPP标准设置 set(CMAKE_CXX_STANDARD 14) # 源文件目录设置 add_subdirectory(src)
src
内CMakeLists.txt
文件填写如下:
1
2
3
4
5# include include_directories(../include "F:\it\eigen") # 生成文件 add_executable(start_eigen main.cpp)
将上述内容修改为你解压Eigen的地址即可。应注意,在Ubuntu中Eigen的地址一般如下:
1
2include_directories("/usr/include/eigen3")
4.引用头文件
打开main.cpp文件,输入如下内容:
1
2
3
4
5
6
7
8
9
10
11
12
13#include<iostream> using namespace std; // 导入Eigen库的核心和用于稠密矩阵运算的Dense #include <Eigen/Core> #include <Eigen/Dense> using namespace Eigen; int main(int argc, chr **argv){ return 0; }
此部分引用了Eigen库的核心Core和用于稠密矩阵线性计算的Dense。
数据类型
Eigen库中最基础的数据类型为矩阵(Matrix)和数组(Array),其类原型如下:
数据原型
矩阵类Matrix
的原型如下:
1
2Matrix<typename _Scalar, int _Rows, int _Cols>;
_Scalar
:元素的数据类型,如int、float、double_Rows_
:矩阵行数_Cols
:矩阵列数
例如,定义一个三行一列的Double类型矩阵:
1
2Matrix<double, 3, 1> matrix_a;
数组类Array
的原型如下,其中参数类似矩阵类参数,不在赘述:
1
2Array<typename _Scalar, int _Rows, int _Cols>;
例如,定义一个三行一列的Double类型数组:
1
2Array<double, 3, 1> array_a;
快捷定义API
为进一步方便定义常用大小的数据,Eigen提供一些API。同时,在矩阵数据中提供了列向量(Vector)的快接定义。
例如定义一个 3 × 3 3times3 3×3的Double类型矩阵,可直接使用API:
1
2Matrix3d matrix_b;
数组类数据同样可调用API定义:
应注意,数组类型不存在向量。故而APIArray2d
定义的大小为
2
×
1
2times 1
2×1,而Array22d
定义的大小才为
2
×
2
2times2
2×2。
向量
在Eigen中提前定义了两类特殊的TypeDef
,分别用于表示列向量(Vector)和行向量(RowVector)。
对于N行一列的矩阵数据,视其为列向量Vector:
例如,定义三维Double类型Vector
1
2Vector3d vector_a;
同样,对于一行N列的矩阵数据,视其为行向量RowVector:
向量本质上为特殊的矩阵数据,故而矩阵类Matrix的所有属性,向量都具备。
动态数据
对于尚未确定大小的数据,可以在该维度上填写-1表示维度未知:
1
2
3// 初始大小2×2的动态矩阵 Matrix<double, -1, -1> matrix(2,2);
同样,定义快捷API用于定义常用类型,在缺失的维度上用X缩写代替:
例如,定义一个三行未知列数的Double类矩阵:
1
2Matrix3Xd m;
数据处理
对于矩阵类Matrix数据和数组类Array数据,具有需要相同的API。若未特殊说明,则表明两类数据都具有此API可使用。
而对于向量类型数据,视其为矩阵数据一种特例,具有矩阵所有API。
数据初始化
定义数据类型及大小时,可对数据进行初始化:
1
2
3
4
5
6
7
8
9// 初始化为全零矩阵 Matrix3d m_zero = Matrix3d::Zero(); // 初始化为全一矩阵 Matrix3d m_one = Matrix3d::Ones(); // 初始化为单位矩阵 Matrix3d m_I = Matrix3d::Identity(); // 初始化为随机矩阵,-1~1 Matrix3d m_rand = Matrix3d::Random();
同样,对于数组数据,具有相同的API(除单位矩阵API)。
元素赋值与获取
对于数据中各个元素的赋值,可以采用逐一赋值的方式进行:
1
2
3
4
5
6
7// 初始化为全零矩阵 Matrix3d m_a = Matrix3d::Zero(); // 逐一输入矩阵数据 m_a << 1, 2, 3, 4, 5, 6, 7, 8, 9;
也可以采用索引方式获取元素,进行赋值:
1
2
3
4
5// 初始化为全零矩阵 Matrix3d m_a = Matrix3d::Zero(); // 修改(1,1)元素值为1 m_a(0,0)=1;
采用迭代方式,能够编译数据获取各个元素:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23#include <iostream> #include <Eigen/Core> #include <Eigen/Dense> using namespace std; using namespace Eigen; int main() { // 初始化为全零矩阵 Matrix3d m_a = Matrix3d::Zero(); // 修改(1,1)元素值为1 m_a(0,0)=1; // 遍历数据进行修改 for(int i=0; i<3; i++){ for(int j=0; j<3; j++){ m_a(i,j)=i-j; } } cout << m_a << endl; return 0; }
输出结果如下:
1
2
3
40 -1 -2 1 0 -1 2 1 0
常用属性
数据大小
对于非动态大小的数据,可以获得其行数、列数、元素个数:
1
2
3
4
5
6
7
8
9
10
11
12
13int main() { Matrix3d m_a = Matrix3d::Identity(); // 矩阵元素个数 int s = m_a.size(); // 矩阵行数 int r = m_a.rows(); // 矩阵列数 int c = m_a.cols(); cout << s << " " << r << " "<< c << endl; return 0; }
输出如下:
1
29 3 3
动态数据大小修改
对于动态数据,可使用resize()
修改元素个数:
1
2
3
4
5// 定义一个初始大小为2*2的动态矩阵 MatrixXd matrix(2, 2); // 修改其大小为3*3 matrix.resize(3, 3);
数据转换
矩阵与数组的转换
在Eigen中,用矩阵数据Matrix进行线性计算,用数组数据Array进行元素间操作。
若此时对声明为矩阵的数据想要使用数组的API,需要将其先转为数组:
1
2
3
4
5// 定义矩阵数据 Matrix3d a = Matrix3d::Identity(); // 转为数组数据使用其API a.array();
反之,若数组数据想要使用矩阵API,应先转为矩阵:
1
2
3
4
5// 定义数组数据 Array33d a = Array33d::Zero(); // 转为矩阵数据使用其API a.matrix();
若要进行数组与矩阵间的计算,也应将其转换为同一类型后再行计算。此外,Eigen支持将数组类型数据赋值给矩阵或相反。
元素类型转换
由于Eigen不支持自动进行类型升级,若要进行不同元素类型的两数据间,应使用显示转换将其转为统一元素类型:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16#include <iostream> #include <Eigen/Core> #include <Eigen/Dense> using namespace std; using namespace Eigen; int main() { // 定义数据 Matrix3d a = Matrix3d::Identity(); Matrix3f b = Matrix3f::Identity(); // 显示转换为float cout << a.cast<float>()+b << endl; return 0; }
输出如下:
1
2
3
42 0 0 0 2 0 0 0 2
最后
以上就是欢喜野狼最近收集整理的关于Eigen库:数据定义及基础属性预备工作数据类型数据处理的全部内容,更多相关Eigen库内容请搜索靠谱客的其他文章。
发表评论 取消回复