





























Eigen 是开源的C++线性代数库,常用在计算机图形学中,之前我们记录了 安装使用方法,本文记录常用功能使用方法。
Matrix模板类的对象,Matrix类有6个模板参数,主要使用前三个,剩下的使用默认值。MaxRowsAtCompileTime 和MaxColsAtCompileTime 在已知动态矩阵的尺寸上界时是可以提升工作效率的。1 | |
默认构造时,指定大小的矩阵,只分配相应大小的空间,不进行初始化。动态大小的矩阵,则未分配空间。
[]操作符可以用于向量元素的获取,但不能用于matrix。
matrix的大小可以通过rows(), cols(), size()获取,resize()可以重新调整矩阵大小。
Matrix 定义的矩阵为静态矩阵,在编译时确定尺寸、分配内存,随机初始化:
1 | |
MatrixX 开头的为动态矩阵,两个维度都可以变化,本质为 Matrix<Type, Dynamic, Dynamic> 定义的类型
例如:
MatrixXd为 double 类型的动态矩阵
1
2
3
4
5
6
7MatrixXd a(3, 3);
cout << a;-->
0 0 0
0 0 0
0 0 0
静态矩阵运算很快,但是有 128k 的堆栈尺寸限制,常用的还是动态矩阵类型
仅变化一个维度的动态矩阵为动态向量 typedef Matrix<float, Dynamic, 1> VectorXf,使用方法类似
Array是类模板,前三个参数必须指定,后三个参数可选。1 | |
类似于 Matrix 类,Array 默认仍会产生静态数组
1 | |
一维动态数组为 ArrayX 开头,二维动态数组为 ArrayXX 开头
1 | |
Matrix对象——>Array对象:.array()函数Array对象——>Matrix对象:.matrix()函数建议矩阵数据都要初始化,不然是十分危险的。
1 | |
赋值初始化
1 | |
可以用其他对象初始化新的相同内容对象
1 | |
1 | |
一下几个函数均为静态矩阵调用的初始化函数,动态矩阵调用会报错:
1YOU CALLED A_FIXED SIZE METHOD ON A DYNAMIC SIZE MATRIX OR VECTOR
Zero()Constant(rows, cols, value)Random()Identity()1 | |
| 函数 | 含义 |
|---|---|
setZero() |
矩阵归零 |
setConstant() |
矩阵归常数 |
setIdentity() |
矩阵归单位阵 |
setOnes() |
矩阵归一 |
setRandom() |
矩阵随机数 |
1 | |
| 函数 | 含义 |
|---|---|
setLinSpaced() |
填充线性间隔的数据 |
setUnit() |
指定向量位置数据置1,其余为0 |
1 | |
主要数据的存取和修改都是通过重载的括号运算符完成的
对于二维矩阵,下标顺序为 row col
对于向量,则只有向量下标需要传入
1 | |
| 块 | 动态矩阵 | 静态矩阵 |
|---|---|---|
| 尺寸 (p, q) 左上角坐标 (i, j) | matrix.block(i,j,p,q); |
matrix.block<p,q>(i,j); |
示例:
1 | |
| 操作 | 方法 |
|---|---|
| 第 i 行 | matrix.row(i); |
| 第 i 列 | matrix.col(j); |
示例:
1 | |
| 块操作 | 动态矩阵语法 | 静态矩阵语法 |
|---|---|---|
| 左上角 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 | |
| 块操作 | 动态矩阵语法 | 静态矩阵语法 |
|---|---|---|
| 向量前 n 个数据 | vector.head(n); |
vector.head<n>(); |
| 向量后 n 个数据 | vector.tail(n); |
vector.tail<n>(); |
| 向量从下标 i 开始的 n 个数据 | vector.segment(i,n); |
vector.segment<n>(i); |
| 操作 | 语法 | 示例 |
|---|---|---|
| 转置 | .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 | |
| 操作 | 语法 | 示例 |
|---|---|---|
| 点乘 | dot() |
v.dot(w) |
| 叉乘 | .cross() |
v.cross(w) |
| 元素个数 | .size() |
v.size() |
| 生成对角阵 | .asDiagonal() |
v.asDiagonal() |
| 向量平方和 | .squaredNorm() |
v.squaredNorm() |
| 向量模长 | .norm() |
v.norm() |
| 操作 | 语法 | 示例 |
|---|---|---|
| 转置 | .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 | |
列向操作相当于 numpy 中的 axis=1,只对列方向做某种操作:
1 | |
| 操作 | 语法 | 示例 |
|---|---|---|
| 矩阵相加 | + | 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 | |
| 操作 | 语法 | 示例 |
|---|---|---|
| 逐元素相乘 | * | 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 | |
逐元素选择:
1 | |
| 分解方法 | 语法 | 输出 |
|---|---|---|
| 柯列斯基分解 | .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 | |
特征向量:
1 | |
eval()函数解决把右值赋值为一个临时矩阵,再赋给左值时可能有造成的混淆。如:1 | |
| 普通函数 | 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() |
noalias()eval()和xxxInPlace()函数解决文章链接:
https://www.zywvvd.com/notes/coding/cpp/eigen/eigen-usage/
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。