Eigen 快速入门指南

Eigen Quick reference guide

模块和头文件

Eigen库分为一个核心模块和几个附加模块。每个模块都有一个相应的头文件,为了使用模块必须包含该头文件。提供了Dense和Eigen头文件,方便地同时访问多个模块。

模块 头文件 内容
Core #include<Eigen/Core> 核心模块,Matrix 矩阵和 Array 数组类,基本线性代数(包括三角形和自伴随乘积),数组操作。
Geometry #include<Eigen/Geometry> 几何模块,提供 Transform 变换、Translation 平移变换、缩放、Rotation2D 2D 旋转和3D rotations3D 旋转功能(使用Quaternion四元数和AngleAxis三轴旋转的方式)
LU #include<Eigen/LU> Inverse逆、行列式和 LU 分解的求解方法(FullPivLU, PartialPivLU)
Cholesky #include<Eigen/Cholesky> 提供 LLTLDLT Cholesky 因式分解
Householder #include<Eigen/Householder> Householder 变换,这个模块被一些线性代数模块所使用
SVD #include<Eigen/SVD> SVD分解与最小二乘求解方法(JacobiSVD, BDCSVD)
QR #include<Eigen/QR> QR 分解求解方法(HouseholderQR, ColPivHouseHolderQR, FullPivHouseholderQR)
Eigenvalues #include<Eigen/Eigenvalues> 特征值、特征向量分解(EigenSolver, SelfAdjointEigenSolver, ComplexEigenSolver)
Sparse #include<Eigen/Sparse> 稀疏矩阵存储及相关的基本线性代数 (SparseMatrix, SparseVector
#include<Eigen/Dense> 包含CoreGeometryLUSVDQREigenvalues头文件
#include<Eigen/Eigen> 包含DenseSparse头文件,即整个Eigen库

数组(Array)、矩阵(Matrix)和向量(vector)类型

Eigen提供了两种密集对象:用模板类Matrix表示的数学矩阵和向量,以及用模板类Array表示的通用1D和2D数组:

typedef Matrix<Scalar, RowsAtCompileTime, ColsAtCompileTime, Options> MyMatrixType;
typedef Array<Scalar, RowsAtCompileTime, ColsAtCompileTime, Options> MyArrayType;
  • Scalar 是标量的系数类型如:floatdoubleintbool等。
  • RowsAtComileTImeColsAtCompileTime 表示矩阵的行列在编译时是否已知,或者是Dynamic 动态的
  • Options 可以是 ColMajorRowMajor 即列主序或行主序(存储时),默认是ColMajor

所有的组合都是允许的:您可以拥有一个具有固定行数和动态列数的矩阵等。以下都是有效的:

Matrix<double, 6, Dynamic>                  // 固定行数,动态列数(堆分配)
Matrix<double, Dynamic, 2>                  // 动态行数,固定列数
Matrix<double, Dynamic, Dynamic, RowMajor>  // 都是动态分配,行主序
Matrix<double, 13, 3>                       // 固定大小(一般在栈上分配)

在大多数情况下,您可以简单地为矩阵和数组使用一个方便的类型定义。如:

// Matrix
Matrix<float,Dynamic,Dynamic>   <=>   MatrixXf
Matrix<double,Dynamic,1>        <=>   VectorXd
Matrix<int,1,Dynamic>           <=>   RowVectorXi
Matrix<float,3,3>               <=>   Matrix3f
Matrix<float,4,1>               <=>   Vector4f// Arrays
Array<float,Dynamic,Dynamic>    <=>   ArrayXXf
Array<double,Dynamic,1>         <=>   ArrayXd
Array<int,1,Dynamic>            <=>   RowArrayXi
Array<float,3,3>                <=>   Array33f
Array<float,4,1>                <=>   Array4f

在 Matrix 和 Array 之间转换:

Array44f a1, a2;
Matrix4f m1, m2;
m1 = a1 * a2;                     // 系数乘法,从数组到矩阵的隐式转换。
a1 = m1 * m2;                     // 矩阵乘法,从矩阵到数组的隐式转换。
a2 = a1 + m1.array();             // 混合使用 array 和 matrix 是禁止的
m2 = a1.matrix() + m1;            // 必须使用显式转换.
ArrayWrapper<Matrix4f> m1a(m1);   // m1a是m1.array()的别名,它们共享相同的系数
MatrixWrapper<Array44f> a1m(a1);

在本文档的其余部分中,我们将使用以下符号来强调特定对象的特征:

  • 线性代数矩阵和向量
  • 数组对象

矩阵基础操作

构造(默认情况下系数未初始化)

// 1D 对象
Vector4d v4;
Vector2f v1(x,y);
Array3i v2(x,y,z);
Vector4d v3(x,y,z,w);
VectorXf v5;ArrayXf v6(size);// 2D 对象
Matrix4f m1;
MatrixXf m5;
MatrixXf m6(nb_rows, nb_columns);

初始化操作(使用逗号运算符)

// simaple
Vector3f v1;
v1 << x, y, z;ArrayXf v2(4);
v2 << 1, 2, 3, 4;Matrix3f m1;
m1 << 1,2,3,4,5,6,7,8,9;// complex
int rows = 5, cols = 5;
MatrixXf m(rows, cols);
m << (Matrix3f() << 1,2,3,4,5,6,7,8,9>>).finished(),MatrixXf::Zero(3, cols-3),MatrixXf::Zero(rows-3, 3),MatrixXf::Identity(rows-3, cols-3);
// output
/*
1 2 3 0 0
4 5 6 0 0
7 8 9 0 0
0 0 0 1 0
0 0 0 0 1
*/

运行时信息

vector.size(); // 向量大小
matrix.size(); // 矩阵大小 cols x rows
matrix.rows(); // 矩阵行大小
matrix.cols(); // 矩阵列大小

编译时信息

ObjectType::Scalar // 系数类型
ObjectType::RealScalar
ObjectType::IndexObjectType::RowsAtCompileTime
ObjectType::ColsAtCompileTime
ObjectType::SizeAtCompileTime

改变矩阵、向量大小

// vector
vector.resize(size); // 改变大小后将丢失原始的数据
vector.resizeLike(other_vector);
vector.conservativeResize(size); // 改变大小后保留矩阵中的数据// matrix
matrix.resize(nb_rows, nb_cols);
matrix.resize(Eigen::NoChange, nb_cols);
matrix.resize(nb_rows, Eigen::NoChange);
matrix.resizeLike(other_matrix);
matrix.conservativeResize(nb_rows, nb_cols);

访问运算符

// 包含范围检测,可在NDEBUG 和 EIGEN_NO_DEBUG 情况下disable
vector(i);
vector[i];
vector.x() <=> vector(0)
vector.y() <=> vector(1)
vector.z() <=> vector(2)
vector.w() <=> vector(3)matrix(i, j);// 取消范围检测
vector.coeff(i);
vector.coeffRef(i);
matrix.coeff(i, j);
matrix.coeffRef(i, j);

赋值或拷贝,会自动改变大小

VectorXd object(4);
object << 1, 2, 3, 4;
cout << "object: \n"<< object << endl;
Vector3d expression = {5, 4, 3};object = expression;
cout << "object: \n"<< object << endl;VectorXf object_of_float(4);
object_of_float << 1.2, 2.4, 4.5, 5.7;
cout << "object_of_float: \n"<< object_of_float << endl;Vector3d expression_of_double = {11.7, 7.8, 9.4};
object_of_float               = expression_of_double.cast<float>();
cout << "object_of_float: \n"<< object_of_float << endl;

预定义矩阵

    cout << "zero: \n"<< Matrix3d::Zero() << endl;   // 0矩阵cout << "constant(1.2): \n"<< Matrix3d::Constant(1.2) << endl;   // 全为1.2的矩阵cout << "random: \n"<< Matrix3d::Random() << endl;   // 随机矩阵cout << "ones: \n"<< Matrix3d::Ones() << endl;   // 全为1的矩阵cout << "linSpaced: \n"<< Vector3d::LinSpaced(1.2, 5.6) << endl;   // 生成线性序列, Vector onlycout << "zero: \n"<< MatrixXd::Zero(3, 4) << endl;cout << "constant(1.2): \n"<< MatrixXd::Constant(3, 4, 1.2) << endl;cout << "random: \n"<< MatrixXd::Random(3, 4) << endl;cout << "ones: \n"<< MatrixXd::Ones(4, 4) << endl;cout << "linSpaced: \n"<< VectorXd::LinSpaced(3, 1.2, 5.6) << endl;   // 生成线性序列, Vector onlycout << "identity: \n"<< Matrix3d::Identity() << endl;   // 单位阵cout << "identity: \n"<< MatrixXd::Identity(4, 3) << endl;cout << "unitx: \n"<< Vector3f::UnitX() << endl; // 单位基向量cout << "unity: \n"<< Vector3f::UnitY() << endl;cout << "unitZ: \n"<< Vector3f::UnitZ() << endl;cout << "unit(4,1): \n"<< VectorXd::Unit(4, 1) << endl;cout << "unit(4,2): \n"<< VectorXd::Unit(4, 2) << endl;

映射到数组

    // 连续内存的使用{float data[] = {1, 2, 3, 4};Map<Vector3f> v1(data);cout << "v1: \n"<< v1 << endl;Map<ArrayXf> v2(data, 3);cout << "v2: \n"<< v2 << endl;Map<Array22f> m1(data);cout << "m1: \n"<< m1 << endl;Map<Matrix<float, Dynamic, Dynamic, RowMajor>> m2(data, 2, 2);   // 按行生成 m2cout << "m2: \n"<< m2 << endl;cout << "m2(0,1): " << m2(0, 1) << endl;}// 步进式生成数据{float data[] = {1, 2, 3, 4, 5, 6, 7, 8, 9};Map<VectorXf, 0, InnerStride<2>> v1(data, 3);                        // = [1,3,5]Map<VectorXf, 0, InnerStride<>>  v2(data, 3, InnerStride<>(3));      // = [1,4,7]Map<MatrixXf, 0, OuterStride<3>> m2(data, 2, 3);                     // both lines     |1,4,7|Map<MatrixXf, 0, OuterStride<>>  m1(data, 2, 3, OuterStride<>(3));   // are equal to:  |2,5,8|cout << "v1: \n"<< v1 << endl;cout << "v2: \n"<< v2 << endl;cout << "m2: \n"<< m2 << endl;cout << "m1: \n"<< m1 << endl;}

算术运算

    Matrix3i m1;m1 << 1, 2, 3, 4, 5, 6, 7, 8, 9;cout << m1 << endl;Matrix3i m2;m2 << 2, 3, 4, 5, 6, 7, 8, 9, 10;cout << m2 << endl;Vector3i v1;v1 << 1, 2, 3;auto v2 = v1.transpose();cout << "m1 + m2: \n"<< m1 + m2 << endl;cout << "m1 - m2: \n"<< m1 - m2 << endl;cout << "m1 * 3: \n"<< m1 * 3 << endl;cout << "m1 / 2: \n"<< m1 / 2 << endl;cout << "m1 * m2: \n"<< m1 * m2 << endl;cout << "m1 * v1: \n"<< m1 * v1 << endl;cout << "v2 * m1: \n"<< v2 * m1 << endl;Matrix2cd m3 = Matrix2cd::Random();cout << "m3(2x2): \n"<< m3 << endl;cout << "m3^T(2x2): \n"<< m3.transpose() << endl;cout << "m3(2x2) 复共轭转置: \n"<< m3.adjoint() << endl;Vector3i v3 = Vector3i::LinSpaced(3, 5);cout << "v3: \n"<< v3 << endl;cout << "v1.dot(v3): " << v1.dot(v3);   // 点乘cout << "v3.dot(v1): " << v3.dot(v1);   // 点乘cout << "v1 * v3^T: \n"<< v1 * v3.transpose() << endl;cout << "v3 2-范: \n"<< v3.norm() << endl;cout << "v3 1-范: \n"<< v3.lpNorm<1>() << endl;cout << "v3 2-范: \n"<< v3.lpNorm<2>() << endl;cout << "v3 无穷范: \n"<< v3.lpNorm<Eigen::Infinity>() << endl;cout << "v3 2-范的平方: \n"<< v3.squaredNorm() << endl;cout << "v3 normalized: \n"<< v3.normalized() << endl;cout << "v1 和 v3 的叉乘: \n"<< v1.cross(v3) << endl;Vector3cf c1 = Vector3cf::Random();cout << "c1: \n"<< c1 << endl;Vector3cf c2 = Vector3cf::Random();cout << "c2: \n"<< c2 << endl;cout << "c1^H * c2: " << c1.adjoint() * c2 << endl;cout << "c1^H * c2(value): " << (c1.adjoint() * c2).value() << endl;

按系数的数组运算

    // 按系数进行运算的函数只能使用在Array上Array2d a1(2, 5);cout << "a1: \n"<< a1 << endl;Array2d a2(3, 4);cout << "a2: \n"<< a2 << endl;// 数组元素之间进行标量运算, 需要维度一致cout << "a1 + a2: \n"<< a1 + a2 << endl;cout << "a1 - a2: \n"<< a1 - a2 << endl;cout << "a1 * a2: \n"<< a1 * a2 << endl;cout << "a1 / a2: \n"<< a1 / a2 << endl;cout << "a1 < a2: \n"<< (a1 < a2) << endl;// 获取 a1 和 a2 中相同位置下的最小值或最大值cout << "a1.min(a2): \n"<< a1.min(a2) << endl;cout << "a1.max(a2): \n"<< a1.max(a2) << endl;// 小于 2 的都保留,大于2的都设为2cout << "a1.min(2): \n"<< a1.min(2) << endl;// 大于 2 的都保留,小于2的都设为2cout << "a1.max(2): \n"<< a1.max(2) << endl;Matrix2d m1;m1 << 1, 2, 3, 4;cout << "m1: \n"<< m1 << endl;Matrix2d m2;m2 << 4, 6, 8, 4;cout << "m2: \n"<< m2 << endl;cout << "将矩阵转换为向量后元素对应相乘 m1 * m2:\n"<< m1.array() * m2.array() << endl;cout << "a1.sqrt(): \n"<< a1.sqrt() << endl;cout << "sqrt(a1): \n"<< sqrt(a1) << endl;cout << "a1 各系数的平方: \n"<< a1.square() << endl;cout << "a1 各系数的立方: \n"<< a1.cube() << endl;cout << "a1 各系数的倒数: \n"<< a1.inverse() << endl;cout << "sin(a1): \n"<< sin(a1) << endl;Array2cd a3;a3 << std::complex<double> {1, 2}, std::complex<double>(3, 4);cout << "arg(a3): \n"   // 复数<< arg(a3) << endl;cout << "a1.isFinite: \n"<< a1.isFinite() << endl;cout << "a1.isInf: \n"<< a1.isInf() << endl;cout << "a1.isNaN: \n"<< a1.isNaN() << endl;Matrix2cd m3 = Matrix2cd::Random();cout << "m3 :\n"<< m3 << endl;cout << "m3 的实部:\n"<< m3.real() << endl;cout << "m3 的虚部:\n"<< m3.imag() << endl;cout << "m3 的共轭复数: \n"<< m3.conjugate() << endl;// 使用 cwise 开头的函数可以在 Matrix 和 Vector 上使用按系数运算的函数

【Eigen】学习Eigen的一些总结——快速入门指南(一)相关推荐

  1. python多久能上手_小白学习Python,怎样能够快速入门上手

    原标题:小白学习Python,怎样能够快速入门上手 时至今日,Python已经成为最受欢迎的编程语言之一,清晰易读,适用广泛.在TIOBE 排行榜中位居第四,成为名副其实的人工智能第一语言. 那么零基 ...

  2. 150页书籍《PyTorch 深度学习快速入门指南》附PDF电子版

    为什么说是极简教程,首先本书只涵盖了150页.内容比较精简,特别适合作为 PyTorch 深度学习的入门书籍.为什么这么说呢?因为很多时候,一份厚重的书籍往往会削弱我们学习的积极性,在学习一门新的语言 ...

  3. geotools学习(一)IntelliJ快速入门

    title: 'geotools学习(一)IntelliJ快速入门' date: 2021-04-29 14:08:52 tags: [] published: true hideInList: fa ...

  4. Servlet和HTTP请求协议-学习笔记01【Servlet_快速入门-生命周期方法、Servlet_3.0注解配置、IDEA与tomcat相关配置】

    Java后端 学习路线 笔记汇总表[黑马程序员] Servlet和HTTP请求协议-学习笔记01[Servlet_快速入门-生命周期方法.Servlet_3.0注解配置.IDEA与tomcat相关配置 ...

  5. JDBC学习笔记01【JDBC快速入门、JDBC各个类详解、JDBC之CRUD练习】

    黑马程序员-JDBC文档(腾讯微云)JDBC笔记.pdf:https://share.weiyun.com/Kxy7LmRm JDBC学习笔记01[JDBC快速入门.JDBC各个类详解.JDBC之CR ...

  6. Python学习笔记--10.Django框架快速入门之后台管理admin(书籍管理系统)

    Python学习笔记--10.Django框架快速入门之后台管理 一.Django框架介绍 二.创建第一个Django项目 三.应用的创建和使用 四.项目的数据库模型 ORM对象关系映射 sqlite ...

  7. Redis学习笔记①基础篇_Redis快速入门

    若文章内容或图片失效,请留言反馈.部分素材来自网络,若不小心影响到您的利益,请联系博主删除. 资料链接:https://pan.baidu.com/s/1189u6u4icQYHg_9_7ovWmA( ...

  8. UE4学习笔记1st:编程快速入门

    UE4学习笔记1st:编程快速入门 今天我开始学习虚幻4游戏引擎,为了此我专门买了新的电脑,我将主要配置写在这里,有想学习的同学可以参考 显卡:丽台K620 CPU:E3-1230-V3 主板:b85 ...

  9. micro-app-vue2 vue3 超详细快速入门指南 学习记录

    micro-app-vue 快速入门指南 简介 micro-app是京东零售推出的一款微前端框架,它基于类WebComponent进行渲染,从组件化的思维实现微前端,旨在降低上手难度.提升工作效率.它 ...

最新文章

  1. OCI读取单条记录(C)
  2. apk可以解压再复制到手机吗_不行了,这个打通手机和电脑的神器,必须得安利给你们...
  3. 线程、进程、程序区别
  4. ASP.NET 安全认证(三)—— 用Form 表单认证实现单点登录(Single Sign On) .
  5. 一个具体的例子学习SAP S/4HANA里Fiori应用的排错分析
  6. sublime text插件emmet的用法教程
  7. [Hadoop in China 2011] HBase在淘宝平台上的应用和改进经验
  8. python之路——面向对象进阶
  9. java线程间ThreadLocal的传递
  10. MyBatis3教程
  11. 戴尔服务器进入pxe启动
  12. 计算机说课大赛ppt,计算机基础说课大赛省一等奖说课课件PPT作品
  13. Delphi动态创建MainMenu和PopupMenu菜单的方法
  14. BIOS INT 10中断功能详解
  15. stm32实现毫秒ms微秒us级延时
  16. 如何用div+css布局页面
  17. Python的IDEL增加清屏功能
  18. 咧咧一下“汉语编程”
  19. Vue框架学习(第十三课)Vuex状态管理中的store和state属性
  20. linux 校时命令

热门文章

  1. 字节某正式员工吐槽:外包员工在外面倒卖字节粽子,没人管吗?网友:都是打工人,哪来的优越感?...
  2. 迅为iTOP-2K1000开发板龙芯中科国产64位Loognix系统工业核心主板
  3. 城市公共汽电车突发事件应急预案
  4. Salesforce Apex初级教程
  5. 美的硅谷研发中心成立,专注人工智能推动产品智能化升级
  6. sci论文检索及获取论文的主要方式
  7. [机器学习]Python中Numpy,Pandas,Matplotlib,Scipy,Seaborn介绍
  8. html下拉列表框做日期,几种常用的控件(下拉框 可选框 起止日期 在HTML页面直接读取当前时间)...
  9. 乔布斯女儿嘲讽iPhone 14没新意;高德打车AR实景找车功能上线;Go语言报告:错误处理仍然是个挑战|极客头条...
  10. 求生之路2 游戏资料详细与细节