ruby-eigen 0.0.9 → 0.0.10.pre1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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