惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
PCI Perspectives
PCI Perspectives
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
Google Online Security Blog
Google Online Security Blog
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
The GitHub Blog
The GitHub Blog
S
Secure Thoughts
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
WordPress大学
WordPress大学
SecWiki News
SecWiki News
B
Blog
小众软件
小众软件
Hacker News - Newest:
Hacker News - Newest: "LLM"
Webroot Blog
Webroot Blog
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
L
LINUX DO - 热门话题
Recent Commits to openclaw:main
Recent Commits to openclaw:main
酷 壳 – CoolShell
酷 壳 – CoolShell
IT之家
IT之家
The Cloudflare Blog
Google DeepMind News
Google DeepMind News
Know Your Adversary
Know Your Adversary
Y
Y Combinator Blog
F
Fortinet All Blogs
W
WeLiveSecurity
博客园 - Franky
MongoDB | Blog
MongoDB | Blog
Last Week in AI
Last Week in AI
The Last Watchdog
The Last Watchdog
S
Schneier on Security
爱范儿
爱范儿
V
V2EX - 技术
L
LINUX DO - 最新话题
月光博客
月光博客
博客园 - 【当耐特】
Latest news
Latest news
阮一峰的网络日志
阮一峰的网络日志
博客园 - 司徒正美
U
Unit 42
Schneier on Security
Schneier on Security
E
Exploit-DB.com RSS Feed
J
Java Code Geeks
Cyberwarzone
Cyberwarzone
T
The Blog of Author Tim Ferriss
TaoSecurity Blog
TaoSecurity Blog
博客园 - 叶小钗
T
Troy Hunt's Blog
大猫的无限游戏
大猫的无限游戏
AI
AI
Security Latest
Security Latest

又见苍岚

COLMAP PatchMatch Stereo 算法详解 事件驱动的状态机框架:从理论到工程实践 Git 在国内网络环境下无法 Push 的排查与修复 —— 配置 Clash 代理 分段五次多项式插值原理详解 路径插值方法深度对比研究 Claude Code 使用指南 OpenClaw 记忆管理与技能创建指南 CBS(Conflict-Based Search)算法详解 A* 算法及其变种详解 OpenClaw 配置多 Agents Windows Powershell 无法加载文件,因为在此系统上禁止运行脚本问题的解决方案 MaxClaw 安装流程 大模型 AI 名词介绍 AList 网盘聚合工具简介 Protobuf 简介与测试 Claude Code 简介以及 GLM 4.7 模型接入 Github 歌词下载工具 163MusicLyrics Python __getattr__ 懒加载 Python TypedDict 机器人仿真平台 Gazebo 安装记录 机器人仿真平台 Gazebo 简介 多机器人路径规划问题(Multi-Agent Path Finding, MAPF)简介 Python exifread 读取修改过的 jpeg 信息错误问题修复 3D 坐标系变换的理解 3D 旋转矩阵基本概念 MongoDB Compass 介绍 Python 环境管理工具 uv Flutter 开发指南 Snipaste 安装下载与黑屏问题解决方案 全局路径规划算法记录 2025 Python 版本性能测试 Flutter Hello World Flutter 安装环境配置 Ubuntu VMware 硬盘扩容后 SMBus Host controller not enabled 报错问题解决 Python NetworkX 教程 Docker GPU 报错 - Failed to initialize NVML Unknown Error 解决方案 Python matplotlib 图表绘制 cuda-toolkit 安装替代 Cuda 与 Cudnn Jinja2 Python 利用 docxtpl 和 Jinja2 生成基于模板的 Word 文档 Docker 实现 CPU 核心隔离 LoFTR 基于 Transformer 的特征提取匹配算法 OmniGlue 特征匹配 SuperGlue 使用图神经网络学习特征匹配 Ubuntu 下将 xlsx 文件按照 sheet 转换为 图片 Python 使用 SQLAlchemy Python FastAPI 教程 openwrt 软路由配置安装 Nav2 地图文件(PGM/YAML)规范标准 3D OBJ 模型转换为 glb 瓦片格式 Python 源码 Redis 数据库介绍 Ubuntu 22.04 内核自动升级导致 MongoDB 7.0.12 错误记录 ubuntu 20.04 安装 ROS Noetic ubuntu 18.04 安装 ROS Melodic VMware Workstation Pro 个人免费版下载、安装、使用指南 Hybrid A-star 路径规划 Reeds-Shepp 曲线 Dubins 曲线 Linux kvm 虚拟机网络不通的问题解决方法 Ubuntu 自动内存清理 BiliBili 缓存视频转 mp4 Python 求解线性规划 3D Gaussian Splatting 官方源码实践记录 ImageMagick 教程 Ubuntu 22.04 安装 Colmap 对数几率 odds Ubuntu nmcli 网络管理工具使用指南 SuperPoint 自监督深度学习特征点提取 SyncTV Music Tag Web 在线音乐信息整理工具 ncm 格式转 mp3 MusicBrainz 音乐元数据百科数据库 Ubuntu 网络流量监控工具 私人云音乐平台 Navidrome 入门 手眼标定 四元数(Quaternions) OHTTPS 实现免费自动 https 证书申请、更新、部署 ubuntu 22.04 安装 CloudCompare 单机 KVM 虚拟机冷迁移 Ubuntu 22.04 使用 mdadm 实现软 raid 小鱼 一键安装 ROS-humble Fluid -46- 基于 Simpletex API 构建公式识别页面 公式识别 API 简介 -- Simpletex 使用 Python web 部署库 waitress 3D Gaussian Splatting for Real-Time Radiance Field Rendering Ubuntu Swap 简介与空间扩展 Ubuntu 24.04 安装 forticlient Clash Verge 使用 MongoDB 7.0.17 集群 Docker 构建源码 Error code - 2013. Lost connection to MySQL server during query 问题解决 Python 日志记录库 loguru 使用指北 Python 实现 Web 日志查看服务 MySQL LOAD DATA LOCAL INFILE 极速数据加载 Image size exceeds limit of 89478485 pixels 解决方案 Docker 使用 NVIDIA GPU 驱动错误解决 阿里云 docker 镜像仓库 Ubuntu中没有wired connected的解决方案 MinIO 简介 subconverter 代理订阅格式转换 修复 node –openssl-legacy-provider is not allowed in NODE_OPTIONS 错误
Eigen 使用教程
Yiwei Zhang · 2023-01-12 · via 又见苍岚

Eigen 是开源的C++线性代数库,常用在计算机图形学中,之前我们记录了 安装使用方法,本文记录常用功能使用方法。

动态矩阵、静态二维矩阵

  • Eigen 官方代码支持的最高维度为二维矩阵,后文的矩阵、数组均为二维。
  • Eigen 在编译期间确定尺寸的矩阵为静态矩阵,运行期间确定尺寸的为动态矩阵(数据类型中带有X)
  • 选用原则:
    • 对于非常小尺寸的矩阵,尽可能使用固定尺寸,特别是小于(大约)16的尺寸,使用固定尺寸对性能非常有益,因为它允许 Eigen 避免动态内存分配和展开循环; 对于小尺寸在内部,一个固定大小的特征矩阵只是一个普通的数组。
    • 对于较大尺寸,或者在必须使用动态尺寸的地方,尽量使用动态尺寸。当矩阵尺寸大于(大约)32时,静态矩阵的性能收益变得可以忽略,而且对于动态矩阵,Eigen 更倾向于尝试使用 SIMD 指令集加速运算。

模板类

  • Eigen 中有几个基础数据结构模板类

Matrix类

  • 所有矩阵和向量都是Matrix模板类的对象,Matrix类有6个模板参数,主要使用前三个,剩下的使用默认值。
  • MaxRowsAtCompileTimeMaxColsAtCompileTime 在已知动态矩阵的尺寸上界时是可以提升工作效率的。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
Matrix<typename Scalar, 
int RowsAtCompileTime,
int ColsAtCompileTime,
int Options = 0,
int MaxRowsAtCompileTime = RowsAtCompileTime,
int MaxColsAtCompileTime = ColsAtCompileTime>
# Scalar 元素类型
# RowsAtCompileTime 行
# ColsAtCompileTime 列
# 例 typedef Matrix<int, 3, 3> Matrix3i;
# Options 比特标志位
# MaxRowsAtCompileTime和MaxColsAtCompileTime表示在编译阶段矩阵的上限。

# 列向量
typedef Matrix<double, 3, 1> Vector3d;
# 行向量
typedef Matrix<float, 1, 3> RowVector3f;

# 动态大小
typedef Matrix<double, Dynamic, Dynamic> MatrixXd;
typedef Matrix<float, Dynamic, 1> VectorXf;
type

  • 默认构造时,指定大小的矩阵,只分配相应大小的空间,不进行初始化。动态大小的矩阵,则未分配空间。

  • []操作符可以用于向量元素的获取,但不能用于matrix

  • matrix的大小可以通过rows(), cols(), size()获取,resize()可以重新调整矩阵大小。

  • Matrix 定义的矩阵为静态矩阵,在编译时确定尺寸、分配内存,随机初始化:

1
2
3
4
5
6
7
Matrix<int, 3, 3> a;
cout << a;

-->
1284850368 32759 1
32759 31 0
1284845929 0 0

  • MatrixX 开头的为动态矩阵,两个维度都可以变化,本质为 Matrix<Type, Dynamic, Dynamic> 定义的类型

    例如: MatrixXd 为 double 类型的动态矩阵

    1
    2
    3
    4
    5
    6
    7
    MatrixXd  a(3, 3);
    cout << a;

    -->
    0 0 0
    0 0 0
    0 0 0

  • 静态矩阵运算很快,但是有 128k 的堆栈尺寸限制,常用的还是动态矩阵类型

  • 仅变化一个维度的动态矩阵为动态向量 typedef Matrix<float, Dynamic, 1> VectorXf,使用方法类似

Array类

  • Array是类模板,前三个参数必须指定,后三个参数可选。
1
2
3
4
5
6
7
8
9
10
11
12
13
Array<typename Scalar,
int RowsAtCompileTime,
int ColsAtCompileTime>
# 常见类定义
typedef Array<float, Dynamic, 1> ArrayXf
typedef Array<float, 3, 1> Array3f
typedef Array<double, Dynamic, Dynamic> ArrayXXd
typedef Array<double, 3, 3> Array33d

ArrayXf a = ArrayXf::Random(5);
a.abs(); # 绝对值
a.sqrt(); # 平方根
a.min(a.abs().sqrt()); # 两个array相应元素的最小值

  • 类似于 Matrix 类,Array 默认仍会产生静态数组

    1
    2
    3
    4
    5
    6
    7
    Array<int, 3, 3> a;
    cout << a;

    -->
    -412990784 32758 1
    32758 31 0
    -412995223 0 0

  • 一维动态数组为 ArrayX 开头,二维动态数组为 ArrayXX 开头

    1
    2
    3
    4
    5
    6
    7
    ArrayXXi  a(3, 3);
    cout << a;

    -->
    6357107 7471220 4522044
    7929971 6422621 6029371
    7667805 7209066 7471185

Array 和 Martix 的区别

  • Martix 表示的是矩阵,运算为矩阵运算,运算时尺寸需要遵循矩阵运算规则
  • Array 和 Matrix 数据组成相同,但运算规则为逐元素运算,需要相同尺寸数据进行运算

Array 和 Martix 的转换

  • Matrix对象——>Array对象:.array()函数
  • Array对象——>Matrix对象:.matrix()函数

初始化

建议矩阵数据都要初始化,不然是十分危险的。

默认初始化

  • 默认初始化为随机数:
1
2
3
4
5
6
ArrayXXi  a(2, 4);
cout << a;

-->
7602273 7209025 7209071 3014707
6029409 6488161 6357092 3014712

赋值初始化

  • 赋值初始化

    1
    2
    3
    4
    5
    6
    7
    Matrix<int, 5, 1> b {1, 2, 3, 4, 5};
    Matrix<double, 2, 3> b {
    {2, 3, 4},
    {5, 6, 7},
    };
    VectorXd a {{1.5, 2.5, 3.5}};
    RowVectorXd b {{1.0, 2.0, 3.0, 4.0}};

对象初始化

  • 可以用其他对象初始化新的相同内容对象

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    Eigen::MatrixXf m(4, 4);

    m << 1, 2, 3, 4,
    5, 6, 7, 8,
    9, 10, 11, 12,
    13, 14, 15, 16;
    MatrixXf n(m);
    m.block(0, 0, 2, 2).swap(n.block(2, 2, 2, 2));

    cout << m;

    -->

    11 12 3 4
    15 16 7 8
    9 10 11 12
    13 14 15 16

逗号初始化

  • 为矩阵元素赋值,顺序是从左到右,从上到下,数目必须匹配。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
ArrayXXi  a(2, 3);
a << 1, 2, 3, 4, 5, 6;
cout << a << endl << endl;

ArrayXXi b(2, 2);
b << 7, 8, 9, 10;
cout << b << endl << endl;

ArrayXXi c(4, 7);
c << b, a, b, a, b, b;
cout << c << endl << endl;

-->
1 2 3
4 5 6

7 8
9 10

7 8 1 2 3 7 8
9 10 4 5 6 9 10
1 2 3 7 8 7 8
4 5 6 9 10 9 10

特殊矩阵初始化

静态矩阵

一下几个函数均为静态矩阵调用的初始化函数,动态矩阵调用会报错:

1
YOU CALLED A_FIXED SIZE METHOD ON A DYNAMIC SIZE MATRIX OR VECTOR
  • 零阵:类静态成员函数Zero()
  • 常量矩阵:Constant(rows, cols, value)
  • 随机矩阵:Random()
  • 单位矩阵:Identity()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
Matrix<int, 3, 3> a;
cout << a << endl << endl;

a = a.Zero();
cout << a << endl << endl;

a = a.Constant(3, 3, 7);
cout << a << endl << endl;

a = a.Random();
cout << a << endl << endl;

a = a.Identity();
cout << a << endl << endl;

-->
1028866792 32759 1
32759 31 0
1028862809 0 0

0 0 0
0 0 0
0 0 0

7 7 7
7 7 7
7 7 7

-16343 10116 -4906
2083 2785 12974
-10050 -660 10578

1 0 0
0 1 0
0 0 1

动态矩阵
函数 含义
setZero() 矩阵归零
setConstant() 矩阵归常数
setIdentity() 矩阵归单位阵
setOnes() 矩阵归一
setRandom() 矩阵随机数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
MatrixXi a(3, 3);
cout << a << endl << endl;
a.setZero();
cout << a << endl << endl;
a.setConstant(2);
cout << a << endl << endl;
a.setIdentity();
cout << a << endl << endl;
a.setOnes();
cout << a << endl << endl;
a.setRandom();
cout << a << endl << endl;

-->
5701724 7536759 6619252
7209065 5439580 3342445
7274596 7536761 6029362

0 0 0
0 0 0
0 0 0

2 2 2
2 2 2
2 2 2

1 0 0
0 1 0
0 0 1

1 1 1
1 1 1
1 1 1

-16343 10116 -4906
2083 2785 12974
-10050 -660 10578

动态向量函数
  • 仅能在向量类型数据中使用
函数 含义
setLinSpaced() 填充线性间隔的数据
setUnit() 指定向量位置数据置1,其余为0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
RowVectorXf b(8);
cout << b << endl << endl;
b.setLinSpaced(0, 14);
cout << b << endl << endl;
b.setUnit(3);
cout << b << endl << endl;
b.setOnes();
cout << b << endl << endl;
b.setConstant(2);
cout << b << endl << endl;

-->
9.91839e-39 9.64288e-39 8.44903e-39 7.80611e-39 5.9694e-39 1.08367e-38 4.50001e-39 4.5e-39

0 2 4 6 8 10 12 14

0 0 0 1 0 0 0 0

1 1 1 1 1 1 1 1

2 2 2 2 2 2 2 2

索引数据

单个数据

  • 主要数据的存取和修改都是通过重载的括号运算符完成的

  • 对于二维矩阵,下标顺序为 row col

  • 对于向量,则只有向量下标需要传入

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    MatrixXd m(2,2);
    m(0,0) = 3;
    m(1,0) = 2.5;
    m(0,1) = -1;
    m(1,1) = m(1,0) + m(0,1);
    cout << m;

    -->
    3 -1
    2.5 1.5

块操作

  • 语法:
动态矩阵 静态矩阵
尺寸 (p, q) 左上角坐标 (i, j) matrix.block(i,j,p,q); matrix.block<p,q>(i,j);
  • 示例:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    Eigen::MatrixXf m(4, 4);
    m << 1, 2, 3, 4,
    5, 6, 7, 8,
    9, 10, 11, 12,
    13, 14, 15, 16;

    m.block<2, 2>(0, 0) = m.block<2, 2>(0, 0) * 3;
    m.block<2, 2>(2, 2).setConstant(0);
    cout << m << endl << endl;

    -->
    18 21 3 4
    30 33 7 8
    9 10 0 0
    13 14 0 0

行列操作

  • 语法:
操作 方法
第 i 行 matrix.row(i);
第 i 列 matrix.col(j);
  • 示例:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    Eigen::MatrixXf m(3, 3);
    m << 1, 2, 3,
    4, 5, 6,
    7, 8, 9;
    cout << "Here is the matrix m:" << endl << m << endl;
    cout << "2nd Row: " << m.row(1) << endl;
    m.col(2) += 3 * m.col(0);
    cout << "After adding 3 times the first column into the third column, the matrix m is:\n";
    cout << m << endl;

    -->
    Here is the matrix m:
    1 2 3
    4 5 6
    7 8 9
    2nd Row: 4 5 6
    After adding 3 times the first column into the third column, the matrix m is:
    1 2 6
    4 5 18
    7 8 30

角操作

  • 语法:
块操作 动态矩阵语法 静态矩阵语法
左上角 p 行 q 列 matrix.topLeftCorner(p,q); matrix.topLeftCorner<p,q>();
左下角 p 行 q 列 matrix.bottomLeftCorner(p,q); matrix.bottomLeftCorner<p,q>();
右上角 p 行 q 列 matrix.topRightCorner(p,q); matrix.topRightCorner<p,q>();
右下角 p 行 q 列 matrix.bottomRightCorner(p,q); matrix.bottomRightCorner<p,q>();
前 q 行 matrix.topRows(q); matrix.topRows<q>();
后 q 行 matrix.bottomRows(q); matrix.bottomRows<q>();
前 p 列 matrix.leftCols(p); matrix.leftCols<p>();
后 p 列 matrix.rightCols(q); matrix.rightCols<q>();
第 i 列开始取 q 列 matrix.middleCols(i,q); matrix.middleCols<q>(i);
第 i 行开始取 q 行 matrix.middleRows(i,q); matrix.middleRows<q>(i);
  • 示例:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    Eigen::Matrix4f m;
    m << 1, 2, 3, 4,
    5, 6, 7, 8,
    9, 10,11,12,
    13,14,15,16;
    cout << "m.leftCols(2) =" << endl << m.leftCols(2) << endl << endl;
    cout << "m.bottomRows<2>() =" << endl << m.bottomRows<2>() << endl << endl;
    m.topLeftCorner(1,3) = m.bottomRightCorner(3,1).transpose();
    cout << "After assignment, m = " << endl << m << endl;

    -->
    m.leftCols(2) =
    1 2
    5 6
    9 10
    13 14

    m.bottomRows<2>() =
    9 10 11 12
    13 14 15 16

    After assignment, m =
    8 12 16 4
    5 6 7 8
    9 10 11 12
    13 14 15 16

向量块操作

块操作 动态矩阵语法 静态矩阵语法
向量前 n 个数据 vector.head(n); vector.head<n>();
向量后 n 个数据 vector.tail(n); vector.tail<n>();
向量从下标 i 开始的 n 个数据 vector.segment(i,n); vector.segment<n>(i);

常用操作

  • 大多数情况下,Eigen 要求操作的数据类型一致

布尔归约

操作 语法 示例
转置 .transpose() v.transpose()
所有元素为 true(非0),返回 bool 值 all() m.all()
存在元素为 true(非0),返回 bool 值 any() m.any()
统计 true(非0) 的个数 count() m.count()

数据类型转换

操作 语法 示例
数据类型转换为 double .cast<double>() A.cast<double>()
数据类型转换为 float .cast<float>() A.cast<float>()
数据类型转换为 int .cast<int>() A.cast<int>()
数据类型转换为实部 .real() A.real()
数据类型转换为虚部 .imag() A.imag()
内存数据转 Eigen Map<>() Map<Matrix3i>(array)
  • 内存数据转 Eigen:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    int array[9];
    for (int i = 0; i < 9; ++i) {
    array[i] = i;
    }
    cout << Map<Matrix3i>(array).transpose() << endl;

    -->
    0 1 2
    3 4 5
    6 7 8

Vector 向量操作

操作 语法 示例
点乘 dot() v.dot(w)
叉乘 .cross() v.cross(w)
元素个数 .size() v.size()
生成对角阵 .asDiagonal() v.asDiagonal()
向量平方和 .squaredNorm() v.squaredNorm()
向量模长 .norm() v.norm()

Matrix 矩阵操作

操作 语法 示例
转置 .transpose() v.transpose()
共轭 .conjugate() a.conjugate()
共轭转置 .adjoint() a.adjoint()
元素个数 .size() a.size()
行数 .rows() a.rows()
列数 .rols() a.rols()
填充 .fill() a.fill(6)
交换行/列 .swap() m.block(0, 0, 2, 2).swap(n.block(2, 2, 2, 2));
获取对角线 .diagonal() a.diagonal()
列向操作 .colwise() m.colwise().sum()
元素颠倒 .reverse() m.reverse()
  • 赋值经过优化:

    行可以给列赋值,这个其实还是挺可怕的,需要格外小心。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    Eigen::MatrixXf m(4, 4);
    m << 1, 2, 3, 4,
    5, 6, 7, 8,
    9, 10, 11, 12,
    13, 14, 15, 16;
    m.row(0) = m.col(3);
    cout << m;

    -->
    4 8 12 16
    5 6 7 8
    9 10 11 12
    13 14 15 16

  • 列向操作相当于 numpy 中的 axis=1,只对列方向做某种操作:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    Eigen::MatrixXf m(4, 4);
    m << 1, 2, 3, 4,
    5, 6, 7, 8,
    9, 10, 11, 12,
    13, 14, 15, 16;

    cout << "Here is the matrix m:" << endl << m << endl;
    cout << "Here is the sum of each column:" << endl << m.colwise().sum() << endl;
    cout << "Here is the maximum absolute value of each column:"
    << endl << m.cwiseAbs().colwise().maxCoeff() << endl;

    -->
    Here is the matrix m:
    1 2 3 4
    5 6 7 8
    9 10 11 12
    13 14 15 16
    Here is the sum of each column:
    28 32 36 40
    Here is the maximum absolute value of each column:
    13 14 15 16

Matrix 矩阵运算

操作 语法 示例
矩阵相加 + a + b
矩阵相减 - a - b
负号 - - a
复合算子加 += a += b
复合算子减 -= a -= b
标量乘法 * matrix*scalar / scalar*matrix
标量除法 / matrix/scalar
复合算子乘 *= matrix*=scalar
复合算子除 /= matrix/=scalar
矩阵\向量乘法 * matrix*matrix, matrix*vector
矩阵求和 .sum() mat.sum()
所有元素乘积 .prod() mat.prod()
矩阵均值 .mean() mat.mean()
矩阵最小值 .minCoeff() mat.minCoeff()
矩阵最大值 .maxCoeff() mat.maxCoeff()
矩阵最小值,带位置 .minCoeff(&r, &c) mat.minCoeff(&r, &c)
矩阵最大值,带位置 .maxCoeff(&r, &c) mat.maxCoeff(&r, &c)
.trace() mat.trace()
逐元素绝对值 .cwiseAbs() mat.cwiseAbs()
逐元素相乘 .cwiseProduct() mat = mat.cwiseProduct(mat)
逐元素相除 .cwiseQuotient() mat = mat.cwiseQuotient(mat)
逐元素取倒数 .cwiseInverse() mat.cwiseInverse()
逐元素开根号 .cwiseSqrt() mat.cwiseSqrt()
逐元素最大值 .cwiseMax(m) mat.cwiseMax(mat2)
逐元素最小值 .cwiseMin(m) mat.cwiseMin(mat2)
元素平方和 .squaredNorm() mat.squaredNorm()
矩阵二阶范数 .norm() mat.norm()
p 阶范数 .lpNorm<p>() mat.lpNorm<3>()
  • 最大值、最小值

    返回最大、最小值,同时定位位置

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    Matrix3f m = Matrix3f::Random();
    std::ptrdiff_t i, j;
    float minOfM = m.minCoeff(&i,&j);
    cout << "Here is the matrix m:\n" << m << endl;
    cout << "Its minimum coefficient (" << minOfM
    << ") is at position (" << i << "," << j << ")\n\n";

    RowVector4i v = RowVector4i::Random();
    int maxOfV = v.maxCoeff(&i);
    cout << "Here is the vector v: " << v << endl;
    cout << "Its maximum coefficient (" << maxOfV
    << ") is at position " << i << endl;

    -->

    Here is the matrix m:
    -0.997497 0.617481 -0.299417
    0.127171 0.170019 0.791925
    -0.613392 -0.0402539 0.64568
    Its minimum coefficient (-0.997497) is at position (0,0)

    Here is the vector v: 8080 -10679 11761 6897
    Its maximum coefficient (11761) is at position 2

Array 数组运算

操作 语法 示例
逐元素相乘 * a * b
逐元素相除 / a * b
矩阵相加 + a + b
矩阵相减 - a - b
负号 - - a
复合算子加 += a += b
复合算子减 -= a -= b
逐元素比较 <, >, >=, <=, == a < b
逐元素标量计算 +, -, *, / a + 3
逐元素标量复合计算 +=, -=, *=, /= a /= 3
逐元素取倒数 .inverse() a.inverse()
逐元素 sin .sin() a.sin()
逐元素 cos .cos() a.cos()
逐元素乘方 .pow(s) a.pow(3)
逐元素平方 .square() a.square()
逐元素立方 .cube() a.cube()
逐元素开根号 .sqrt() a.sqrt()
逐元素计算自然指数 .exp() a.exp()
逐元素计算自然对数 .log() a.log()
逐元素最小值 .min() a.min(b)
逐元素最大值 .max() a.max(b)
逐元素绝对值 .abs() a.abs()
逐元素选择 .select() (R.array() < s).select(P,Q)
  • 逐元素比较:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    Eigen::MatrixXf m(4, 4);
    m << 1, 2, 3, 4,
    5, 6, 7, 8,
    9, 10, 11, 12,
    13, 14, 15, 16;

    cout << (m.array() > m.reverse().array());

    -->
    0 0 0 0
    0 0 0 0
    1 1 1 1
    1 1 1 1

  • 逐元素选择:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    Eigen::MatrixXf m(4, 4);
    m << 1, 2, 3, 4,
    5, 6, 7, 8,
    9, 10, 11, 12,
    13, 14, 15, 16;

    MatrixXf n(4, 4), p(4, 4);
    n.setZero();

    p = (m.array() < 10).select(m, n);
    cout << p;

    -->
    1 2 3 4
    5 6 7 8
    9 0 0 0
    0 0 0 0

矩阵分解与解线性方程组

矩阵分解

分解方法 语法 输出
柯列斯基分解 .ldlt() .matrixL() and .matrixD()
LLT 分解 .llt() .matrixL()
部分旋转的 LU分解 .lu() .matrixL() and .matrixU()
QR 分解 .qr() .matrixQ() and .matrixR()
SVD 分解 .svd() .matrixU(), .singularValues(), and .matrixV()

求解线性方程组

  • 对应不同矩阵分解方式,有不同的解方程组的方法
语法 描述
x = A.ldlt().solve(b)); A sym. p.s.d. #include <Eigen/Cholesky>
x = A.llt() .solve(b)); A sym. p.d. #include <Eigen/Cholesky>
x = A.lu() .solve(b)); Stable and fast. #include <Eigen/LU>
x = A.qr() .solve(b)); No pivoting. #include <Eigen/QR>
x = A.svd() .solve(b)); Stable, slowest. #include <Eigen/SVD>

特征值特征向量

  • 特征值:

    1
    A.eigenvalues();
  • 特征向量:

    1
    eig.eigenvectors();  

混淆问题

  • 使用eval()函数解决把右值赋值为一个临时矩阵,再赋给左值时可能有造成的混淆。如:
1
2
3
MatrixXi mat(3,3);
mat << 1,2,3, 4,5,6, 7,8,9;
mat.bottomRightCorner(2,2) = mat.topLeftCorner(2,2).eval();
  • 原地操作的一类函数:
普通函数 inplace函数
MatrixBase::adjoint() MatrixBase::adjointInPlace()
DenseBase::reverse() DenseBase::reverseInPlace()
LDLT::solve() LDLT::solveInPlace()
LLT::solve() LLT::solveInPlace()
TriangularView::solve() TriangularView::solveInPlace()
DenseBase::transpose() DenseBase::transposeInPlace()
  1. 当相同的矩阵或array出现在等式左右时,容易出现混淆
  2. 当确定不会出现混淆时,可以使用noalias()
  3. 混淆出现时,可以使用eval()xxxInPlace()函数解决

参考资料

文章链接:
https://www.zywvvd.com/notes/coding/cpp/eigen/eigen-usage/