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
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
|
namespace Eigen {
/** \page Eigen2ToEigen3 Porting from Eigen2 to Eigen3
This page lists the most important API changes between Eigen2 and Eigen3,
and gives tips to help porting your application from Eigen2 to Eigen3.
\b Table \b of \b contents
- \ref CompatibilitySupport
- \ref Using
- \ref ComplexDot
- \ref VectorBlocks
- \ref Corners
- \ref CoefficientWiseOperations
- \ref PartAndExtract
- \ref TriangularSolveInPlace
- \ref Decompositions
- \ref LinearSolvers
- \ref GeometryModule
- \ref Transform
- \ref LazyVsNoalias
- \ref AlignMacros
- \ref AlignedMap
- \ref StdContainers
- \ref eiPrefix
\section CompatibilitySupport Eigen2 compatibility support
In order to ease the switch from Eigen2 to Eigen3, Eigen3 features \ref Eigen2SupportModes "Eigen2 support modes".
The quick way to enable this is to define the \c EIGEN2_SUPPORT preprocessor token \b before including any Eigen header (typically it should be set in your project options).
A more powerful, \em staged migration path is also provided, which may be useful to migrate larger projects from Eigen2 to Eigen3. This is explained in the \ref Eigen2SupportModes "Eigen 2 support modes" page.
\section Using The USING_PART_OF_NAMESPACE_EIGEN macro
The USING_PART_OF_NAMESPACE_EIGEN macro has been removed. In Eigen 3, just do:
\code
using namespace Eigen;
\endcode
\section ComplexDot Dot products over complex numbers
This is the single trickiest change between Eigen 2 and Eigen 3. It only affects code using \c std::complex numbers as scalar type.
Eigen 2's dot product was linear in the first variable. Eigen 3's dot product is linear in the second variable. In other words, the Eigen 2 code \code x.dot(y) \endcode is equivalent to the Eigen 3 code \code y.dot(x) \endcode In yet other words, dot products are complex-conjugated in Eigen 3 compared to Eigen 2. The switch to the new convention was commanded by common usage, especially with the notation \f$ x^Ty \f$ for dot products of column-vectors.
\section VectorBlocks Vector blocks
<table class="manual">
<tr><th>Eigen 2</th><th>Eigen 3</th></th>
<tr><td>\code
vector.start(length)
vector.start<length>()
vector.end(length)
vector.end<length>()
\endcode</td><td>\code
vector.head(length)
vector.head<length>()
vector.tail(length)
vector.tail<length>()
\endcode</td></tr>
</table>
\section Corners Matrix Corners
<table class="manual">
<tr><th>Eigen 2</th><th>Eigen 3</th></th>
<tr><td>\code
matrix.corner(TopLeft,r,c)
matrix.corner(TopRight,r,c)
matrix.corner(BottomLeft,r,c)
matrix.corner(BottomRight,r,c)
matrix.corner<r,c>(TopLeft)
matrix.corner<r,c>(TopRight)
matrix.corner<r,c>(BottomLeft)
matrix.corner<r,c>(BottomRight)
\endcode</td><td>\code
matrix.topLeftCorner(r,c)
matrix.topRightCorner(r,c)
matrix.bottomLeftCorner(r,c)
matrix.bottomRightCorner(r,c)
matrix.topLeftCorner<r,c>()
matrix.topRightCorner<r,c>()
matrix.bottomLeftCorner<r,c>()
matrix.bottomRightCorner<r,c>()
\endcode</td>
</tr>
</table>
Notice that Eigen3 also provides these new convenience methods: topRows(), bottomRows(), leftCols(), rightCols(). See in class DenseBase.
\section CoefficientWiseOperations Coefficient wise operations
In Eigen2, coefficient wise operations which have no proper mathematical definition (as a coefficient wise product)
were achieved using the .cwise() prefix, e.g.:
\code a.cwise() * b \endcode
In Eigen3 this .cwise() prefix has been superseded by a new kind of matrix type called
Array for which all operations are performed coefficient wise. You can easily view a matrix as an array and vice versa using
the MatrixBase::array() and ArrayBase::matrix() functions respectively. Here is an example:
\code
Vector4f a, b, c;
c = a.array() * b.array();
\endcode
Note that the .array() function is not at all a synonym of the deprecated .cwise() prefix.
While the .cwise() prefix changed the behavior of the following operator, the array() function performs
a permanent conversion to the array world. Therefore, for binary operations such as the coefficient wise product,
both sides must be converted to an \em array as in the above example. On the other hand, when you
concatenate multiple coefficient wise operations you only have to do the conversion once, e.g.:
\code
Vector4f a, b, c;
c = a.array().abs().pow(3) * b.array().abs().sin();
\endcode
With Eigen2 you would have written:
\code
c = (a.cwise().abs().cwise().pow(3)).cwise() * (b.cwise().abs().cwise().sin());
\endcode
\section PartAndExtract Triangular and self-adjoint matrices
In Eigen 2 you had to play with the part, extract, and marked functions to deal with triangular and selfadjoint matrices. In Eigen 3, all these functions have been removed in favor of the concept of \em views:
<table class="manual">
<tr><th>Eigen 2</th><th>Eigen 3</th></tr>
<tr><td>\code
A.part<UpperTriangular>();
A.part<StrictlyLowerTriangular>(); \endcode</td>
<td>\code
A.triangularView<Upper>()
A.triangularView<StrictlyLower>()\endcode</td></tr>
<tr><td>\code
A.extract<UpperTriangular>();
A.extract<StrictlyLowerTriangular>();\endcode</td>
<td>\code
A.triangularView<Upper>()
A.triangularView<StrictlyLower>()\endcode</td></tr>
<tr><td>\code
A.marked<UpperTriangular>();
A.marked<StrictlyLowerTriangular>();\endcode</td>
<td>\code
A.triangularView<Upper>()
A.triangularView<StrictlyLower>()\endcode</td></tr>
<tr><td colspan="2"></td></tr>
<tr><td>\code
A.part<SelfAdfjoint|UpperTriangular>();
A.extract<SelfAdfjoint|LowerTriangular>();\endcode</td>
<td>\code
A.selfadjointView<Upper>()
A.selfadjointView<Lower>()\endcode</td></tr>
<tr><td colspan="2"></td></tr>
<tr><td>\code
UpperTriangular
LowerTriangular
UnitUpperTriangular
UnitLowerTriangular
StrictlyUpperTriangular
StrictlyLowerTriangular
\endcode</td><td>\code
Upper
Lower
UnitUpper
UnitLower
StrictlyUpper
StrictlyLower
\endcode</td>
</tr>
</table>
\sa class TriangularView, class SelfAdjointView
\section TriangularSolveInPlace Triangular in-place solving
<table class="manual">
<tr><th>Eigen 2</th><th>Eigen 3</th></tr>
<tr><td>\code A.triangularSolveInPlace<XxxTriangular>(Y);\endcode</td><td>\code A.triangularView<Xxx>().solveInPlace(Y);\endcode</td></tr>
</table>
\section Decompositions Matrix decompositions
Some of Eigen 2's matrix decompositions have been renamed in Eigen 3, while some others have been removed and are replaced by other decompositions in Eigen 3.
<table class="manual">
<tr>
<th>Eigen 2</th>
<th>Eigen 3</th>
<th>Notes</th>
</tr>
<tr>
<td>LU</td>
<td>FullPivLU</td>
<td class="alt">See also the new PartialPivLU, it's much faster</td>
</tr>
<tr>
<td>QR</td>
<td>HouseholderQR</td>
<td class="alt">See also the new ColPivHouseholderQR, it's more reliable</td>
</tr>
<tr>
<td>SVD</td>
<td>JacobiSVD</td>
<td class="alt">We currently don't have a bidiagonalizing SVD; of course this is planned.</td>
</tr>
<tr>
<td>EigenSolver and friends</td>
<td>\code #include<Eigen/Eigenvalues> \endcode </td>
<td class="alt">Moved to separate module</td>
</tr>
</table>
\section LinearSolvers Linear solvers
<table class="manual">
<tr><th>Eigen 2</th><th>Eigen 3</th><th>Notes</th></tr>
<tr><td>\code A.lu();\endcode</td>
<td>\code A.fullPivLu();\endcode</td>
<td class="alt">Now A.lu() returns a PartialPivLU</td></tr>
<tr><td>\code A.lu().solve(B,&X);\endcode</td>
<td>\code X = A.lu().solve(B);
X = A.fullPivLu().solve(B);\endcode</td>
<td class="alt">The returned by value is fully optimized</td></tr>
<tr><td>\code A.llt().solve(B,&X);\endcode</td>
<td>\code X = A.llt().solve(B);
X = A.selfadjointView<Lower>.llt().solve(B);
X = A.selfadjointView<Upper>.llt().solve(B);\endcode</td>
<td class="alt">The returned by value is fully optimized and \n
the selfadjointView API allows you to select the \n
triangular part to work on (default is lower part)</td></tr>
<tr><td>\code A.llt().solveInPlace(B);\endcode</td>
<td>\code B = A.llt().solve(B);
B = A.selfadjointView<Lower>.llt().solve(B);
B = A.selfadjointView<Upper>.llt().solve(B);\endcode</td>
<td class="alt">In place solving</td></tr>
<tr><td>\code A.ldlt().solve(B,&X);\endcode</td>
<td>\code X = A.ldlt().solve(B);
X = A.selfadjointView<Lower>.ldlt().solve(B);
X = A.selfadjointView<Upper>.ldlt().solve(B);\endcode</td>
<td class="alt">The returned by value is fully optimized and \n
the selfadjointView API allows you to select the \n
triangular part to work on</td></tr>
</table>
\section GeometryModule Changes in the Geometry module
The Geometry module is the one that changed the most. If you rely heavily on it, it's probably a good idea to use the \ref Eigen2SupportModes "Eigen 2 support modes" to perform your migration.
\section Transform The Transform class
In Eigen 2, the Transform class didn't really know whether it was a projective or affine transformation. In Eigen 3, it takes a new \a Mode template parameter, which indicates whether it's \a Projective or \a Affine transform. There is no default value.
The Transform3f (etc) typedefs are no more. In Eigen 3, the Transform typedefs explicitly refer to the \a Projective and \a Affine modes:
<table class="manual">
<tr><th>Eigen 2</th><th>Eigen 3</th><th>Notes</th></tr>
<tr>
<td> Transform3f </td>
<td> Affine3f or Projective3f </td>
<td> Of course 3f is just an example here </td>
</tr>
</table>
\section LazyVsNoalias Lazy evaluation and noalias
In Eigen all operations are performed in a lazy fashion except the matrix products which are always evaluated into a temporary by default.
In Eigen2, lazy evaluation could be enforced by tagging a product using the .lazy() function. However, in complex expressions it was not
easy to determine where to put the lazy() function. In Eigen3, the lazy() feature has been superseded by the MatrixBase::noalias() function
which can be used on the left hand side of an assignment when no aliasing can occur. Here is an example:
\code
MatrixXf a, b, c;
...
c.noalias() += 2 * a.transpose() * b;
\endcode
However, the noalias mechanism does not cover all the features of the old .lazy(). Indeed, in some extremely rare cases,
it might be useful to explicit request for a lay product, i.e., for a product which will be evaluated one coefficient at once, on request,
just like any other expressions. To this end you can use the MatrixBase::lazyProduct() function, however we strongly discourage you to
use it unless you are sure of what you are doing, i.e., you have rigourosly measured a speed improvement.
\section AlignMacros Alignment-related macros
The EIGEN_ALIGN_128 macro has been renamed to EIGEN_ALIGN16. Don't be surprised, it's just that we switched to counting in bytes ;-)
The EIGEN_DONT_ALIGN option still exists in Eigen 3, but it has a new cousin: EIGEN_DONT_ALIGN_STATICALLY. It allows to get rid of all static alignment issues while keeping alignment of dynamic-size heap-allocated arrays, thus keeping vectorization for dynamic-size objects.
\section AlignedMap Aligned Map objects
A common issue with Eigen 2 was that when mapping an array with Map, there was no way to tell Eigen that your array was aligned. There was a ForceAligned option but it didn't mean that; it was just confusing and has been removed.
New in Eigen3 is the #Aligned option. See the documentation of class Map. Use it like this:
\code
Map<Vector4f, Aligned> myMappedVector(some_aligned_array);
\endcode
There also are related convenience static methods, which actually are the preferred way as they take care of such things as constness:
\code
result = Vector4f::MapAligned(some_aligned_array);
\endcode
\section StdContainers STL Containers
In Eigen2, #include<Eigen/StdVector> tweaked std::vector to automatically align elements. The problem was that that was quite invasive. In Eigen3, we only override standard behavior if you use Eigen::aligned_allocator<T> as your allocator type. So for example, if you use std::vector<Matrix4f>, you need to do the following change (note that aligned_allocator is under namespace Eigen):
<table class="manual">
<tr><th>Eigen 2</th><th>Eigen 3</th></tr>
<tr>
<td> \code std::vector<Matrix4f> \endcode </td>
<td> \code std::vector<Matrix4f, aligned_allocator<Matrix4f> > \endcode </td>
</tr>
</table>
\section eiPrefix Internal ei_ prefix
In Eigen2, global internal functions and structures were prefixed by \c ei_. In Eigen3, they all have been moved into the more explicit \c internal namespace. So, e.g., \c ei_sqrt(x) now becomes \c internal::sqrt(x). Of course it is not recommended to rely on Eigen's internal features.
*/
}
|