aboutsummaryrefslogtreecommitdiffhomepage
path: root/doc/I12_ClassHierarchy.dox
blob: 700d01802d0db580756743a2b500f5934f60e20f (plain)
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
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
namespace Eigen {

/** \page TopicClassHierarchy The class hierarchy

This page explains the design of the core classes in Eigen's class hierarchy and how they fit together. Casual
users probably need not concern themselves with these details, but it may be useful for both advanced users
and Eigen developers.

<b>Table of contents</b>
  - \ref TopicClassHierarchyPrinciples
  - \ref TopicClassHierarchyCoreClasses
  - \ref TopicClassHierarchyBaseClasses
  - \ref TopicClassHierarchyInheritanceDiagrams 


\section TopicClassHierarchyPrinciples Principles

Eigen's class hierarchy is designed so that virtual functions are avoided where their overhead would
significantly impair performance. Instead, Eigen achieves polymorphism with the Curiously Recurring Template
Pattern (CRTP). In this pattern, the base class (for instance, \c MatrixBase) is in fact a template class, and
the derived class (for instance, \c Matrix) inherits the base class with the derived class itself as a
template argument (in this case, \c Matrix inherits from \c MatrixBase&lt;Matrix&gt;). This allows Eigen to
resolve the polymorphic function calls at compile time.

In addition, the design avoids multiple inheritance. One reason for this is that in our experience, some
compilers (like MSVC) fail to perform empty base class optimization, which is crucial for our fixed-size
types.


\section TopicClassHierarchyCoreClasses The core classes

These are the classes that you need to know about if you want to write functions that accept or return Eigen
objects.

  - Matrix means plain dense matrix. If \c m is a \c %Matrix, then, for instance, \c m+m is no longer a 
    \c %Matrix, it is a "matrix expression".
  - MatrixBase means dense matrix expression. This means that a \c %MatrixBase is something that can be
    added, matrix-multiplied, LU-decomposed, QR-decomposed... All matrix expression classes, including 
    \c %Matrix itself, inherit \c %MatrixBase.
  - Array means plain dense array. If \c x is an \c %Array, then, for instance, \c x+x is no longer an 
    \c %Array, it is an "array expression".
  - ArrayBase means dense array expression. This means that an \c %ArrayBase is something that can be
    added, array-multiplied, and on which you can perform all sorts of array operations... All array
    expression classes, including \c %Array itself, inherit \c %ArrayBase.
  - DenseBase means dense (matrix or array) expression. Both \c %ArrayBase and \c %MatrixBase inherit
    \c %DenseBase. \c %DenseBase is where all the methods go that apply to dense expressions regardless of
    whether they are matrix or array expressions. For example, the \link DenseBase::block() block(...) \endlink
    methods are in \c %DenseBase.

\section TopicClassHierarchyBaseClasses Base classes

These classes serve as base classes for the five core classes mentioned above. They are more internal and so
less interesting for users of the Eigen library.

  - PlainObjectBase means dense (matrix or array) plain object, i.e. something that stores its own dense
    array of coefficients. This is where, for instance, the \link PlainObjectBase::resize() resize() \endlink
    methods go. \c %PlainObjectBase is inherited by \c %Matrix and by \c %Array. But above, we said that 
    \c %Matrix inherits \c %MatrixBase and \c %Array inherits \c %ArrayBase. So does that mean multiple
    inheritance? No, because \c %PlainObjectBase \e itself inherits \c %MatrixBase or \c %ArrayBase depending
    on whether we are in the matrix or array case. When we said above that \c %Matrix inherited 
    \c %MatrixBase, we omitted to say it does so indirectly via \c %PlainObjectBase. Same for \c %Array.
  - DenseCoeffsBase means something that has dense coefficient accessors. It is a base class for
    \c %DenseBase. The reason for \c %DenseCoeffsBase to exist is that the set of available coefficient
    accessors is very different depending on whether a dense expression has direct memory access or not (the
    \c DirectAccessBit flag). For example, if \c x is a plain matrix, then \c x has direct access, and 
    \c x.transpose() and \c x.block(...) also have direct access, because their coefficients can be read right
    off memory, but for example, \c x+x does not have direct memory access, because obtaining any of its
    coefficients requires a computation (an addition), it can't be just read off memory.
  - EigenBase means anything that can be evaluated into a plain dense matrix or array (even if that would
    be a bad idea). \c %EigenBase is really the absolute base class for anything that remotely looks like a
    matrix or array. It is a base class for \c %DenseCoeffsBase, so it sits below all our dense class
    hierarchy, but it is not limited to dense expressions. For example, \c %EigenBase is also inherited by
    diagonal matrices, sparse matrices, etc...


\section TopicClassHierarchyInheritanceDiagrams Inheritance diagrams

The inheritance diagram for Matrix looks as follows:

<pre>
EigenBase&lt;%Matrix&gt;
  <-- DenseCoeffsBase&lt;%Matrix&gt;    (direct access case)
    <-- DenseBase&lt;%Matrix&gt;
      <-- MatrixBase&lt;%Matrix&gt;
        <-- PlainObjectBase&lt;%Matrix&gt;    (matrix case)
          <-- Matrix
</pre>

The inheritance diagram for Array looks as follows:

<pre>
EigenBase&lt;%Array&gt;
  <-- DenseCoeffsBase&lt;%Array&gt;    (direct access case)
    <-- DenseBase&lt;%Array&gt;
      <-- ArrayBase&lt;%Array&gt;
        <-- PlainObjectBase&lt;%Array&gt;    (array case)
          <-- Array
</pre>

The inheritance diagram for some other matrix expression class, here denoted by \c SomeMatrixXpr, looks as
follows:

<pre>
EigenBase&lt;SomeMatrixXpr&gt;
  <-- DenseCoeffsBase&lt;SomeMatrixXpr&gt;    (direct access or no direct access case)
    <-- DenseBase&lt;SomeMatrixXpr&gt;
      <-- MatrixBase&lt;SomeMatrixXpr&gt;
        <-- SomeMatrixXpr
</pre>

The inheritance diagram for some other array expression class, here denoted by \c SomeArrayXpr, looks as
follows:

<pre>
EigenBase&lt;SomeArrayXpr&gt;
  <-- DenseCoeffsBase&lt;SomeArrayXpr&gt;    (direct access or no direct access case)
    <-- DenseBase&lt;SomeArrayXpr&gt;
      <-- ArrayBase&lt;SomeArrayXpr&gt;
        <-- SomeArrayXpr
</pre>

Finally, consider an example of something that is not a dense expression, for instance a diagonal matrix. The
corresponding inheritance diagram is:

<pre>
EigenBase&lt;%DiagonalMatrix&gt;
  <-- DiagonalBase&lt;%DiagonalMatrix&gt;
    <-- DiagonalMatrix
</pre>


*/
}