You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

299 lines
12 KiB

  1. namespace StormEigen {
  2. /** \page Eigen2ToEigen3 Porting from Eigen2 to Eigen3
  3. This page lists the most important API changes between Eigen2 and Eigen3,
  4. and gives tips to help porting your application from Eigen2 to Eigen3.
  5. \eigenAutoToc
  6. \section CompatibilitySupport Eigen2 compatibility support
  7. Up to version 3.2 %Eigen provides <a href="http://eigen.tuxfamily.org/dox/Eigen2SupportModes.html">Eigen2 support modes</a>. These are removed now, because they were barely used anymore and became hard to maintain after internal re-designs.
  8. You can still use them by first <a href="http://eigen.tuxfamily.org/dox/Eigen2ToEigen3.html">porting your code to Eigen 3.2</a>.
  9. \section Using The USING_PART_OF_NAMESPACE_STORMEIGEN macro
  10. The USING_PART_OF_NAMESPACE_STORMEIGEN macro has been removed. In Eigen 3, just do:
  11. \code
  12. using namespace StormEigen;
  13. \endcode
  14. \section ComplexDot Dot products over complex numbers
  15. This is the single trickiest change between Eigen 2 and Eigen 3. It only affects code using \c std::complex numbers as scalar type.
  16. 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.
  17. \section VectorBlocks Vector blocks
  18. <table class="manual">
  19. <tr><th>Eigen 2</th><th>Eigen 3</th></th>
  20. <tr><td>\code
  21. vector.start(length)
  22. vector.start<length>()
  23. vector.end(length)
  24. vector.end<length>()
  25. \endcode</td><td>\code
  26. vector.head(length)
  27. vector.head<length>()
  28. vector.tail(length)
  29. vector.tail<length>()
  30. \endcode</td></tr>
  31. </table>
  32. \section Corners Matrix Corners
  33. <table class="manual">
  34. <tr><th>Eigen 2</th><th>Eigen 3</th></th>
  35. <tr><td>\code
  36. matrix.corner(TopLeft,r,c)
  37. matrix.corner(TopRight,r,c)
  38. matrix.corner(BottomLeft,r,c)
  39. matrix.corner(BottomRight,r,c)
  40. matrix.corner<r,c>(TopLeft)
  41. matrix.corner<r,c>(TopRight)
  42. matrix.corner<r,c>(BottomLeft)
  43. matrix.corner<r,c>(BottomRight)
  44. \endcode</td><td>\code
  45. matrix.topLeftCorner(r,c)
  46. matrix.topRightCorner(r,c)
  47. matrix.bottomLeftCorner(r,c)
  48. matrix.bottomRightCorner(r,c)
  49. matrix.topLeftCorner<r,c>()
  50. matrix.topRightCorner<r,c>()
  51. matrix.bottomLeftCorner<r,c>()
  52. matrix.bottomRightCorner<r,c>()
  53. \endcode</td>
  54. </tr>
  55. </table>
  56. Notice that Eigen3 also provides these new convenience methods: topRows(), bottomRows(), leftCols(), rightCols(). See in class DenseBase.
  57. \section CoefficientWiseOperations Coefficient wise operations
  58. In Eigen2, coefficient wise operations which have no proper mathematical definition (as a coefficient wise product)
  59. were achieved using the .cwise() prefix, e.g.:
  60. \code a.cwise() * b \endcode
  61. In Eigen3 this .cwise() prefix has been superseded by a new kind of matrix type called
  62. Array for which all operations are performed coefficient wise. You can easily view a matrix as an array and vice versa using
  63. the MatrixBase::array() and ArrayBase::matrix() functions respectively. Here is an example:
  64. \code
  65. Vector4f a, b, c;
  66. c = a.array() * b.array();
  67. \endcode
  68. Note that the .array() function is not at all a synonym of the deprecated .cwise() prefix.
  69. While the .cwise() prefix changed the behavior of the following operator, the array() function performs
  70. a permanent conversion to the array world. Therefore, for binary operations such as the coefficient wise product,
  71. both sides must be converted to an \em array as in the above example. On the other hand, when you
  72. concatenate multiple coefficient wise operations you only have to do the conversion once, e.g.:
  73. \code
  74. Vector4f a, b, c;
  75. c = a.array().abs().pow(3) * b.array().abs().sin();
  76. \endcode
  77. With Eigen2 you would have written:
  78. \code
  79. c = (a.cwise().abs().cwise().pow(3)).cwise() * (b.cwise().abs().cwise().sin());
  80. \endcode
  81. \section PartAndExtract Triangular and self-adjoint matrices
  82. 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:
  83. <table class="manual">
  84. <tr><th>Eigen 2</th><th>Eigen 3</th></tr>
  85. <tr><td>\code
  86. A.part<UpperTriangular>();
  87. A.part<StrictlyLowerTriangular>(); \endcode</td>
  88. <td>\code
  89. A.triangularView<Upper>()
  90. A.triangularView<StrictlyLower>()\endcode</td></tr>
  91. <tr><td>\code
  92. A.extract<UpperTriangular>();
  93. A.extract<StrictlyLowerTriangular>();\endcode</td>
  94. <td>\code
  95. A.triangularView<Upper>()
  96. A.triangularView<StrictlyLower>()\endcode</td></tr>
  97. <tr><td>\code
  98. A.marked<UpperTriangular>();
  99. A.marked<StrictlyLowerTriangular>();\endcode</td>
  100. <td>\code
  101. A.triangularView<Upper>()
  102. A.triangularView<StrictlyLower>()\endcode</td></tr>
  103. <tr><td colspan="2"></td></tr>
  104. <tr><td>\code
  105. A.part<SelfAdfjoint|UpperTriangular>();
  106. A.extract<SelfAdfjoint|LowerTriangular>();\endcode</td>
  107. <td>\code
  108. A.selfadjointView<Upper>()
  109. A.selfadjointView<Lower>()\endcode</td></tr>
  110. <tr><td colspan="2"></td></tr>
  111. <tr><td>\code
  112. UpperTriangular
  113. LowerTriangular
  114. UnitUpperTriangular
  115. UnitLowerTriangular
  116. StrictlyUpperTriangular
  117. StrictlyLowerTriangular
  118. \endcode</td><td>\code
  119. Upper
  120. Lower
  121. UnitUpper
  122. UnitLower
  123. StrictlyUpper
  124. StrictlyLower
  125. \endcode</td>
  126. </tr>
  127. </table>
  128. \sa class TriangularView, class SelfAdjointView
  129. \section TriangularSolveInPlace Triangular in-place solving
  130. <table class="manual">
  131. <tr><th>Eigen 2</th><th>Eigen 3</th></tr>
  132. <tr><td>\code A.triangularSolveInPlace<XxxTriangular>(Y);\endcode</td><td>\code A.triangularView<Xxx>().solveInPlace(Y);\endcode</td></tr>
  133. </table>
  134. \section Decompositions Matrix decompositions
  135. 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.
  136. <table class="manual">
  137. <tr>
  138. <th>Eigen 2</th>
  139. <th>Eigen 3</th>
  140. <th>Notes</th>
  141. </tr>
  142. <tr>
  143. <td>LU</td>
  144. <td>FullPivLU</td>
  145. <td class="alt">See also the new PartialPivLU, it's much faster</td>
  146. </tr>
  147. <tr>
  148. <td>QR</td>
  149. <td>HouseholderQR</td>
  150. <td class="alt">See also the new ColPivHouseholderQR, it's more reliable</td>
  151. </tr>
  152. <tr>
  153. <td>SVD</td>
  154. <td>JacobiSVD</td>
  155. <td class="alt">We currently don't have a bidiagonalizing SVD; of course this is planned.</td>
  156. </tr>
  157. <tr>
  158. <td>EigenSolver and friends</td>
  159. <td>\code #include<StormEigen/Eigenvalues> \endcode </td>
  160. <td class="alt">Moved to separate module</td>
  161. </tr>
  162. </table>
  163. \section LinearSolvers Linear solvers
  164. <table class="manual">
  165. <tr><th>Eigen 2</th><th>Eigen 3</th><th>Notes</th></tr>
  166. <tr><td>\code A.lu();\endcode</td>
  167. <td>\code A.fullPivLu();\endcode</td>
  168. <td class="alt">Now A.lu() returns a PartialPivLU</td></tr>
  169. <tr><td>\code A.lu().solve(B,&X);\endcode</td>
  170. <td>\code X = A.lu().solve(B);
  171. X = A.fullPivLu().solve(B);\endcode</td>
  172. <td class="alt">The returned by value is fully optimized</td></tr>
  173. <tr><td>\code A.llt().solve(B,&X);\endcode</td>
  174. <td>\code X = A.llt().solve(B);
  175. X = A.selfadjointView<Lower>.llt().solve(B);
  176. X = A.selfadjointView<Upper>.llt().solve(B);\endcode</td>
  177. <td class="alt">The returned by value is fully optimized and \n
  178. the selfadjointView API allows you to select the \n
  179. triangular part to work on (default is lower part)</td></tr>
  180. <tr><td>\code A.llt().solveInPlace(B);\endcode</td>
  181. <td>\code B = A.llt().solve(B);
  182. B = A.selfadjointView<Lower>.llt().solve(B);
  183. B = A.selfadjointView<Upper>.llt().solve(B);\endcode</td>
  184. <td class="alt">In place solving</td></tr>
  185. <tr><td>\code A.ldlt().solve(B,&X);\endcode</td>
  186. <td>\code X = A.ldlt().solve(B);
  187. X = A.selfadjointView<Lower>.ldlt().solve(B);
  188. X = A.selfadjointView<Upper>.ldlt().solve(B);\endcode</td>
  189. <td class="alt">The returned by value is fully optimized and \n
  190. the selfadjointView API allows you to select the \n
  191. triangular part to work on</td></tr>
  192. </table>
  193. \section GeometryModule Changes in the Geometry module
  194. 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.
  195. \section Transform The Transform class
  196. 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.
  197. The Transform3f (etc) typedefs are no more. In Eigen 3, the Transform typedefs explicitly refer to the \a Projective and \a Affine modes:
  198. <table class="manual">
  199. <tr><th>Eigen 2</th><th>Eigen 3</th><th>Notes</th></tr>
  200. <tr>
  201. <td> Transform3f </td>
  202. <td> Affine3f or Projective3f </td>
  203. <td> Of course 3f is just an example here </td>
  204. </tr>
  205. </table>
  206. \section LazyVsNoalias Lazy evaluation and noalias
  207. In Eigen all operations are performed in a lazy fashion except the matrix products which are always evaluated into a temporary by default.
  208. In Eigen2, lazy evaluation could be enforced by tagging a product using the .lazy() function. However, in complex expressions it was not
  209. easy to determine where to put the lazy() function. In Eigen3, the lazy() feature has been superseded by the MatrixBase::noalias() function
  210. which can be used on the left hand side of an assignment when no aliasing can occur. Here is an example:
  211. \code
  212. MatrixXf a, b, c;
  213. ...
  214. c.noalias() += 2 * a.transpose() * b;
  215. \endcode
  216. However, the noalias mechanism does not cover all the features of the old .lazy(). Indeed, in some extremely rare cases,
  217. 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,
  218. just like any other expressions. To this end you can use the MatrixBase::lazyProduct() function, however we strongly discourage you to
  219. use it unless you are sure of what you are doing, i.e., you have rigourosly measured a speed improvement.
  220. \section AlignMacros Alignment-related macros
  221. The STORMEIGEN_ALIGN_128 macro has been renamed to STORMEIGEN_ALIGN16. Don't be surprised, it's just that we switched to counting in bytes ;-)
  222. The STORMEIGEN_DONT_ALIGN option still exists in Eigen 3, but it has a new cousin: STORMEIGEN_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.
  223. \section AlignedMap Aligned Map objects
  224. 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.
  225. New in Eigen3 is the #Aligned option. See the documentation of class Map. Use it like this:
  226. \code
  227. Map<Vector4f, Aligned> myMappedVector(some_aligned_array);
  228. \endcode
  229. There also are related convenience static methods, which actually are the preferred way as they take care of such things as constness:
  230. \code
  231. result = Vector4f::MapAligned(some_aligned_array);
  232. \endcode
  233. \section StdContainers STL Containers
  234. In Eigen2, <tt>\#include\<StormEigen/StdVector\></tt> 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 StormEigen::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 StormEigen):
  235. <table class="manual">
  236. <tr><th>Eigen 2</th><th>Eigen 3</th></tr>
  237. <tr>
  238. <td> \code std::vector<Matrix4f> \endcode </td>
  239. <td> \code std::vector<Matrix4f, aligned_allocator<Matrix4f> > \endcode </td>
  240. </tr>
  241. </table>
  242. \section eiPrefix Internal ei_ prefix
  243. 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.
  244. */
  245. }