[Eigen中文文档] 深入了解 Eigen - 类层次结构

简介: 本页面介绍了Eigen类层次结构中 Core 类的设计及其相互关系。一般用户可能不需要关注这些细节,但对于高级用户和Eigen开发人员可能会有用。

文档总目录

英文原文(The class hierarchy)

本页面介绍了Eigen类层次结构中 Core 类的设计及其相互关系。一般用户可能不需要关注这些细节,但对于高级用户和Eigen开发人员可能会有用。

原则

Eigen的类层次结构的设计是为了避免虚函数的开销会严重影响性能。相反,Eigen使用奇怪递归模板模式(Curiously Recurring Template Pattern,CRTP)实现多态性。在这个模式中,基类(比如MatrixBase)本质上是一个模板类,派生类(比如Matrix)继承了基类,派生类本身作为模板参数(在这种情况下,MatrixMatrixBase<Matrix>继承)。这样,Eigen可以在编译时解析多态函数调用。

此外,该设计避免了多继承。其中一个原因是,根据我们的经验,一些编译器(如MSVC)无法执行空基类优化,而这对于我们的固定大小类型至关重要。

Core 类

如果你想编写接受或返回Eigen对象的函数,那么你需要了解以下类:

  • Matrix:是指密集的平面矩阵。如果m是一个矩阵,那么例如m+m不再是一个矩阵,它是一个“矩阵表达式”。
  • MatrixBase:指的是密集矩阵表达式。这意味着MatrixBase是可以进行加法、矩阵乘法、LU分解、QR分解等操作的。所有的矩阵表达式类,包括Matrix本身,都继承自MatrixBase
  • Array:指的是普通的密集数组。如果x是一个Array,那么例如x+x就不再是一个Array,而是一个"数组表达式"。
  • ArrayBase:指的是密集数组表达式。这意味着ArrayBase是可以相加、数组乘法以及执行各种数组操作的表达式。所有的数组表达式类,包括Array本身,在继承时都会继承ArrayBase
  • DenseBase:指的是密集(矩阵或数组)表达式。ArrayBaseMatrixBase都继承自DenseBaseDenseBase是所有方法的集合,这些方法适用于密集表达式,无论是矩阵还是数组表达式。例如,block(...)方法就属于DenseBase

基类

这些类是上述五个核心(Core)类的基类。它们更多是内部使用,对于使用Eigen库的用户来说不太常见。

  • PlainObjectBase:表示密集(矩阵或数组)的普通对象,即存储其自己的密集系数数组的对象。例如,resize()方法就在这里。PlainObjectBaseMatrixArray继承。但是,上面我们说Matrix继承了MatrixBaseArray继承了ArrayBase。那么这是否意味着多重继承?不是的,因为PlainObjectBase本身会根据我们是处于矩阵还是数组情形而继承MatrixBaseArrayBase。当我们说Matrix通过PlainObjectBase间接继承MatrixBase时,我们省略了这一点。Array也是同理。

  • DenseCoeffsBase:表示具有密集系数访问器的对象。它是DenseBase的一个基类。DenseCoeffsBase存在的原因是,可用系数访问器的集合取决于密集表达式是否具有直接访问内存的能力(DirectAccessBit标志)。例如,如果x是一个普通矩阵,则x具有直接访问,x.transpose()x.block(...)也具有直接访问,因为它们的系数可以直接从内存中读取,但是x+x没有直接内存访问,因为获取它的任何系数都需要计算(加法),不能直接从内存中读取。

  • EigenBase:表示任何可以计算为普通密集矩阵或数组的东西(即使这可能不是一个好主意)。EigenBase实际上是任何类似于矩阵或数组的东西的绝对基类。它是DenseCoeffsBase的一个基类,因此它位于我们所有密集类的层次结构之下,但它并不限于密集表达式。例如,EigenBase也被对角矩阵、稀疏矩阵等继承。

继承图

Matrix 的继承图如下所示:

EigenBase<Matrix>
  <-- DenseCoeffsBase<Matrix>    (direct access case)
    <-- DenseBase<Matrix>
      <-- MatrixBase<Matrix>
        <-- PlainObjectBase<Matrix>    (matrix case)
          <-- Matrix

Array 的继承图如下所示:

EigenBase<Array>
  <-- DenseCoeffsBase<Array>    (direct access case)
    <-- DenseBase<Array>
      <-- ArrayBase<Array>
        <-- PlainObjectBase<Array>    (array case)
          <-- Array

另一个矩阵表达式类的继承图如下,此处用SomeMatrixXpr表示:

EigenBase<SomeMatrixXpr>
  <-- DenseCoeffsBase<SomeMatrixXpr>    (direct access or no direct access case)
    <-- DenseBase<SomeMatrixXpr>
      <-- MatrixBase<SomeMatrixXpr>
        <-- SomeMatrixXpr

另一个数组表达式类的继承图如下,此处用SomeMatrixXpr表示:

EigenBase<SomeArrayXpr>
  <-- DenseCoeffsBase<SomeArrayXpr>    (direct access or no direct access case)
    <-- DenseBase<SomeArrayXpr>
      <-- ArrayBase<SomeArrayXpr>
        <-- SomeArrayXpr

最后,一个不是密集表达式的示例,例如对角矩阵。相应的继承图如下:

EigenBase<DiagonalMatrix>
  <-- DiagonalBase<DiagonalMatrix>
    <-- DiagonalMatrix
相关文章
|
存储 C语言 C++
|
存储 并行计算 算法
[Eigen中文文档] 概述(总目录)
Eigen是基于线性代数的C ++模板库,主要用于矩阵,向量,数值求解器和相关算法。常用的Ceres、G2O等项目均是基于Eigen库。 本系列文章将通过官方文档带你了解Eigen。
1525 1
|
存储 编译器
|
存储 缓存
[Eigen中文文档] 深入了解 Eigen - 惰性求值与混叠(Aliasing)
Eigen具有智能的编译时机制,可以实现惰性求值并在适当的情况下删除临时变量。它会自动处理大多数情况下的混叠问题,例如矩阵乘积。自动行为可以通过使用MatrixBase::eval()和MatrixBase::noalias()方法手动覆盖。
357 0
|
存储 NoSQL API
[Eigen中文文档] Matrix类
在Eigen中,所有矩阵和向量都是Matrix模板类的对象。向量只是行数或者列数为1的特殊矩阵。
478 1
|
测试技术 API C++
[Eigen中文文档] 扩展/自定义Eigen(一)
在本节中,将介绍如何向MatrixBase添加自定义方法。由于所有表达式和矩阵类型都继承自MatrixBase,因此将方法添加到MatrixBase会立即使其对所有表达式可用!一个典型的用例是,使Eigen与另一个API兼容。
339 0
|
编译器 索引
[Eigen中文文档] 块操作
本文介绍了块操作。块是matrix或array的部分矩形元素。块表达式既可以用作右值也可以用作左值。与Eigen表达式一样,如果让编译器进行优化,则块操作的运行时间成本为零。
176 0
|
测试技术
[Eigen中文文档] 线性代数与分解
本节将说明如何求解线性系统,计算各种分解,如 LU、QR、SVD、特征分解……
283 0
|
并行计算 算法 安全
[Eigen中文文档] Eigen 和多线程
某些 Eigen 算法可以利用硬件中存在的多个内核。
531 0
|
存储 算法 NoSQL
[Eigen中文文档] 稀疏矩阵操作
在许多应用中(例如,有限元方法),通常要处理非常大的矩阵,其中只有少数系数不为零。在这种情况下,可以通过使用仅存储非零系数的特殊表示来减少内存消耗并提高性能。这样的矩阵称为稀疏矩阵。
531 0

热门文章

最新文章