ruby-eigen 0.0.9 → 0.0.10.pre1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (293) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE +22 -0
  3. data/README.md +21 -0
  4. data/ext/eigen/eigen3/COPYING.BSD +26 -0
  5. data/ext/eigen/eigen3/COPYING.MPL2 +373 -0
  6. data/ext/eigen/eigen3/COPYING.README +18 -0
  7. data/ext/eigen/eigen3/Eigen/Array +11 -0
  8. data/ext/eigen/eigen3/Eigen/Cholesky +32 -0
  9. data/ext/eigen/eigen3/Eigen/CholmodSupport +45 -0
  10. data/ext/eigen/eigen3/Eigen/Core +376 -0
  11. data/ext/eigen/eigen3/Eigen/Dense +7 -0
  12. data/ext/eigen/eigen3/Eigen/Eigen +2 -0
  13. data/ext/eigen/eigen3/Eigen/Eigen2Support +95 -0
  14. data/ext/eigen/eigen3/Eigen/Eigenvalues +48 -0
  15. data/ext/eigen/eigen3/Eigen/Geometry +63 -0
  16. data/ext/eigen/eigen3/Eigen/Householder +23 -0
  17. data/ext/eigen/eigen3/Eigen/IterativeLinearSolvers +40 -0
  18. data/ext/eigen/eigen3/Eigen/Jacobi +26 -0
  19. data/ext/eigen/eigen3/Eigen/LU +41 -0
  20. data/ext/eigen/eigen3/Eigen/LeastSquares +32 -0
  21. data/ext/eigen/eigen3/Eigen/MetisSupport +28 -0
  22. data/ext/eigen/eigen3/Eigen/PaStiXSupport +46 -0
  23. data/ext/eigen/eigen3/Eigen/PardisoSupport +30 -0
  24. data/ext/eigen/eigen3/Eigen/QR +45 -0
  25. data/ext/eigen/eigen3/Eigen/QtAlignedMalloc +34 -0
  26. data/ext/eigen/eigen3/Eigen/SPQRSupport +29 -0
  27. data/ext/eigen/eigen3/Eigen/SVD +37 -0
  28. data/ext/eigen/eigen3/Eigen/Sparse +27 -0
  29. data/ext/eigen/eigen3/Eigen/SparseCore +64 -0
  30. data/ext/eigen/eigen3/Eigen/SparseLU +49 -0
  31. data/ext/eigen/eigen3/Eigen/SparseQR +33 -0
  32. data/ext/eigen/eigen3/Eigen/StdDeque +27 -0
  33. data/ext/eigen/eigen3/Eigen/StdList +26 -0
  34. data/ext/eigen/eigen3/Eigen/StdVector +27 -0
  35. data/ext/eigen/eigen3/Eigen/SuperLUSupport +59 -0
  36. data/ext/eigen/eigen3/Eigen/UmfPackSupport +36 -0
  37. data/ext/eigen/eigen3/Eigen/src/Cholesky/LDLT.h +611 -0
  38. data/ext/eigen/eigen3/Eigen/src/Cholesky/LLT.h +498 -0
  39. data/ext/eigen/eigen3/Eigen/src/Cholesky/LLT_MKL.h +102 -0
  40. data/ext/eigen/eigen3/Eigen/src/CholmodSupport/CholmodSupport.h +607 -0
  41. data/ext/eigen/eigen3/Eigen/src/Core/Array.h +323 -0
  42. data/ext/eigen/eigen3/Eigen/src/Core/ArrayBase.h +226 -0
  43. data/ext/eigen/eigen3/Eigen/src/Core/ArrayWrapper.h +264 -0
  44. data/ext/eigen/eigen3/Eigen/src/Core/Assign.h +590 -0
  45. data/ext/eigen/eigen3/Eigen/src/Core/Assign_MKL.h +224 -0
  46. data/ext/eigen/eigen3/Eigen/src/Core/BandMatrix.h +334 -0
  47. data/ext/eigen/eigen3/Eigen/src/Core/Block.h +406 -0
  48. data/ext/eigen/eigen3/Eigen/src/Core/BooleanRedux.h +154 -0
  49. data/ext/eigen/eigen3/Eigen/src/Core/CommaInitializer.h +154 -0
  50. data/ext/eigen/eigen3/Eigen/src/Core/CoreIterators.h +61 -0
  51. data/ext/eigen/eigen3/Eigen/src/Core/CwiseBinaryOp.h +230 -0
  52. data/ext/eigen/eigen3/Eigen/src/Core/CwiseNullaryOp.h +864 -0
  53. data/ext/eigen/eigen3/Eigen/src/Core/CwiseUnaryOp.h +126 -0
  54. data/ext/eigen/eigen3/Eigen/src/Core/CwiseUnaryView.h +139 -0
  55. data/ext/eigen/eigen3/Eigen/src/Core/DenseBase.h +521 -0
  56. data/ext/eigen/eigen3/Eigen/src/Core/DenseCoeffsBase.h +754 -0
  57. data/ext/eigen/eigen3/Eigen/src/Core/DenseStorage.h +434 -0
  58. data/ext/eigen/eigen3/Eigen/src/Core/Diagonal.h +237 -0
  59. data/ext/eigen/eigen3/Eigen/src/Core/DiagonalMatrix.h +313 -0
  60. data/ext/eigen/eigen3/Eigen/src/Core/DiagonalProduct.h +131 -0
  61. data/ext/eigen/eigen3/Eigen/src/Core/Dot.h +263 -0
  62. data/ext/eigen/eigen3/Eigen/src/Core/EigenBase.h +131 -0
  63. data/ext/eigen/eigen3/Eigen/src/Core/Flagged.h +140 -0
  64. data/ext/eigen/eigen3/Eigen/src/Core/ForceAlignedAccess.h +146 -0
  65. data/ext/eigen/eigen3/Eigen/src/Core/Functors.h +1026 -0
  66. data/ext/eigen/eigen3/Eigen/src/Core/Fuzzy.h +150 -0
  67. data/ext/eigen/eigen3/Eigen/src/Core/GeneralProduct.h +635 -0
  68. data/ext/eigen/eigen3/Eigen/src/Core/GenericPacketMath.h +350 -0
  69. data/ext/eigen/eigen3/Eigen/src/Core/GlobalFunctions.h +92 -0
  70. data/ext/eigen/eigen3/Eigen/src/Core/IO.h +250 -0
  71. data/ext/eigen/eigen3/Eigen/src/Core/Map.h +192 -0
  72. data/ext/eigen/eigen3/Eigen/src/Core/MapBase.h +247 -0
  73. data/ext/eigen/eigen3/Eigen/src/Core/MathFunctions.h +768 -0
  74. data/ext/eigen/eigen3/Eigen/src/Core/Matrix.h +420 -0
  75. data/ext/eigen/eigen3/Eigen/src/Core/MatrixBase.h +563 -0
  76. data/ext/eigen/eigen3/Eigen/src/Core/NestByValue.h +111 -0
  77. data/ext/eigen/eigen3/Eigen/src/Core/NoAlias.h +134 -0
  78. data/ext/eigen/eigen3/Eigen/src/Core/NumTraits.h +150 -0
  79. data/ext/eigen/eigen3/Eigen/src/Core/PermutationMatrix.h +721 -0
  80. data/ext/eigen/eigen3/Eigen/src/Core/PlainObjectBase.h +822 -0
  81. data/ext/eigen/eigen3/Eigen/src/Core/ProductBase.h +290 -0
  82. data/ext/eigen/eigen3/Eigen/src/Core/Random.h +152 -0
  83. data/ext/eigen/eigen3/Eigen/src/Core/Redux.h +409 -0
  84. data/ext/eigen/eigen3/Eigen/src/Core/Ref.h +278 -0
  85. data/ext/eigen/eigen3/Eigen/src/Core/Replicate.h +177 -0
  86. data/ext/eigen/eigen3/Eigen/src/Core/ReturnByValue.h +99 -0
  87. data/ext/eigen/eigen3/Eigen/src/Core/Reverse.h +224 -0
  88. data/ext/eigen/eigen3/Eigen/src/Core/Select.h +162 -0
  89. data/ext/eigen/eigen3/Eigen/src/Core/SelfAdjointView.h +314 -0
  90. data/ext/eigen/eigen3/Eigen/src/Core/SelfCwiseBinaryOp.h +191 -0
  91. data/ext/eigen/eigen3/Eigen/src/Core/SolveTriangular.h +260 -0
  92. data/ext/eigen/eigen3/Eigen/src/Core/StableNorm.h +203 -0
  93. data/ext/eigen/eigen3/Eigen/src/Core/Stride.h +108 -0
  94. data/ext/eigen/eigen3/Eigen/src/Core/Swap.h +126 -0
  95. data/ext/eigen/eigen3/Eigen/src/Core/Transpose.h +419 -0
  96. data/ext/eigen/eigen3/Eigen/src/Core/Transpositions.h +436 -0
  97. data/ext/eigen/eigen3/Eigen/src/Core/TriangularMatrix.h +839 -0
  98. data/ext/eigen/eigen3/Eigen/src/Core/VectorBlock.h +95 -0
  99. data/ext/eigen/eigen3/Eigen/src/Core/VectorwiseOp.h +642 -0
  100. data/ext/eigen/eigen3/Eigen/src/Core/Visitor.h +237 -0
  101. data/ext/eigen/eigen3/Eigen/src/Core/arch/AltiVec/Complex.h +217 -0
  102. data/ext/eigen/eigen3/Eigen/src/Core/arch/AltiVec/PacketMath.h +501 -0
  103. data/ext/eigen/eigen3/Eigen/src/Core/arch/Default/Settings.h +49 -0
  104. data/ext/eigen/eigen3/Eigen/src/Core/arch/NEON/Complex.h +253 -0
  105. data/ext/eigen/eigen3/Eigen/src/Core/arch/NEON/PacketMath.h +420 -0
  106. data/ext/eigen/eigen3/Eigen/src/Core/arch/SSE/Complex.h +442 -0
  107. data/ext/eigen/eigen3/Eigen/src/Core/arch/SSE/MathFunctions.h +475 -0
  108. data/ext/eigen/eigen3/Eigen/src/Core/arch/SSE/PacketMath.h +649 -0
  109. data/ext/eigen/eigen3/Eigen/src/Core/products/CoeffBasedProduct.h +476 -0
  110. data/ext/eigen/eigen3/Eigen/src/Core/products/GeneralBlockPanelKernel.h +1341 -0
  111. data/ext/eigen/eigen3/Eigen/src/Core/products/GeneralMatrixMatrix.h +427 -0
  112. data/ext/eigen/eigen3/Eigen/src/Core/products/GeneralMatrixMatrixTriangular.h +278 -0
  113. data/ext/eigen/eigen3/Eigen/src/Core/products/GeneralMatrixMatrixTriangular_MKL.h +146 -0
  114. data/ext/eigen/eigen3/Eigen/src/Core/products/GeneralMatrixMatrix_MKL.h +118 -0
  115. data/ext/eigen/eigen3/Eigen/src/Core/products/GeneralMatrixVector.h +566 -0
  116. data/ext/eigen/eigen3/Eigen/src/Core/products/GeneralMatrixVector_MKL.h +131 -0
  117. data/ext/eigen/eigen3/Eigen/src/Core/products/Parallelizer.h +162 -0
  118. data/ext/eigen/eigen3/Eigen/src/Core/products/SelfadjointMatrixMatrix.h +436 -0
  119. data/ext/eigen/eigen3/Eigen/src/Core/products/SelfadjointMatrixMatrix_MKL.h +295 -0
  120. data/ext/eigen/eigen3/Eigen/src/Core/products/SelfadjointMatrixVector.h +281 -0
  121. data/ext/eigen/eigen3/Eigen/src/Core/products/SelfadjointMatrixVector_MKL.h +114 -0
  122. data/ext/eigen/eigen3/Eigen/src/Core/products/SelfadjointProduct.h +123 -0
  123. data/ext/eigen/eigen3/Eigen/src/Core/products/SelfadjointRank2Update.h +93 -0
  124. data/ext/eigen/eigen3/Eigen/src/Core/products/TriangularMatrixMatrix.h +427 -0
  125. data/ext/eigen/eigen3/Eigen/src/Core/products/TriangularMatrixMatrix_MKL.h +309 -0
  126. data/ext/eigen/eigen3/Eigen/src/Core/products/TriangularMatrixVector.h +348 -0
  127. data/ext/eigen/eigen3/Eigen/src/Core/products/TriangularMatrixVector_MKL.h +247 -0
  128. data/ext/eigen/eigen3/Eigen/src/Core/products/TriangularSolverMatrix.h +332 -0
  129. data/ext/eigen/eigen3/Eigen/src/Core/products/TriangularSolverMatrix_MKL.h +155 -0
  130. data/ext/eigen/eigen3/Eigen/src/Core/products/TriangularSolverVector.h +139 -0
  131. data/ext/eigen/eigen3/Eigen/src/Core/util/BlasUtil.h +264 -0
  132. data/ext/eigen/eigen3/Eigen/src/Core/util/Constants.h +451 -0
  133. data/ext/eigen/eigen3/Eigen/src/Core/util/DisableStupidWarnings.h +40 -0
  134. data/ext/eigen/eigen3/Eigen/src/Core/util/ForwardDeclarations.h +302 -0
  135. data/ext/eigen/eigen3/Eigen/src/Core/util/MKL_support.h +158 -0
  136. data/ext/eigen/eigen3/Eigen/src/Core/util/Macros.h +451 -0
  137. data/ext/eigen/eigen3/Eigen/src/Core/util/Memory.h +977 -0
  138. data/ext/eigen/eigen3/Eigen/src/Core/util/Meta.h +243 -0
  139. data/ext/eigen/eigen3/Eigen/src/Core/util/NonMPL2.h +3 -0
  140. data/ext/eigen/eigen3/Eigen/src/Core/util/ReenableStupidWarnings.h +14 -0
  141. data/ext/eigen/eigen3/Eigen/src/Core/util/StaticAssert.h +208 -0
  142. data/ext/eigen/eigen3/Eigen/src/Core/util/XprHelper.h +469 -0
  143. data/ext/eigen/eigen3/Eigen/src/Eigen2Support/Block.h +126 -0
  144. data/ext/eigen/eigen3/Eigen/src/Eigen2Support/Cwise.h +192 -0
  145. data/ext/eigen/eigen3/Eigen/src/Eigen2Support/CwiseOperators.h +298 -0
  146. data/ext/eigen/eigen3/Eigen/src/Eigen2Support/Geometry/AlignedBox.h +159 -0
  147. data/ext/eigen/eigen3/Eigen/src/Eigen2Support/Geometry/All.h +115 -0
  148. data/ext/eigen/eigen3/Eigen/src/Eigen2Support/Geometry/AngleAxis.h +214 -0
  149. data/ext/eigen/eigen3/Eigen/src/Eigen2Support/Geometry/Hyperplane.h +254 -0
  150. data/ext/eigen/eigen3/Eigen/src/Eigen2Support/Geometry/ParametrizedLine.h +141 -0
  151. data/ext/eigen/eigen3/Eigen/src/Eigen2Support/Geometry/Quaternion.h +495 -0
  152. data/ext/eigen/eigen3/Eigen/src/Eigen2Support/Geometry/Rotation2D.h +145 -0
  153. data/ext/eigen/eigen3/Eigen/src/Eigen2Support/Geometry/RotationBase.h +123 -0
  154. data/ext/eigen/eigen3/Eigen/src/Eigen2Support/Geometry/Scaling.h +167 -0
  155. data/ext/eigen/eigen3/Eigen/src/Eigen2Support/Geometry/Transform.h +786 -0
  156. data/ext/eigen/eigen3/Eigen/src/Eigen2Support/Geometry/Translation.h +184 -0
  157. data/ext/eigen/eigen3/Eigen/src/Eigen2Support/LU.h +120 -0
  158. data/ext/eigen/eigen3/Eigen/src/Eigen2Support/Lazy.h +71 -0
  159. data/ext/eigen/eigen3/Eigen/src/Eigen2Support/LeastSquares.h +169 -0
  160. data/ext/eigen/eigen3/Eigen/src/Eigen2Support/Macros.h +20 -0
  161. data/ext/eigen/eigen3/Eigen/src/Eigen2Support/MathFunctions.h +57 -0
  162. data/ext/eigen/eigen3/Eigen/src/Eigen2Support/Memory.h +45 -0
  163. data/ext/eigen/eigen3/Eigen/src/Eigen2Support/Meta.h +75 -0
  164. data/ext/eigen/eigen3/Eigen/src/Eigen2Support/Minor.h +117 -0
  165. data/ext/eigen/eigen3/Eigen/src/Eigen2Support/QR.h +67 -0
  166. data/ext/eigen/eigen3/Eigen/src/Eigen2Support/SVD.h +637 -0
  167. data/ext/eigen/eigen3/Eigen/src/Eigen2Support/TriangularSolver.h +42 -0
  168. data/ext/eigen/eigen3/Eigen/src/Eigen2Support/VectorBlock.h +94 -0
  169. data/ext/eigen/eigen3/Eigen/src/Eigenvalues/ComplexEigenSolver.h +341 -0
  170. data/ext/eigen/eigen3/Eigen/src/Eigenvalues/ComplexSchur.h +456 -0
  171. data/ext/eigen/eigen3/Eigen/src/Eigenvalues/ComplexSchur_MKL.h +94 -0
  172. data/ext/eigen/eigen3/Eigen/src/Eigenvalues/EigenSolver.h +607 -0
  173. data/ext/eigen/eigen3/Eigen/src/Eigenvalues/GeneralizedEigenSolver.h +350 -0
  174. data/ext/eigen/eigen3/Eigen/src/Eigenvalues/GeneralizedSelfAdjointEigenSolver.h +227 -0
  175. data/ext/eigen/eigen3/Eigen/src/Eigenvalues/HessenbergDecomposition.h +373 -0
  176. data/ext/eigen/eigen3/Eigen/src/Eigenvalues/MatrixBaseEigenvalues.h +160 -0
  177. data/ext/eigen/eigen3/Eigen/src/Eigenvalues/RealQZ.h +624 -0
  178. data/ext/eigen/eigen3/Eigen/src/Eigenvalues/RealSchur.h +525 -0
  179. data/ext/eigen/eigen3/Eigen/src/Eigenvalues/RealSchur_MKL.h +83 -0
  180. data/ext/eigen/eigen3/Eigen/src/Eigenvalues/SelfAdjointEigenSolver.h +801 -0
  181. data/ext/eigen/eigen3/Eigen/src/Eigenvalues/SelfAdjointEigenSolver_MKL.h +92 -0
  182. data/ext/eigen/eigen3/Eigen/src/Eigenvalues/Tridiagonalization.h +557 -0
  183. data/ext/eigen/eigen3/Eigen/src/Geometry/AlignedBox.h +392 -0
  184. data/ext/eigen/eigen3/Eigen/src/Geometry/AngleAxis.h +233 -0
  185. data/ext/eigen/eigen3/Eigen/src/Geometry/EulerAngles.h +104 -0
  186. data/ext/eigen/eigen3/Eigen/src/Geometry/Homogeneous.h +307 -0
  187. data/ext/eigen/eigen3/Eigen/src/Geometry/Hyperplane.h +280 -0
  188. data/ext/eigen/eigen3/Eigen/src/Geometry/OrthoMethods.h +218 -0
  189. data/ext/eigen/eigen3/Eigen/src/Geometry/ParametrizedLine.h +195 -0
  190. data/ext/eigen/eigen3/Eigen/src/Geometry/Quaternion.h +776 -0
  191. data/ext/eigen/eigen3/Eigen/src/Geometry/Rotation2D.h +160 -0
  192. data/ext/eigen/eigen3/Eigen/src/Geometry/RotationBase.h +206 -0
  193. data/ext/eigen/eigen3/Eigen/src/Geometry/Scaling.h +166 -0
  194. data/ext/eigen/eigen3/Eigen/src/Geometry/Transform.h +1455 -0
  195. data/ext/eigen/eigen3/Eigen/src/Geometry/Translation.h +206 -0
  196. data/ext/eigen/eigen3/Eigen/src/Geometry/Umeyama.h +177 -0
  197. data/ext/eigen/eigen3/Eigen/src/Geometry/arch/Geometry_SSE.h +115 -0
  198. data/ext/eigen/eigen3/Eigen/src/Householder/BlockHouseholder.h +68 -0
  199. data/ext/eigen/eigen3/Eigen/src/Householder/Householder.h +171 -0
  200. data/ext/eigen/eigen3/Eigen/src/Householder/HouseholderSequence.h +441 -0
  201. data/ext/eigen/eigen3/Eigen/src/IterativeLinearSolvers/BasicPreconditioners.h +149 -0
  202. data/ext/eigen/eigen3/Eigen/src/IterativeLinearSolvers/BiCGSTAB.h +263 -0
  203. data/ext/eigen/eigen3/Eigen/src/IterativeLinearSolvers/ConjugateGradient.h +256 -0
  204. data/ext/eigen/eigen3/Eigen/src/IterativeLinearSolvers/IterativeSolverBase.h +282 -0
  205. data/ext/eigen/eigen3/Eigen/src/Jacobi/Jacobi.h +433 -0
  206. data/ext/eigen/eigen3/Eigen/src/LU/Determinant.h +101 -0
  207. data/ext/eigen/eigen3/Eigen/src/LU/FullPivLU.h +751 -0
  208. data/ext/eigen/eigen3/Eigen/src/LU/Inverse.h +400 -0
  209. data/ext/eigen/eigen3/Eigen/src/LU/PartialPivLU.h +509 -0
  210. data/ext/eigen/eigen3/Eigen/src/LU/PartialPivLU_MKL.h +85 -0
  211. data/ext/eigen/eigen3/Eigen/src/LU/arch/Inverse_SSE.h +329 -0
  212. data/ext/eigen/eigen3/Eigen/src/MetisSupport/MetisSupport.h +137 -0
  213. data/ext/eigen/eigen3/Eigen/src/OrderingMethods/Amd.h +444 -0
  214. data/ext/eigen/eigen3/Eigen/src/OrderingMethods/Eigen_Colamd.h +1850 -0
  215. data/ext/eigen/eigen3/Eigen/src/PaStiXSupport/PaStiXSupport.h +721 -0
  216. data/ext/eigen/eigen3/Eigen/src/PardisoSupport/PardisoSupport.h +592 -0
  217. data/ext/eigen/eigen3/Eigen/src/QR/ColPivHouseholderQR.h +580 -0
  218. data/ext/eigen/eigen3/Eigen/src/QR/ColPivHouseholderQR_MKL.h +99 -0
  219. data/ext/eigen/eigen3/Eigen/src/QR/FullPivHouseholderQR.h +622 -0
  220. data/ext/eigen/eigen3/Eigen/src/QR/HouseholderQR.h +388 -0
  221. data/ext/eigen/eigen3/Eigen/src/QR/HouseholderQR_MKL.h +71 -0
  222. data/ext/eigen/eigen3/Eigen/src/SPQRSupport/SuiteSparseQRSupport.h +338 -0
  223. data/ext/eigen/eigen3/Eigen/src/SVD/JacobiSVD.h +976 -0
  224. data/ext/eigen/eigen3/Eigen/src/SVD/JacobiSVD_MKL.h +92 -0
  225. data/ext/eigen/eigen3/Eigen/src/SVD/UpperBidiagonalization.h +148 -0
  226. data/ext/eigen/eigen3/Eigen/src/SparseCholesky/SimplicialCholesky.h +671 -0
  227. data/ext/eigen/eigen3/Eigen/src/SparseCholesky/SimplicialCholesky_impl.h +199 -0
  228. data/ext/eigen/eigen3/Eigen/src/SparseCore/AmbiVector.h +373 -0
  229. data/ext/eigen/eigen3/Eigen/src/SparseCore/CompressedStorage.h +233 -0
  230. data/ext/eigen/eigen3/Eigen/src/SparseCore/ConservativeSparseSparseProduct.h +245 -0
  231. data/ext/eigen/eigen3/Eigen/src/SparseCore/MappedSparseMatrix.h +181 -0
  232. data/ext/eigen/eigen3/Eigen/src/SparseCore/SparseBlock.h +537 -0
  233. data/ext/eigen/eigen3/Eigen/src/SparseCore/SparseColEtree.h +206 -0
  234. data/ext/eigen/eigen3/Eigen/src/SparseCore/SparseCwiseBinaryOp.h +325 -0
  235. data/ext/eigen/eigen3/Eigen/src/SparseCore/SparseCwiseUnaryOp.h +163 -0
  236. data/ext/eigen/eigen3/Eigen/src/SparseCore/SparseDenseProduct.h +311 -0
  237. data/ext/eigen/eigen3/Eigen/src/SparseCore/SparseDiagonalProduct.h +196 -0
  238. data/ext/eigen/eigen3/Eigen/src/SparseCore/SparseDot.h +101 -0
  239. data/ext/eigen/eigen3/Eigen/src/SparseCore/SparseFuzzy.h +26 -0
  240. data/ext/eigen/eigen3/Eigen/src/SparseCore/SparseMatrix.h +1262 -0
  241. data/ext/eigen/eigen3/Eigen/src/SparseCore/SparseMatrixBase.h +461 -0
  242. data/ext/eigen/eigen3/Eigen/src/SparseCore/SparsePermutation.h +148 -0
  243. data/ext/eigen/eigen3/Eigen/src/SparseCore/SparseProduct.h +188 -0
  244. data/ext/eigen/eigen3/Eigen/src/SparseCore/SparseRedux.h +45 -0
  245. data/ext/eigen/eigen3/Eigen/src/SparseCore/SparseSelfAdjointView.h +507 -0
  246. data/ext/eigen/eigen3/Eigen/src/SparseCore/SparseSparseProductWithPruning.h +150 -0
  247. data/ext/eigen/eigen3/Eigen/src/SparseCore/SparseTranspose.h +63 -0
  248. data/ext/eigen/eigen3/Eigen/src/SparseCore/SparseTriangularView.h +179 -0
  249. data/ext/eigen/eigen3/Eigen/src/SparseCore/SparseUtil.h +172 -0
  250. data/ext/eigen/eigen3/Eigen/src/SparseCore/SparseVector.h +448 -0
  251. data/ext/eigen/eigen3/Eigen/src/SparseCore/SparseView.h +99 -0
  252. data/ext/eigen/eigen3/Eigen/src/SparseCore/TriangularSolver.h +334 -0
  253. data/ext/eigen/eigen3/Eigen/src/SparseLU/SparseLU.h +806 -0
  254. data/ext/eigen/eigen3/Eigen/src/SparseLU/SparseLUImpl.h +66 -0
  255. data/ext/eigen/eigen3/Eigen/src/SparseLU/SparseLU_Memory.h +227 -0
  256. data/ext/eigen/eigen3/Eigen/src/SparseLU/SparseLU_Structs.h +111 -0
  257. data/ext/eigen/eigen3/Eigen/src/SparseLU/SparseLU_SupernodalMatrix.h +298 -0
  258. data/ext/eigen/eigen3/Eigen/src/SparseLU/SparseLU_Utils.h +80 -0
  259. data/ext/eigen/eigen3/Eigen/src/SparseLU/SparseLU_column_bmod.h +180 -0
  260. data/ext/eigen/eigen3/Eigen/src/SparseLU/SparseLU_column_dfs.h +177 -0
  261. data/ext/eigen/eigen3/Eigen/src/SparseLU/SparseLU_copy_to_ucol.h +106 -0
  262. data/ext/eigen/eigen3/Eigen/src/SparseLU/SparseLU_gemm_kernel.h +279 -0
  263. data/ext/eigen/eigen3/Eigen/src/SparseLU/SparseLU_heap_relax_snode.h +127 -0
  264. data/ext/eigen/eigen3/Eigen/src/SparseLU/SparseLU_kernel_bmod.h +130 -0
  265. data/ext/eigen/eigen3/Eigen/src/SparseLU/SparseLU_panel_bmod.h +223 -0
  266. data/ext/eigen/eigen3/Eigen/src/SparseLU/SparseLU_panel_dfs.h +258 -0
  267. data/ext/eigen/eigen3/Eigen/src/SparseLU/SparseLU_pivotL.h +137 -0
  268. data/ext/eigen/eigen3/Eigen/src/SparseLU/SparseLU_pruneL.h +135 -0
  269. data/ext/eigen/eigen3/Eigen/src/SparseLU/SparseLU_relax_snode.h +83 -0
  270. data/ext/eigen/eigen3/Eigen/src/SparseQR/SparseQR.h +714 -0
  271. data/ext/eigen/eigen3/Eigen/src/StlSupport/StdDeque.h +134 -0
  272. data/ext/eigen/eigen3/Eigen/src/StlSupport/StdList.h +114 -0
  273. data/ext/eigen/eigen3/Eigen/src/StlSupport/StdVector.h +126 -0
  274. data/ext/eigen/eigen3/Eigen/src/StlSupport/details.h +84 -0
  275. data/ext/eigen/eigen3/Eigen/src/SuperLUSupport/SuperLUSupport.h +1026 -0
  276. data/ext/eigen/eigen3/Eigen/src/UmfPackSupport/UmfPackSupport.h +474 -0
  277. data/ext/eigen/eigen3/Eigen/src/misc/Image.h +84 -0
  278. data/ext/eigen/eigen3/Eigen/src/misc/Kernel.h +81 -0
  279. data/ext/eigen/eigen3/Eigen/src/misc/Solve.h +76 -0
  280. data/ext/eigen/eigen3/Eigen/src/misc/SparseSolve.h +128 -0
  281. data/ext/eigen/eigen3/Eigen/src/misc/blas.h +658 -0
  282. data/ext/eigen/eigen3/Eigen/src/plugins/ArrayCwiseBinaryOps.h +253 -0
  283. data/ext/eigen/eigen3/Eigen/src/plugins/ArrayCwiseUnaryOps.h +187 -0
  284. data/ext/eigen/eigen3/Eigen/src/plugins/BlockMethods.h +935 -0
  285. data/ext/eigen/eigen3/Eigen/src/plugins/CommonCwiseBinaryOps.h +46 -0
  286. data/ext/eigen/eigen3/Eigen/src/plugins/CommonCwiseUnaryOps.h +172 -0
  287. data/ext/eigen/eigen3/Eigen/src/plugins/MatrixCwiseBinaryOps.h +143 -0
  288. data/ext/eigen/eigen3/Eigen/src/plugins/MatrixCwiseUnaryOps.h +52 -0
  289. data/ext/eigen/eigen3/signature_of_eigen3_matrix_library +1 -0
  290. data/ext/eigen/eigen_wrap.cxx +19420 -10396
  291. data/ext/eigen/extconf.rb +37 -2
  292. data/lib/eigen.rb +146 -3
  293. metadata +294 -7
@@ -0,0 +1,338 @@
1
+ // This file is part of Eigen, a lightweight C++ template library
2
+ // for linear algebra.
3
+ //
4
+ // Copyright (C) 2012 Desire Nuentsa <desire.nuentsa_wakam@inria.fr>
5
+ //
6
+ // This Source Code Form is subject to the terms of the Mozilla
7
+ // Public License v. 2.0. If a copy of the MPL was not distributed
8
+ // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
9
+
10
+ #ifndef EIGEN_SUITESPARSEQRSUPPORT_H
11
+ #define EIGEN_SUITESPARSEQRSUPPORT_H
12
+
13
+ namespace Eigen {
14
+
15
+ template<typename MatrixType> class SPQR;
16
+ template<typename SPQRType> struct SPQRMatrixQReturnType;
17
+ template<typename SPQRType> struct SPQRMatrixQTransposeReturnType;
18
+ template <typename SPQRType, typename Derived> struct SPQR_QProduct;
19
+ namespace internal {
20
+ template <typename SPQRType> struct traits<SPQRMatrixQReturnType<SPQRType> >
21
+ {
22
+ typedef typename SPQRType::MatrixType ReturnType;
23
+ };
24
+ template <typename SPQRType> struct traits<SPQRMatrixQTransposeReturnType<SPQRType> >
25
+ {
26
+ typedef typename SPQRType::MatrixType ReturnType;
27
+ };
28
+ template <typename SPQRType, typename Derived> struct traits<SPQR_QProduct<SPQRType, Derived> >
29
+ {
30
+ typedef typename Derived::PlainObject ReturnType;
31
+ };
32
+ } // End namespace internal
33
+
34
+ /**
35
+ * \ingroup SPQRSupport_Module
36
+ * \class SPQR
37
+ * \brief Sparse QR factorization based on SuiteSparseQR library
38
+ *
39
+ * This class is used to perform a multithreaded and multifrontal rank-revealing QR decomposition
40
+ * of sparse matrices. The result is then used to solve linear leasts_square systems.
41
+ * Clearly, a QR factorization is returned such that A*P = Q*R where :
42
+ *
43
+ * P is the column permutation. Use colsPermutation() to get it.
44
+ *
45
+ * Q is the orthogonal matrix represented as Householder reflectors.
46
+ * Use matrixQ() to get an expression and matrixQ().transpose() to get the transpose.
47
+ * You can then apply it to a vector.
48
+ *
49
+ * R is the sparse triangular factor. Use matrixQR() to get it as SparseMatrix.
50
+ * NOTE : The Index type of R is always SuiteSparse_long. You can get it with SPQR::Index
51
+ *
52
+ * \tparam _MatrixType The type of the sparse matrix A, must be a column-major SparseMatrix<>
53
+ * NOTE
54
+ *
55
+ */
56
+ template<typename _MatrixType>
57
+ class SPQR
58
+ {
59
+ public:
60
+ typedef typename _MatrixType::Scalar Scalar;
61
+ typedef typename _MatrixType::RealScalar RealScalar;
62
+ typedef SuiteSparse_long Index ;
63
+ typedef SparseMatrix<Scalar, ColMajor, Index> MatrixType;
64
+ typedef PermutationMatrix<Dynamic, Dynamic> PermutationType;
65
+ public:
66
+ SPQR()
67
+ : m_isInitialized(false), m_ordering(SPQR_ORDERING_DEFAULT), m_allow_tol(SPQR_DEFAULT_TOL), m_tolerance (NumTraits<Scalar>::epsilon()), m_useDefaultThreshold(true)
68
+ {
69
+ cholmod_l_start(&m_cc);
70
+ }
71
+
72
+ SPQR(const _MatrixType& matrix)
73
+ : m_isInitialized(false), m_ordering(SPQR_ORDERING_DEFAULT), m_allow_tol(SPQR_DEFAULT_TOL), m_tolerance (NumTraits<Scalar>::epsilon()), m_useDefaultThreshold(true)
74
+ {
75
+ cholmod_l_start(&m_cc);
76
+ compute(matrix);
77
+ }
78
+
79
+ ~SPQR()
80
+ {
81
+ SPQR_free();
82
+ cholmod_l_finish(&m_cc);
83
+ }
84
+ void SPQR_free()
85
+ {
86
+ cholmod_l_free_sparse(&m_H, &m_cc);
87
+ cholmod_l_free_sparse(&m_cR, &m_cc);
88
+ cholmod_l_free_dense(&m_HTau, &m_cc);
89
+ std::free(m_E);
90
+ std::free(m_HPinv);
91
+ }
92
+
93
+ void compute(const _MatrixType& matrix)
94
+ {
95
+ if(m_isInitialized) SPQR_free();
96
+
97
+ MatrixType mat(matrix);
98
+
99
+ /* Compute the default threshold as in MatLab, see:
100
+ * Tim Davis, "Algorithm 915, SuiteSparseQR: Multifrontal Multithreaded Rank-Revealing
101
+ * Sparse QR Factorization, ACM Trans. on Math. Soft. 38(1), 2011, Page 8:3
102
+ */
103
+ RealScalar pivotThreshold = m_tolerance;
104
+ if(m_useDefaultThreshold)
105
+ {
106
+ using std::max;
107
+ RealScalar max2Norm = 0.0;
108
+ for (int j = 0; j < mat.cols(); j++) max2Norm = (max)(max2Norm, mat.col(j).norm());
109
+ if(max2Norm==RealScalar(0))
110
+ max2Norm = RealScalar(1);
111
+ pivotThreshold = 20 * (mat.rows() + mat.cols()) * max2Norm * NumTraits<RealScalar>::epsilon();
112
+ }
113
+
114
+ cholmod_sparse A;
115
+ A = viewAsCholmod(mat);
116
+ Index col = matrix.cols();
117
+ m_rank = SuiteSparseQR<Scalar>(m_ordering, pivotThreshold, col, &A,
118
+ &m_cR, &m_E, &m_H, &m_HPinv, &m_HTau, &m_cc);
119
+
120
+ if (!m_cR)
121
+ {
122
+ m_info = NumericalIssue;
123
+ m_isInitialized = false;
124
+ return;
125
+ }
126
+ m_info = Success;
127
+ m_isInitialized = true;
128
+ m_isRUpToDate = false;
129
+ }
130
+ /**
131
+ * Get the number of rows of the input matrix and the Q matrix
132
+ */
133
+ inline Index rows() const {return m_cR->nrow; }
134
+
135
+ /**
136
+ * Get the number of columns of the input matrix.
137
+ */
138
+ inline Index cols() const { return m_cR->ncol; }
139
+
140
+ /** \returns the solution X of \f$ A X = B \f$ using the current decomposition of A.
141
+ *
142
+ * \sa compute()
143
+ */
144
+ template<typename Rhs>
145
+ inline const internal::solve_retval<SPQR, Rhs> solve(const MatrixBase<Rhs>& B) const
146
+ {
147
+ eigen_assert(m_isInitialized && " The QR factorization should be computed first, call compute()");
148
+ eigen_assert(this->rows()==B.rows()
149
+ && "SPQR::solve(): invalid number of rows of the right hand side matrix B");
150
+ return internal::solve_retval<SPQR, Rhs>(*this, B.derived());
151
+ }
152
+
153
+ template<typename Rhs, typename Dest>
154
+ void _solve(const MatrixBase<Rhs> &b, MatrixBase<Dest> &dest) const
155
+ {
156
+ eigen_assert(m_isInitialized && " The QR factorization should be computed first, call compute()");
157
+ eigen_assert(b.cols()==1 && "This method is for vectors only");
158
+
159
+ //Compute Q^T * b
160
+ typename Dest::PlainObject y, y2;
161
+ y = matrixQ().transpose() * b;
162
+
163
+ // Solves with the triangular matrix R
164
+ Index rk = this->rank();
165
+ y2 = y;
166
+ y.resize((std::max)(cols(),Index(y.rows())),y.cols());
167
+ y.topRows(rk) = this->matrixR().topLeftCorner(rk, rk).template triangularView<Upper>().solve(y2.topRows(rk));
168
+
169
+ // Apply the column permutation
170
+ // colsPermutation() performs a copy of the permutation,
171
+ // so let's apply it manually:
172
+ for(Index i = 0; i < rk; ++i) dest.row(m_E[i]) = y.row(i);
173
+ for(Index i = rk; i < cols(); ++i) dest.row(m_E[i]).setZero();
174
+
175
+ // y.bottomRows(y.rows()-rk).setZero();
176
+ // dest = colsPermutation() * y.topRows(cols());
177
+
178
+ m_info = Success;
179
+ }
180
+
181
+ /** \returns the sparse triangular factor R. It is a sparse matrix
182
+ */
183
+ const MatrixType matrixR() const
184
+ {
185
+ eigen_assert(m_isInitialized && " The QR factorization should be computed first, call compute()");
186
+ if(!m_isRUpToDate) {
187
+ m_R = viewAsEigen<Scalar,ColMajor, typename MatrixType::Index>(*m_cR);
188
+ m_isRUpToDate = true;
189
+ }
190
+ return m_R;
191
+ }
192
+ /// Get an expression of the matrix Q
193
+ SPQRMatrixQReturnType<SPQR> matrixQ() const
194
+ {
195
+ return SPQRMatrixQReturnType<SPQR>(*this);
196
+ }
197
+ /// Get the permutation that was applied to columns of A
198
+ PermutationType colsPermutation() const
199
+ {
200
+ eigen_assert(m_isInitialized && "Decomposition is not initialized.");
201
+ Index n = m_cR->ncol;
202
+ PermutationType colsPerm(n);
203
+ for(Index j = 0; j <n; j++) colsPerm.indices()(j) = m_E[j];
204
+ return colsPerm;
205
+
206
+ }
207
+ /**
208
+ * Gets the rank of the matrix.
209
+ * It should be equal to matrixQR().cols if the matrix is full-rank
210
+ */
211
+ Index rank() const
212
+ {
213
+ eigen_assert(m_isInitialized && "Decomposition is not initialized.");
214
+ return m_cc.SPQR_istat[4];
215
+ }
216
+ /// Set the fill-reducing ordering method to be used
217
+ void setSPQROrdering(int ord) { m_ordering = ord;}
218
+ /// Set the tolerance tol to treat columns with 2-norm < =tol as zero
219
+ void setPivotThreshold(const RealScalar& tol)
220
+ {
221
+ m_useDefaultThreshold = false;
222
+ m_tolerance = tol;
223
+ }
224
+
225
+ /** \returns a pointer to the SPQR workspace */
226
+ cholmod_common *cholmodCommon() const { return &m_cc; }
227
+
228
+
229
+ /** \brief Reports whether previous computation was successful.
230
+ *
231
+ * \returns \c Success if computation was succesful,
232
+ * \c NumericalIssue if the sparse QR can not be computed
233
+ */
234
+ ComputationInfo info() const
235
+ {
236
+ eigen_assert(m_isInitialized && "Decomposition is not initialized.");
237
+ return m_info;
238
+ }
239
+ protected:
240
+ bool m_isInitialized;
241
+ bool m_analysisIsOk;
242
+ bool m_factorizationIsOk;
243
+ mutable bool m_isRUpToDate;
244
+ mutable ComputationInfo m_info;
245
+ int m_ordering; // Ordering method to use, see SPQR's manual
246
+ int m_allow_tol; // Allow to use some tolerance during numerical factorization.
247
+ RealScalar m_tolerance; // treat columns with 2-norm below this tolerance as zero
248
+ mutable cholmod_sparse *m_cR; // The sparse R factor in cholmod format
249
+ mutable MatrixType m_R; // The sparse matrix R in Eigen format
250
+ mutable Index *m_E; // The permutation applied to columns
251
+ mutable cholmod_sparse *m_H; //The householder vectors
252
+ mutable Index *m_HPinv; // The row permutation of H
253
+ mutable cholmod_dense *m_HTau; // The Householder coefficients
254
+ mutable Index m_rank; // The rank of the matrix
255
+ mutable cholmod_common m_cc; // Workspace and parameters
256
+ bool m_useDefaultThreshold; // Use default threshold
257
+ template<typename ,typename > friend struct SPQR_QProduct;
258
+ };
259
+
260
+ template <typename SPQRType, typename Derived>
261
+ struct SPQR_QProduct : ReturnByValue<SPQR_QProduct<SPQRType,Derived> >
262
+ {
263
+ typedef typename SPQRType::Scalar Scalar;
264
+ typedef typename SPQRType::Index Index;
265
+ //Define the constructor to get reference to argument types
266
+ SPQR_QProduct(const SPQRType& spqr, const Derived& other, bool transpose) : m_spqr(spqr),m_other(other),m_transpose(transpose) {}
267
+
268
+ inline Index rows() const { return m_transpose ? m_spqr.rows() : m_spqr.cols(); }
269
+ inline Index cols() const { return m_other.cols(); }
270
+ // Assign to a vector
271
+ template<typename ResType>
272
+ void evalTo(ResType& res) const
273
+ {
274
+ cholmod_dense y_cd;
275
+ cholmod_dense *x_cd;
276
+ int method = m_transpose ? SPQR_QTX : SPQR_QX;
277
+ cholmod_common *cc = m_spqr.cholmodCommon();
278
+ y_cd = viewAsCholmod(m_other.const_cast_derived());
279
+ x_cd = SuiteSparseQR_qmult<Scalar>(method, m_spqr.m_H, m_spqr.m_HTau, m_spqr.m_HPinv, &y_cd, cc);
280
+ res = Matrix<Scalar,ResType::RowsAtCompileTime,ResType::ColsAtCompileTime>::Map(reinterpret_cast<Scalar*>(x_cd->x), x_cd->nrow, x_cd->ncol);
281
+ cholmod_l_free_dense(&x_cd, cc);
282
+ }
283
+ const SPQRType& m_spqr;
284
+ const Derived& m_other;
285
+ bool m_transpose;
286
+
287
+ };
288
+ template<typename SPQRType>
289
+ struct SPQRMatrixQReturnType{
290
+
291
+ SPQRMatrixQReturnType(const SPQRType& spqr) : m_spqr(spqr) {}
292
+ template<typename Derived>
293
+ SPQR_QProduct<SPQRType, Derived> operator*(const MatrixBase<Derived>& other)
294
+ {
295
+ return SPQR_QProduct<SPQRType,Derived>(m_spqr,other.derived(),false);
296
+ }
297
+ SPQRMatrixQTransposeReturnType<SPQRType> adjoint() const
298
+ {
299
+ return SPQRMatrixQTransposeReturnType<SPQRType>(m_spqr);
300
+ }
301
+ // To use for operations with the transpose of Q
302
+ SPQRMatrixQTransposeReturnType<SPQRType> transpose() const
303
+ {
304
+ return SPQRMatrixQTransposeReturnType<SPQRType>(m_spqr);
305
+ }
306
+ const SPQRType& m_spqr;
307
+ };
308
+
309
+ template<typename SPQRType>
310
+ struct SPQRMatrixQTransposeReturnType{
311
+ SPQRMatrixQTransposeReturnType(const SPQRType& spqr) : m_spqr(spqr) {}
312
+ template<typename Derived>
313
+ SPQR_QProduct<SPQRType,Derived> operator*(const MatrixBase<Derived>& other)
314
+ {
315
+ return SPQR_QProduct<SPQRType,Derived>(m_spqr,other.derived(), true);
316
+ }
317
+ const SPQRType& m_spqr;
318
+ };
319
+
320
+ namespace internal {
321
+
322
+ template<typename _MatrixType, typename Rhs>
323
+ struct solve_retval<SPQR<_MatrixType>, Rhs>
324
+ : solve_retval_base<SPQR<_MatrixType>, Rhs>
325
+ {
326
+ typedef SPQR<_MatrixType> Dec;
327
+ EIGEN_MAKE_SOLVE_HELPERS(Dec,Rhs)
328
+
329
+ template<typename Dest> void evalTo(Dest& dst) const
330
+ {
331
+ dec()._solve(rhs(),dst);
332
+ }
333
+ };
334
+
335
+ } // end namespace internal
336
+
337
+ }// End namespace Eigen
338
+ #endif
@@ -0,0 +1,976 @@
1
+ // This file is part of Eigen, a lightweight C++ template library
2
+ // for linear algebra.
3
+ //
4
+ // Copyright (C) 2009-2010 Benoit Jacob <jacob.benoit.1@gmail.com>
5
+ //
6
+ // This Source Code Form is subject to the terms of the Mozilla
7
+ // Public License v. 2.0. If a copy of the MPL was not distributed
8
+ // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
9
+
10
+ #ifndef EIGEN_JACOBISVD_H
11
+ #define EIGEN_JACOBISVD_H
12
+
13
+ namespace Eigen {
14
+
15
+ namespace internal {
16
+ // forward declaration (needed by ICC)
17
+ // the empty body is required by MSVC
18
+ template<typename MatrixType, int QRPreconditioner,
19
+ bool IsComplex = NumTraits<typename MatrixType::Scalar>::IsComplex>
20
+ struct svd_precondition_2x2_block_to_be_real {};
21
+
22
+ /*** QR preconditioners (R-SVD)
23
+ ***
24
+ *** Their role is to reduce the problem of computing the SVD to the case of a square matrix.
25
+ *** This approach, known as R-SVD, is an optimization for rectangular-enough matrices, and is a requirement for
26
+ *** JacobiSVD which by itself is only able to work on square matrices.
27
+ ***/
28
+
29
+ enum { PreconditionIfMoreColsThanRows, PreconditionIfMoreRowsThanCols };
30
+
31
+ template<typename MatrixType, int QRPreconditioner, int Case>
32
+ struct qr_preconditioner_should_do_anything
33
+ {
34
+ enum { a = MatrixType::RowsAtCompileTime != Dynamic &&
35
+ MatrixType::ColsAtCompileTime != Dynamic &&
36
+ MatrixType::ColsAtCompileTime <= MatrixType::RowsAtCompileTime,
37
+ b = MatrixType::RowsAtCompileTime != Dynamic &&
38
+ MatrixType::ColsAtCompileTime != Dynamic &&
39
+ MatrixType::RowsAtCompileTime <= MatrixType::ColsAtCompileTime,
40
+ ret = !( (QRPreconditioner == NoQRPreconditioner) ||
41
+ (Case == PreconditionIfMoreColsThanRows && bool(a)) ||
42
+ (Case == PreconditionIfMoreRowsThanCols && bool(b)) )
43
+ };
44
+ };
45
+
46
+ template<typename MatrixType, int QRPreconditioner, int Case,
47
+ bool DoAnything = qr_preconditioner_should_do_anything<MatrixType, QRPreconditioner, Case>::ret
48
+ > struct qr_preconditioner_impl {};
49
+
50
+ template<typename MatrixType, int QRPreconditioner, int Case>
51
+ class qr_preconditioner_impl<MatrixType, QRPreconditioner, Case, false>
52
+ {
53
+ public:
54
+ typedef typename MatrixType::Index Index;
55
+ void allocate(const JacobiSVD<MatrixType, QRPreconditioner>&) {}
56
+ bool run(JacobiSVD<MatrixType, QRPreconditioner>&, const MatrixType&)
57
+ {
58
+ return false;
59
+ }
60
+ };
61
+
62
+ /*** preconditioner using FullPivHouseholderQR ***/
63
+
64
+ template<typename MatrixType>
65
+ class qr_preconditioner_impl<MatrixType, FullPivHouseholderQRPreconditioner, PreconditionIfMoreRowsThanCols, true>
66
+ {
67
+ public:
68
+ typedef typename MatrixType::Index Index;
69
+ typedef typename MatrixType::Scalar Scalar;
70
+ enum
71
+ {
72
+ RowsAtCompileTime = MatrixType::RowsAtCompileTime,
73
+ MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime
74
+ };
75
+ typedef Matrix<Scalar, 1, RowsAtCompileTime, RowMajor, 1, MaxRowsAtCompileTime> WorkspaceType;
76
+
77
+ void allocate(const JacobiSVD<MatrixType, FullPivHouseholderQRPreconditioner>& svd)
78
+ {
79
+ if (svd.rows() != m_qr.rows() || svd.cols() != m_qr.cols())
80
+ {
81
+ m_qr.~QRType();
82
+ ::new (&m_qr) QRType(svd.rows(), svd.cols());
83
+ }
84
+ if (svd.m_computeFullU) m_workspace.resize(svd.rows());
85
+ }
86
+
87
+ bool run(JacobiSVD<MatrixType, FullPivHouseholderQRPreconditioner>& svd, const MatrixType& matrix)
88
+ {
89
+ if(matrix.rows() > matrix.cols())
90
+ {
91
+ m_qr.compute(matrix);
92
+ svd.m_workMatrix = m_qr.matrixQR().block(0,0,matrix.cols(),matrix.cols()).template triangularView<Upper>();
93
+ if(svd.m_computeFullU) m_qr.matrixQ().evalTo(svd.m_matrixU, m_workspace);
94
+ if(svd.computeV()) svd.m_matrixV = m_qr.colsPermutation();
95
+ return true;
96
+ }
97
+ return false;
98
+ }
99
+ private:
100
+ typedef FullPivHouseholderQR<MatrixType> QRType;
101
+ QRType m_qr;
102
+ WorkspaceType m_workspace;
103
+ };
104
+
105
+ template<typename MatrixType>
106
+ class qr_preconditioner_impl<MatrixType, FullPivHouseholderQRPreconditioner, PreconditionIfMoreColsThanRows, true>
107
+ {
108
+ public:
109
+ typedef typename MatrixType::Index Index;
110
+ typedef typename MatrixType::Scalar Scalar;
111
+ enum
112
+ {
113
+ RowsAtCompileTime = MatrixType::RowsAtCompileTime,
114
+ ColsAtCompileTime = MatrixType::ColsAtCompileTime,
115
+ MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime,
116
+ MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime,
117
+ Options = MatrixType::Options
118
+ };
119
+ typedef Matrix<Scalar, ColsAtCompileTime, RowsAtCompileTime, Options, MaxColsAtCompileTime, MaxRowsAtCompileTime>
120
+ TransposeTypeWithSameStorageOrder;
121
+
122
+ void allocate(const JacobiSVD<MatrixType, FullPivHouseholderQRPreconditioner>& svd)
123
+ {
124
+ if (svd.cols() != m_qr.rows() || svd.rows() != m_qr.cols())
125
+ {
126
+ m_qr.~QRType();
127
+ ::new (&m_qr) QRType(svd.cols(), svd.rows());
128
+ }
129
+ m_adjoint.resize(svd.cols(), svd.rows());
130
+ if (svd.m_computeFullV) m_workspace.resize(svd.cols());
131
+ }
132
+
133
+ bool run(JacobiSVD<MatrixType, FullPivHouseholderQRPreconditioner>& svd, const MatrixType& matrix)
134
+ {
135
+ if(matrix.cols() > matrix.rows())
136
+ {
137
+ m_adjoint = matrix.adjoint();
138
+ m_qr.compute(m_adjoint);
139
+ svd.m_workMatrix = m_qr.matrixQR().block(0,0,matrix.rows(),matrix.rows()).template triangularView<Upper>().adjoint();
140
+ if(svd.m_computeFullV) m_qr.matrixQ().evalTo(svd.m_matrixV, m_workspace);
141
+ if(svd.computeU()) svd.m_matrixU = m_qr.colsPermutation();
142
+ return true;
143
+ }
144
+ else return false;
145
+ }
146
+ private:
147
+ typedef FullPivHouseholderQR<TransposeTypeWithSameStorageOrder> QRType;
148
+ QRType m_qr;
149
+ TransposeTypeWithSameStorageOrder m_adjoint;
150
+ typename internal::plain_row_type<MatrixType>::type m_workspace;
151
+ };
152
+
153
+ /*** preconditioner using ColPivHouseholderQR ***/
154
+
155
+ template<typename MatrixType>
156
+ class qr_preconditioner_impl<MatrixType, ColPivHouseholderQRPreconditioner, PreconditionIfMoreRowsThanCols, true>
157
+ {
158
+ public:
159
+ typedef typename MatrixType::Index Index;
160
+
161
+ void allocate(const JacobiSVD<MatrixType, ColPivHouseholderQRPreconditioner>& svd)
162
+ {
163
+ if (svd.rows() != m_qr.rows() || svd.cols() != m_qr.cols())
164
+ {
165
+ m_qr.~QRType();
166
+ ::new (&m_qr) QRType(svd.rows(), svd.cols());
167
+ }
168
+ if (svd.m_computeFullU) m_workspace.resize(svd.rows());
169
+ else if (svd.m_computeThinU) m_workspace.resize(svd.cols());
170
+ }
171
+
172
+ bool run(JacobiSVD<MatrixType, ColPivHouseholderQRPreconditioner>& svd, const MatrixType& matrix)
173
+ {
174
+ if(matrix.rows() > matrix.cols())
175
+ {
176
+ m_qr.compute(matrix);
177
+ svd.m_workMatrix = m_qr.matrixQR().block(0,0,matrix.cols(),matrix.cols()).template triangularView<Upper>();
178
+ if(svd.m_computeFullU) m_qr.householderQ().evalTo(svd.m_matrixU, m_workspace);
179
+ else if(svd.m_computeThinU)
180
+ {
181
+ svd.m_matrixU.setIdentity(matrix.rows(), matrix.cols());
182
+ m_qr.householderQ().applyThisOnTheLeft(svd.m_matrixU, m_workspace);
183
+ }
184
+ if(svd.computeV()) svd.m_matrixV = m_qr.colsPermutation();
185
+ return true;
186
+ }
187
+ return false;
188
+ }
189
+
190
+ private:
191
+ typedef ColPivHouseholderQR<MatrixType> QRType;
192
+ QRType m_qr;
193
+ typename internal::plain_col_type<MatrixType>::type m_workspace;
194
+ };
195
+
196
+ template<typename MatrixType>
197
+ class qr_preconditioner_impl<MatrixType, ColPivHouseholderQRPreconditioner, PreconditionIfMoreColsThanRows, true>
198
+ {
199
+ public:
200
+ typedef typename MatrixType::Index Index;
201
+ typedef typename MatrixType::Scalar Scalar;
202
+ enum
203
+ {
204
+ RowsAtCompileTime = MatrixType::RowsAtCompileTime,
205
+ ColsAtCompileTime = MatrixType::ColsAtCompileTime,
206
+ MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime,
207
+ MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime,
208
+ Options = MatrixType::Options
209
+ };
210
+
211
+ typedef Matrix<Scalar, ColsAtCompileTime, RowsAtCompileTime, Options, MaxColsAtCompileTime, MaxRowsAtCompileTime>
212
+ TransposeTypeWithSameStorageOrder;
213
+
214
+ void allocate(const JacobiSVD<MatrixType, ColPivHouseholderQRPreconditioner>& svd)
215
+ {
216
+ if (svd.cols() != m_qr.rows() || svd.rows() != m_qr.cols())
217
+ {
218
+ m_qr.~QRType();
219
+ ::new (&m_qr) QRType(svd.cols(), svd.rows());
220
+ }
221
+ if (svd.m_computeFullV) m_workspace.resize(svd.cols());
222
+ else if (svd.m_computeThinV) m_workspace.resize(svd.rows());
223
+ m_adjoint.resize(svd.cols(), svd.rows());
224
+ }
225
+
226
+ bool run(JacobiSVD<MatrixType, ColPivHouseholderQRPreconditioner>& svd, const MatrixType& matrix)
227
+ {
228
+ if(matrix.cols() > matrix.rows())
229
+ {
230
+ m_adjoint = matrix.adjoint();
231
+ m_qr.compute(m_adjoint);
232
+
233
+ svd.m_workMatrix = m_qr.matrixQR().block(0,0,matrix.rows(),matrix.rows()).template triangularView<Upper>().adjoint();
234
+ if(svd.m_computeFullV) m_qr.householderQ().evalTo(svd.m_matrixV, m_workspace);
235
+ else if(svd.m_computeThinV)
236
+ {
237
+ svd.m_matrixV.setIdentity(matrix.cols(), matrix.rows());
238
+ m_qr.householderQ().applyThisOnTheLeft(svd.m_matrixV, m_workspace);
239
+ }
240
+ if(svd.computeU()) svd.m_matrixU = m_qr.colsPermutation();
241
+ return true;
242
+ }
243
+ else return false;
244
+ }
245
+
246
+ private:
247
+ typedef ColPivHouseholderQR<TransposeTypeWithSameStorageOrder> QRType;
248
+ QRType m_qr;
249
+ TransposeTypeWithSameStorageOrder m_adjoint;
250
+ typename internal::plain_row_type<MatrixType>::type m_workspace;
251
+ };
252
+
253
+ /*** preconditioner using HouseholderQR ***/
254
+
255
+ template<typename MatrixType>
256
+ class qr_preconditioner_impl<MatrixType, HouseholderQRPreconditioner, PreconditionIfMoreRowsThanCols, true>
257
+ {
258
+ public:
259
+ typedef typename MatrixType::Index Index;
260
+
261
+ void allocate(const JacobiSVD<MatrixType, HouseholderQRPreconditioner>& svd)
262
+ {
263
+ if (svd.rows() != m_qr.rows() || svd.cols() != m_qr.cols())
264
+ {
265
+ m_qr.~QRType();
266
+ ::new (&m_qr) QRType(svd.rows(), svd.cols());
267
+ }
268
+ if (svd.m_computeFullU) m_workspace.resize(svd.rows());
269
+ else if (svd.m_computeThinU) m_workspace.resize(svd.cols());
270
+ }
271
+
272
+ bool run(JacobiSVD<MatrixType, HouseholderQRPreconditioner>& svd, const MatrixType& matrix)
273
+ {
274
+ if(matrix.rows() > matrix.cols())
275
+ {
276
+ m_qr.compute(matrix);
277
+ svd.m_workMatrix = m_qr.matrixQR().block(0,0,matrix.cols(),matrix.cols()).template triangularView<Upper>();
278
+ if(svd.m_computeFullU) m_qr.householderQ().evalTo(svd.m_matrixU, m_workspace);
279
+ else if(svd.m_computeThinU)
280
+ {
281
+ svd.m_matrixU.setIdentity(matrix.rows(), matrix.cols());
282
+ m_qr.householderQ().applyThisOnTheLeft(svd.m_matrixU, m_workspace);
283
+ }
284
+ if(svd.computeV()) svd.m_matrixV.setIdentity(matrix.cols(), matrix.cols());
285
+ return true;
286
+ }
287
+ return false;
288
+ }
289
+ private:
290
+ typedef HouseholderQR<MatrixType> QRType;
291
+ QRType m_qr;
292
+ typename internal::plain_col_type<MatrixType>::type m_workspace;
293
+ };
294
+
295
+ template<typename MatrixType>
296
+ class qr_preconditioner_impl<MatrixType, HouseholderQRPreconditioner, PreconditionIfMoreColsThanRows, true>
297
+ {
298
+ public:
299
+ typedef typename MatrixType::Index Index;
300
+ typedef typename MatrixType::Scalar Scalar;
301
+ enum
302
+ {
303
+ RowsAtCompileTime = MatrixType::RowsAtCompileTime,
304
+ ColsAtCompileTime = MatrixType::ColsAtCompileTime,
305
+ MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime,
306
+ MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime,
307
+ Options = MatrixType::Options
308
+ };
309
+
310
+ typedef Matrix<Scalar, ColsAtCompileTime, RowsAtCompileTime, Options, MaxColsAtCompileTime, MaxRowsAtCompileTime>
311
+ TransposeTypeWithSameStorageOrder;
312
+
313
+ void allocate(const JacobiSVD<MatrixType, HouseholderQRPreconditioner>& svd)
314
+ {
315
+ if (svd.cols() != m_qr.rows() || svd.rows() != m_qr.cols())
316
+ {
317
+ m_qr.~QRType();
318
+ ::new (&m_qr) QRType(svd.cols(), svd.rows());
319
+ }
320
+ if (svd.m_computeFullV) m_workspace.resize(svd.cols());
321
+ else if (svd.m_computeThinV) m_workspace.resize(svd.rows());
322
+ m_adjoint.resize(svd.cols(), svd.rows());
323
+ }
324
+
325
+ bool run(JacobiSVD<MatrixType, HouseholderQRPreconditioner>& svd, const MatrixType& matrix)
326
+ {
327
+ if(matrix.cols() > matrix.rows())
328
+ {
329
+ m_adjoint = matrix.adjoint();
330
+ m_qr.compute(m_adjoint);
331
+
332
+ svd.m_workMatrix = m_qr.matrixQR().block(0,0,matrix.rows(),matrix.rows()).template triangularView<Upper>().adjoint();
333
+ if(svd.m_computeFullV) m_qr.householderQ().evalTo(svd.m_matrixV, m_workspace);
334
+ else if(svd.m_computeThinV)
335
+ {
336
+ svd.m_matrixV.setIdentity(matrix.cols(), matrix.rows());
337
+ m_qr.householderQ().applyThisOnTheLeft(svd.m_matrixV, m_workspace);
338
+ }
339
+ if(svd.computeU()) svd.m_matrixU.setIdentity(matrix.rows(), matrix.rows());
340
+ return true;
341
+ }
342
+ else return false;
343
+ }
344
+
345
+ private:
346
+ typedef HouseholderQR<TransposeTypeWithSameStorageOrder> QRType;
347
+ QRType m_qr;
348
+ TransposeTypeWithSameStorageOrder m_adjoint;
349
+ typename internal::plain_row_type<MatrixType>::type m_workspace;
350
+ };
351
+
352
+ /*** 2x2 SVD implementation
353
+ ***
354
+ *** JacobiSVD consists in performing a series of 2x2 SVD subproblems
355
+ ***/
356
+
357
+ template<typename MatrixType, int QRPreconditioner>
358
+ struct svd_precondition_2x2_block_to_be_real<MatrixType, QRPreconditioner, false>
359
+ {
360
+ typedef JacobiSVD<MatrixType, QRPreconditioner> SVD;
361
+ typedef typename SVD::Index Index;
362
+ static void run(typename SVD::WorkMatrixType&, SVD&, Index, Index) {}
363
+ };
364
+
365
+ template<typename MatrixType, int QRPreconditioner>
366
+ struct svd_precondition_2x2_block_to_be_real<MatrixType, QRPreconditioner, true>
367
+ {
368
+ typedef JacobiSVD<MatrixType, QRPreconditioner> SVD;
369
+ typedef typename MatrixType::Scalar Scalar;
370
+ typedef typename MatrixType::RealScalar RealScalar;
371
+ typedef typename SVD::Index Index;
372
+ static void run(typename SVD::WorkMatrixType& work_matrix, SVD& svd, Index p, Index q)
373
+ {
374
+ using std::sqrt;
375
+ Scalar z;
376
+ JacobiRotation<Scalar> rot;
377
+ RealScalar n = sqrt(numext::abs2(work_matrix.coeff(p,p)) + numext::abs2(work_matrix.coeff(q,p)));
378
+
379
+ if(n==0)
380
+ {
381
+ z = abs(work_matrix.coeff(p,q)) / work_matrix.coeff(p,q);
382
+ work_matrix.row(p) *= z;
383
+ if(svd.computeU()) svd.m_matrixU.col(p) *= conj(z);
384
+ if(work_matrix.coeff(q,q)!=Scalar(0))
385
+ {
386
+ z = abs(work_matrix.coeff(q,q)) / work_matrix.coeff(q,q);
387
+ work_matrix.row(q) *= z;
388
+ if(svd.computeU()) svd.m_matrixU.col(q) *= conj(z);
389
+ }
390
+ // otherwise the second row is already zero, so we have nothing to do.
391
+ }
392
+ else
393
+ {
394
+ rot.c() = conj(work_matrix.coeff(p,p)) / n;
395
+ rot.s() = work_matrix.coeff(q,p) / n;
396
+ work_matrix.applyOnTheLeft(p,q,rot);
397
+ if(svd.computeU()) svd.m_matrixU.applyOnTheRight(p,q,rot.adjoint());
398
+ if(work_matrix.coeff(p,q) != Scalar(0))
399
+ {
400
+ Scalar z = abs(work_matrix.coeff(p,q)) / work_matrix.coeff(p,q);
401
+ work_matrix.col(q) *= z;
402
+ if(svd.computeV()) svd.m_matrixV.col(q) *= z;
403
+ }
404
+ if(work_matrix.coeff(q,q) != Scalar(0))
405
+ {
406
+ z = abs(work_matrix.coeff(q,q)) / work_matrix.coeff(q,q);
407
+ work_matrix.row(q) *= z;
408
+ if(svd.computeU()) svd.m_matrixU.col(q) *= conj(z);
409
+ }
410
+ }
411
+ }
412
+ };
413
+
414
+ template<typename MatrixType, typename RealScalar, typename Index>
415
+ void real_2x2_jacobi_svd(const MatrixType& matrix, Index p, Index q,
416
+ JacobiRotation<RealScalar> *j_left,
417
+ JacobiRotation<RealScalar> *j_right)
418
+ {
419
+ using std::sqrt;
420
+ using std::abs;
421
+ Matrix<RealScalar,2,2> m;
422
+ m << numext::real(matrix.coeff(p,p)), numext::real(matrix.coeff(p,q)),
423
+ numext::real(matrix.coeff(q,p)), numext::real(matrix.coeff(q,q));
424
+ JacobiRotation<RealScalar> rot1;
425
+ RealScalar t = m.coeff(0,0) + m.coeff(1,1);
426
+ RealScalar d = m.coeff(1,0) - m.coeff(0,1);
427
+ if(t == RealScalar(0))
428
+ {
429
+ rot1.c() = RealScalar(0);
430
+ rot1.s() = d > RealScalar(0) ? RealScalar(1) : RealScalar(-1);
431
+ }
432
+ else
433
+ {
434
+ RealScalar t2d2 = numext::hypot(t,d);
435
+ rot1.c() = abs(t)/t2d2;
436
+ rot1.s() = d/t2d2;
437
+ if(t<RealScalar(0))
438
+ rot1.s() = -rot1.s();
439
+ }
440
+ m.applyOnTheLeft(0,1,rot1);
441
+ j_right->makeJacobi(m,0,1);
442
+ *j_left = rot1 * j_right->transpose();
443
+ }
444
+
445
+ } // end namespace internal
446
+
447
+ /** \ingroup SVD_Module
448
+ *
449
+ *
450
+ * \class JacobiSVD
451
+ *
452
+ * \brief Two-sided Jacobi SVD decomposition of a rectangular matrix
453
+ *
454
+ * \param MatrixType the type of the matrix of which we are computing the SVD decomposition
455
+ * \param QRPreconditioner this optional parameter allows to specify the type of QR decomposition that will be used internally
456
+ * for the R-SVD step for non-square matrices. See discussion of possible values below.
457
+ *
458
+ * SVD decomposition consists in decomposing any n-by-p matrix \a A as a product
459
+ * \f[ A = U S V^* \f]
460
+ * where \a U is a n-by-n unitary, \a V is a p-by-p unitary, and \a S is a n-by-p real positive matrix which is zero outside of its main diagonal;
461
+ * the diagonal entries of S are known as the \em singular \em values of \a A and the columns of \a U and \a V are known as the left
462
+ * and right \em singular \em vectors of \a A respectively.
463
+ *
464
+ * Singular values are always sorted in decreasing order.
465
+ *
466
+ * This JacobiSVD decomposition computes only the singular values by default. If you want \a U or \a V, you need to ask for them explicitly.
467
+ *
468
+ * You can ask for only \em thin \a U or \a V to be computed, meaning the following. In case of a rectangular n-by-p matrix, letting \a m be the
469
+ * smaller value among \a n and \a p, there are only \a m singular vectors; the remaining columns of \a U and \a V do not correspond to actual
470
+ * singular vectors. Asking for \em thin \a U or \a V means asking for only their \a m first columns to be formed. So \a U is then a n-by-m matrix,
471
+ * and \a V is then a p-by-m matrix. Notice that thin \a U and \a V are all you need for (least squares) solving.
472
+ *
473
+ * Here's an example demonstrating basic usage:
474
+ * \include JacobiSVD_basic.cpp
475
+ * Output: \verbinclude JacobiSVD_basic.out
476
+ *
477
+ * This JacobiSVD class is a two-sided Jacobi R-SVD decomposition, ensuring optimal reliability and accuracy. The downside is that it's slower than
478
+ * bidiagonalizing SVD algorithms for large square matrices; however its complexity is still \f$ O(n^2p) \f$ where \a n is the smaller dimension and
479
+ * \a p is the greater dimension, meaning that it is still of the same order of complexity as the faster bidiagonalizing R-SVD algorithms.
480
+ * In particular, like any R-SVD, it takes advantage of non-squareness in that its complexity is only linear in the greater dimension.
481
+ *
482
+ * If the input matrix has inf or nan coefficients, the result of the computation is undefined, but the computation is guaranteed to
483
+ * terminate in finite (and reasonable) time.
484
+ *
485
+ * The possible values for QRPreconditioner are:
486
+ * \li ColPivHouseholderQRPreconditioner is the default. In practice it's very safe. It uses column-pivoting QR.
487
+ * \li FullPivHouseholderQRPreconditioner, is the safest and slowest. It uses full-pivoting QR.
488
+ * Contrary to other QRs, it doesn't allow computing thin unitaries.
489
+ * \li HouseholderQRPreconditioner is the fastest, and less safe and accurate than the pivoting variants. It uses non-pivoting QR.
490
+ * This is very similar in safety and accuracy to the bidiagonalization process used by bidiagonalizing SVD algorithms (since bidiagonalization
491
+ * is inherently non-pivoting). However the resulting SVD is still more reliable than bidiagonalizing SVDs because the Jacobi-based iterarive
492
+ * process is more reliable than the optimized bidiagonal SVD iterations.
493
+ * \li NoQRPreconditioner allows not to use a QR preconditioner at all. This is useful if you know that you will only be computing
494
+ * JacobiSVD decompositions of square matrices. Non-square matrices require a QR preconditioner. Using this option will result in
495
+ * faster compilation and smaller executable code. It won't significantly speed up computation, since JacobiSVD is always checking
496
+ * if QR preconditioning is needed before applying it anyway.
497
+ *
498
+ * \sa MatrixBase::jacobiSvd()
499
+ */
500
+ template<typename _MatrixType, int QRPreconditioner> class JacobiSVD
501
+ {
502
+ public:
503
+
504
+ typedef _MatrixType MatrixType;
505
+ typedef typename MatrixType::Scalar Scalar;
506
+ typedef typename NumTraits<typename MatrixType::Scalar>::Real RealScalar;
507
+ typedef typename MatrixType::Index Index;
508
+ enum {
509
+ RowsAtCompileTime = MatrixType::RowsAtCompileTime,
510
+ ColsAtCompileTime = MatrixType::ColsAtCompileTime,
511
+ DiagSizeAtCompileTime = EIGEN_SIZE_MIN_PREFER_DYNAMIC(RowsAtCompileTime,ColsAtCompileTime),
512
+ MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime,
513
+ MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime,
514
+ MaxDiagSizeAtCompileTime = EIGEN_SIZE_MIN_PREFER_FIXED(MaxRowsAtCompileTime,MaxColsAtCompileTime),
515
+ MatrixOptions = MatrixType::Options
516
+ };
517
+
518
+ typedef Matrix<Scalar, RowsAtCompileTime, RowsAtCompileTime,
519
+ MatrixOptions, MaxRowsAtCompileTime, MaxRowsAtCompileTime>
520
+ MatrixUType;
521
+ typedef Matrix<Scalar, ColsAtCompileTime, ColsAtCompileTime,
522
+ MatrixOptions, MaxColsAtCompileTime, MaxColsAtCompileTime>
523
+ MatrixVType;
524
+ typedef typename internal::plain_diag_type<MatrixType, RealScalar>::type SingularValuesType;
525
+ typedef typename internal::plain_row_type<MatrixType>::type RowType;
526
+ typedef typename internal::plain_col_type<MatrixType>::type ColType;
527
+ typedef Matrix<Scalar, DiagSizeAtCompileTime, DiagSizeAtCompileTime,
528
+ MatrixOptions, MaxDiagSizeAtCompileTime, MaxDiagSizeAtCompileTime>
529
+ WorkMatrixType;
530
+
531
+ /** \brief Default Constructor.
532
+ *
533
+ * The default constructor is useful in cases in which the user intends to
534
+ * perform decompositions via JacobiSVD::compute(const MatrixType&).
535
+ */
536
+ JacobiSVD()
537
+ : m_isInitialized(false),
538
+ m_isAllocated(false),
539
+ m_usePrescribedThreshold(false),
540
+ m_computationOptions(0),
541
+ m_rows(-1), m_cols(-1), m_diagSize(0)
542
+ {}
543
+
544
+
545
+ /** \brief Default Constructor with memory preallocation
546
+ *
547
+ * Like the default constructor but with preallocation of the internal data
548
+ * according to the specified problem size.
549
+ * \sa JacobiSVD()
550
+ */
551
+ JacobiSVD(Index rows, Index cols, unsigned int computationOptions = 0)
552
+ : m_isInitialized(false),
553
+ m_isAllocated(false),
554
+ m_usePrescribedThreshold(false),
555
+ m_computationOptions(0),
556
+ m_rows(-1), m_cols(-1)
557
+ {
558
+ allocate(rows, cols, computationOptions);
559
+ }
560
+
561
+ /** \brief Constructor performing the decomposition of given matrix.
562
+ *
563
+ * \param matrix the matrix to decompose
564
+ * \param computationOptions optional parameter allowing to specify if you want full or thin U or V unitaries to be computed.
565
+ * By default, none is computed. This is a bit-field, the possible bits are #ComputeFullU, #ComputeThinU,
566
+ * #ComputeFullV, #ComputeThinV.
567
+ *
568
+ * Thin unitaries are only available if your matrix type has a Dynamic number of columns (for example MatrixXf). They also are not
569
+ * available with the (non-default) FullPivHouseholderQR preconditioner.
570
+ */
571
+ JacobiSVD(const MatrixType& matrix, unsigned int computationOptions = 0)
572
+ : m_isInitialized(false),
573
+ m_isAllocated(false),
574
+ m_usePrescribedThreshold(false),
575
+ m_computationOptions(0),
576
+ m_rows(-1), m_cols(-1)
577
+ {
578
+ compute(matrix, computationOptions);
579
+ }
580
+
581
+ /** \brief Method performing the decomposition of given matrix using custom options.
582
+ *
583
+ * \param matrix the matrix to decompose
584
+ * \param computationOptions optional parameter allowing to specify if you want full or thin U or V unitaries to be computed.
585
+ * By default, none is computed. This is a bit-field, the possible bits are #ComputeFullU, #ComputeThinU,
586
+ * #ComputeFullV, #ComputeThinV.
587
+ *
588
+ * Thin unitaries are only available if your matrix type has a Dynamic number of columns (for example MatrixXf). They also are not
589
+ * available with the (non-default) FullPivHouseholderQR preconditioner.
590
+ */
591
+ JacobiSVD& compute(const MatrixType& matrix, unsigned int computationOptions);
592
+
593
+ /** \brief Method performing the decomposition of given matrix using current options.
594
+ *
595
+ * \param matrix the matrix to decompose
596
+ *
597
+ * This method uses the current \a computationOptions, as already passed to the constructor or to compute(const MatrixType&, unsigned int).
598
+ */
599
+ JacobiSVD& compute(const MatrixType& matrix)
600
+ {
601
+ return compute(matrix, m_computationOptions);
602
+ }
603
+
604
+ /** \returns the \a U matrix.
605
+ *
606
+ * For the SVD decomposition of a n-by-p matrix, letting \a m be the minimum of \a n and \a p,
607
+ * the U matrix is n-by-n if you asked for #ComputeFullU, and is n-by-m if you asked for #ComputeThinU.
608
+ *
609
+ * The \a m first columns of \a U are the left singular vectors of the matrix being decomposed.
610
+ *
611
+ * This method asserts that you asked for \a U to be computed.
612
+ */
613
+ const MatrixUType& matrixU() const
614
+ {
615
+ eigen_assert(m_isInitialized && "JacobiSVD is not initialized.");
616
+ eigen_assert(computeU() && "This JacobiSVD decomposition didn't compute U. Did you ask for it?");
617
+ return m_matrixU;
618
+ }
619
+
620
+ /** \returns the \a V matrix.
621
+ *
622
+ * For the SVD decomposition of a n-by-p matrix, letting \a m be the minimum of \a n and \a p,
623
+ * the V matrix is p-by-p if you asked for #ComputeFullV, and is p-by-m if you asked for ComputeThinV.
624
+ *
625
+ * The \a m first columns of \a V are the right singular vectors of the matrix being decomposed.
626
+ *
627
+ * This method asserts that you asked for \a V to be computed.
628
+ */
629
+ const MatrixVType& matrixV() const
630
+ {
631
+ eigen_assert(m_isInitialized && "JacobiSVD is not initialized.");
632
+ eigen_assert(computeV() && "This JacobiSVD decomposition didn't compute V. Did you ask for it?");
633
+ return m_matrixV;
634
+ }
635
+
636
+ /** \returns the vector of singular values.
637
+ *
638
+ * For the SVD decomposition of a n-by-p matrix, letting \a m be the minimum of \a n and \a p, the
639
+ * returned vector has size \a m. Singular values are always sorted in decreasing order.
640
+ */
641
+ const SingularValuesType& singularValues() const
642
+ {
643
+ eigen_assert(m_isInitialized && "JacobiSVD is not initialized.");
644
+ return m_singularValues;
645
+ }
646
+
647
+ /** \returns true if \a U (full or thin) is asked for in this SVD decomposition */
648
+ inline bool computeU() const { return m_computeFullU || m_computeThinU; }
649
+ /** \returns true if \a V (full or thin) is asked for in this SVD decomposition */
650
+ inline bool computeV() const { return m_computeFullV || m_computeThinV; }
651
+
652
+ /** \returns a (least squares) solution of \f$ A x = b \f$ using the current SVD decomposition of A.
653
+ *
654
+ * \param b the right-hand-side of the equation to solve.
655
+ *
656
+ * \note Solving requires both U and V to be computed. Thin U and V are enough, there is no need for full U or V.
657
+ *
658
+ * \note SVD solving is implicitly least-squares. Thus, this method serves both purposes of exact solving and least-squares solving.
659
+ * In other words, the returned solution is guaranteed to minimize the Euclidean norm \f$ \Vert A x - b \Vert \f$.
660
+ */
661
+ template<typename Rhs>
662
+ inline const internal::solve_retval<JacobiSVD, Rhs>
663
+ solve(const MatrixBase<Rhs>& b) const
664
+ {
665
+ eigen_assert(m_isInitialized && "JacobiSVD is not initialized.");
666
+ eigen_assert(computeU() && computeV() && "JacobiSVD::solve() requires both unitaries U and V to be computed (thin unitaries suffice).");
667
+ return internal::solve_retval<JacobiSVD, Rhs>(*this, b.derived());
668
+ }
669
+
670
+ /** \returns the number of singular values that are not exactly 0 */
671
+ Index nonzeroSingularValues() const
672
+ {
673
+ eigen_assert(m_isInitialized && "JacobiSVD is not initialized.");
674
+ return m_nonzeroSingularValues;
675
+ }
676
+
677
+ /** \returns the rank of the matrix of which \c *this is the SVD.
678
+ *
679
+ * \note This method has to determine which singular values should be considered nonzero.
680
+ * For that, it uses the threshold value that you can control by calling
681
+ * setThreshold(const RealScalar&).
682
+ */
683
+ inline Index rank() const
684
+ {
685
+ using std::abs;
686
+ eigen_assert(m_isInitialized && "JacobiSVD is not initialized.");
687
+ if(m_singularValues.size()==0) return 0;
688
+ RealScalar premultiplied_threshold = m_singularValues.coeff(0) * threshold();
689
+ Index i = m_nonzeroSingularValues-1;
690
+ while(i>=0 && m_singularValues.coeff(i) < premultiplied_threshold) --i;
691
+ return i+1;
692
+ }
693
+
694
+ /** Allows to prescribe a threshold to be used by certain methods, such as rank() and solve(),
695
+ * which need to determine when singular values are to be considered nonzero.
696
+ * This is not used for the SVD decomposition itself.
697
+ *
698
+ * When it needs to get the threshold value, Eigen calls threshold().
699
+ * The default is \c NumTraits<Scalar>::epsilon()
700
+ *
701
+ * \param threshold The new value to use as the threshold.
702
+ *
703
+ * A singular value will be considered nonzero if its value is strictly greater than
704
+ * \f$ \vert singular value \vert \leqslant threshold \times \vert max singular value \vert \f$.
705
+ *
706
+ * If you want to come back to the default behavior, call setThreshold(Default_t)
707
+ */
708
+ JacobiSVD& setThreshold(const RealScalar& threshold)
709
+ {
710
+ m_usePrescribedThreshold = true;
711
+ m_prescribedThreshold = threshold;
712
+ return *this;
713
+ }
714
+
715
+ /** Allows to come back to the default behavior, letting Eigen use its default formula for
716
+ * determining the threshold.
717
+ *
718
+ * You should pass the special object Eigen::Default as parameter here.
719
+ * \code svd.setThreshold(Eigen::Default); \endcode
720
+ *
721
+ * See the documentation of setThreshold(const RealScalar&).
722
+ */
723
+ JacobiSVD& setThreshold(Default_t)
724
+ {
725
+ m_usePrescribedThreshold = false;
726
+ return *this;
727
+ }
728
+
729
+ /** Returns the threshold that will be used by certain methods such as rank().
730
+ *
731
+ * See the documentation of setThreshold(const RealScalar&).
732
+ */
733
+ RealScalar threshold() const
734
+ {
735
+ eigen_assert(m_isInitialized || m_usePrescribedThreshold);
736
+ return m_usePrescribedThreshold ? m_prescribedThreshold
737
+ : (std::max<Index>)(1,m_diagSize)*NumTraits<Scalar>::epsilon();
738
+ }
739
+
740
+ inline Index rows() const { return m_rows; }
741
+ inline Index cols() const { return m_cols; }
742
+
743
+ private:
744
+ void allocate(Index rows, Index cols, unsigned int computationOptions);
745
+
746
+ static void check_template_parameters()
747
+ {
748
+ EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar);
749
+ }
750
+
751
+ protected:
752
+ MatrixUType m_matrixU;
753
+ MatrixVType m_matrixV;
754
+ SingularValuesType m_singularValues;
755
+ WorkMatrixType m_workMatrix;
756
+ bool m_isInitialized, m_isAllocated, m_usePrescribedThreshold;
757
+ bool m_computeFullU, m_computeThinU;
758
+ bool m_computeFullV, m_computeThinV;
759
+ unsigned int m_computationOptions;
760
+ Index m_nonzeroSingularValues, m_rows, m_cols, m_diagSize;
761
+ RealScalar m_prescribedThreshold;
762
+
763
+ template<typename __MatrixType, int _QRPreconditioner, bool _IsComplex>
764
+ friend struct internal::svd_precondition_2x2_block_to_be_real;
765
+ template<typename __MatrixType, int _QRPreconditioner, int _Case, bool _DoAnything>
766
+ friend struct internal::qr_preconditioner_impl;
767
+
768
+ internal::qr_preconditioner_impl<MatrixType, QRPreconditioner, internal::PreconditionIfMoreColsThanRows> m_qr_precond_morecols;
769
+ internal::qr_preconditioner_impl<MatrixType, QRPreconditioner, internal::PreconditionIfMoreRowsThanCols> m_qr_precond_morerows;
770
+ MatrixType m_scaledMatrix;
771
+ };
772
+
773
+ template<typename MatrixType, int QRPreconditioner>
774
+ void JacobiSVD<MatrixType, QRPreconditioner>::allocate(Index rows, Index cols, unsigned int computationOptions)
775
+ {
776
+ eigen_assert(rows >= 0 && cols >= 0);
777
+
778
+ if (m_isAllocated &&
779
+ rows == m_rows &&
780
+ cols == m_cols &&
781
+ computationOptions == m_computationOptions)
782
+ {
783
+ return;
784
+ }
785
+
786
+ m_rows = rows;
787
+ m_cols = cols;
788
+ m_isInitialized = false;
789
+ m_isAllocated = true;
790
+ m_computationOptions = computationOptions;
791
+ m_computeFullU = (computationOptions & ComputeFullU) != 0;
792
+ m_computeThinU = (computationOptions & ComputeThinU) != 0;
793
+ m_computeFullV = (computationOptions & ComputeFullV) != 0;
794
+ m_computeThinV = (computationOptions & ComputeThinV) != 0;
795
+ eigen_assert(!(m_computeFullU && m_computeThinU) && "JacobiSVD: you can't ask for both full and thin U");
796
+ eigen_assert(!(m_computeFullV && m_computeThinV) && "JacobiSVD: you can't ask for both full and thin V");
797
+ eigen_assert(EIGEN_IMPLIES(m_computeThinU || m_computeThinV, MatrixType::ColsAtCompileTime==Dynamic) &&
798
+ "JacobiSVD: thin U and V are only available when your matrix has a dynamic number of columns.");
799
+ if (QRPreconditioner == FullPivHouseholderQRPreconditioner)
800
+ {
801
+ eigen_assert(!(m_computeThinU || m_computeThinV) &&
802
+ "JacobiSVD: can't compute thin U or thin V with the FullPivHouseholderQR preconditioner. "
803
+ "Use the ColPivHouseholderQR preconditioner instead.");
804
+ }
805
+ m_diagSize = (std::min)(m_rows, m_cols);
806
+ m_singularValues.resize(m_diagSize);
807
+ if(RowsAtCompileTime==Dynamic)
808
+ m_matrixU.resize(m_rows, m_computeFullU ? m_rows
809
+ : m_computeThinU ? m_diagSize
810
+ : 0);
811
+ if(ColsAtCompileTime==Dynamic)
812
+ m_matrixV.resize(m_cols, m_computeFullV ? m_cols
813
+ : m_computeThinV ? m_diagSize
814
+ : 0);
815
+ m_workMatrix.resize(m_diagSize, m_diagSize);
816
+
817
+ if(m_cols>m_rows) m_qr_precond_morecols.allocate(*this);
818
+ if(m_rows>m_cols) m_qr_precond_morerows.allocate(*this);
819
+ if(m_cols!=m_cols) m_scaledMatrix.resize(rows,cols);
820
+ }
821
+
822
+ template<typename MatrixType, int QRPreconditioner>
823
+ JacobiSVD<MatrixType, QRPreconditioner>&
824
+ JacobiSVD<MatrixType, QRPreconditioner>::compute(const MatrixType& matrix, unsigned int computationOptions)
825
+ {
826
+ check_template_parameters();
827
+
828
+ using std::abs;
829
+ allocate(matrix.rows(), matrix.cols(), computationOptions);
830
+
831
+ // currently we stop when we reach precision 2*epsilon as the last bit of precision can require an unreasonable number of iterations,
832
+ // only worsening the precision of U and V as we accumulate more rotations
833
+ const RealScalar precision = RealScalar(2) * NumTraits<Scalar>::epsilon();
834
+
835
+ // limit for very small denormal numbers to be considered zero in order to avoid infinite loops (see bug 286)
836
+ const RealScalar considerAsZero = RealScalar(2) * std::numeric_limits<RealScalar>::denorm_min();
837
+
838
+ // Scaling factor to reduce over/under-flows
839
+ RealScalar scale = matrix.cwiseAbs().maxCoeff();
840
+ if(scale==RealScalar(0)) scale = RealScalar(1);
841
+
842
+ /*** step 1. The R-SVD step: we use a QR decomposition to reduce to the case of a square matrix */
843
+
844
+ if(m_rows!=m_cols)
845
+ {
846
+ m_scaledMatrix = matrix / scale;
847
+ m_qr_precond_morecols.run(*this, m_scaledMatrix);
848
+ m_qr_precond_morerows.run(*this, m_scaledMatrix);
849
+ }
850
+ else
851
+ {
852
+ m_workMatrix = matrix.block(0,0,m_diagSize,m_diagSize) / scale;
853
+ if(m_computeFullU) m_matrixU.setIdentity(m_rows,m_rows);
854
+ if(m_computeThinU) m_matrixU.setIdentity(m_rows,m_diagSize);
855
+ if(m_computeFullV) m_matrixV.setIdentity(m_cols,m_cols);
856
+ if(m_computeThinV) m_matrixV.setIdentity(m_cols, m_diagSize);
857
+ }
858
+
859
+ /*** step 2. The main Jacobi SVD iteration. ***/
860
+
861
+ bool finished = false;
862
+ while(!finished)
863
+ {
864
+ finished = true;
865
+
866
+ // do a sweep: for all index pairs (p,q), perform SVD of the corresponding 2x2 sub-matrix
867
+
868
+ for(Index p = 1; p < m_diagSize; ++p)
869
+ {
870
+ for(Index q = 0; q < p; ++q)
871
+ {
872
+ // if this 2x2 sub-matrix is not diagonal already...
873
+ // notice that this comparison will evaluate to false if any NaN is involved, ensuring that NaN's don't
874
+ // keep us iterating forever. Similarly, small denormal numbers are considered zero.
875
+ using std::max;
876
+ RealScalar threshold = (max)(considerAsZero, precision * (max)(abs(m_workMatrix.coeff(p,p)),
877
+ abs(m_workMatrix.coeff(q,q))));
878
+ // We compare both values to threshold instead of calling max to be robust to NaN (See bug 791)
879
+ if(abs(m_workMatrix.coeff(p,q))>threshold || abs(m_workMatrix.coeff(q,p)) > threshold)
880
+ {
881
+ finished = false;
882
+
883
+ // perform SVD decomposition of 2x2 sub-matrix corresponding to indices p,q to make it diagonal
884
+ internal::svd_precondition_2x2_block_to_be_real<MatrixType, QRPreconditioner>::run(m_workMatrix, *this, p, q);
885
+ JacobiRotation<RealScalar> j_left, j_right;
886
+ internal::real_2x2_jacobi_svd(m_workMatrix, p, q, &j_left, &j_right);
887
+
888
+ // accumulate resulting Jacobi rotations
889
+ m_workMatrix.applyOnTheLeft(p,q,j_left);
890
+ if(computeU()) m_matrixU.applyOnTheRight(p,q,j_left.transpose());
891
+
892
+ m_workMatrix.applyOnTheRight(p,q,j_right);
893
+ if(computeV()) m_matrixV.applyOnTheRight(p,q,j_right);
894
+ }
895
+ }
896
+ }
897
+ }
898
+
899
+ /*** step 3. The work matrix is now diagonal, so ensure it's positive so its diagonal entries are the singular values ***/
900
+
901
+ for(Index i = 0; i < m_diagSize; ++i)
902
+ {
903
+ RealScalar a = abs(m_workMatrix.coeff(i,i));
904
+ m_singularValues.coeffRef(i) = a;
905
+ if(computeU() && (a!=RealScalar(0))) m_matrixU.col(i) *= m_workMatrix.coeff(i,i)/a;
906
+ }
907
+
908
+ /*** step 4. Sort singular values in descending order and compute the number of nonzero singular values ***/
909
+
910
+ m_nonzeroSingularValues = m_diagSize;
911
+ for(Index i = 0; i < m_diagSize; i++)
912
+ {
913
+ Index pos;
914
+ RealScalar maxRemainingSingularValue = m_singularValues.tail(m_diagSize-i).maxCoeff(&pos);
915
+ if(maxRemainingSingularValue == RealScalar(0))
916
+ {
917
+ m_nonzeroSingularValues = i;
918
+ break;
919
+ }
920
+ if(pos)
921
+ {
922
+ pos += i;
923
+ std::swap(m_singularValues.coeffRef(i), m_singularValues.coeffRef(pos));
924
+ if(computeU()) m_matrixU.col(pos).swap(m_matrixU.col(i));
925
+ if(computeV()) m_matrixV.col(pos).swap(m_matrixV.col(i));
926
+ }
927
+ }
928
+
929
+ m_singularValues *= scale;
930
+
931
+ m_isInitialized = true;
932
+ return *this;
933
+ }
934
+
935
+ namespace internal {
936
+ template<typename _MatrixType, int QRPreconditioner, typename Rhs>
937
+ struct solve_retval<JacobiSVD<_MatrixType, QRPreconditioner>, Rhs>
938
+ : solve_retval_base<JacobiSVD<_MatrixType, QRPreconditioner>, Rhs>
939
+ {
940
+ typedef JacobiSVD<_MatrixType, QRPreconditioner> JacobiSVDType;
941
+ EIGEN_MAKE_SOLVE_HELPERS(JacobiSVDType,Rhs)
942
+
943
+ template<typename Dest> void evalTo(Dest& dst) const
944
+ {
945
+ eigen_assert(rhs().rows() == dec().rows());
946
+
947
+ // A = U S V^*
948
+ // So A^{-1} = V S^{-1} U^*
949
+
950
+ Matrix<Scalar, Dynamic, Rhs::ColsAtCompileTime, 0, _MatrixType::MaxRowsAtCompileTime, Rhs::MaxColsAtCompileTime> tmp;
951
+ Index rank = dec().rank();
952
+
953
+ tmp.noalias() = dec().matrixU().leftCols(rank).adjoint() * rhs();
954
+ tmp = dec().singularValues().head(rank).asDiagonal().inverse() * tmp;
955
+ dst = dec().matrixV().leftCols(rank) * tmp;
956
+ }
957
+ };
958
+ } // end namespace internal
959
+
960
+ /** \svd_module
961
+ *
962
+ * \return the singular value decomposition of \c *this computed by two-sided
963
+ * Jacobi transformations.
964
+ *
965
+ * \sa class JacobiSVD
966
+ */
967
+ template<typename Derived>
968
+ JacobiSVD<typename MatrixBase<Derived>::PlainObject>
969
+ MatrixBase<Derived>::jacobiSvd(unsigned int computationOptions) const
970
+ {
971
+ return JacobiSVD<PlainObject>(*this, computationOptions);
972
+ }
973
+
974
+ } // end namespace Eigen
975
+
976
+ #endif // EIGEN_JACOBISVD_H