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,137 @@
1
+ // This file is part of Eigen, a lightweight C++ template library
2
+ // for linear algebra.
3
+ //
4
+ // Copyright (C) 2012 Désiré Nuentsa-Wakam <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
+ /*
11
+
12
+ * NOTE: This file is the modified version of xpivotL.c file in SuperLU
13
+
14
+ * -- SuperLU routine (version 3.0) --
15
+ * Univ. of California Berkeley, Xerox Palo Alto Research Center,
16
+ * and Lawrence Berkeley National Lab.
17
+ * October 15, 2003
18
+ *
19
+ * Copyright (c) 1994 by Xerox Corporation. All rights reserved.
20
+ *
21
+ * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
22
+ * EXPRESSED OR IMPLIED. ANY USE IS AT YOUR OWN RISK.
23
+ *
24
+ * Permission is hereby granted to use or copy this program for any
25
+ * purpose, provided the above notices are retained on all copies.
26
+ * Permission to modify the code and to distribute modified code is
27
+ * granted, provided the above notices are retained, and a notice that
28
+ * the code was modified is included with the above copyright notice.
29
+ */
30
+ #ifndef SPARSELU_PIVOTL_H
31
+ #define SPARSELU_PIVOTL_H
32
+
33
+ namespace Eigen {
34
+ namespace internal {
35
+
36
+ /**
37
+ * \brief Performs the numerical pivotin on the current column of L, and the CDIV operation.
38
+ *
39
+ * Pivot policy :
40
+ * (1) Compute thresh = u * max_(i>=j) abs(A_ij);
41
+ * (2) IF user specifies pivot row k and abs(A_kj) >= thresh THEN
42
+ * pivot row = k;
43
+ * ELSE IF abs(A_jj) >= thresh THEN
44
+ * pivot row = j;
45
+ * ELSE
46
+ * pivot row = m;
47
+ *
48
+ * Note: If you absolutely want to use a given pivot order, then set u=0.0.
49
+ *
50
+ * \param jcol The current column of L
51
+ * \param diagpivotthresh diagonal pivoting threshold
52
+ * \param[in,out] perm_r Row permutation (threshold pivoting)
53
+ * \param[in] iperm_c column permutation - used to finf diagonal of Pc*A*Pc'
54
+ * \param[out] pivrow The pivot row
55
+ * \param glu Global LU data
56
+ * \return 0 if success, i > 0 if U(i,i) is exactly zero
57
+ *
58
+ */
59
+ template <typename Scalar, typename Index>
60
+ Index SparseLUImpl<Scalar,Index>::pivotL(const Index jcol, const RealScalar& diagpivotthresh, IndexVector& perm_r, IndexVector& iperm_c, Index& pivrow, GlobalLU_t& glu)
61
+ {
62
+
63
+ Index fsupc = (glu.xsup)((glu.supno)(jcol)); // First column in the supernode containing the column jcol
64
+ Index nsupc = jcol - fsupc; // Number of columns in the supernode portion, excluding jcol; nsupc >=0
65
+ Index lptr = glu.xlsub(fsupc); // pointer to the starting location of the row subscripts for this supernode portion
66
+ Index nsupr = glu.xlsub(fsupc+1) - lptr; // Number of rows in the supernode
67
+ Index lda = glu.xlusup(fsupc+1) - glu.xlusup(fsupc); // leading dimension
68
+ Scalar* lu_sup_ptr = &(glu.lusup.data()[glu.xlusup(fsupc)]); // Start of the current supernode
69
+ Scalar* lu_col_ptr = &(glu.lusup.data()[glu.xlusup(jcol)]); // Start of jcol in the supernode
70
+ Index* lsub_ptr = &(glu.lsub.data()[lptr]); // Start of row indices of the supernode
71
+
72
+ // Determine the largest abs numerical value for partial pivoting
73
+ Index diagind = iperm_c(jcol); // diagonal index
74
+ RealScalar pivmax(-1.0);
75
+ Index pivptr = nsupc;
76
+ Index diag = emptyIdxLU;
77
+ RealScalar rtemp;
78
+ Index isub, icol, itemp, k;
79
+ for (isub = nsupc; isub < nsupr; ++isub) {
80
+ using std::abs;
81
+ rtemp = abs(lu_col_ptr[isub]);
82
+ if (rtemp > pivmax) {
83
+ pivmax = rtemp;
84
+ pivptr = isub;
85
+ }
86
+ if (lsub_ptr[isub] == diagind) diag = isub;
87
+ }
88
+
89
+ // Test for singularity
90
+ if ( pivmax <= RealScalar(0.0) ) {
91
+ // if pivmax == -1, the column is structurally empty, otherwise it is only numerically zero
92
+ pivrow = pivmax < RealScalar(0.0) ? diagind : lsub_ptr[pivptr];
93
+ perm_r(pivrow) = jcol;
94
+ return (jcol+1);
95
+ }
96
+
97
+ RealScalar thresh = diagpivotthresh * pivmax;
98
+
99
+ // Choose appropriate pivotal element
100
+
101
+ {
102
+ // Test if the diagonal element can be used as a pivot (given the threshold value)
103
+ if (diag >= 0 )
104
+ {
105
+ // Diagonal element exists
106
+ using std::abs;
107
+ rtemp = abs(lu_col_ptr[diag]);
108
+ if (rtemp != 0.0 && rtemp >= thresh) pivptr = diag;
109
+ }
110
+ pivrow = lsub_ptr[pivptr];
111
+ }
112
+
113
+ // Record pivot row
114
+ perm_r(pivrow) = jcol;
115
+ // Interchange row subscripts
116
+ if (pivptr != nsupc )
117
+ {
118
+ std::swap( lsub_ptr[pivptr], lsub_ptr[nsupc] );
119
+ // Interchange numerical values as well, for the two rows in the whole snode
120
+ // such that L is indexed the same way as A
121
+ for (icol = 0; icol <= nsupc; icol++)
122
+ {
123
+ itemp = pivptr + icol * lda;
124
+ std::swap(lu_sup_ptr[itemp], lu_sup_ptr[nsupc + icol * lda]);
125
+ }
126
+ }
127
+ // cdiv operations
128
+ Scalar temp = Scalar(1.0) / lu_col_ptr[nsupc];
129
+ for (k = nsupc+1; k < nsupr; k++)
130
+ lu_col_ptr[k] *= temp;
131
+ return 0;
132
+ }
133
+
134
+ } // end namespace internal
135
+ } // end namespace Eigen
136
+
137
+ #endif // SPARSELU_PIVOTL_H
@@ -0,0 +1,135 @@
1
+ // This file is part of Eigen, a lightweight C++ template library
2
+ // for linear algebra.
3
+ //
4
+ // Copyright (C) 2012 Désiré Nuentsa-Wakam <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
+ /*
11
+
12
+ * NOTE: This file is the modified version of [s,d,c,z]pruneL.c file in SuperLU
13
+
14
+ * -- SuperLU routine (version 2.0) --
15
+ * Univ. of California Berkeley, Xerox Palo Alto Research Center,
16
+ * and Lawrence Berkeley National Lab.
17
+ * November 15, 1997
18
+ *
19
+ * Copyright (c) 1994 by Xerox Corporation. All rights reserved.
20
+ *
21
+ * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
22
+ * EXPRESSED OR IMPLIED. ANY USE IS AT YOUR OWN RISK.
23
+ *
24
+ * Permission is hereby granted to use or copy this program for any
25
+ * purpose, provided the above notices are retained on all copies.
26
+ * Permission to modify the code and to distribute modified code is
27
+ * granted, provided the above notices are retained, and a notice that
28
+ * the code was modified is included with the above copyright notice.
29
+ */
30
+ #ifndef SPARSELU_PRUNEL_H
31
+ #define SPARSELU_PRUNEL_H
32
+
33
+ namespace Eigen {
34
+ namespace internal {
35
+
36
+ /**
37
+ * \brief Prunes the L-structure.
38
+ *
39
+ * It prunes the L-structure of supernodes whose L-structure contains the current pivot row "pivrow"
40
+ *
41
+ *
42
+ * \param jcol The current column of L
43
+ * \param[in] perm_r Row permutation
44
+ * \param[out] pivrow The pivot row
45
+ * \param nseg Number of segments
46
+ * \param segrep
47
+ * \param repfnz
48
+ * \param[out] xprune
49
+ * \param glu Global LU data
50
+ *
51
+ */
52
+ template <typename Scalar, typename Index>
53
+ void SparseLUImpl<Scalar,Index>::pruneL(const Index jcol, const IndexVector& perm_r, const Index pivrow, const Index nseg, const IndexVector& segrep, BlockIndexVector repfnz, IndexVector& xprune, GlobalLU_t& glu)
54
+ {
55
+ // For each supernode-rep irep in U(*,j]
56
+ Index jsupno = glu.supno(jcol);
57
+ Index i,irep,irep1;
58
+ bool movnum, do_prune = false;
59
+ Index kmin = 0, kmax = 0, minloc, maxloc,krow;
60
+ for (i = 0; i < nseg; i++)
61
+ {
62
+ irep = segrep(i);
63
+ irep1 = irep + 1;
64
+ do_prune = false;
65
+
66
+ // Don't prune with a zero U-segment
67
+ if (repfnz(irep) == emptyIdxLU) continue;
68
+
69
+ // If a snode overlaps with the next panel, then the U-segment
70
+ // is fragmented into two parts -- irep and irep1. We should let
71
+ // pruning occur at the rep-column in irep1s snode.
72
+ if (glu.supno(irep) == glu.supno(irep1) ) continue; // don't prune
73
+
74
+ // If it has not been pruned & it has a nonz in row L(pivrow,i)
75
+ if (glu.supno(irep) != jsupno )
76
+ {
77
+ if ( xprune (irep) >= glu.xlsub(irep1) )
78
+ {
79
+ kmin = glu.xlsub(irep);
80
+ kmax = glu.xlsub(irep1) - 1;
81
+ for (krow = kmin; krow <= kmax; krow++)
82
+ {
83
+ if (glu.lsub(krow) == pivrow)
84
+ {
85
+ do_prune = true;
86
+ break;
87
+ }
88
+ }
89
+ }
90
+
91
+ if (do_prune)
92
+ {
93
+ // do a quicksort-type partition
94
+ // movnum=true means that the num values have to be exchanged
95
+ movnum = false;
96
+ if (irep == glu.xsup(glu.supno(irep)) ) // Snode of size 1
97
+ movnum = true;
98
+
99
+ while (kmin <= kmax)
100
+ {
101
+ if (perm_r(glu.lsub(kmax)) == emptyIdxLU)
102
+ kmax--;
103
+ else if ( perm_r(glu.lsub(kmin)) != emptyIdxLU)
104
+ kmin++;
105
+ else
106
+ {
107
+ // kmin below pivrow (not yet pivoted), and kmax
108
+ // above pivrow: interchange the two suscripts
109
+ std::swap(glu.lsub(kmin), glu.lsub(kmax));
110
+
111
+ // If the supernode has only one column, then we
112
+ // only keep one set of subscripts. For any subscript
113
+ // intercnahge performed, similar interchange must be
114
+ // done on the numerical values.
115
+ if (movnum)
116
+ {
117
+ minloc = glu.xlusup(irep) + ( kmin - glu.xlsub(irep) );
118
+ maxloc = glu.xlusup(irep) + ( kmax - glu.xlsub(irep) );
119
+ std::swap(glu.lusup(minloc), glu.lusup(maxloc));
120
+ }
121
+ kmin++;
122
+ kmax--;
123
+ }
124
+ } // end while
125
+
126
+ xprune(irep) = kmin; //Pruning
127
+ } // end if do_prune
128
+ } // end pruning
129
+ } // End for each U-segment
130
+ }
131
+
132
+ } // end namespace internal
133
+ } // end namespace Eigen
134
+
135
+ #endif // SPARSELU_PRUNEL_H
@@ -0,0 +1,83 @@
1
+ // This file is part of Eigen, a lightweight C++ template library
2
+ // for linear algebra.
3
+ //
4
+ // Copyright (C) 2012 Désiré Nuentsa-Wakam <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
+ /* This file is a modified version of heap_relax_snode.c file in SuperLU
11
+ * -- SuperLU routine (version 3.0) --
12
+ * Univ. of California Berkeley, Xerox Palo Alto Research Center,
13
+ * and Lawrence Berkeley National Lab.
14
+ * October 15, 2003
15
+ *
16
+ * Copyright (c) 1994 by Xerox Corporation. All rights reserved.
17
+ *
18
+ * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
19
+ * EXPRESSED OR IMPLIED. ANY USE IS AT YOUR OWN RISK.
20
+ *
21
+ * Permission is hereby granted to use or copy this program for any
22
+ * purpose, provided the above notices are retained on all copies.
23
+ * Permission to modify the code and to distribute modified code is
24
+ * granted, provided the above notices are retained, and a notice that
25
+ * the code was modified is included with the above copyright notice.
26
+ */
27
+
28
+ #ifndef SPARSELU_RELAX_SNODE_H
29
+ #define SPARSELU_RELAX_SNODE_H
30
+
31
+ namespace Eigen {
32
+
33
+ namespace internal {
34
+
35
+ /**
36
+ * \brief Identify the initial relaxed supernodes
37
+ *
38
+ * This routine is applied to a column elimination tree.
39
+ * It assumes that the matrix has been reordered according to the postorder of the etree
40
+ * \param n the number of columns
41
+ * \param et elimination tree
42
+ * \param relax_columns Maximum number of columns allowed in a relaxed snode
43
+ * \param descendants Number of descendants of each node in the etree
44
+ * \param relax_end last column in a supernode
45
+ */
46
+ template <typename Scalar, typename Index>
47
+ void SparseLUImpl<Scalar,Index>::relax_snode (const Index n, IndexVector& et, const Index relax_columns, IndexVector& descendants, IndexVector& relax_end)
48
+ {
49
+
50
+ // compute the number of descendants of each node in the etree
51
+ Index j, parent;
52
+ relax_end.setConstant(emptyIdxLU);
53
+ descendants.setZero();
54
+ for (j = 0; j < n; j++)
55
+ {
56
+ parent = et(j);
57
+ if (parent != n) // not the dummy root
58
+ descendants(parent) += descendants(j) + 1;
59
+ }
60
+ // Identify the relaxed supernodes by postorder traversal of the etree
61
+ Index snode_start; // beginning of a snode
62
+ for (j = 0; j < n; )
63
+ {
64
+ parent = et(j);
65
+ snode_start = j;
66
+ while ( parent != n && descendants(parent) < relax_columns )
67
+ {
68
+ j = parent;
69
+ parent = et(j);
70
+ }
71
+ // Found a supernode in postordered etree, j is the last column
72
+ relax_end(snode_start) = j; // Record last column
73
+ j++;
74
+ // Search for a new leaf
75
+ while (descendants(j) != 0 && j < n) j++;
76
+ } // End postorder traversal of the etree
77
+
78
+ }
79
+
80
+ } // end namespace internal
81
+
82
+ } // end namespace Eigen
83
+ #endif
@@ -0,0 +1,714 @@
1
+ // This file is part of Eigen, a lightweight C++ template library
2
+ // for linear algebra.
3
+ //
4
+ // Copyright (C) 2012-2013 Desire Nuentsa <desire.nuentsa_wakam@inria.fr>
5
+ // Copyright (C) 2012-2014 Gael Guennebaud <gael.guennebaud@inria.fr>
6
+ //
7
+ // This Source Code Form is subject to the terms of the Mozilla
8
+ // Public License v. 2.0. If a copy of the MPL was not distributed
9
+ // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
10
+
11
+ #ifndef EIGEN_SPARSE_QR_H
12
+ #define EIGEN_SPARSE_QR_H
13
+
14
+ namespace Eigen {
15
+
16
+ template<typename MatrixType, typename OrderingType> class SparseQR;
17
+ template<typename SparseQRType> struct SparseQRMatrixQReturnType;
18
+ template<typename SparseQRType> struct SparseQRMatrixQTransposeReturnType;
19
+ template<typename SparseQRType, typename Derived> struct SparseQR_QProduct;
20
+ namespace internal {
21
+ template <typename SparseQRType> struct traits<SparseQRMatrixQReturnType<SparseQRType> >
22
+ {
23
+ typedef typename SparseQRType::MatrixType ReturnType;
24
+ typedef typename ReturnType::Index Index;
25
+ typedef typename ReturnType::StorageKind StorageKind;
26
+ };
27
+ template <typename SparseQRType> struct traits<SparseQRMatrixQTransposeReturnType<SparseQRType> >
28
+ {
29
+ typedef typename SparseQRType::MatrixType ReturnType;
30
+ };
31
+ template <typename SparseQRType, typename Derived> struct traits<SparseQR_QProduct<SparseQRType, Derived> >
32
+ {
33
+ typedef typename Derived::PlainObject ReturnType;
34
+ };
35
+ } // End namespace internal
36
+
37
+ /**
38
+ * \ingroup SparseQR_Module
39
+ * \class SparseQR
40
+ * \brief Sparse left-looking rank-revealing QR factorization
41
+ *
42
+ * This class implements a left-looking rank-revealing QR decomposition
43
+ * of sparse matrices. When a column has a norm less than a given tolerance
44
+ * it is implicitly permuted to the end. The QR factorization thus obtained is
45
+ * given by A*P = Q*R where R is upper triangular or trapezoidal.
46
+ *
47
+ * P is the column permutation which is the product of the fill-reducing and the
48
+ * rank-revealing permutations. Use colsPermutation() to get it.
49
+ *
50
+ * Q is the orthogonal matrix represented as products of Householder reflectors.
51
+ * Use matrixQ() to get an expression and matrixQ().transpose() to get the transpose.
52
+ * You can then apply it to a vector.
53
+ *
54
+ * R is the sparse triangular or trapezoidal matrix. The later occurs when A is rank-deficient.
55
+ * matrixR().topLeftCorner(rank(), rank()) always returns a triangular factor of full rank.
56
+ *
57
+ * \tparam _MatrixType The type of the sparse matrix A, must be a column-major SparseMatrix<>
58
+ * \tparam _OrderingType The fill-reducing ordering method. See the \link OrderingMethods_Module
59
+ * OrderingMethods \endlink module for the list of built-in and external ordering methods.
60
+ *
61
+ * \warning The input sparse matrix A must be in compressed mode (see SparseMatrix::makeCompressed()).
62
+ *
63
+ */
64
+ template<typename _MatrixType, typename _OrderingType>
65
+ class SparseQR
66
+ {
67
+ public:
68
+ typedef _MatrixType MatrixType;
69
+ typedef _OrderingType OrderingType;
70
+ typedef typename MatrixType::Scalar Scalar;
71
+ typedef typename MatrixType::RealScalar RealScalar;
72
+ typedef typename MatrixType::Index Index;
73
+ typedef SparseMatrix<Scalar,ColMajor,Index> QRMatrixType;
74
+ typedef Matrix<Index, Dynamic, 1> IndexVector;
75
+ typedef Matrix<Scalar, Dynamic, 1> ScalarVector;
76
+ typedef PermutationMatrix<Dynamic, Dynamic, Index> PermutationType;
77
+ public:
78
+ SparseQR () : m_isInitialized(false), m_analysisIsok(false), m_lastError(""), m_useDefaultThreshold(true),m_isQSorted(false),m_isEtreeOk(false)
79
+ { }
80
+
81
+ /** Construct a QR factorization of the matrix \a mat.
82
+ *
83
+ * \warning The matrix \a mat must be in compressed mode (see SparseMatrix::makeCompressed()).
84
+ *
85
+ * \sa compute()
86
+ */
87
+ SparseQR(const MatrixType& mat) : m_isInitialized(false), m_analysisIsok(false), m_lastError(""), m_useDefaultThreshold(true),m_isQSorted(false),m_isEtreeOk(false)
88
+ {
89
+ compute(mat);
90
+ }
91
+
92
+ /** Computes the QR factorization of the sparse matrix \a mat.
93
+ *
94
+ * \warning The matrix \a mat must be in compressed mode (see SparseMatrix::makeCompressed()).
95
+ *
96
+ * \sa analyzePattern(), factorize()
97
+ */
98
+ void compute(const MatrixType& mat)
99
+ {
100
+ analyzePattern(mat);
101
+ factorize(mat);
102
+ }
103
+ void analyzePattern(const MatrixType& mat);
104
+ void factorize(const MatrixType& mat);
105
+
106
+ /** \returns the number of rows of the represented matrix.
107
+ */
108
+ inline Index rows() const { return m_pmat.rows(); }
109
+
110
+ /** \returns the number of columns of the represented matrix.
111
+ */
112
+ inline Index cols() const { return m_pmat.cols();}
113
+
114
+ /** \returns a const reference to the \b sparse upper triangular matrix R of the QR factorization.
115
+ */
116
+ const QRMatrixType& matrixR() const { return m_R; }
117
+
118
+ /** \returns the number of non linearly dependent columns as determined by the pivoting threshold.
119
+ *
120
+ * \sa setPivotThreshold()
121
+ */
122
+ Index rank() const
123
+ {
124
+ eigen_assert(m_isInitialized && "The factorization should be called first, use compute()");
125
+ return m_nonzeropivots;
126
+ }
127
+
128
+ /** \returns an expression of the matrix Q as products of sparse Householder reflectors.
129
+ * The common usage of this function is to apply it to a dense matrix or vector
130
+ * \code
131
+ * VectorXd B1, B2;
132
+ * // Initialize B1
133
+ * B2 = matrixQ() * B1;
134
+ * \endcode
135
+ *
136
+ * To get a plain SparseMatrix representation of Q:
137
+ * \code
138
+ * SparseMatrix<double> Q;
139
+ * Q = SparseQR<SparseMatrix<double> >(A).matrixQ();
140
+ * \endcode
141
+ * Internally, this call simply performs a sparse product between the matrix Q
142
+ * and a sparse identity matrix. However, due to the fact that the sparse
143
+ * reflectors are stored unsorted, two transpositions are needed to sort
144
+ * them before performing the product.
145
+ */
146
+ SparseQRMatrixQReturnType<SparseQR> matrixQ() const
147
+ { return SparseQRMatrixQReturnType<SparseQR>(*this); }
148
+
149
+ /** \returns a const reference to the column permutation P that was applied to A such that A*P = Q*R
150
+ * It is the combination of the fill-in reducing permutation and numerical column pivoting.
151
+ */
152
+ const PermutationType& colsPermutation() const
153
+ {
154
+ eigen_assert(m_isInitialized && "Decomposition is not initialized.");
155
+ return m_outputPerm_c;
156
+ }
157
+
158
+ /** \returns A string describing the type of error.
159
+ * This method is provided to ease debugging, not to handle errors.
160
+ */
161
+ std::string lastErrorMessage() const { return m_lastError; }
162
+
163
+ /** \internal */
164
+ template<typename Rhs, typename Dest>
165
+ bool _solve(const MatrixBase<Rhs> &B, MatrixBase<Dest> &dest) const
166
+ {
167
+ eigen_assert(m_isInitialized && "The factorization should be called first, use compute()");
168
+ eigen_assert(this->rows() == B.rows() && "SparseQR::solve() : invalid number of rows in the right hand side matrix");
169
+
170
+ Index rank = this->rank();
171
+
172
+ // Compute Q^T * b;
173
+ typename Dest::PlainObject y, b;
174
+ y = this->matrixQ().transpose() * B;
175
+ b = y;
176
+
177
+ // Solve with the triangular matrix R
178
+ y.resize((std::max)(cols(),Index(y.rows())),y.cols());
179
+ y.topRows(rank) = this->matrixR().topLeftCorner(rank, rank).template triangularView<Upper>().solve(b.topRows(rank));
180
+ y.bottomRows(y.rows()-rank).setZero();
181
+
182
+ // Apply the column permutation
183
+ if (m_perm_c.size()) dest = colsPermutation() * y.topRows(cols());
184
+ else dest = y.topRows(cols());
185
+
186
+ m_info = Success;
187
+ return true;
188
+ }
189
+
190
+
191
+ /** Sets the threshold that is used to determine linearly dependent columns during the factorization.
192
+ *
193
+ * In practice, if during the factorization the norm of the column that has to be eliminated is below
194
+ * this threshold, then the entire column is treated as zero, and it is moved at the end.
195
+ */
196
+ void setPivotThreshold(const RealScalar& threshold)
197
+ {
198
+ m_useDefaultThreshold = false;
199
+ m_threshold = threshold;
200
+ }
201
+
202
+ /** \returns the solution X of \f$ A X = B \f$ using the current decomposition of A.
203
+ *
204
+ * \sa compute()
205
+ */
206
+ template<typename Rhs>
207
+ inline const internal::solve_retval<SparseQR, Rhs> solve(const MatrixBase<Rhs>& B) const
208
+ {
209
+ eigen_assert(m_isInitialized && "The factorization should be called first, use compute()");
210
+ eigen_assert(this->rows() == B.rows() && "SparseQR::solve() : invalid number of rows in the right hand side matrix");
211
+ return internal::solve_retval<SparseQR, Rhs>(*this, B.derived());
212
+ }
213
+ template<typename Rhs>
214
+ inline const internal::sparse_solve_retval<SparseQR, Rhs> solve(const SparseMatrixBase<Rhs>& B) const
215
+ {
216
+ eigen_assert(m_isInitialized && "The factorization should be called first, use compute()");
217
+ eigen_assert(this->rows() == B.rows() && "SparseQR::solve() : invalid number of rows in the right hand side matrix");
218
+ return internal::sparse_solve_retval<SparseQR, Rhs>(*this, B.derived());
219
+ }
220
+
221
+ /** \brief Reports whether previous computation was successful.
222
+ *
223
+ * \returns \c Success if computation was successful,
224
+ * \c NumericalIssue if the QR factorization reports a numerical problem
225
+ * \c InvalidInput if the input matrix is invalid
226
+ *
227
+ * \sa iparm()
228
+ */
229
+ ComputationInfo info() const
230
+ {
231
+ eigen_assert(m_isInitialized && "Decomposition is not initialized.");
232
+ return m_info;
233
+ }
234
+
235
+ protected:
236
+ inline void sort_matrix_Q()
237
+ {
238
+ if(this->m_isQSorted) return;
239
+ // The matrix Q is sorted during the transposition
240
+ SparseMatrix<Scalar, RowMajor, Index> mQrm(this->m_Q);
241
+ this->m_Q = mQrm;
242
+ this->m_isQSorted = true;
243
+ }
244
+
245
+
246
+ protected:
247
+ bool m_isInitialized;
248
+ bool m_analysisIsok;
249
+ bool m_factorizationIsok;
250
+ mutable ComputationInfo m_info;
251
+ std::string m_lastError;
252
+ QRMatrixType m_pmat; // Temporary matrix
253
+ QRMatrixType m_R; // The triangular factor matrix
254
+ QRMatrixType m_Q; // The orthogonal reflectors
255
+ ScalarVector m_hcoeffs; // The Householder coefficients
256
+ PermutationType m_perm_c; // Fill-reducing Column permutation
257
+ PermutationType m_pivotperm; // The permutation for rank revealing
258
+ PermutationType m_outputPerm_c; // The final column permutation
259
+ RealScalar m_threshold; // Threshold to determine null Householder reflections
260
+ bool m_useDefaultThreshold; // Use default threshold
261
+ Index m_nonzeropivots; // Number of non zero pivots found
262
+ IndexVector m_etree; // Column elimination tree
263
+ IndexVector m_firstRowElt; // First element in each row
264
+ bool m_isQSorted; // whether Q is sorted or not
265
+ bool m_isEtreeOk; // whether the elimination tree match the initial input matrix
266
+
267
+ template <typename, typename > friend struct SparseQR_QProduct;
268
+ template <typename > friend struct SparseQRMatrixQReturnType;
269
+
270
+ };
271
+
272
+ /** \brief Preprocessing step of a QR factorization
273
+ *
274
+ * \warning The matrix \a mat must be in compressed mode (see SparseMatrix::makeCompressed()).
275
+ *
276
+ * In this step, the fill-reducing permutation is computed and applied to the columns of A
277
+ * and the column elimination tree is computed as well. Only the sparsity pattern of \a mat is exploited.
278
+ *
279
+ * \note In this step it is assumed that there is no empty row in the matrix \a mat.
280
+ */
281
+ template <typename MatrixType, typename OrderingType>
282
+ void SparseQR<MatrixType,OrderingType>::analyzePattern(const MatrixType& mat)
283
+ {
284
+ eigen_assert(mat.isCompressed() && "SparseQR requires a sparse matrix in compressed mode. Call .makeCompressed() before passing it to SparseQR");
285
+ // Copy to a column major matrix if the input is rowmajor
286
+ typename internal::conditional<MatrixType::IsRowMajor,QRMatrixType,const MatrixType&>::type matCpy(mat);
287
+ // Compute the column fill reducing ordering
288
+ OrderingType ord;
289
+ ord(matCpy, m_perm_c);
290
+ Index n = mat.cols();
291
+ Index m = mat.rows();
292
+ Index diagSize = (std::min)(m,n);
293
+
294
+ if (!m_perm_c.size())
295
+ {
296
+ m_perm_c.resize(n);
297
+ m_perm_c.indices().setLinSpaced(n, 0,n-1);
298
+ }
299
+
300
+ // Compute the column elimination tree of the permuted matrix
301
+ m_outputPerm_c = m_perm_c.inverse();
302
+ internal::coletree(matCpy, m_etree, m_firstRowElt, m_outputPerm_c.indices().data());
303
+ m_isEtreeOk = true;
304
+
305
+ m_R.resize(m, n);
306
+ m_Q.resize(m, diagSize);
307
+
308
+ // Allocate space for nonzero elements : rough estimation
309
+ m_R.reserve(2*mat.nonZeros()); //FIXME Get a more accurate estimation through symbolic factorization with the etree
310
+ m_Q.reserve(2*mat.nonZeros());
311
+ m_hcoeffs.resize(diagSize);
312
+ m_analysisIsok = true;
313
+ }
314
+
315
+ /** \brief Performs the numerical QR factorization of the input matrix
316
+ *
317
+ * The function SparseQR::analyzePattern(const MatrixType&) must have been called beforehand with
318
+ * a matrix having the same sparsity pattern than \a mat.
319
+ *
320
+ * \param mat The sparse column-major matrix
321
+ */
322
+ template <typename MatrixType, typename OrderingType>
323
+ void SparseQR<MatrixType,OrderingType>::factorize(const MatrixType& mat)
324
+ {
325
+ using std::abs;
326
+ using std::max;
327
+
328
+ eigen_assert(m_analysisIsok && "analyzePattern() should be called before this step");
329
+ Index m = mat.rows();
330
+ Index n = mat.cols();
331
+ Index diagSize = (std::min)(m,n);
332
+ IndexVector mark((std::max)(m,n)); mark.setConstant(-1); // Record the visited nodes
333
+ IndexVector Ridx(n), Qidx(m); // Store temporarily the row indexes for the current column of R and Q
334
+ Index nzcolR, nzcolQ; // Number of nonzero for the current column of R and Q
335
+ ScalarVector tval(m); // The dense vector used to compute the current column
336
+ RealScalar pivotThreshold = m_threshold;
337
+
338
+ m_R.setZero();
339
+ m_Q.setZero();
340
+ m_pmat = mat;
341
+ if(!m_isEtreeOk)
342
+ {
343
+ m_outputPerm_c = m_perm_c.inverse();
344
+ internal::coletree(m_pmat, m_etree, m_firstRowElt, m_outputPerm_c.indices().data());
345
+ m_isEtreeOk = true;
346
+ }
347
+
348
+ m_pmat.uncompress(); // To have the innerNonZeroPtr allocated
349
+
350
+ // Apply the fill-in reducing permutation lazily:
351
+ {
352
+ // If the input is row major, copy the original column indices,
353
+ // otherwise directly use the input matrix
354
+ //
355
+ IndexVector originalOuterIndicesCpy;
356
+ const Index *originalOuterIndices = mat.outerIndexPtr();
357
+ if(MatrixType::IsRowMajor)
358
+ {
359
+ originalOuterIndicesCpy = IndexVector::Map(m_pmat.outerIndexPtr(),n+1);
360
+ originalOuterIndices = originalOuterIndicesCpy.data();
361
+ }
362
+
363
+ for (int i = 0; i < n; i++)
364
+ {
365
+ Index p = m_perm_c.size() ? m_perm_c.indices()(i) : i;
366
+ m_pmat.outerIndexPtr()[p] = originalOuterIndices[i];
367
+ m_pmat.innerNonZeroPtr()[p] = originalOuterIndices[i+1] - originalOuterIndices[i];
368
+ }
369
+ }
370
+
371
+ /* Compute the default threshold as in MatLab, see:
372
+ * Tim Davis, "Algorithm 915, SuiteSparseQR: Multifrontal Multithreaded Rank-Revealing
373
+ * Sparse QR Factorization, ACM Trans. on Math. Soft. 38(1), 2011, Page 8:3
374
+ */
375
+ if(m_useDefaultThreshold)
376
+ {
377
+ RealScalar max2Norm = 0.0;
378
+ for (int j = 0; j < n; j++) max2Norm = (max)(max2Norm, m_pmat.col(j).norm());
379
+ if(max2Norm==RealScalar(0))
380
+ max2Norm = RealScalar(1);
381
+ pivotThreshold = 20 * (m + n) * max2Norm * NumTraits<RealScalar>::epsilon();
382
+ }
383
+
384
+ // Initialize the numerical permutation
385
+ m_pivotperm.setIdentity(n);
386
+
387
+ Index nonzeroCol = 0; // Record the number of valid pivots
388
+ m_Q.startVec(0);
389
+
390
+ // Left looking rank-revealing QR factorization: compute a column of R and Q at a time
391
+ for (Index col = 0; col < n; ++col)
392
+ {
393
+ mark.setConstant(-1);
394
+ m_R.startVec(col);
395
+ mark(nonzeroCol) = col;
396
+ Qidx(0) = nonzeroCol;
397
+ nzcolR = 0; nzcolQ = 1;
398
+ bool found_diag = nonzeroCol>=m;
399
+ tval.setZero();
400
+
401
+ // Symbolic factorization: find the nonzero locations of the column k of the factors R and Q, i.e.,
402
+ // all the nodes (with indexes lower than rank) reachable through the column elimination tree (etree) rooted at node k.
403
+ // Note: if the diagonal entry does not exist, then its contribution must be explicitly added,
404
+ // thus the trick with found_diag that permits to do one more iteration on the diagonal element if this one has not been found.
405
+ for (typename QRMatrixType::InnerIterator itp(m_pmat, col); itp || !found_diag; ++itp)
406
+ {
407
+ Index curIdx = nonzeroCol;
408
+ if(itp) curIdx = itp.row();
409
+ if(curIdx == nonzeroCol) found_diag = true;
410
+
411
+ // Get the nonzeros indexes of the current column of R
412
+ Index st = m_firstRowElt(curIdx); // The traversal of the etree starts here
413
+ if (st < 0 )
414
+ {
415
+ m_lastError = "Empty row found during numerical factorization";
416
+ m_info = InvalidInput;
417
+ return;
418
+ }
419
+
420
+ // Traverse the etree
421
+ Index bi = nzcolR;
422
+ for (; mark(st) != col; st = m_etree(st))
423
+ {
424
+ Ridx(nzcolR) = st; // Add this row to the list,
425
+ mark(st) = col; // and mark this row as visited
426
+ nzcolR++;
427
+ }
428
+
429
+ // Reverse the list to get the topological ordering
430
+ Index nt = nzcolR-bi;
431
+ for(Index i = 0; i < nt/2; i++) std::swap(Ridx(bi+i), Ridx(nzcolR-i-1));
432
+
433
+ // Copy the current (curIdx,pcol) value of the input matrix
434
+ if(itp) tval(curIdx) = itp.value();
435
+ else tval(curIdx) = Scalar(0);
436
+
437
+ // Compute the pattern of Q(:,k)
438
+ if(curIdx > nonzeroCol && mark(curIdx) != col )
439
+ {
440
+ Qidx(nzcolQ) = curIdx; // Add this row to the pattern of Q,
441
+ mark(curIdx) = col; // and mark it as visited
442
+ nzcolQ++;
443
+ }
444
+ }
445
+
446
+ // Browse all the indexes of R(:,col) in reverse order
447
+ for (Index i = nzcolR-1; i >= 0; i--)
448
+ {
449
+ Index curIdx = Ridx(i);
450
+
451
+ // Apply the curIdx-th householder vector to the current column (temporarily stored into tval)
452
+ Scalar tdot(0);
453
+
454
+ // First compute q' * tval
455
+ tdot = m_Q.col(curIdx).dot(tval);
456
+
457
+ tdot *= m_hcoeffs(curIdx);
458
+
459
+ // Then update tval = tval - q * tau
460
+ // FIXME: tval -= tdot * m_Q.col(curIdx) should amount to the same (need to check/add support for efficient "dense ?= sparse")
461
+ for (typename QRMatrixType::InnerIterator itq(m_Q, curIdx); itq; ++itq)
462
+ tval(itq.row()) -= itq.value() * tdot;
463
+
464
+ // Detect fill-in for the current column of Q
465
+ if(m_etree(Ridx(i)) == nonzeroCol)
466
+ {
467
+ for (typename QRMatrixType::InnerIterator itq(m_Q, curIdx); itq; ++itq)
468
+ {
469
+ Index iQ = itq.row();
470
+ if (mark(iQ) != col)
471
+ {
472
+ Qidx(nzcolQ++) = iQ; // Add this row to the pattern of Q,
473
+ mark(iQ) = col; // and mark it as visited
474
+ }
475
+ }
476
+ }
477
+ } // End update current column
478
+
479
+ Scalar tau = 0;
480
+ RealScalar beta = 0;
481
+
482
+ if(nonzeroCol < diagSize)
483
+ {
484
+ // Compute the Householder reflection that eliminate the current column
485
+ // FIXME this step should call the Householder module.
486
+ Scalar c0 = nzcolQ ? tval(Qidx(0)) : Scalar(0);
487
+
488
+ // First, the squared norm of Q((col+1):m, col)
489
+ RealScalar sqrNorm = 0.;
490
+ for (Index itq = 1; itq < nzcolQ; ++itq) sqrNorm += numext::abs2(tval(Qidx(itq)));
491
+ if(sqrNorm == RealScalar(0) && numext::imag(c0) == RealScalar(0))
492
+ {
493
+ beta = numext::real(c0);
494
+ tval(Qidx(0)) = 1;
495
+ }
496
+ else
497
+ {
498
+ using std::sqrt;
499
+ beta = sqrt(numext::abs2(c0) + sqrNorm);
500
+ if(numext::real(c0) >= RealScalar(0))
501
+ beta = -beta;
502
+ tval(Qidx(0)) = 1;
503
+ for (Index itq = 1; itq < nzcolQ; ++itq)
504
+ tval(Qidx(itq)) /= (c0 - beta);
505
+ tau = numext::conj((beta-c0) / beta);
506
+
507
+ }
508
+ }
509
+
510
+ // Insert values in R
511
+ for (Index i = nzcolR-1; i >= 0; i--)
512
+ {
513
+ Index curIdx = Ridx(i);
514
+ if(curIdx < nonzeroCol)
515
+ {
516
+ m_R.insertBackByOuterInnerUnordered(col, curIdx) = tval(curIdx);
517
+ tval(curIdx) = Scalar(0.);
518
+ }
519
+ }
520
+
521
+ if(nonzeroCol < diagSize && abs(beta) >= pivotThreshold)
522
+ {
523
+ m_R.insertBackByOuterInner(col, nonzeroCol) = beta;
524
+ // The householder coefficient
525
+ m_hcoeffs(nonzeroCol) = tau;
526
+ // Record the householder reflections
527
+ for (Index itq = 0; itq < nzcolQ; ++itq)
528
+ {
529
+ Index iQ = Qidx(itq);
530
+ m_Q.insertBackByOuterInnerUnordered(nonzeroCol,iQ) = tval(iQ);
531
+ tval(iQ) = Scalar(0.);
532
+ }
533
+ nonzeroCol++;
534
+ if(nonzeroCol<diagSize)
535
+ m_Q.startVec(nonzeroCol);
536
+ }
537
+ else
538
+ {
539
+ // Zero pivot found: move implicitly this column to the end
540
+ for (Index j = nonzeroCol; j < n-1; j++)
541
+ std::swap(m_pivotperm.indices()(j), m_pivotperm.indices()[j+1]);
542
+
543
+ // Recompute the column elimination tree
544
+ internal::coletree(m_pmat, m_etree, m_firstRowElt, m_pivotperm.indices().data());
545
+ m_isEtreeOk = false;
546
+ }
547
+ }
548
+
549
+ m_hcoeffs.tail(diagSize-nonzeroCol).setZero();
550
+
551
+ // Finalize the column pointers of the sparse matrices R and Q
552
+ m_Q.finalize();
553
+ m_Q.makeCompressed();
554
+ m_R.finalize();
555
+ m_R.makeCompressed();
556
+ m_isQSorted = false;
557
+
558
+ m_nonzeropivots = nonzeroCol;
559
+
560
+ if(nonzeroCol<n)
561
+ {
562
+ // Permute the triangular factor to put the 'dead' columns to the end
563
+ QRMatrixType tempR(m_R);
564
+ m_R = tempR * m_pivotperm;
565
+
566
+ // Update the column permutation
567
+ m_outputPerm_c = m_outputPerm_c * m_pivotperm;
568
+ }
569
+
570
+ m_isInitialized = true;
571
+ m_factorizationIsok = true;
572
+ m_info = Success;
573
+ }
574
+
575
+ namespace internal {
576
+
577
+ template<typename _MatrixType, typename OrderingType, typename Rhs>
578
+ struct solve_retval<SparseQR<_MatrixType,OrderingType>, Rhs>
579
+ : solve_retval_base<SparseQR<_MatrixType,OrderingType>, Rhs>
580
+ {
581
+ typedef SparseQR<_MatrixType,OrderingType> Dec;
582
+ EIGEN_MAKE_SOLVE_HELPERS(Dec,Rhs)
583
+
584
+ template<typename Dest> void evalTo(Dest& dst) const
585
+ {
586
+ dec()._solve(rhs(),dst);
587
+ }
588
+ };
589
+ template<typename _MatrixType, typename OrderingType, typename Rhs>
590
+ struct sparse_solve_retval<SparseQR<_MatrixType, OrderingType>, Rhs>
591
+ : sparse_solve_retval_base<SparseQR<_MatrixType, OrderingType>, Rhs>
592
+ {
593
+ typedef SparseQR<_MatrixType, OrderingType> Dec;
594
+ EIGEN_MAKE_SPARSE_SOLVE_HELPERS(Dec, Rhs)
595
+
596
+ template<typename Dest> void evalTo(Dest& dst) const
597
+ {
598
+ this->defaultEvalTo(dst);
599
+ }
600
+ };
601
+ } // end namespace internal
602
+
603
+ template <typename SparseQRType, typename Derived>
604
+ struct SparseQR_QProduct : ReturnByValue<SparseQR_QProduct<SparseQRType, Derived> >
605
+ {
606
+ typedef typename SparseQRType::QRMatrixType MatrixType;
607
+ typedef typename SparseQRType::Scalar Scalar;
608
+ typedef typename SparseQRType::Index Index;
609
+ // Get the references
610
+ SparseQR_QProduct(const SparseQRType& qr, const Derived& other, bool transpose) :
611
+ m_qr(qr),m_other(other),m_transpose(transpose) {}
612
+ inline Index rows() const { return m_transpose ? m_qr.rows() : m_qr.cols(); }
613
+ inline Index cols() const { return m_other.cols(); }
614
+
615
+ // Assign to a vector
616
+ template<typename DesType>
617
+ void evalTo(DesType& res) const
618
+ {
619
+ Index m = m_qr.rows();
620
+ Index n = m_qr.cols();
621
+ Index diagSize = (std::min)(m,n);
622
+ res = m_other;
623
+ if (m_transpose)
624
+ {
625
+ eigen_assert(m_qr.m_Q.rows() == m_other.rows() && "Non conforming object sizes");
626
+ //Compute res = Q' * other column by column
627
+ for(Index j = 0; j < res.cols(); j++){
628
+ for (Index k = 0; k < diagSize; k++)
629
+ {
630
+ Scalar tau = Scalar(0);
631
+ tau = m_qr.m_Q.col(k).dot(res.col(j));
632
+ if(tau==Scalar(0)) continue;
633
+ tau = tau * m_qr.m_hcoeffs(k);
634
+ res.col(j) -= tau * m_qr.m_Q.col(k);
635
+ }
636
+ }
637
+ }
638
+ else
639
+ {
640
+ eigen_assert(m_qr.m_Q.rows() == m_other.rows() && "Non conforming object sizes");
641
+ // Compute res = Q * other column by column
642
+ for(Index j = 0; j < res.cols(); j++)
643
+ {
644
+ for (Index k = diagSize-1; k >=0; k--)
645
+ {
646
+ Scalar tau = Scalar(0);
647
+ tau = m_qr.m_Q.col(k).dot(res.col(j));
648
+ if(tau==Scalar(0)) continue;
649
+ tau = tau * m_qr.m_hcoeffs(k);
650
+ res.col(j) -= tau * m_qr.m_Q.col(k);
651
+ }
652
+ }
653
+ }
654
+ }
655
+
656
+ const SparseQRType& m_qr;
657
+ const Derived& m_other;
658
+ bool m_transpose;
659
+ };
660
+
661
+ template<typename SparseQRType>
662
+ struct SparseQRMatrixQReturnType : public EigenBase<SparseQRMatrixQReturnType<SparseQRType> >
663
+ {
664
+ typedef typename SparseQRType::Index Index;
665
+ typedef typename SparseQRType::Scalar Scalar;
666
+ typedef Matrix<Scalar,Dynamic,Dynamic> DenseMatrix;
667
+ SparseQRMatrixQReturnType(const SparseQRType& qr) : m_qr(qr) {}
668
+ template<typename Derived>
669
+ SparseQR_QProduct<SparseQRType, Derived> operator*(const MatrixBase<Derived>& other)
670
+ {
671
+ return SparseQR_QProduct<SparseQRType,Derived>(m_qr,other.derived(),false);
672
+ }
673
+ SparseQRMatrixQTransposeReturnType<SparseQRType> adjoint() const
674
+ {
675
+ return SparseQRMatrixQTransposeReturnType<SparseQRType>(m_qr);
676
+ }
677
+ inline Index rows() const { return m_qr.rows(); }
678
+ inline Index cols() const { return (std::min)(m_qr.rows(),m_qr.cols()); }
679
+ // To use for operations with the transpose of Q
680
+ SparseQRMatrixQTransposeReturnType<SparseQRType> transpose() const
681
+ {
682
+ return SparseQRMatrixQTransposeReturnType<SparseQRType>(m_qr);
683
+ }
684
+ template<typename Dest> void evalTo(MatrixBase<Dest>& dest) const
685
+ {
686
+ dest.derived() = m_qr.matrixQ() * Dest::Identity(m_qr.rows(), m_qr.rows());
687
+ }
688
+ template<typename Dest> void evalTo(SparseMatrixBase<Dest>& dest) const
689
+ {
690
+ Dest idMat(m_qr.rows(), m_qr.rows());
691
+ idMat.setIdentity();
692
+ // Sort the sparse householder reflectors if needed
693
+ const_cast<SparseQRType *>(&m_qr)->sort_matrix_Q();
694
+ dest.derived() = SparseQR_QProduct<SparseQRType, Dest>(m_qr, idMat, false);
695
+ }
696
+
697
+ const SparseQRType& m_qr;
698
+ };
699
+
700
+ template<typename SparseQRType>
701
+ struct SparseQRMatrixQTransposeReturnType
702
+ {
703
+ SparseQRMatrixQTransposeReturnType(const SparseQRType& qr) : m_qr(qr) {}
704
+ template<typename Derived>
705
+ SparseQR_QProduct<SparseQRType,Derived> operator*(const MatrixBase<Derived>& other)
706
+ {
707
+ return SparseQR_QProduct<SparseQRType,Derived>(m_qr,other.derived(), true);
708
+ }
709
+ const SparseQRType& m_qr;
710
+ };
711
+
712
+ } // end namespace Eigen
713
+
714
+ #endif