Eigen库:数据定义及基础属性

预备工作

1.环境

博主最近在整理知识点,发现之前整理的Eigen笔记有不少地方存在错误,现重新整理。

此次开发环境为Windows10+CLion,首先前往Eigen官网下载源文件:Eigen官网地址

在这里插入图片描述

此处安装3.2版本的Eigen。下载压缩包后解压至某一地方存放。使用Ubuntu进行开发时,可使用如下指令安装Eigen3:

sudo apt-get install -y libeigen3-dev

安装的默认位置一般为:/usr/include/eigen3,可以使用如下指令查看库文件的具体安装位置。

sudo update
locate eigen3

2.新建工程

打开Clion,新建工程study,在该工程下新建子目录includesrc,并在src内新建源文件及CMakeLists.txt文件,整体结构如下:

在这里插入图片描述

3.CMakeLists.txt配置

根目录下的CMakeLists.txt填写内容如下:

# Cmake最低版本
cmake_minimum_required(VERSION 3.20)
# 工程名
project(study)
# CPP标准设置
set(CMAKE_CXX_STANDARD 14)
# 源文件目录设置
add_subdirectory(src)

srcCMakeLists.txt文件填写如下:

# include
include_directories(../include "F:\\it\\eigen")
# 生成文件
add_executable(start_eigen main.cpp)

将上述内容修改为你解压Eigen的地址即可。应注意,在Ubuntu中Eigen的地址一般如下:

include_directories("/usr/include/eigen3")

4.引用头文件

打开main.cpp文件,输入如下内容:

#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的原型如下:

Matrix<typename _Scalar, int _Rows, int _Cols>;
  • _Scalar:元素的数据类型,如int、float、double
  • _Rows_:矩阵行数
  • _Cols:矩阵列数

例如,定义一个三行一列的Double类型矩阵:

Matrix<double, 3, 1> matrix_a;

数组类Array的原型如下,其中参数类似矩阵类参数,不在赘述:

Array<typename _Scalar, int _Rows, int _Cols>;

例如,定义一个三行一列的Double类型数组:

Array<double, 3, 1> array_a;

快捷定义API

为进一步方便定义常用大小的数据,Eigen提供一些API。同时,在矩阵数据中提供了列向量(Vector)的快接定义。

在这里插入图片描述

例如定义一个 3 × 3 3\times3 3×3的Double类型矩阵,可直接使用API:

Matrix3d matrix_b;

数组类数据同样可调用API定义:

在这里插入图片描述

应注意,数组类型不存在向量。故而APIArray2d定义的大小为 2 × 1 2\times 1 2×1,而Array22d定义的大小才为 2 × 2 2\times2 2×2

向量

在Eigen中提前定义了两类特殊的TypeDef,分别用于表示列向量(Vector)和行向量(RowVector)。

对于N行一列的矩阵数据,视其为列向量Vector:

在这里插入图片描述

例如,定义三维Double类型Vector

Vector3d vector_a;

同样,对于一行N列的矩阵数据,视其为行向量RowVector:

在这里插入图片描述

向量本质上为特殊的矩阵数据,故而矩阵类Matrix的所有属性,向量都具备。

动态数据

对于尚未确定大小的数据,可以在该维度上填写-1表示维度未知:

// 初始大小2×2的动态矩阵
Matrix<double, -1, -1> matrix(2,2);

同样,定义快捷API用于定义常用类型,在缺失的维度上用X缩写代替:

在这里插入图片描述

例如,定义一个三行未知列数的Double类矩阵:

Matrix3Xd m;

数据处理

对于矩阵类Matrix数据和数组类Array数据,具有需要相同的API。若未特殊说明,则表明两类数据都具有此API可使用。

而对于向量类型数据,视其为矩阵数据一种特例,具有矩阵所有API。

数据初始化

定义数据类型及大小时,可对数据进行初始化:

//  初始化为全零矩阵
Matrix3d m_zero = Matrix3d::Zero();
//  初始化为全一矩阵
Matrix3d m_one = Matrix3d::Ones();
//  初始化为单位矩阵
Matrix3d m_I = Matrix3d::Identity();
//  初始化为随机矩阵,-1~1
Matrix3d m_rand = Matrix3d::Random();

同样,对于数组数据,具有相同的API(除单位矩阵API)。

元素赋值与获取

对于数据中各个元素的赋值,可以采用逐一赋值的方式进行:

//  初始化为全零矩阵
Matrix3d m_a = Matrix3d::Zero();
//  逐一输入矩阵数据
m_a << 1, 2, 3,
	   4, 5, 6,
	   7, 8, 9;

也可以采用索引方式获取元素,进行赋值:

//  初始化为全零矩阵
Matrix3d m_a = Matrix3d::Zero();
//  修改(1,1)元素值为1
m_a(0,0)=1;

采用迭代方式,能够编译数据获取各个元素:

#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;
}

输出结果如下:

 0 -1 -2
 1  0 -1
 2  1  0

常用属性

数据大小

对于非动态大小的数据,可以获得其行数、列数、元素个数:

int 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;
}

输出如下:

9  3  3

动态数据大小修改

对于动态数据,可使用resize()修改元素个数:

// 定义一个初始大小为2*2的动态矩阵
MatrixXd matrix(2, 2);
// 修改其大小为3*3
matrix.resize(3, 3);

数据转换

矩阵与数组的转换

在Eigen中,用矩阵数据Matrix进行线性计算,用数组数据Array进行元素间操作。

若此时对声明为矩阵的数据想要使用数组的API,需要将其先转为数组:

// 定义矩阵数据
Matrix3d a = Matrix3d::Identity();
//  转为数组数据使用其API
a.array();

反之,若数组数据想要使用矩阵API,应先转为矩阵:

// 定义数组数据
Array33d a = Array33d::Zero();
//  转为矩阵数据使用其API
a.matrix();

若要进行数组与矩阵间的计算,也应将其转换为同一类型后再行计算。此外,Eigen支持将数组类型数据赋值给矩阵或相反。

元素类型转换

由于Eigen不支持自动进行类型升级,若要进行不同元素类型的两数据间,应使用显示转换将其转为统一元素类型:

#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;
}

输出如下:

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值