C++ Eigen 矩阵运算

news2025/1/16 12:37:17

文章目录

    • 1 Eigen的安装与CMakeLists.txt的编写
      • 1.1、Eigen的安装
      • 1.2、Eigen的CMakeLists.txt编写
      • 1.3、版本查看
    • 2、Eigen的头文件
    • 3、Eigen的基础
      • 3.1 Eigen初始化
        • 3.1.1 一些常用的初始化方法
      • 3.2 矩阵大小
      • 3.3 Eigen矩阵类
      • 3.4 Eigen矩阵的创建
      • 4 Eigen的Array类
      • 4.1 Array的初始化
      • 4.2 Array的其他操作
      • 4. 3、Array与Matrix之间的互相转换
    • 5 矩阵运算
      • 5.1 Matrix的转置和共轭
      • 5.2 向量的点积和叉积
      • 5.3 矩阵的基础的算术(求和,平均值等)
      • 5.4矩阵的块操作
      • 5.5 矩阵的行列操作
      • 5.6 矩阵边角相关的操作
      • 5.7 向量的块操作
      • 5.8 范数计算
    • 参考链接:

1 Eigen的安装与CMakeLists.txt的编写

Eigen是一个高层次的C ++库,有效支持线性代数矩阵矢量运算数值分析及其相关的算法。Eigen是一个开源库,从3.1.1版本开始遵从MPL2许可。

1.1、Eigen的安装

eigen3在linux下的安装可以直接用命令安装:

sudo apt-get install libeigen3-dev

1.2、Eigen的CMakeLists.txt编写

eigen库采用模板编程技术,仅由一些头文件组成,运行速度快。用cmake管理项目的时候,只需要在CMakeLists.txt里面头文件的路径即可:

find_package(Eigen3 REQUIRED)
include_directories(${EIGEN3_INCLUDE_DIR})

1.3、版本查看

tac /usr/include/eigen3/Eigen/src/Core/util/Macros.h    # tac表示从文本的后面往前输出

在这里插入图片描述

2、Eigen的头文件

Eigen所有的头文件及头文件里面的类的作用见下表
在这里插入图片描述
一般为了省事,可以直接导入#include <Eigen/Dense> 或者#include <Eigen/Eigen>

3、Eigen的基础

  • 先来一个最简单的eigen程序体验下

在这里插入图片描述
在这里插入图片描述

  • 一个简单的Matrixvector程序
  • 在这里插入图片描述

在这里插入图片描述
输出
在这里插入图片描述

3.1 Eigen初始化

Eigen提供了一种逗号初始化器语法,该语法使用户可以轻松设置矩阵,向量或数组的所有系数。只需列出系数,从左上角开始,从左到右,从上到下移动。需要预先指定对象的大小。如果列出的系数太少或太多,编译器就会报错。

此外,初始化列表的元素本身可以是向量或矩阵。通常的用途是将向量或矩阵连接在一起。例如,这是如何将两个行向量连接在一起。请记住,必须先设置大小,然后才能使用逗号初始化程序。

在这里插入图片描述
输出
在这里插入图片描述

3.1.1 一些常用的初始化方法

初始化为0,初始化为1,初始化为单位矩阵

在这里插入图片描述
输出
在这里插入图片描述

3.2 矩阵大小

矩阵的当前大小可以通过rows()cols()和size()检索。这些方法分别返回行数,列数和系数数。调整动态大小矩阵的大小是通过resize()方法完成的。
动态矩阵可以随意调整矩阵大小,固定尺寸`的矩阵无法调整大小
在这里插入图片描述
在这里插入图片描述

什么时候应该使用固定尺寸(例如Matrix4f),什么时候应该使用动态尺寸(例如MatrixXf)?简单的答案是:在可能的地方使用固定尺寸来显示非常小的尺寸,在需要的地方使用动态尺寸来显示较大的尺寸。

对于小尺寸,尤其是对于小于(大约)16的尺寸,使用固定尺寸对性能有极大的好处,因为它使Eigen避免了动态内存分配并展开了循环。在内部,固定大小的本征矩阵只是一个简单的数组,即

Matrix4f mymatrix;
等同于: 
float mymatrix[16];

因此,这确实具有零运行时间成本。相比之下,动态大小矩阵的数组始终分配在堆上,因此

MatrixXf mymatrix(rows,columns);
等同于: 
float mymatrix = new float[rows*columns];

矩阵分别有 .rows()、.cols()、.size() 函数来分别获取矩阵的行数、列数以及元素个数;
使用 .resize() 函数可以改变矩阵的大小
在这里插入图片描述
在这里插入图片描述

3.3 Eigen矩阵类

Matrix的3个必需模板参数是:

Matrix<typename Scalar, int RowsAtCompileTime, int ColsAtCompileTime>
  • Scalar 是标量类型,即系数的类型。也就是说,如果要使用浮点数矩阵,此处选择float。有关所有受支持的标量类型的列表以及如何将支持扩展到新类型的信息,请参见标量类型。
  • RowsAtCompileTime和ColsAtCompileTime是在编译时已知的矩阵的行数和列数。
    这里提供了许多方便的typedef来覆盖通常的情况。例如,Matrix4f是一个4x4的浮点矩阵。这是Eigen定义的:
typedef Matrix <float44> Matrix4f;

Eigen里面用到了很多的typedef简化名称长度,例如下面:

typedef Matrix<float, 3, 1>                               Vector3f;
typedef Matrix<int, 1, 2>                                 RowVector2i;
typedef Matrix<double, Dynamic, Dynamic> MatrixXd;
typedef Matrix<int, Dynamic, 1>                           VectorXi;
typedef Array<float,Dynamic,Dynamic>                      ArrayXXf
typedef Array<double,Dynamic,1>                           ArrayXd
typedef Array<int,1,Dynamic>                              RowArrayXi
typedef Array<float,3,3>                                  Array33f
typedef Array<float,4,1>                                  Array4f
......

在Eigen中可以使用 () 来获取矩阵中的元素,可以直接对矩阵中的元素进行赋值
如:m(4,7)就表示获取4行7列的元素
.data()函数用于返回一个指向矩阵或向量的首地址的指针
在这里插入图片描述
在这里插入图片描述

3.4 Eigen矩阵的创建

一般而言,创建一个矩阵需要调用 Matrix<> 构造,其共包含6个参数,前3个为必须参数,后3个为可选参数,有默认值。3个必须参数如下:
在这里插入图片描述

  • 向量的矩阵,例是列数恒为 1, 如
    在这里插入图片描述
    Eigen 库中预先定义了一些固定大小的矩阵和向量类型,如下所示:
    在这里插入图片描述
    可以指定矩阵的行数或者列数为 Dynamic ,创建动态大小的矩阵,如下所示:
    在这里插入图片描述

4 Eigen的Array类

Eigen 不仅提供了MatrixVector结构,还提供了Array结构。

区别如下,Matrix和Vector就是线性代数中定义的矩阵和向量,所有的数学运算都和数学上一致。但是存在一个问题是数学上的定义并不一定能完全满足现实需求。比如,数学上并没有定义一个矩阵和一个标量的加法运算。但是如果想给一个矩阵的每个元素都加上同一个数,那么这个操作就需要自己去实现,这显然并不方便。

Array 提供了一个Array类,也提供了大量的矩阵未定义的操作,且Array和Matrix之间很容易相互转换 ,所以相当于给矩阵提供更多的方法。也为使用者的不同需求提供了更多的选择。

  • Array类和Matrix有相同的参数。
Array<typename Scalar, int RowsAtCompileTime , int ColsAtCompileTime >

上面参数的意义和Matrix中参数的意义是相同的。
Array也对常用的情况作了一些类型定义。

typedef Array<float ,Dynamic,1> ArrayXf;
typedef Array<float,3,1> Array3f;
typedef Array<double,Dynamic ,Dynamic > ArrayXXd;
typedef Array<double ,3,3 > Array33d;

4.1 Array的初始化

Eigen::Array类重载了+、-、*、/ 运算符,可以直接用这些运算符对Array对象进行操作。相乘操作是对应的数字相乘,相除是对应的元素相除
在这里插入图片描述

4.2 Array的其他操作

Array 还定义了 绝对值 abs() ,开平方根sqrt() , 以及找对应元素最小值操作min()
在这里插入图片描述

4. 3、Array与Matrix之间的互相转换

Matrix类和Array类之间可以相互转换,必须显式转换,才能对他们进行加减乘除运算。

  • Array 有 .matrix( ) 方法。
  • Matrix 有 .array( )方法。

在这里插入图片描述

5 矩阵运算

5.1 Matrix的转置和共轭

对矩阵的转置、共轭和共轭转置由成员函数transpose(),conjugate(),adjoint()实现。

在这里插入图片描述

在这里插入图片描述
a = a.transpose();无法运行,这称为别名问题,在debug模式下当assertions没有禁止时,这种问题会被自动检测到。要避免错误,可以使用in-place转置。类似的还有adjointInPlace()。
所以正确的操作见下面程序:

    // a = a.transpose(); //   不要这样写代码,无法运行
    a.transposeInPlace();

5.2 向量的点积和叉积

对于点积和叉积,直接使用dot()cross()方法。
在这里插入图片描述

在这里插入图片描述
注意:记住叉积仅仅用于尺寸为3的向量!点积可以用于任意尺寸的向量,当使用复数时,Eigen的点积操作是第一个变量为共轭线性的,第二个为线性的。

5.3 矩阵的基础的算术(求和,平均值等)

Eigen提供了一些对于矩阵或向量的规约操作,如sum(),prod(),maxCoeff()minCoeff()
在这里插入图片描述
在这里插入图片描述

trace为矩阵的迹,也可以由a.diagonal().sum()得到。
minCoeffmaxCoeff函数也可以返回相应的元素的位置信息

5.4矩阵的块操作

块指的是矩阵或数组中的一个矩形区域,块表达式可以用于左值或者右值,同样不会耗费运行时间,由编译器优化。
Eigen中最常用的块操作是block()方法,共有两个版本。
在这里插入图片描述
在这里插入图片描述

上述例子中的块操作方法作为表达式的右值,意味着是只读形式的,然而,块操作也可以作为左值使用,意味着你可以给他赋值。下面的例子说明了这一点,当然对于矩阵的操作是一样的。

在这里插入图片描述
在这里插入图片描述
尽管block()方法可用于任何形式的块操作,还是有特殊的方法API用于特殊情况的,主要是为了更好的性能。
说到性能,最重要的是在编译阶段给Eigen尽可能多的信息。

比如,如果你的块是一个矩阵中的一列,那么使用col()方法会更好。本节其余的介绍都是关于这些特殊的方法的。

5.5 矩阵的行列操作

行和列是一中特殊的块。Eigen提供了特殊的方法:col() 列 row() 行。
在这里插入图片描述

5.6 矩阵边角相关的操作

Eigen同样提供了对于挨着矩阵或数组的边、角的特殊操作方法,比如topLeftCorner()方法可用于操作矩阵左上角的区域。总结如下:

在这里插入图片描述

5.7 向量的块操作

Eigen也提供了一些针对向量和一维数组的块操作方法:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

5.8 范数计算

向量的平方范数由squaredNorm()获得,等价于向量对自身做点积,也等同于所有元素额平方和。Eigen也提供了norm()范数,返回的是squaredNorm()的根。这些操作也适用于矩阵。

如果想使用其他元素级的范数,使用lpNorm()方法,当求无穷范数时,模板参数p可以取特殊值Infinity,得到的是所有元素的最大绝对值。
在这里插入图片描述

在这里插入图片描述

参考链接:

  • https://blog.csdn.net/hongge_smile/article/details/107296658
  • https://mp.weixin.qq.com/s/tLLb0N38s-wDV7iko2zyFg
  • https://mp.weixin.qq.com/s/zN-NTds0qvB_OsZwx5l1Hg

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1104563.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

JavaScript爬虫程序实现自动化爬取tiktok数据教程

以下是一个使用 request-promise 和 JavaScript 的爬虫程序&#xff0c;用于爬取tiktok的内容。此程序使用了 https://www.duoip.cn/get_proxy 这段代码。 // 引入 request-promise 库 const rp require(request-promise);// 定义 get\_proxy 函数 function get_proxy() {retu…

千兆光模块存在哪些局限性

千兆光模块是目前使用最广泛的光模块之一&#xff0c;可以实现1Gbps的传输速度。随着科技的进步和应用场景的多样性&#xff0c;千兆光模块也因其固有的局限性而面临越来越多的挑战。以下是千兆光模块的局限性和如何克服这些局限性的讨论&#xff1a; 千兆光模块可以实现最大…

钻井平台升降装置锁紧液压系统比例阀放大器

钻井平台升降装置锁紧液压系统为钻井平台桩腿的锁紧装置提供动力&#xff0c;通过液压马达驱动垂直布置的上下螺杆传动装置的伸缩&#xff0c;使锁紧齿条和桩腿上的弦管齿条啮合和分离&#xff0c;实现平台的锁紧、负载转移、均载和解锁。

05 依赖倒置原则

官方定义&#xff1a; 依赖倒置原则&#xff08;Dependence Inversion Principle&#xff0c;DIP&#xff09;是指在设计代码架构 时&#xff0c;高层模块不应该依赖于底层模块&#xff0c;二者都应该依赖于抽象。抽象不应该依 赖于细节&#xff0c;细节应该依赖于抽象。 通俗…

Linux系统添加硬件设备流程

Linux系统添加硬件设备的流程 添加硬盘设备的操作&#xff1a; 一、在虚拟机中模拟添加入一块新的硬盘存储设备 &#xff08;步骤见《Linux这么学》P191&#xff09; 二、依次进行分区、格式化、挂载操作 1.分区 &#xff08;1&#xff09;新建、修改及删除磁盘的分区表信息 #…

PAM从入门到精通(五)

接前一篇文章&#xff1a;PAM从入门到精通&#xff08;四&#xff09; 本文参考&#xff1a; 《The Linux-PAM Application Developers Guide》 先再来重温一下PAM系统架构&#xff1a; 更加形象的形式&#xff1a; 五、主要函数详解 3. pam_set_item 概述&#xff1a; 设置…

可追溯性在MES管理系统解决方案中的重要性

在当今制造业中&#xff0c;“可追溯性”已经变得至关重要。它能够在产品出现问题时迅速定位问题源头&#xff0c;并持续优化生产流程&#xff0c;确保产品质量得到提升和保持稳定。 可追溯性不仅涉及追踪产品来源&#xff0c;还是一种保障数据真实性的手段。与数据安全技术相…

OTP语音芯片和TTS语音芯片的差异性

OTP&#xff08;One-Time Programmable&#xff09;语音芯片和TTS&#xff08;Text-to-Speech&#xff09;语音芯片是两种不同类型的声音处理芯片。OTP主要用于播放预录声音片段&#xff0c;而TTS则根据文本实时生成语音。OTP的灵活性较弱&#xff0c;适用于固定声音输出&#…

组件自定义事件 和 解绑事件

组件自定义事件 和 解绑事件 组件自定义事件 功能&#xff1a;父组件绑定数据&#xff0c;子组件触发事件。&#xff08;父绑子触发&#xff09; 实现步骤&#xff08;前三步在父组件实现&#xff0c;第四步在子组件实现&#xff09;&#xff1a; 第一步&#xff1a;提供事件…

图文结合丨Prometheus+Grafana+GreatSQL性能监控系统搭建指南(下)

一、环境介绍 本文环境&#xff0c;以及本文所采用数据库为GreatSQL 8.0.32-24 $ cat /etc/system-release Red Hat Enterprise Linux Server release 7.9 (Maipo) $ uname -a Linux gip 3.10.0-1160.el7.x86_64 #1 SMP Tue Aug 18 14:50:17 EDT 2020 x86_64 x86_64 x86_64 G…

单电源、轨到轨输入输出、高精度运放MS8551/8552/8554,可替代ADI的8551/8552/8554

MS8551/8552/8554 是输入输出轨到轨的高精度运算放大器&#xff0c;它 有极低的输入失调电压和偏置电流&#xff0c;单电源电压范围为 1.8V 到 5V 。 轨到轨的输入输出范围使 MS8551/8552/8554 可以轻松地放大高 电平和低电平的传感信号。所有特性使得 MS8551/8552/8…

C# 快速简单反射操作

文章目录 前言新反射使用BindingFlags以公有属性使用举例运行结果 前言 我之前写过一篇博客&#xff0c;是关于C# 反射的&#xff0c;我那时候使用的C# 反射写起来还是比较麻烦&#xff0c;需要获取Properies,再遍历Property&#xff0c;再找到对应Property&#xff0c;再使用…

Apache DolphinScheduler 官方发布3.2.0版本!大数据调度【重磅更新】

今天&#xff0c;Apache DolphinScheduler 3.2.0 版本在万众期待中终于发布了&#xff01;在之前的预告中&#xff0c;包括《重磅预告&#xff01;Apache DolphinScheduler 3.2.0 新功能“剧透”》、《3.2.0 版本预告&#xff01;Apache DolphinScheduler API 增强相关功能》、…

抖音电商商品卡实时免佣进入正式期!订单佣金实时返还,你拿到了吗?

“卖更多免更多”&#xff0c;抖音电商商品卡免佣政策落地至今&#xff0c;因其操作简单、门槛低&#xff0c;流量渠道丰富以及能够实实在在为商家降低经营成本的优势&#xff0c;迎来超百万商家踊跃参与。在政策持续进行过程中&#xff0c;切切实实助力新商家从0到1快速打开生…

Day17|110.平衡二叉树

一、110.平衡二叉树 题目链接&#xff1a;https://leetcode.cn/problems/balanced-binary-tree/ 文章链接&#xff1a;https://programmercarl.com/0110.%E5%B9%B3%E8%A1%A1%E4%BA%8C%E5%8F%89%E6%A0%91.html#%E7%AE%97%E6%B3%95%E5%85%AC%E5%BC%80%E8%AF%BE 视频链接&#xff…

安卓系统如何在WIFI里设置s5静态IP

在 Android 设备上使用 Wi-Fi Settings 设置s5的详细教程&#xff1a; 1、首先&#xff0c;打开您的 Android 设备的 “设置” 应用。 2、在设置菜单中&#xff0c;点击 “Wi-Fi” 选项。 3、确保您已经连接到一个 Wi-Fi 网络。如果没有连接&#xff0c;请点击 “添加网络” …

小程序技术在信创操作系统中的应用趋势:适配能力有哪些?

小程序技术在信创操作系统中的应用前景非常广阔&#xff0c;但也面临着一些挑战和问题。开发者需要积极应对这些挑战和问题&#xff0c;为信创操作系统的发展和推广做出贡献。同时&#xff0c;开发者也需要关注小程序技术在信创操作系统中的应用趋势&#xff0c;积极探索新的应…

Web安全系列——越权访问(权限控制失效)

一、前言 越权访问是当前Web应用中最常见的安全风险之一。 本文将介绍越权访问的原理、风险以及典型攻击场景&#xff0c;并为开发者提供有效的防范措施&#xff0c;帮助构建安全的Web应用。 二、什么是越权访问 越权访问&#xff0c;是指用户在不具备相应权限&#xff08;…

DevOps2023现状报告|注重文化、以用户为中心是成功的关键

Google Cloud DORA 团队的一份新研究报告强调了企业文化和关注用户作为成功软件交付支柱的重要性。 2023 DevOps 状况报告分析了过去 9 年来通过此类最大规模调查收集的全球 36,000 多名 IT 专业人员的数据。今年的报告是继 2022 年调查之后发布的&#xff0c;该调查发现越来…

使用RCurl和R来爬虫视频

以下是一个使用RCurl和R来爬虫视频的示例代码&#xff0c;代码中使用了https://www.duoip.cn/get_proxy来获取代理IP&#xff1a; # 引入必要的库 library(RCurl) library(rjson)# 获取代理IP proxy_url <- "https://www.duoip.cn/get_proxy" proxy <- getURL…