@smake/eigen 1.1.0 → 1.1.1
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.
- package/README.md +1 -1
- package/eigen/Eigen/AccelerateSupport +52 -0
- package/eigen/Eigen/Cholesky +18 -20
- package/eigen/Eigen/CholmodSupport +28 -28
- package/eigen/Eigen/Core +187 -120
- package/eigen/Eigen/Eigenvalues +16 -13
- package/eigen/Eigen/Geometry +18 -18
- package/eigen/Eigen/Householder +9 -7
- package/eigen/Eigen/IterativeLinearSolvers +8 -4
- package/eigen/Eigen/Jacobi +14 -13
- package/eigen/Eigen/KLUSupport +23 -21
- package/eigen/Eigen/LU +15 -16
- package/eigen/Eigen/MetisSupport +12 -12
- package/eigen/Eigen/OrderingMethods +54 -51
- package/eigen/Eigen/PaStiXSupport +23 -21
- package/eigen/Eigen/PardisoSupport +17 -14
- package/eigen/Eigen/QR +18 -20
- package/eigen/Eigen/QtAlignedMalloc +5 -12
- package/eigen/Eigen/SPQRSupport +21 -14
- package/eigen/Eigen/SVD +23 -17
- package/eigen/Eigen/Sparse +1 -2
- package/eigen/Eigen/SparseCholesky +18 -15
- package/eigen/Eigen/SparseCore +18 -17
- package/eigen/Eigen/SparseLU +9 -9
- package/eigen/Eigen/SparseQR +16 -14
- package/eigen/Eigen/StdDeque +5 -2
- package/eigen/Eigen/StdList +5 -2
- package/eigen/Eigen/StdVector +5 -2
- package/eigen/Eigen/SuperLUSupport +30 -24
- package/eigen/Eigen/ThreadPool +80 -0
- package/eigen/Eigen/UmfPackSupport +19 -17
- package/eigen/Eigen/Version +14 -0
- package/eigen/Eigen/src/AccelerateSupport/AccelerateSupport.h +423 -0
- package/eigen/Eigen/src/AccelerateSupport/InternalHeaderCheck.h +3 -0
- package/eigen/Eigen/src/Cholesky/InternalHeaderCheck.h +3 -0
- package/eigen/Eigen/src/Cholesky/LDLT.h +366 -405
- package/eigen/Eigen/src/Cholesky/LLT.h +323 -367
- package/eigen/Eigen/src/Cholesky/LLT_LAPACKE.h +81 -56
- package/eigen/Eigen/src/CholmodSupport/CholmodSupport.h +585 -529
- package/eigen/Eigen/src/CholmodSupport/InternalHeaderCheck.h +3 -0
- package/eigen/Eigen/src/Core/ArithmeticSequence.h +143 -317
- package/eigen/Eigen/src/Core/Array.h +329 -370
- package/eigen/Eigen/src/Core/ArrayBase.h +190 -203
- package/eigen/Eigen/src/Core/ArrayWrapper.h +126 -170
- package/eigen/Eigen/src/Core/Assign.h +30 -40
- package/eigen/Eigen/src/Core/AssignEvaluator.h +651 -604
- package/eigen/Eigen/src/Core/Assign_MKL.h +125 -120
- package/eigen/Eigen/src/Core/BandMatrix.h +267 -282
- package/eigen/Eigen/src/Core/Block.h +371 -390
- package/eigen/Eigen/src/Core/CommaInitializer.h +85 -100
- package/eigen/Eigen/src/Core/ConditionEstimator.h +51 -53
- package/eigen/Eigen/src/Core/CoreEvaluators.h +1214 -937
- package/eigen/Eigen/src/Core/CoreIterators.h +72 -63
- package/eigen/Eigen/src/Core/CwiseBinaryOp.h +112 -129
- package/eigen/Eigen/src/Core/CwiseNullaryOp.h +676 -702
- package/eigen/Eigen/src/Core/CwiseTernaryOp.h +77 -103
- package/eigen/Eigen/src/Core/CwiseUnaryOp.h +55 -67
- package/eigen/Eigen/src/Core/CwiseUnaryView.h +127 -92
- package/eigen/Eigen/src/Core/DenseBase.h +630 -658
- package/eigen/Eigen/src/Core/DenseCoeffsBase.h +511 -628
- package/eigen/Eigen/src/Core/DenseStorage.h +511 -590
- package/eigen/Eigen/src/Core/DeviceWrapper.h +153 -0
- package/eigen/Eigen/src/Core/Diagonal.h +168 -207
- package/eigen/Eigen/src/Core/DiagonalMatrix.h +346 -317
- package/eigen/Eigen/src/Core/DiagonalProduct.h +12 -10
- package/eigen/Eigen/src/Core/Dot.h +167 -217
- package/eigen/Eigen/src/Core/EigenBase.h +74 -85
- package/eigen/Eigen/src/Core/Fill.h +138 -0
- package/eigen/Eigen/src/Core/FindCoeff.h +464 -0
- package/eigen/Eigen/src/Core/ForceAlignedAccess.h +90 -113
- package/eigen/Eigen/src/Core/Fuzzy.h +82 -105
- package/eigen/Eigen/src/Core/GeneralProduct.h +315 -261
- package/eigen/Eigen/src/Core/GenericPacketMath.h +1182 -520
- package/eigen/Eigen/src/Core/GlobalFunctions.h +193 -157
- package/eigen/Eigen/src/Core/IO.h +131 -156
- package/eigen/Eigen/src/Core/IndexedView.h +209 -125
- package/eigen/Eigen/src/Core/InnerProduct.h +260 -0
- package/eigen/Eigen/src/Core/InternalHeaderCheck.h +3 -0
- package/eigen/Eigen/src/Core/Inverse.h +50 -59
- package/eigen/Eigen/src/Core/Map.h +123 -141
- package/eigen/Eigen/src/Core/MapBase.h +255 -282
- package/eigen/Eigen/src/Core/MathFunctions.h +1247 -1201
- package/eigen/Eigen/src/Core/MathFunctionsImpl.h +162 -99
- package/eigen/Eigen/src/Core/Matrix.h +463 -494
- package/eigen/Eigen/src/Core/MatrixBase.h +468 -470
- package/eigen/Eigen/src/Core/NestByValue.h +58 -52
- package/eigen/Eigen/src/Core/NoAlias.h +79 -86
- package/eigen/Eigen/src/Core/NumTraits.h +206 -206
- package/eigen/Eigen/src/Core/PartialReduxEvaluator.h +163 -142
- package/eigen/Eigen/src/Core/PermutationMatrix.h +461 -511
- package/eigen/Eigen/src/Core/PlainObjectBase.h +858 -972
- package/eigen/Eigen/src/Core/Product.h +246 -130
- package/eigen/Eigen/src/Core/ProductEvaluators.h +779 -671
- package/eigen/Eigen/src/Core/Random.h +153 -164
- package/eigen/Eigen/src/Core/RandomImpl.h +262 -0
- package/eigen/Eigen/src/Core/RealView.h +250 -0
- package/eigen/Eigen/src/Core/Redux.h +334 -314
- package/eigen/Eigen/src/Core/Ref.h +259 -257
- package/eigen/Eigen/src/Core/Replicate.h +92 -104
- package/eigen/Eigen/src/Core/Reshaped.h +215 -271
- package/eigen/Eigen/src/Core/ReturnByValue.h +47 -55
- package/eigen/Eigen/src/Core/Reverse.h +133 -148
- package/eigen/Eigen/src/Core/Select.h +68 -140
- package/eigen/Eigen/src/Core/SelfAdjointView.h +254 -290
- package/eigen/Eigen/src/Core/SelfCwiseBinaryOp.h +23 -20
- package/eigen/Eigen/src/Core/SkewSymmetricMatrix3.h +382 -0
- package/eigen/Eigen/src/Core/Solve.h +88 -102
- package/eigen/Eigen/src/Core/SolveTriangular.h +126 -124
- package/eigen/Eigen/src/Core/SolverBase.h +132 -133
- package/eigen/Eigen/src/Core/StableNorm.h +113 -147
- package/eigen/Eigen/src/Core/StlIterators.h +404 -248
- package/eigen/Eigen/src/Core/Stride.h +90 -92
- package/eigen/Eigen/src/Core/Swap.h +70 -39
- package/eigen/Eigen/src/Core/Transpose.h +258 -295
- package/eigen/Eigen/src/Core/Transpositions.h +270 -333
- package/eigen/Eigen/src/Core/TriangularMatrix.h +642 -743
- package/eigen/Eigen/src/Core/VectorBlock.h +59 -72
- package/eigen/Eigen/src/Core/VectorwiseOp.h +653 -704
- package/eigen/Eigen/src/Core/Visitor.h +464 -308
- package/eigen/Eigen/src/Core/arch/AVX/Complex.h +380 -187
- package/eigen/Eigen/src/Core/arch/AVX/MathFunctions.h +65 -163
- package/eigen/Eigen/src/Core/arch/AVX/PacketMath.h +2145 -638
- package/eigen/Eigen/src/Core/arch/AVX/Reductions.h +353 -0
- package/eigen/Eigen/src/Core/arch/AVX/TypeCasting.h +253 -60
- package/eigen/Eigen/src/Core/arch/AVX512/Complex.h +278 -228
- package/eigen/Eigen/src/Core/arch/AVX512/GemmKernel.h +1245 -0
- package/eigen/Eigen/src/Core/arch/AVX512/MathFunctions.h +48 -269
- package/eigen/Eigen/src/Core/arch/AVX512/MathFunctionsFP16.h +75 -0
- package/eigen/Eigen/src/Core/arch/AVX512/PacketMath.h +1597 -754
- package/eigen/Eigen/src/Core/arch/AVX512/PacketMathFP16.h +1413 -0
- package/eigen/Eigen/src/Core/arch/AVX512/Reductions.h +297 -0
- package/eigen/Eigen/src/Core/arch/AVX512/TrsmKernel.h +1167 -0
- package/eigen/Eigen/src/Core/arch/AVX512/TrsmUnrolls.inc +1219 -0
- package/eigen/Eigen/src/Core/arch/AVX512/TypeCasting.h +229 -41
- package/eigen/Eigen/src/Core/arch/AVX512/TypeCastingFP16.h +130 -0
- package/eigen/Eigen/src/Core/arch/AltiVec/Complex.h +420 -184
- package/eigen/Eigen/src/Core/arch/AltiVec/MathFunctions.h +40 -49
- package/eigen/Eigen/src/Core/arch/AltiVec/MatrixProduct.h +2962 -2213
- package/eigen/Eigen/src/Core/arch/AltiVec/MatrixProductCommon.h +196 -212
- package/eigen/Eigen/src/Core/arch/AltiVec/MatrixProductMMA.h +713 -441
- package/eigen/Eigen/src/Core/arch/AltiVec/MatrixProductMMAbfloat16.h +742 -0
- package/eigen/Eigen/src/Core/arch/AltiVec/MatrixVectorProduct.inc +2818 -0
- package/eigen/Eigen/src/Core/arch/AltiVec/PacketMath.h +2380 -1362
- package/eigen/Eigen/src/Core/arch/AltiVec/TypeCasting.h +153 -0
- package/eigen/Eigen/src/Core/arch/Default/BFloat16.h +390 -224
- package/eigen/Eigen/src/Core/arch/Default/ConjHelper.h +78 -67
- package/eigen/Eigen/src/Core/arch/Default/GenericPacketMathFunctions.h +1784 -799
- package/eigen/Eigen/src/Core/arch/Default/GenericPacketMathFunctionsFwd.h +167 -50
- package/eigen/Eigen/src/Core/arch/Default/Half.h +528 -379
- package/eigen/Eigen/src/Core/arch/Default/Settings.h +10 -12
- package/eigen/Eigen/src/Core/arch/GPU/Complex.h +244 -0
- package/eigen/Eigen/src/Core/arch/GPU/MathFunctions.h +41 -40
- package/eigen/Eigen/src/Core/arch/GPU/PacketMath.h +550 -523
- package/eigen/Eigen/src/Core/arch/GPU/Tuple.h +268 -0
- package/eigen/Eigen/src/Core/arch/GPU/TypeCasting.h +27 -30
- package/eigen/Eigen/src/Core/arch/HIP/hcc/math_constants.h +8 -8
- package/eigen/Eigen/src/Core/arch/HVX/PacketMath.h +1088 -0
- package/eigen/Eigen/src/Core/arch/LSX/Complex.h +520 -0
- package/eigen/Eigen/src/Core/arch/LSX/GeneralBlockPanelKernel.h +23 -0
- package/eigen/Eigen/src/Core/arch/LSX/MathFunctions.h +43 -0
- package/eigen/Eigen/src/Core/arch/LSX/PacketMath.h +2866 -0
- package/eigen/Eigen/src/Core/arch/LSX/TypeCasting.h +526 -0
- package/eigen/Eigen/src/Core/arch/MSA/Complex.h +54 -82
- package/eigen/Eigen/src/Core/arch/MSA/MathFunctions.h +84 -92
- package/eigen/Eigen/src/Core/arch/MSA/PacketMath.h +51 -47
- package/eigen/Eigen/src/Core/arch/NEON/Complex.h +454 -306
- package/eigen/Eigen/src/Core/arch/NEON/GeneralBlockPanelKernel.h +175 -115
- package/eigen/Eigen/src/Core/arch/NEON/MathFunctions.h +23 -30
- package/eigen/Eigen/src/Core/arch/NEON/PacketMath.h +4366 -2857
- package/eigen/Eigen/src/Core/arch/NEON/TypeCasting.h +616 -393
- package/eigen/Eigen/src/Core/arch/NEON/UnaryFunctors.h +57 -0
- package/eigen/Eigen/src/Core/arch/SSE/Complex.h +350 -198
- package/eigen/Eigen/src/Core/arch/SSE/MathFunctions.h +38 -149
- package/eigen/Eigen/src/Core/arch/SSE/PacketMath.h +1791 -912
- package/eigen/Eigen/src/Core/arch/SSE/Reductions.h +324 -0
- package/eigen/Eigen/src/Core/arch/SSE/TypeCasting.h +128 -40
- package/eigen/Eigen/src/Core/arch/SVE/MathFunctions.h +10 -6
- package/eigen/Eigen/src/Core/arch/SVE/PacketMath.h +156 -234
- package/eigen/Eigen/src/Core/arch/SVE/TypeCasting.h +6 -3
- package/eigen/Eigen/src/Core/arch/SYCL/InteropHeaders.h +27 -32
- package/eigen/Eigen/src/Core/arch/SYCL/MathFunctions.h +119 -117
- package/eigen/Eigen/src/Core/arch/SYCL/PacketMath.h +325 -419
- package/eigen/Eigen/src/Core/arch/SYCL/TypeCasting.h +15 -17
- package/eigen/Eigen/src/Core/arch/ZVector/Complex.h +325 -181
- package/eigen/Eigen/src/Core/arch/ZVector/MathFunctions.h +94 -83
- package/eigen/Eigen/src/Core/arch/ZVector/PacketMath.h +811 -458
- package/eigen/Eigen/src/Core/functors/AssignmentFunctors.h +121 -124
- package/eigen/Eigen/src/Core/functors/BinaryFunctors.h +576 -370
- package/eigen/Eigen/src/Core/functors/NullaryFunctors.h +194 -109
- package/eigen/Eigen/src/Core/functors/StlFunctors.h +95 -112
- package/eigen/Eigen/src/Core/functors/TernaryFunctors.h +34 -7
- package/eigen/Eigen/src/Core/functors/UnaryFunctors.h +1038 -749
- package/eigen/Eigen/src/Core/products/GeneralBlockPanelKernel.h +1883 -1375
- package/eigen/Eigen/src/Core/products/GeneralMatrixMatrix.h +312 -370
- package/eigen/Eigen/src/Core/products/GeneralMatrixMatrixTriangular.h +189 -176
- package/eigen/Eigen/src/Core/products/GeneralMatrixMatrixTriangular_BLAS.h +84 -81
- package/eigen/Eigen/src/Core/products/GeneralMatrixMatrix_BLAS.h +154 -73
- package/eigen/Eigen/src/Core/products/GeneralMatrixVector.h +292 -337
- package/eigen/Eigen/src/Core/products/GeneralMatrixVector_BLAS.h +80 -77
- package/eigen/Eigen/src/Core/products/Parallelizer.h +207 -105
- package/eigen/Eigen/src/Core/products/SelfadjointMatrixMatrix.h +327 -388
- package/eigen/Eigen/src/Core/products/SelfadjointMatrixMatrix_BLAS.h +206 -224
- package/eigen/Eigen/src/Core/products/SelfadjointMatrixVector.h +138 -147
- package/eigen/Eigen/src/Core/products/SelfadjointMatrixVector_BLAS.h +58 -61
- package/eigen/Eigen/src/Core/products/SelfadjointProduct.h +71 -71
- package/eigen/Eigen/src/Core/products/SelfadjointRank2Update.h +48 -47
- package/eigen/Eigen/src/Core/products/TriangularMatrixMatrix.h +294 -369
- package/eigen/Eigen/src/Core/products/TriangularMatrixMatrix_BLAS.h +246 -238
- package/eigen/Eigen/src/Core/products/TriangularMatrixVector.h +244 -247
- package/eigen/Eigen/src/Core/products/TriangularMatrixVector_BLAS.h +212 -192
- package/eigen/Eigen/src/Core/products/TriangularSolverMatrix.h +328 -277
- package/eigen/Eigen/src/Core/products/TriangularSolverMatrix_BLAS.h +108 -109
- package/eigen/Eigen/src/Core/products/TriangularSolverVector.h +68 -94
- package/eigen/Eigen/src/Core/util/Assert.h +158 -0
- package/eigen/Eigen/src/Core/util/BlasUtil.h +342 -303
- package/eigen/Eigen/src/Core/util/ConfigureVectorization.h +348 -317
- package/eigen/Eigen/src/Core/util/Constants.h +297 -262
- package/eigen/Eigen/src/Core/util/DisableStupidWarnings.h +130 -90
- package/eigen/Eigen/src/Core/util/EmulateArray.h +270 -0
- package/eigen/Eigen/src/Core/util/ForwardDeclarations.h +449 -247
- package/eigen/Eigen/src/Core/util/GpuHipCudaDefines.inc +101 -0
- package/eigen/Eigen/src/Core/util/GpuHipCudaUndefines.inc +45 -0
- package/eigen/Eigen/src/Core/util/IndexedViewHelper.h +417 -116
- package/eigen/Eigen/src/Core/util/IntegralConstant.h +211 -204
- package/eigen/Eigen/src/Core/util/MKL_support.h +39 -37
- package/eigen/Eigen/src/Core/util/Macros.h +655 -773
- package/eigen/Eigen/src/Core/util/MaxSizeVector.h +139 -0
- package/eigen/Eigen/src/Core/util/Memory.h +970 -748
- package/eigen/Eigen/src/Core/util/Meta.h +581 -633
- package/eigen/Eigen/src/Core/util/MoreMeta.h +638 -0
- package/eigen/Eigen/src/Core/util/ReenableStupidWarnings.h +32 -19
- package/eigen/Eigen/src/Core/util/ReshapedHelper.h +17 -17
- package/eigen/Eigen/src/Core/util/Serializer.h +209 -0
- package/eigen/Eigen/src/Core/util/StaticAssert.h +50 -166
- package/eigen/Eigen/src/Core/util/SymbolicIndex.h +377 -225
- package/eigen/Eigen/src/Core/util/XprHelper.h +784 -547
- package/eigen/Eigen/src/Eigenvalues/ComplexEigenSolver.h +246 -277
- package/eigen/Eigen/src/Eigenvalues/ComplexSchur.h +299 -319
- package/eigen/Eigen/src/Eigenvalues/ComplexSchur_LAPACKE.h +52 -48
- package/eigen/Eigen/src/Eigenvalues/EigenSolver.h +413 -456
- package/eigen/Eigen/src/Eigenvalues/GeneralizedEigenSolver.h +309 -325
- package/eigen/Eigen/src/Eigenvalues/GeneralizedSelfAdjointEigenSolver.h +157 -171
- package/eigen/Eigen/src/Eigenvalues/HessenbergDecomposition.h +292 -310
- package/eigen/Eigen/src/Eigenvalues/InternalHeaderCheck.h +3 -0
- package/eigen/Eigen/src/Eigenvalues/MatrixBaseEigenvalues.h +89 -105
- package/eigen/Eigen/src/Eigenvalues/RealQZ.h +537 -607
- package/eigen/Eigen/src/Eigenvalues/RealSchur.h +342 -381
- package/eigen/Eigen/src/Eigenvalues/RealSchur_LAPACKE.h +41 -35
- package/eigen/Eigen/src/Eigenvalues/SelfAdjointEigenSolver.h +541 -595
- package/eigen/Eigen/src/Eigenvalues/SelfAdjointEigenSolver_LAPACKE.h +47 -44
- package/eigen/Eigen/src/Eigenvalues/Tridiagonalization.h +430 -462
- package/eigen/Eigen/src/Geometry/AlignedBox.h +226 -227
- package/eigen/Eigen/src/Geometry/AngleAxis.h +131 -133
- package/eigen/Eigen/src/Geometry/EulerAngles.h +163 -74
- package/eigen/Eigen/src/Geometry/Homogeneous.h +285 -333
- package/eigen/Eigen/src/Geometry/Hyperplane.h +151 -160
- package/eigen/Eigen/src/Geometry/InternalHeaderCheck.h +3 -0
- package/eigen/Eigen/src/Geometry/OrthoMethods.h +168 -146
- package/eigen/Eigen/src/Geometry/ParametrizedLine.h +127 -127
- package/eigen/Eigen/src/Geometry/Quaternion.h +566 -506
- package/eigen/Eigen/src/Geometry/Rotation2D.h +107 -105
- package/eigen/Eigen/src/Geometry/RotationBase.h +148 -145
- package/eigen/Eigen/src/Geometry/Scaling.h +113 -106
- package/eigen/Eigen/src/Geometry/Transform.h +858 -936
- package/eigen/Eigen/src/Geometry/Translation.h +94 -92
- package/eigen/Eigen/src/Geometry/Umeyama.h +79 -84
- package/eigen/Eigen/src/Geometry/arch/Geometry_SIMD.h +90 -104
- package/eigen/Eigen/src/Householder/BlockHouseholder.h +51 -46
- package/eigen/Eigen/src/Householder/Householder.h +102 -124
- package/eigen/Eigen/src/Householder/HouseholderSequence.h +412 -453
- package/eigen/Eigen/src/Householder/InternalHeaderCheck.h +3 -0
- package/eigen/Eigen/src/IterativeLinearSolvers/BasicPreconditioners.h +149 -162
- package/eigen/Eigen/src/IterativeLinearSolvers/BiCGSTAB.h +124 -119
- package/eigen/Eigen/src/IterativeLinearSolvers/ConjugateGradient.h +92 -104
- package/eigen/Eigen/src/IterativeLinearSolvers/IncompleteCholesky.h +251 -243
- package/eigen/Eigen/src/IterativeLinearSolvers/IncompleteLUT.h +224 -228
- package/eigen/Eigen/src/IterativeLinearSolvers/InternalHeaderCheck.h +3 -0
- package/eigen/Eigen/src/IterativeLinearSolvers/IterativeSolverBase.h +178 -227
- package/eigen/Eigen/src/IterativeLinearSolvers/LeastSquareConjugateGradient.h +79 -84
- package/eigen/Eigen/src/IterativeLinearSolvers/SolveWithGuess.h +54 -60
- package/eigen/Eigen/src/Jacobi/InternalHeaderCheck.h +3 -0
- package/eigen/Eigen/src/Jacobi/Jacobi.h +252 -308
- package/eigen/Eigen/src/KLUSupport/InternalHeaderCheck.h +3 -0
- package/eigen/Eigen/src/KLUSupport/KLUSupport.h +208 -227
- package/eigen/Eigen/src/LU/Determinant.h +50 -69
- package/eigen/Eigen/src/LU/FullPivLU.h +545 -596
- package/eigen/Eigen/src/LU/InternalHeaderCheck.h +3 -0
- package/eigen/Eigen/src/LU/InverseImpl.h +206 -285
- package/eigen/Eigen/src/LU/PartialPivLU.h +390 -428
- package/eigen/Eigen/src/LU/PartialPivLU_LAPACKE.h +54 -40
- package/eigen/Eigen/src/LU/arch/InverseSize4.h +72 -70
- package/eigen/Eigen/src/MetisSupport/InternalHeaderCheck.h +3 -0
- package/eigen/Eigen/src/MetisSupport/MetisSupport.h +81 -93
- package/eigen/Eigen/src/OrderingMethods/Amd.h +243 -265
- package/eigen/Eigen/src/OrderingMethods/Eigen_Colamd.h +831 -1004
- package/eigen/Eigen/src/OrderingMethods/InternalHeaderCheck.h +3 -0
- package/eigen/Eigen/src/OrderingMethods/Ordering.h +112 -119
- package/eigen/Eigen/src/PaStiXSupport/InternalHeaderCheck.h +3 -0
- package/eigen/Eigen/src/PaStiXSupport/PaStiXSupport.h +524 -570
- package/eigen/Eigen/src/PardisoSupport/InternalHeaderCheck.h +3 -0
- package/eigen/Eigen/src/PardisoSupport/PardisoSupport.h +385 -430
- package/eigen/Eigen/src/QR/ColPivHouseholderQR.h +479 -479
- package/eigen/Eigen/src/QR/ColPivHouseholderQR_LAPACKE.h +120 -56
- package/eigen/Eigen/src/QR/CompleteOrthogonalDecomposition.h +166 -153
- package/eigen/Eigen/src/QR/FullPivHouseholderQR.h +495 -475
- package/eigen/Eigen/src/QR/HouseholderQR.h +394 -285
- package/eigen/Eigen/src/QR/HouseholderQR_LAPACKE.h +32 -23
- package/eigen/Eigen/src/QR/InternalHeaderCheck.h +3 -0
- package/eigen/Eigen/src/SPQRSupport/InternalHeaderCheck.h +3 -0
- package/eigen/Eigen/src/SPQRSupport/SuiteSparseQRSupport.h +244 -264
- package/eigen/Eigen/src/SVD/BDCSVD.h +817 -713
- package/eigen/Eigen/src/SVD/BDCSVD_LAPACKE.h +174 -0
- package/eigen/Eigen/src/SVD/InternalHeaderCheck.h +3 -0
- package/eigen/Eigen/src/SVD/JacobiSVD.h +577 -543
- package/eigen/Eigen/src/SVD/JacobiSVD_LAPACKE.h +85 -49
- package/eigen/Eigen/src/SVD/SVDBase.h +242 -182
- package/eigen/Eigen/src/SVD/UpperBidiagonalization.h +200 -235
- package/eigen/Eigen/src/SparseCholesky/InternalHeaderCheck.h +3 -0
- package/eigen/Eigen/src/SparseCholesky/SimplicialCholesky.h +765 -594
- package/eigen/Eigen/src/SparseCholesky/SimplicialCholesky_impl.h +308 -94
- package/eigen/Eigen/src/SparseCore/AmbiVector.h +202 -251
- package/eigen/Eigen/src/SparseCore/CompressedStorage.h +184 -252
- package/eigen/Eigen/src/SparseCore/ConservativeSparseSparseProduct.h +134 -178
- package/eigen/Eigen/src/SparseCore/InternalHeaderCheck.h +3 -0
- package/eigen/Eigen/src/SparseCore/SparseAssign.h +149 -140
- package/eigen/Eigen/src/SparseCore/SparseBlock.h +403 -440
- package/eigen/Eigen/src/SparseCore/SparseColEtree.h +100 -112
- package/eigen/Eigen/src/SparseCore/SparseCompressedBase.h +525 -303
- package/eigen/Eigen/src/SparseCore/SparseCwiseBinaryOp.h +555 -339
- package/eigen/Eigen/src/SparseCore/SparseCwiseUnaryOp.h +100 -108
- package/eigen/Eigen/src/SparseCore/SparseDenseProduct.h +169 -197
- package/eigen/Eigen/src/SparseCore/SparseDiagonalProduct.h +71 -71
- package/eigen/Eigen/src/SparseCore/SparseDot.h +49 -47
- package/eigen/Eigen/src/SparseCore/SparseFuzzy.h +13 -11
- package/eigen/Eigen/src/SparseCore/SparseMap.h +243 -253
- package/eigen/Eigen/src/SparseCore/SparseMatrix.h +1603 -1245
- package/eigen/Eigen/src/SparseCore/SparseMatrixBase.h +403 -350
- package/eigen/Eigen/src/SparseCore/SparsePermutation.h +186 -115
- package/eigen/Eigen/src/SparseCore/SparseProduct.h +94 -97
- package/eigen/Eigen/src/SparseCore/SparseRedux.h +22 -24
- package/eigen/Eigen/src/SparseCore/SparseRef.h +268 -295
- package/eigen/Eigen/src/SparseCore/SparseSelfAdjointView.h +370 -416
- package/eigen/Eigen/src/SparseCore/SparseSolverBase.h +78 -87
- package/eigen/Eigen/src/SparseCore/SparseSparseProductWithPruning.h +81 -95
- package/eigen/Eigen/src/SparseCore/SparseTranspose.h +62 -71
- package/eigen/Eigen/src/SparseCore/SparseTriangularView.h +132 -144
- package/eigen/Eigen/src/SparseCore/SparseUtil.h +138 -115
- package/eigen/Eigen/src/SparseCore/SparseVector.h +426 -372
- package/eigen/Eigen/src/SparseCore/SparseView.h +164 -193
- package/eigen/Eigen/src/SparseCore/TriangularSolver.h +129 -170
- package/eigen/Eigen/src/SparseLU/InternalHeaderCheck.h +3 -0
- package/eigen/Eigen/src/SparseLU/SparseLU.h +756 -710
- package/eigen/Eigen/src/SparseLU/SparseLUImpl.h +61 -48
- package/eigen/Eigen/src/SparseLU/SparseLU_Memory.h +102 -118
- package/eigen/Eigen/src/SparseLU/SparseLU_Structs.h +38 -35
- package/eigen/Eigen/src/SparseLU/SparseLU_SupernodalMatrix.h +245 -301
- package/eigen/Eigen/src/SparseLU/SparseLU_Utils.h +44 -49
- package/eigen/Eigen/src/SparseLU/SparseLU_column_bmod.h +104 -108
- package/eigen/Eigen/src/SparseLU/SparseLU_column_dfs.h +89 -100
- package/eigen/Eigen/src/SparseLU/SparseLU_copy_to_ucol.h +57 -58
- package/eigen/Eigen/src/SparseLU/SparseLU_heap_relax_snode.h +43 -55
- package/eigen/Eigen/src/SparseLU/SparseLU_kernel_bmod.h +74 -71
- package/eigen/Eigen/src/SparseLU/SparseLU_panel_bmod.h +124 -132
- package/eigen/Eigen/src/SparseLU/SparseLU_panel_dfs.h +136 -159
- package/eigen/Eigen/src/SparseLU/SparseLU_pivotL.h +51 -52
- package/eigen/Eigen/src/SparseLU/SparseLU_pruneL.h +67 -73
- package/eigen/Eigen/src/SparseLU/SparseLU_relax_snode.h +24 -26
- package/eigen/Eigen/src/SparseQR/InternalHeaderCheck.h +3 -0
- package/eigen/Eigen/src/SparseQR/SparseQR.h +450 -502
- package/eigen/Eigen/src/StlSupport/StdDeque.h +28 -93
- package/eigen/Eigen/src/StlSupport/StdList.h +28 -84
- package/eigen/Eigen/src/StlSupport/StdVector.h +28 -108
- package/eigen/Eigen/src/StlSupport/details.h +48 -50
- package/eigen/Eigen/src/SuperLUSupport/InternalHeaderCheck.h +3 -0
- package/eigen/Eigen/src/SuperLUSupport/SuperLUSupport.h +634 -730
- package/eigen/Eigen/src/ThreadPool/Barrier.h +70 -0
- package/eigen/Eigen/src/ThreadPool/CoreThreadPoolDevice.h +336 -0
- package/eigen/Eigen/src/ThreadPool/EventCount.h +241 -0
- package/eigen/Eigen/src/ThreadPool/ForkJoin.h +140 -0
- package/eigen/Eigen/src/ThreadPool/InternalHeaderCheck.h +4 -0
- package/eigen/Eigen/src/ThreadPool/NonBlockingThreadPool.h +587 -0
- package/eigen/Eigen/src/ThreadPool/RunQueue.h +230 -0
- package/eigen/Eigen/src/ThreadPool/ThreadCancel.h +21 -0
- package/eigen/Eigen/src/ThreadPool/ThreadEnvironment.h +43 -0
- package/eigen/Eigen/src/ThreadPool/ThreadLocal.h +289 -0
- package/eigen/Eigen/src/ThreadPool/ThreadPoolInterface.h +50 -0
- package/eigen/Eigen/src/ThreadPool/ThreadYield.h +16 -0
- package/eigen/Eigen/src/UmfPackSupport/InternalHeaderCheck.h +3 -0
- package/eigen/Eigen/src/UmfPackSupport/UmfPackSupport.h +428 -464
- package/eigen/Eigen/src/misc/Image.h +41 -43
- package/eigen/Eigen/src/misc/InternalHeaderCheck.h +3 -0
- package/eigen/Eigen/src/misc/Kernel.h +39 -41
- package/eigen/Eigen/src/misc/RealSvd2x2.h +19 -21
- package/eigen/Eigen/src/misc/blas.h +83 -426
- package/eigen/Eigen/src/misc/lapacke.h +9972 -16179
- package/eigen/Eigen/src/misc/lapacke_helpers.h +163 -0
- package/eigen/Eigen/src/misc/lapacke_mangling.h +4 -5
- package/eigen/Eigen/src/plugins/ArrayCwiseBinaryOps.inc +344 -0
- package/eigen/Eigen/src/plugins/ArrayCwiseUnaryOps.inc +544 -0
- package/eigen/Eigen/src/plugins/{BlockMethods.h → BlockMethods.inc} +434 -506
- package/eigen/Eigen/src/plugins/CommonCwiseBinaryOps.inc +116 -0
- package/eigen/Eigen/src/plugins/{CommonCwiseUnaryOps.h → CommonCwiseUnaryOps.inc} +58 -68
- package/eigen/Eigen/src/plugins/IndexedViewMethods.inc +192 -0
- package/eigen/Eigen/src/plugins/InternalHeaderCheck.inc +3 -0
- package/eigen/Eigen/src/plugins/MatrixCwiseBinaryOps.inc +331 -0
- package/eigen/Eigen/src/plugins/MatrixCwiseUnaryOps.inc +118 -0
- package/eigen/Eigen/src/plugins/ReshapedMethods.inc +133 -0
- package/package.json +1 -1
- package/eigen/COPYING.APACHE +0 -203
- package/eigen/COPYING.BSD +0 -26
- package/eigen/COPYING.GPL +0 -674
- package/eigen/COPYING.LGPL +0 -502
- package/eigen/COPYING.MINPACK +0 -51
- package/eigen/COPYING.MPL2 +0 -373
- package/eigen/COPYING.README +0 -18
- package/eigen/Eigen/src/Core/BooleanRedux.h +0 -162
- package/eigen/Eigen/src/Core/arch/CUDA/Complex.h +0 -258
- package/eigen/Eigen/src/Core/arch/Default/TypeCasting.h +0 -120
- package/eigen/Eigen/src/Core/arch/SYCL/SyclMemoryModel.h +0 -694
- package/eigen/Eigen/src/Core/util/NonMPL2.h +0 -3
- package/eigen/Eigen/src/SparseCore/MappedSparseMatrix.h +0 -67
- package/eigen/Eigen/src/SparseLU/SparseLU_gemm_kernel.h +0 -280
- package/eigen/Eigen/src/misc/lapack.h +0 -152
- package/eigen/Eigen/src/plugins/ArrayCwiseBinaryOps.h +0 -358
- package/eigen/Eigen/src/plugins/ArrayCwiseUnaryOps.h +0 -696
- package/eigen/Eigen/src/plugins/CommonCwiseBinaryOps.h +0 -115
- package/eigen/Eigen/src/plugins/IndexedViewMethods.h +0 -262
- package/eigen/Eigen/src/plugins/MatrixCwiseBinaryOps.h +0 -152
- package/eigen/Eigen/src/plugins/MatrixCwiseUnaryOps.h +0 -95
- package/eigen/Eigen/src/plugins/ReshapedMethods.h +0 -149
- package/eigen/README.md +0 -5
|
@@ -11,469 +11,459 @@
|
|
|
11
11
|
#ifndef EIGEN_SPARSE_QR_H
|
|
12
12
|
#define EIGEN_SPARSE_QR_H
|
|
13
13
|
|
|
14
|
+
// IWYU pragma: private
|
|
15
|
+
#include "./InternalHeaderCheck.h"
|
|
16
|
+
|
|
14
17
|
namespace Eigen {
|
|
15
18
|
|
|
16
|
-
template<typename MatrixType, typename OrderingType>
|
|
17
|
-
|
|
18
|
-
template<typename SparseQRType>
|
|
19
|
-
|
|
19
|
+
template <typename MatrixType, typename OrderingType>
|
|
20
|
+
class SparseQR;
|
|
21
|
+
template <typename SparseQRType>
|
|
22
|
+
struct SparseQRMatrixQReturnType;
|
|
23
|
+
template <typename SparseQRType>
|
|
24
|
+
struct SparseQRMatrixQTransposeReturnType;
|
|
25
|
+
template <typename SparseQRType, typename Derived>
|
|
26
|
+
struct SparseQR_QProduct;
|
|
20
27
|
namespace internal {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
typedef typename Derived::PlainObject ReturnType;
|
|
38
|
-
};
|
|
39
|
-
} // End namespace internal
|
|
28
|
+
template <typename SparseQRType>
|
|
29
|
+
struct traits<SparseQRMatrixQReturnType<SparseQRType> > {
|
|
30
|
+
typedef typename SparseQRType::MatrixType ReturnType;
|
|
31
|
+
typedef typename ReturnType::StorageIndex StorageIndex;
|
|
32
|
+
typedef typename ReturnType::StorageKind StorageKind;
|
|
33
|
+
enum { RowsAtCompileTime = Dynamic, ColsAtCompileTime = Dynamic };
|
|
34
|
+
};
|
|
35
|
+
template <typename SparseQRType>
|
|
36
|
+
struct traits<SparseQRMatrixQTransposeReturnType<SparseQRType> > {
|
|
37
|
+
typedef typename SparseQRType::MatrixType ReturnType;
|
|
38
|
+
};
|
|
39
|
+
template <typename SparseQRType, typename Derived>
|
|
40
|
+
struct traits<SparseQR_QProduct<SparseQRType, Derived> > {
|
|
41
|
+
typedef typename Derived::PlainObject ReturnType;
|
|
42
|
+
};
|
|
43
|
+
} // End namespace internal
|
|
40
44
|
|
|
41
45
|
/**
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
template<typename
|
|
84
|
-
class SparseQR : public SparseSolverBase<SparseQR<
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
{
|
|
118
|
-
compute(mat);
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
/** Computes the QR factorization of the sparse matrix \a mat.
|
|
122
|
-
*
|
|
123
|
-
* \warning The matrix \a mat must be in compressed mode (see SparseMatrix::makeCompressed()).
|
|
124
|
-
*
|
|
125
|
-
* \sa analyzePattern(), factorize()
|
|
126
|
-
*/
|
|
127
|
-
void compute(const MatrixType& mat)
|
|
128
|
-
{
|
|
129
|
-
analyzePattern(mat);
|
|
130
|
-
factorize(mat);
|
|
131
|
-
}
|
|
132
|
-
void analyzePattern(const MatrixType& mat);
|
|
133
|
-
void factorize(const MatrixType& mat);
|
|
134
|
-
|
|
135
|
-
/** \returns the number of rows of the represented matrix.
|
|
136
|
-
*/
|
|
137
|
-
inline Index rows() const { return m_pmat.rows(); }
|
|
138
|
-
|
|
139
|
-
/** \returns the number of columns of the represented matrix.
|
|
140
|
-
*/
|
|
141
|
-
inline Index cols() const { return m_pmat.cols();}
|
|
142
|
-
|
|
143
|
-
/** \returns a const reference to the \b sparse upper triangular matrix R of the QR factorization.
|
|
144
|
-
* \warning The entries of the returned matrix are not sorted. This means that using it in algorithms
|
|
145
|
-
* expecting sorted entries will fail. This include random coefficient accesses (SpaseMatrix::coeff()),
|
|
146
|
-
* and coefficient-wise operations. Matrix products and triangular solves are fine though.
|
|
147
|
-
*
|
|
148
|
-
* To sort the entries, you can assign it to a row-major matrix, and if a column-major matrix
|
|
149
|
-
* is required, you can copy it again:
|
|
150
|
-
* \code
|
|
151
|
-
* SparseMatrix<double> R = qr.matrixR(); // column-major, not sorted!
|
|
152
|
-
* SparseMatrix<double,RowMajor> Rr = qr.matrixR(); // row-major, sorted
|
|
153
|
-
* SparseMatrix<double> Rc = Rr; // column-major, sorted
|
|
154
|
-
* \endcode
|
|
155
|
-
*/
|
|
156
|
-
const QRMatrixType& matrixR() const { return m_R; }
|
|
157
|
-
|
|
158
|
-
/** \returns the number of non linearly dependent columns as determined by the pivoting threshold.
|
|
159
|
-
*
|
|
160
|
-
* \sa setPivotThreshold()
|
|
161
|
-
*/
|
|
162
|
-
Index rank() const
|
|
163
|
-
{
|
|
164
|
-
eigen_assert(m_isInitialized && "The factorization should be called first, use compute()");
|
|
165
|
-
return m_nonzeropivots;
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
/** \returns an expression of the matrix Q as products of sparse Householder reflectors.
|
|
169
|
-
* The common usage of this function is to apply it to a dense matrix or vector
|
|
170
|
-
* \code
|
|
171
|
-
* VectorXd B1, B2;
|
|
172
|
-
* // Initialize B1
|
|
173
|
-
* B2 = matrixQ() * B1;
|
|
174
|
-
* \endcode
|
|
175
|
-
*
|
|
176
|
-
* To get a plain SparseMatrix representation of Q:
|
|
177
|
-
* \code
|
|
178
|
-
* SparseMatrix<double> Q;
|
|
179
|
-
* Q = SparseQR<SparseMatrix<double> >(A).matrixQ();
|
|
180
|
-
* \endcode
|
|
181
|
-
* Internally, this call simply performs a sparse product between the matrix Q
|
|
182
|
-
* and a sparse identity matrix. However, due to the fact that the sparse
|
|
183
|
-
* reflectors are stored unsorted, two transpositions are needed to sort
|
|
184
|
-
* them before performing the product.
|
|
185
|
-
*/
|
|
186
|
-
SparseQRMatrixQReturnType<SparseQR> matrixQ() const
|
|
187
|
-
{ return SparseQRMatrixQReturnType<SparseQR>(*this); }
|
|
188
|
-
|
|
189
|
-
/** \returns a const reference to the column permutation P that was applied to A such that A*P = Q*R
|
|
190
|
-
* It is the combination of the fill-in reducing permutation and numerical column pivoting.
|
|
191
|
-
*/
|
|
192
|
-
const PermutationType& colsPermutation() const
|
|
193
|
-
{
|
|
194
|
-
eigen_assert(m_isInitialized && "Decomposition is not initialized.");
|
|
195
|
-
return m_outputPerm_c;
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
/** \returns A string describing the type of error.
|
|
199
|
-
* This method is provided to ease debugging, not to handle errors.
|
|
200
|
-
*/
|
|
201
|
-
std::string lastErrorMessage() const { return m_lastError; }
|
|
202
|
-
|
|
203
|
-
/** \internal */
|
|
204
|
-
template<typename Rhs, typename Dest>
|
|
205
|
-
bool _solve_impl(const MatrixBase<Rhs> &B, MatrixBase<Dest> &dest) const
|
|
206
|
-
{
|
|
207
|
-
eigen_assert(m_isInitialized && "The factorization should be called first, use compute()");
|
|
208
|
-
eigen_assert(this->rows() == B.rows() && "SparseQR::solve() : invalid number of rows in the right hand side matrix");
|
|
209
|
-
|
|
210
|
-
Index rank = this->rank();
|
|
211
|
-
|
|
212
|
-
// Compute Q^* * b;
|
|
213
|
-
typename Dest::PlainObject y, b;
|
|
214
|
-
y = this->matrixQ().adjoint() * B;
|
|
215
|
-
b = y;
|
|
216
|
-
|
|
217
|
-
// Solve with the triangular matrix R
|
|
218
|
-
y.resize((std::max<Index>)(cols(),y.rows()),y.cols());
|
|
219
|
-
y.topRows(rank) = this->matrixR().topLeftCorner(rank, rank).template triangularView<Upper>().solve(b.topRows(rank));
|
|
220
|
-
y.bottomRows(y.rows()-rank).setZero();
|
|
221
|
-
|
|
222
|
-
// Apply the column permutation
|
|
223
|
-
if (m_perm_c.size()) dest = colsPermutation() * y.topRows(cols());
|
|
224
|
-
else dest = y.topRows(cols());
|
|
225
|
-
|
|
226
|
-
m_info = Success;
|
|
227
|
-
return true;
|
|
228
|
-
}
|
|
46
|
+
* \ingroup SparseQR_Module
|
|
47
|
+
* \class SparseQR
|
|
48
|
+
* \brief Sparse left-looking QR factorization with numerical column pivoting
|
|
49
|
+
*
|
|
50
|
+
* This class implements a left-looking QR decomposition of sparse matrices
|
|
51
|
+
* with numerical column pivoting.
|
|
52
|
+
* When a column has a norm less than a given tolerance
|
|
53
|
+
* it is implicitly permuted to the end. The QR factorization thus obtained is
|
|
54
|
+
* given by A*P = Q*R where R is upper triangular or trapezoidal.
|
|
55
|
+
*
|
|
56
|
+
* P is the column permutation which is the product of the fill-reducing and the
|
|
57
|
+
* numerical permutations. Use colsPermutation() to get it.
|
|
58
|
+
*
|
|
59
|
+
* Q is the orthogonal matrix represented as products of Householder reflectors.
|
|
60
|
+
* Use matrixQ() to get an expression and matrixQ().adjoint() to get the adjoint.
|
|
61
|
+
* You can then apply it to a vector.
|
|
62
|
+
*
|
|
63
|
+
* R is the sparse triangular or trapezoidal matrix. The later occurs when A is rank-deficient.
|
|
64
|
+
* matrixR().topLeftCorner(rank(), rank()) always returns a triangular factor of full rank.
|
|
65
|
+
*
|
|
66
|
+
* \tparam MatrixType_ The type of the sparse matrix A, must be a column-major SparseMatrix<>
|
|
67
|
+
* \tparam OrderingType_ The fill-reducing ordering method. See the \link OrderingMethods_Module
|
|
68
|
+
* OrderingMethods \endlink module for the list of built-in and external ordering methods.
|
|
69
|
+
*
|
|
70
|
+
* \implsparsesolverconcept
|
|
71
|
+
*
|
|
72
|
+
* The numerical pivoting strategy and default threshold are the same as in SuiteSparse QR, and
|
|
73
|
+
* detailed in the following paper:
|
|
74
|
+
* <i>
|
|
75
|
+
* Tim Davis, "Algorithm 915, SuiteSparseQR: Multifrontal Multithreaded Rank-Revealing
|
|
76
|
+
* Sparse QR Factorization", ACM Trans. on Math. Soft. 38(1), 2011.
|
|
77
|
+
* </i>
|
|
78
|
+
* Even though it is qualified as "rank-revealing", this strategy might fail for some
|
|
79
|
+
* rank deficient problems. When this class is used to solve linear or least-square problems
|
|
80
|
+
* it is thus strongly recommended to check the accuracy of the computed solution. If it
|
|
81
|
+
* failed, it usually helps to increase the threshold with setPivotThreshold.
|
|
82
|
+
*
|
|
83
|
+
* \warning The input sparse matrix A must be in compressed mode (see SparseMatrix::makeCompressed()).
|
|
84
|
+
* \warning For complex matrices matrixQ().transpose() will actually return the adjoint matrix.
|
|
85
|
+
*
|
|
86
|
+
*/
|
|
87
|
+
template <typename MatrixType_, typename OrderingType_>
|
|
88
|
+
class SparseQR : public SparseSolverBase<SparseQR<MatrixType_, OrderingType_> > {
|
|
89
|
+
protected:
|
|
90
|
+
typedef SparseSolverBase<SparseQR<MatrixType_, OrderingType_> > Base;
|
|
91
|
+
using Base::m_isInitialized;
|
|
92
|
+
|
|
93
|
+
public:
|
|
94
|
+
using Base::_solve_impl;
|
|
95
|
+
typedef MatrixType_ MatrixType;
|
|
96
|
+
typedef OrderingType_ OrderingType;
|
|
97
|
+
typedef typename MatrixType::Scalar Scalar;
|
|
98
|
+
typedef typename MatrixType::RealScalar RealScalar;
|
|
99
|
+
typedef typename MatrixType::StorageIndex StorageIndex;
|
|
100
|
+
typedef SparseMatrix<Scalar, ColMajor, StorageIndex> QRMatrixType;
|
|
101
|
+
typedef Matrix<StorageIndex, Dynamic, 1> IndexVector;
|
|
102
|
+
typedef Matrix<Scalar, Dynamic, 1> ScalarVector;
|
|
103
|
+
typedef PermutationMatrix<Dynamic, Dynamic, StorageIndex> PermutationType;
|
|
104
|
+
|
|
105
|
+
enum { ColsAtCompileTime = MatrixType::ColsAtCompileTime, MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime };
|
|
106
|
+
|
|
107
|
+
public:
|
|
108
|
+
SparseQR()
|
|
109
|
+
: m_analysisIsok(false), m_lastError(""), m_useDefaultThreshold(true), m_isQSorted(false), m_isEtreeOk(false) {}
|
|
110
|
+
|
|
111
|
+
/** Construct a QR factorization of the matrix \a mat.
|
|
112
|
+
*
|
|
113
|
+
* \warning The matrix \a mat must be in compressed mode (see SparseMatrix::makeCompressed()).
|
|
114
|
+
*
|
|
115
|
+
* \sa compute()
|
|
116
|
+
*/
|
|
117
|
+
explicit SparseQR(const MatrixType& mat)
|
|
118
|
+
: m_analysisIsok(false), m_lastError(""), m_useDefaultThreshold(true), m_isQSorted(false), m_isEtreeOk(false) {
|
|
119
|
+
compute(mat);
|
|
120
|
+
}
|
|
229
121
|
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
*
|
|
243
|
-
* \sa compute()
|
|
244
|
-
*/
|
|
245
|
-
template<typename Rhs>
|
|
246
|
-
inline const Solve<SparseQR, Rhs> solve(const MatrixBase<Rhs>& B) const
|
|
247
|
-
{
|
|
248
|
-
eigen_assert(m_isInitialized && "The factorization should be called first, use compute()");
|
|
249
|
-
eigen_assert(this->rows() == B.rows() && "SparseQR::solve() : invalid number of rows in the right hand side matrix");
|
|
250
|
-
return Solve<SparseQR, Rhs>(*this, B.derived());
|
|
251
|
-
}
|
|
252
|
-
template<typename Rhs>
|
|
253
|
-
inline const Solve<SparseQR, Rhs> solve(const SparseMatrixBase<Rhs>& B) const
|
|
254
|
-
{
|
|
255
|
-
eigen_assert(m_isInitialized && "The factorization should be called first, use compute()");
|
|
256
|
-
eigen_assert(this->rows() == B.rows() && "SparseQR::solve() : invalid number of rows in the right hand side matrix");
|
|
257
|
-
return Solve<SparseQR, Rhs>(*this, B.derived());
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
/** \brief Reports whether previous computation was successful.
|
|
261
|
-
*
|
|
262
|
-
* \returns \c Success if computation was successful,
|
|
263
|
-
* \c NumericalIssue if the QR factorization reports a numerical problem
|
|
264
|
-
* \c InvalidInput if the input matrix is invalid
|
|
265
|
-
*
|
|
266
|
-
* \sa iparm()
|
|
267
|
-
*/
|
|
268
|
-
ComputationInfo info() const
|
|
269
|
-
{
|
|
270
|
-
eigen_assert(m_isInitialized && "Decomposition is not initialized.");
|
|
271
|
-
return m_info;
|
|
272
|
-
}
|
|
122
|
+
/** Computes the QR factorization of the sparse matrix \a mat.
|
|
123
|
+
*
|
|
124
|
+
* \warning The matrix \a mat must be in compressed mode (see SparseMatrix::makeCompressed()).
|
|
125
|
+
*
|
|
126
|
+
* \sa analyzePattern(), factorize()
|
|
127
|
+
*/
|
|
128
|
+
void compute(const MatrixType& mat) {
|
|
129
|
+
analyzePattern(mat);
|
|
130
|
+
factorize(mat);
|
|
131
|
+
}
|
|
132
|
+
void analyzePattern(const MatrixType& mat);
|
|
133
|
+
void factorize(const MatrixType& mat);
|
|
273
134
|
|
|
135
|
+
/** \returns the number of rows of the represented matrix.
|
|
136
|
+
*/
|
|
137
|
+
inline Index rows() const { return m_pmat.rows(); }
|
|
274
138
|
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
139
|
+
/** \returns the number of columns of the represented matrix.
|
|
140
|
+
*/
|
|
141
|
+
inline Index cols() const { return m_pmat.cols(); }
|
|
142
|
+
|
|
143
|
+
/** \returns a const reference to the \b sparse upper triangular matrix R of the QR factorization.
|
|
144
|
+
* \warning The entries of the returned matrix are not sorted. This means that using it in algorithms
|
|
145
|
+
* expecting sorted entries will fail. This include random coefficient accesses (SpaseMatrix::coeff()),
|
|
146
|
+
* and coefficient-wise operations. Matrix products and triangular solves are fine though.
|
|
147
|
+
*
|
|
148
|
+
* To sort the entries, you can assign it to a row-major matrix, and if a column-major matrix
|
|
149
|
+
* is required, you can copy it again:
|
|
150
|
+
* \code
|
|
151
|
+
* SparseMatrix<double> R = qr.matrixR(); // column-major, not sorted!
|
|
152
|
+
* SparseMatrix<double,RowMajor> Rr = qr.matrixR(); // row-major, sorted
|
|
153
|
+
* SparseMatrix<double> Rc = Rr; // column-major, sorted
|
|
154
|
+
* \endcode
|
|
155
|
+
*/
|
|
156
|
+
const QRMatrixType& matrixR() const { return m_R; }
|
|
157
|
+
|
|
158
|
+
/** \returns the number of non linearly dependent columns as determined by the pivoting threshold.
|
|
159
|
+
*
|
|
160
|
+
* \sa setPivotThreshold()
|
|
161
|
+
*/
|
|
162
|
+
Index rank() const {
|
|
163
|
+
eigen_assert(m_isInitialized && "The factorization should be called first, use compute()");
|
|
164
|
+
return m_nonzeropivots;
|
|
165
|
+
}
|
|
284
166
|
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
167
|
+
/** \returns an expression of the matrix Q as products of sparse Householder reflectors.
|
|
168
|
+
* The common usage of this function is to apply it to a dense matrix or vector
|
|
169
|
+
* \code
|
|
170
|
+
* VectorXd B1, B2;
|
|
171
|
+
* // Initialize B1
|
|
172
|
+
* B2 = matrixQ() * B1;
|
|
173
|
+
* \endcode
|
|
174
|
+
*
|
|
175
|
+
* To get a plain SparseMatrix representation of Q:
|
|
176
|
+
* \code
|
|
177
|
+
* SparseMatrix<double> Q;
|
|
178
|
+
* Q = SparseQR<SparseMatrix<double> >(A).matrixQ();
|
|
179
|
+
* \endcode
|
|
180
|
+
* Internally, this call simply performs a sparse product between the matrix Q
|
|
181
|
+
* and a sparse identity matrix. However, due to the fact that the sparse
|
|
182
|
+
* reflectors are stored unsorted, two transpositions are needed to sort
|
|
183
|
+
* them before performing the product.
|
|
184
|
+
*/
|
|
185
|
+
SparseQRMatrixQReturnType<SparseQR> matrixQ() const { return SparseQRMatrixQReturnType<SparseQR>(*this); }
|
|
186
|
+
|
|
187
|
+
/** \returns a const reference to the column permutation P that was applied to A such that A*P = Q*R
|
|
188
|
+
* It is the combination of the fill-in reducing permutation and numerical column pivoting.
|
|
189
|
+
*/
|
|
190
|
+
const PermutationType& colsPermutation() const {
|
|
191
|
+
eigen_assert(m_isInitialized && "Decomposition is not initialized.");
|
|
192
|
+
return m_outputPerm_c;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
/** \returns A string describing the type of error.
|
|
196
|
+
* This method is provided to ease debugging, not to handle errors.
|
|
197
|
+
*/
|
|
198
|
+
std::string lastErrorMessage() const { return m_lastError; }
|
|
199
|
+
|
|
200
|
+
/** \internal */
|
|
201
|
+
template <typename Rhs, typename Dest>
|
|
202
|
+
bool _solve_impl(const MatrixBase<Rhs>& B, MatrixBase<Dest>& dest) const {
|
|
203
|
+
eigen_assert(m_isInitialized && "The factorization should be called first, use compute()");
|
|
204
|
+
eigen_assert(this->rows() == B.rows() &&
|
|
205
|
+
"SparseQR::solve() : invalid number of rows in the right hand side matrix");
|
|
206
|
+
|
|
207
|
+
Index rank = this->rank();
|
|
208
|
+
|
|
209
|
+
// Compute Q^* * b;
|
|
210
|
+
typename Dest::PlainObject y, b;
|
|
211
|
+
y = this->matrixQ().adjoint() * B;
|
|
212
|
+
b = y;
|
|
213
|
+
|
|
214
|
+
// Solve with the triangular matrix R
|
|
215
|
+
y.resize((std::max<Index>)(cols(), y.rows()), y.cols());
|
|
216
|
+
y.topRows(rank) = this->matrixR().topLeftCorner(rank, rank).template triangularView<Upper>().solve(b.topRows(rank));
|
|
217
|
+
y.bottomRows(y.rows() - rank).setZero();
|
|
218
|
+
|
|
219
|
+
// Apply the column permutation
|
|
220
|
+
if (m_perm_c.size())
|
|
221
|
+
dest = colsPermutation() * y.topRows(cols());
|
|
222
|
+
else
|
|
223
|
+
dest = y.topRows(cols());
|
|
224
|
+
|
|
225
|
+
m_info = Success;
|
|
226
|
+
return true;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
/** Sets the threshold that is used to determine linearly dependent columns during the factorization.
|
|
230
|
+
*
|
|
231
|
+
* In practice, if during the factorization the norm of the column that has to be eliminated is below
|
|
232
|
+
* this threshold, then the entire column is treated as zero, and it is moved at the end.
|
|
233
|
+
*/
|
|
234
|
+
void setPivotThreshold(const RealScalar& threshold) {
|
|
235
|
+
m_useDefaultThreshold = false;
|
|
236
|
+
m_threshold = threshold;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
/** \returns the solution X of \f$ A X = B \f$ using the current decomposition of A.
|
|
240
|
+
*
|
|
241
|
+
* \sa compute()
|
|
242
|
+
*/
|
|
243
|
+
template <typename Rhs>
|
|
244
|
+
inline const Solve<SparseQR, Rhs> solve(const MatrixBase<Rhs>& B) const {
|
|
245
|
+
eigen_assert(m_isInitialized && "The factorization should be called first, use compute()");
|
|
246
|
+
eigen_assert(this->rows() == B.rows() &&
|
|
247
|
+
"SparseQR::solve() : invalid number of rows in the right hand side matrix");
|
|
248
|
+
return Solve<SparseQR, Rhs>(*this, B.derived());
|
|
249
|
+
}
|
|
250
|
+
template <typename Rhs>
|
|
251
|
+
inline const Solve<SparseQR, Rhs> solve(const SparseMatrixBase<Rhs>& B) const {
|
|
252
|
+
eigen_assert(m_isInitialized && "The factorization should be called first, use compute()");
|
|
253
|
+
eigen_assert(this->rows() == B.rows() &&
|
|
254
|
+
"SparseQR::solve() : invalid number of rows in the right hand side matrix");
|
|
255
|
+
return Solve<SparseQR, Rhs>(*this, B.derived());
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
/** \brief Reports whether previous computation was successful.
|
|
259
|
+
*
|
|
260
|
+
* \returns \c Success if computation was successful,
|
|
261
|
+
* \c NumericalIssue if the QR factorization reports a numerical problem
|
|
262
|
+
* \c InvalidInput if the input matrix is invalid
|
|
263
|
+
*
|
|
264
|
+
* \sa iparm()
|
|
265
|
+
*/
|
|
266
|
+
ComputationInfo info() const {
|
|
267
|
+
eigen_assert(m_isInitialized && "Decomposition is not initialized.");
|
|
268
|
+
return m_info;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
/** \internal */
|
|
272
|
+
inline void _sort_matrix_Q() {
|
|
273
|
+
if (this->m_isQSorted) return;
|
|
274
|
+
// The matrix Q is sorted during the transposition
|
|
275
|
+
SparseMatrix<Scalar, RowMajor, Index> mQrm(this->m_Q);
|
|
276
|
+
this->m_Q = mQrm;
|
|
277
|
+
this->m_isQSorted = true;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
protected:
|
|
281
|
+
bool m_analysisIsok;
|
|
282
|
+
bool m_factorizationIsok;
|
|
283
|
+
mutable ComputationInfo m_info;
|
|
284
|
+
std::string m_lastError;
|
|
285
|
+
QRMatrixType m_pmat; // Temporary matrix
|
|
286
|
+
QRMatrixType m_R; // The triangular factor matrix
|
|
287
|
+
QRMatrixType m_Q; // The orthogonal reflectors
|
|
288
|
+
ScalarVector m_hcoeffs; // The Householder coefficients
|
|
289
|
+
PermutationType m_perm_c; // Fill-reducing Column permutation
|
|
290
|
+
PermutationType m_pivotperm; // The permutation for rank revealing
|
|
291
|
+
PermutationType m_outputPerm_c; // The final column permutation
|
|
292
|
+
RealScalar m_threshold; // Threshold to determine null Householder reflections
|
|
293
|
+
bool m_useDefaultThreshold; // Use default threshold
|
|
294
|
+
Index m_nonzeropivots; // Number of non zero pivots found
|
|
295
|
+
IndexVector m_etree; // Column elimination tree
|
|
296
|
+
IndexVector m_firstRowElt; // First element in each row
|
|
297
|
+
bool m_isQSorted; // whether Q is sorted or not
|
|
298
|
+
bool m_isEtreeOk; // whether the elimination tree match the initial input matrix
|
|
299
|
+
|
|
300
|
+
template <typename, typename>
|
|
301
|
+
friend struct SparseQR_QProduct;
|
|
308
302
|
};
|
|
309
303
|
|
|
310
|
-
/** \brief Preprocessing step of a QR factorization
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
304
|
+
/** \brief Preprocessing step of a QR factorization
|
|
305
|
+
*
|
|
306
|
+
* \warning The matrix \a mat must be in compressed mode (see SparseMatrix::makeCompressed()).
|
|
307
|
+
*
|
|
308
|
+
* In this step, the fill-reducing permutation is computed and applied to the columns of A
|
|
309
|
+
* and the column elimination tree is computed as well. Only the sparsity pattern of \a mat is exploited.
|
|
310
|
+
*
|
|
311
|
+
* \note In this step it is assumed that there is no empty row in the matrix \a mat.
|
|
312
|
+
*/
|
|
319
313
|
template <typename MatrixType, typename OrderingType>
|
|
320
|
-
void SparseQR<MatrixType,OrderingType>::analyzePattern(const MatrixType& mat)
|
|
321
|
-
|
|
322
|
-
|
|
314
|
+
void SparseQR<MatrixType, OrderingType>::analyzePattern(const MatrixType& mat) {
|
|
315
|
+
eigen_assert(
|
|
316
|
+
mat.isCompressed() &&
|
|
317
|
+
"SparseQR requires a sparse matrix in compressed mode. Call .makeCompressed() before passing it to SparseQR");
|
|
323
318
|
// Copy to a column major matrix if the input is rowmajor
|
|
324
|
-
|
|
319
|
+
std::conditional_t<MatrixType::IsRowMajor, QRMatrixType, const MatrixType&> matCpy(mat);
|
|
325
320
|
// Compute the column fill reducing ordering
|
|
326
|
-
OrderingType ord;
|
|
327
|
-
ord(matCpy, m_perm_c);
|
|
321
|
+
OrderingType ord;
|
|
322
|
+
ord(matCpy, m_perm_c);
|
|
328
323
|
Index n = mat.cols();
|
|
329
324
|
Index m = mat.rows();
|
|
330
|
-
Index diagSize = (std::min)(m,n);
|
|
331
|
-
|
|
332
|
-
if (!m_perm_c.size())
|
|
333
|
-
{
|
|
325
|
+
Index diagSize = (std::min)(m, n);
|
|
326
|
+
|
|
327
|
+
if (!m_perm_c.size()) {
|
|
334
328
|
m_perm_c.resize(n);
|
|
335
|
-
m_perm_c.indices().setLinSpaced(n, 0,StorageIndex(n-1));
|
|
329
|
+
m_perm_c.indices().setLinSpaced(n, 0, StorageIndex(n - 1));
|
|
336
330
|
}
|
|
337
|
-
|
|
331
|
+
|
|
338
332
|
// Compute the column elimination tree of the permuted matrix
|
|
339
333
|
m_outputPerm_c = m_perm_c.inverse();
|
|
340
334
|
internal::coletree(matCpy, m_etree, m_firstRowElt, m_outputPerm_c.indices().data());
|
|
341
335
|
m_isEtreeOk = true;
|
|
342
|
-
|
|
336
|
+
|
|
343
337
|
m_R.resize(m, n);
|
|
344
338
|
m_Q.resize(m, diagSize);
|
|
345
|
-
|
|
339
|
+
|
|
346
340
|
// Allocate space for nonzero elements: rough estimation
|
|
347
|
-
m_R.reserve(2*mat.nonZeros());
|
|
348
|
-
|
|
341
|
+
m_R.reserve(2 * mat.nonZeros()); // FIXME Get a more accurate estimation through symbolic factorization with the
|
|
342
|
+
// etree
|
|
343
|
+
m_Q.reserve(2 * mat.nonZeros());
|
|
349
344
|
m_hcoeffs.resize(diagSize);
|
|
350
345
|
m_analysisIsok = true;
|
|
351
346
|
}
|
|
352
347
|
|
|
353
348
|
/** \brief Performs the numerical QR factorization of the input matrix
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
349
|
+
*
|
|
350
|
+
* The function SparseQR::analyzePattern(const MatrixType&) must have been called beforehand with
|
|
351
|
+
* a matrix having the same sparsity pattern than \a mat.
|
|
352
|
+
*
|
|
353
|
+
* \param mat The sparse column-major matrix
|
|
354
|
+
*/
|
|
360
355
|
template <typename MatrixType, typename OrderingType>
|
|
361
|
-
void SparseQR<MatrixType,OrderingType>::factorize(const MatrixType& mat)
|
|
362
|
-
{
|
|
356
|
+
void SparseQR<MatrixType, OrderingType>::factorize(const MatrixType& mat) {
|
|
363
357
|
using std::abs;
|
|
364
|
-
|
|
358
|
+
|
|
365
359
|
eigen_assert(m_analysisIsok && "analyzePattern() should be called before this step");
|
|
366
360
|
StorageIndex m = StorageIndex(mat.rows());
|
|
367
361
|
StorageIndex n = StorageIndex(mat.cols());
|
|
368
|
-
StorageIndex diagSize = (std::min)(m,n);
|
|
369
|
-
IndexVector mark((std::max)(m,n));
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
362
|
+
StorageIndex diagSize = (std::min)(m, n);
|
|
363
|
+
IndexVector mark((std::max)(m, n));
|
|
364
|
+
mark.setConstant(-1); // Record the visited nodes
|
|
365
|
+
IndexVector Ridx(n), Qidx(m); // Store temporarily the row indexes for the current column of R and Q
|
|
366
|
+
Index nzcolR, nzcolQ; // Number of nonzero for the current column of R and Q
|
|
367
|
+
ScalarVector tval(m); // The dense vector used to compute the current column
|
|
368
|
+
|
|
375
369
|
m_R.setZero();
|
|
376
370
|
m_Q.setZero();
|
|
377
371
|
m_pmat = mat;
|
|
378
|
-
if(!m_isEtreeOk)
|
|
379
|
-
{
|
|
372
|
+
if (!m_isEtreeOk) {
|
|
380
373
|
m_outputPerm_c = m_perm_c.inverse();
|
|
381
374
|
internal::coletree(m_pmat, m_etree, m_firstRowElt, m_outputPerm_c.indices().data());
|
|
382
375
|
m_isEtreeOk = true;
|
|
383
376
|
}
|
|
384
377
|
|
|
385
|
-
m_pmat.uncompress();
|
|
386
|
-
|
|
378
|
+
m_pmat.uncompress(); // To have the innerNonZeroPtr allocated
|
|
379
|
+
|
|
387
380
|
// Apply the fill-in reducing permutation lazily:
|
|
388
381
|
{
|
|
389
382
|
// If the input is row major, copy the original column indices,
|
|
390
383
|
// otherwise directly use the input matrix
|
|
391
|
-
//
|
|
384
|
+
//
|
|
392
385
|
IndexVector originalOuterIndicesCpy;
|
|
393
|
-
const StorageIndex
|
|
394
|
-
if(MatrixType::IsRowMajor)
|
|
395
|
-
|
|
396
|
-
originalOuterIndicesCpy = IndexVector::Map(m_pmat.outerIndexPtr(),n+1);
|
|
386
|
+
const StorageIndex* originalOuterIndices = mat.outerIndexPtr();
|
|
387
|
+
if (MatrixType::IsRowMajor) {
|
|
388
|
+
originalOuterIndicesCpy = IndexVector::Map(m_pmat.outerIndexPtr(), n + 1);
|
|
397
389
|
originalOuterIndices = originalOuterIndicesCpy.data();
|
|
398
390
|
}
|
|
399
|
-
|
|
400
|
-
for (int i = 0; i < n; i++)
|
|
401
|
-
{
|
|
391
|
+
|
|
392
|
+
for (int i = 0; i < n; i++) {
|
|
402
393
|
Index p = m_perm_c.size() ? m_perm_c.indices()(i) : i;
|
|
403
|
-
m_pmat.outerIndexPtr()[p] = originalOuterIndices[i];
|
|
404
|
-
m_pmat.innerNonZeroPtr()[p] = originalOuterIndices[i+1] - originalOuterIndices[i];
|
|
394
|
+
m_pmat.outerIndexPtr()[p] = originalOuterIndices[i];
|
|
395
|
+
m_pmat.innerNonZeroPtr()[p] = originalOuterIndices[i + 1] - originalOuterIndices[i];
|
|
405
396
|
}
|
|
406
397
|
}
|
|
407
|
-
|
|
398
|
+
|
|
408
399
|
/* Compute the default threshold as in MatLab, see:
|
|
409
400
|
* Tim Davis, "Algorithm 915, SuiteSparseQR: Multifrontal Multithreaded Rank-Revealing
|
|
410
|
-
* Sparse QR Factorization, ACM Trans. on Math. Soft. 38(1), 2011, Page 8:3
|
|
401
|
+
* Sparse QR Factorization, ACM Trans. on Math. Soft. 38(1), 2011, Page 8:3
|
|
411
402
|
*/
|
|
412
|
-
|
|
413
|
-
{
|
|
403
|
+
RealScalar pivotThreshold;
|
|
404
|
+
if (m_useDefaultThreshold) {
|
|
414
405
|
RealScalar max2Norm = 0.0;
|
|
415
406
|
for (int j = 0; j < n; j++) max2Norm = numext::maxi(max2Norm, m_pmat.col(j).norm());
|
|
416
|
-
if(max2Norm==RealScalar(0))
|
|
417
|
-
max2Norm = RealScalar(1);
|
|
407
|
+
if (max2Norm == RealScalar(0)) max2Norm = RealScalar(1);
|
|
418
408
|
pivotThreshold = 20 * (m + n) * max2Norm * NumTraits<RealScalar>::epsilon();
|
|
409
|
+
} else {
|
|
410
|
+
pivotThreshold = m_threshold;
|
|
419
411
|
}
|
|
420
|
-
|
|
412
|
+
|
|
421
413
|
// Initialize the numerical permutation
|
|
422
414
|
m_pivotperm.setIdentity(n);
|
|
423
|
-
|
|
424
|
-
StorageIndex nonzeroCol = 0;
|
|
415
|
+
|
|
416
|
+
StorageIndex nonzeroCol = 0; // Record the number of valid pivots
|
|
425
417
|
m_Q.startVec(0);
|
|
426
418
|
|
|
427
419
|
// Left looking rank-revealing QR factorization: compute a column of R and Q at a time
|
|
428
|
-
for (StorageIndex col = 0; col < n; ++col)
|
|
429
|
-
{
|
|
420
|
+
for (StorageIndex col = 0; col < n; ++col) {
|
|
430
421
|
mark.setConstant(-1);
|
|
431
422
|
m_R.startVec(col);
|
|
432
423
|
mark(nonzeroCol) = col;
|
|
433
424
|
Qidx(0) = nonzeroCol;
|
|
434
|
-
nzcolR = 0;
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
425
|
+
nzcolR = 0;
|
|
426
|
+
nzcolQ = 1;
|
|
427
|
+
bool found_diag = nonzeroCol >= m;
|
|
428
|
+
tval.setZero();
|
|
429
|
+
|
|
438
430
|
// Symbolic factorization: find the nonzero locations of the column k of the factors R and Q, i.e.,
|
|
439
|
-
// all the nodes (with indexes lower than rank) reachable through the column elimination tree (etree) rooted at node
|
|
440
|
-
// Note: if the diagonal entry does not exist, then its contribution must be explicitly added,
|
|
441
|
-
//
|
|
442
|
-
for (typename QRMatrixType::InnerIterator itp(m_pmat, col); itp || !found_diag; ++itp)
|
|
443
|
-
{
|
|
431
|
+
// all the nodes (with indexes lower than rank) reachable through the column elimination tree (etree) rooted at node
|
|
432
|
+
// k. Note: if the diagonal entry does not exist, then its contribution must be explicitly added, thus the trick
|
|
433
|
+
// with found_diag that permits to do one more iteration on the diagonal element if this one has not been found.
|
|
434
|
+
for (typename QRMatrixType::InnerIterator itp(m_pmat, col); itp || !found_diag; ++itp) {
|
|
444
435
|
StorageIndex curIdx = nonzeroCol;
|
|
445
|
-
if(itp) curIdx = StorageIndex(itp.row());
|
|
446
|
-
if(curIdx == nonzeroCol) found_diag = true;
|
|
447
|
-
|
|
436
|
+
if (itp) curIdx = StorageIndex(itp.row());
|
|
437
|
+
if (curIdx == nonzeroCol) found_diag = true;
|
|
438
|
+
|
|
448
439
|
// Get the nonzeros indexes of the current column of R
|
|
449
|
-
StorageIndex st = m_firstRowElt(curIdx);
|
|
450
|
-
if (st < 0
|
|
451
|
-
{
|
|
440
|
+
StorageIndex st = m_firstRowElt(curIdx); // The traversal of the etree starts here
|
|
441
|
+
if (st < 0) {
|
|
452
442
|
m_lastError = "Empty row found during numerical factorization";
|
|
453
443
|
m_info = InvalidInput;
|
|
454
444
|
return;
|
|
455
445
|
}
|
|
456
446
|
|
|
457
|
-
// Traverse the etree
|
|
447
|
+
// Traverse the etree
|
|
458
448
|
Index bi = nzcolR;
|
|
459
|
-
for (; mark(st) != col; st = m_etree(st))
|
|
460
|
-
{
|
|
449
|
+
for (; mark(st) != col; st = m_etree(st)) {
|
|
461
450
|
Ridx(nzcolR) = st; // Add this row to the list,
|
|
462
451
|
mark(st) = col; // and mark this row as visited
|
|
463
452
|
nzcolR++;
|
|
464
453
|
}
|
|
465
454
|
|
|
466
455
|
// Reverse the list to get the topological ordering
|
|
467
|
-
Index nt = nzcolR-bi;
|
|
468
|
-
for(Index i = 0; i < nt/2; i++) std::swap(Ridx(bi+i), Ridx(nzcolR-i-1));
|
|
469
|
-
|
|
456
|
+
Index nt = nzcolR - bi;
|
|
457
|
+
for (Index i = 0; i < nt / 2; i++) std::swap(Ridx(bi + i), Ridx(nzcolR - i - 1));
|
|
458
|
+
|
|
470
459
|
// Copy the current (curIdx,pcol) value of the input matrix
|
|
471
|
-
if
|
|
472
|
-
|
|
473
|
-
|
|
460
|
+
if (itp)
|
|
461
|
+
tval(curIdx) = itp.value();
|
|
462
|
+
else
|
|
463
|
+
tval(curIdx) = Scalar(0);
|
|
464
|
+
|
|
474
465
|
// Compute the pattern of Q(:,k)
|
|
475
|
-
if(curIdx > nonzeroCol && mark(curIdx) != col
|
|
476
|
-
{
|
|
466
|
+
if (curIdx > nonzeroCol && mark(curIdx) != col) {
|
|
477
467
|
Qidx(nzcolQ) = curIdx; // Add this row to the pattern of Q,
|
|
478
468
|
mark(curIdx) = col; // and mark it as visited
|
|
479
469
|
nzcolQ++;
|
|
@@ -481,110 +471,89 @@ void SparseQR<MatrixType,OrderingType>::factorize(const MatrixType& mat)
|
|
|
481
471
|
}
|
|
482
472
|
|
|
483
473
|
// Browse all the indexes of R(:,col) in reverse order
|
|
484
|
-
for (Index i = nzcolR-1; i >= 0; i--)
|
|
485
|
-
{
|
|
474
|
+
for (Index i = nzcolR - 1; i >= 0; i--) {
|
|
486
475
|
Index curIdx = Ridx(i);
|
|
487
|
-
|
|
476
|
+
|
|
488
477
|
// Apply the curIdx-th householder vector to the current column (temporarily stored into tval)
|
|
489
478
|
Scalar tdot(0);
|
|
490
|
-
|
|
479
|
+
|
|
491
480
|
// First compute q' * tval
|
|
492
481
|
tdot = m_Q.col(curIdx).dot(tval);
|
|
493
482
|
|
|
494
483
|
tdot *= m_hcoeffs(curIdx);
|
|
495
|
-
|
|
484
|
+
|
|
496
485
|
// Then update tval = tval - q * tau
|
|
497
|
-
|
|
498
|
-
for (typename QRMatrixType::InnerIterator itq(m_Q, curIdx); itq; ++itq)
|
|
499
|
-
tval(itq.row()) -= itq.value() * tdot;
|
|
486
|
+
tval -= tdot * m_Q.col(curIdx);
|
|
500
487
|
|
|
501
488
|
// Detect fill-in for the current column of Q
|
|
502
|
-
if(m_etree(Ridx(i)) == nonzeroCol)
|
|
503
|
-
|
|
504
|
-
for (typename QRMatrixType::InnerIterator itq(m_Q, curIdx); itq; ++itq)
|
|
505
|
-
{
|
|
489
|
+
if (m_etree(Ridx(i)) == nonzeroCol) {
|
|
490
|
+
for (typename QRMatrixType::InnerIterator itq(m_Q, curIdx); itq; ++itq) {
|
|
506
491
|
StorageIndex iQ = StorageIndex(itq.row());
|
|
507
|
-
if (mark(iQ) != col)
|
|
508
|
-
{
|
|
492
|
+
if (mark(iQ) != col) {
|
|
509
493
|
Qidx(nzcolQ++) = iQ; // Add this row to the pattern of Q,
|
|
510
494
|
mark(iQ) = col; // and mark it as visited
|
|
511
495
|
}
|
|
512
496
|
}
|
|
513
497
|
}
|
|
514
|
-
}
|
|
515
|
-
|
|
498
|
+
} // End update current column
|
|
499
|
+
|
|
516
500
|
Scalar tau = RealScalar(0);
|
|
517
501
|
RealScalar beta = 0;
|
|
518
|
-
|
|
519
|
-
if(nonzeroCol < diagSize)
|
|
520
|
-
{
|
|
502
|
+
|
|
503
|
+
if (nonzeroCol < diagSize) {
|
|
521
504
|
// Compute the Householder reflection that eliminate the current column
|
|
522
505
|
// FIXME this step should call the Householder module.
|
|
523
506
|
Scalar c0 = nzcolQ ? tval(Qidx(0)) : Scalar(0);
|
|
524
|
-
|
|
507
|
+
|
|
525
508
|
// First, the squared norm of Q((col+1):m, col)
|
|
526
509
|
RealScalar sqrNorm = 0.;
|
|
527
510
|
for (Index itq = 1; itq < nzcolQ; ++itq) sqrNorm += numext::abs2(tval(Qidx(itq)));
|
|
528
|
-
if(sqrNorm == RealScalar(0) && numext::imag(c0) == RealScalar(0))
|
|
529
|
-
{
|
|
511
|
+
if (sqrNorm == RealScalar(0) && numext::imag(c0) == RealScalar(0)) {
|
|
530
512
|
beta = numext::real(c0);
|
|
531
513
|
tval(Qidx(0)) = 1;
|
|
532
|
-
}
|
|
533
|
-
else
|
|
534
|
-
{
|
|
514
|
+
} else {
|
|
535
515
|
using std::sqrt;
|
|
536
516
|
beta = sqrt(numext::abs2(c0) + sqrNorm);
|
|
537
|
-
if(numext::real(c0) >= RealScalar(0))
|
|
538
|
-
beta = -beta;
|
|
517
|
+
if (numext::real(c0) >= RealScalar(0)) beta = -beta;
|
|
539
518
|
tval(Qidx(0)) = 1;
|
|
540
|
-
for (Index itq = 1; itq < nzcolQ; ++itq)
|
|
541
|
-
|
|
542
|
-
tau = numext::conj((beta-c0) / beta);
|
|
543
|
-
|
|
519
|
+
for (Index itq = 1; itq < nzcolQ; ++itq) tval(Qidx(itq)) /= (c0 - beta);
|
|
520
|
+
tau = numext::conj((beta - c0) / beta);
|
|
544
521
|
}
|
|
545
522
|
}
|
|
546
523
|
|
|
547
524
|
// Insert values in R
|
|
548
|
-
for (Index
|
|
549
|
-
{
|
|
525
|
+
for (Index i = nzcolR - 1; i >= 0; i--) {
|
|
550
526
|
Index curIdx = Ridx(i);
|
|
551
|
-
if(curIdx < nonzeroCol)
|
|
552
|
-
{
|
|
527
|
+
if (curIdx < nonzeroCol) {
|
|
553
528
|
m_R.insertBackByOuterInnerUnordered(col, curIdx) = tval(curIdx);
|
|
554
529
|
tval(curIdx) = Scalar(0.);
|
|
555
530
|
}
|
|
556
531
|
}
|
|
557
532
|
|
|
558
|
-
if(nonzeroCol < diagSize && abs(beta) >= pivotThreshold)
|
|
559
|
-
{
|
|
533
|
+
if (nonzeroCol < diagSize && abs(beta) >= pivotThreshold) {
|
|
560
534
|
m_R.insertBackByOuterInner(col, nonzeroCol) = beta;
|
|
561
535
|
// The householder coefficient
|
|
562
536
|
m_hcoeffs(nonzeroCol) = tau;
|
|
563
537
|
// Record the householder reflections
|
|
564
|
-
for (Index itq = 0; itq < nzcolQ; ++itq)
|
|
565
|
-
{
|
|
538
|
+
for (Index itq = 0; itq < nzcolQ; ++itq) {
|
|
566
539
|
Index iQ = Qidx(itq);
|
|
567
|
-
m_Q.insertBackByOuterInnerUnordered(nonzeroCol,iQ) = tval(iQ);
|
|
540
|
+
m_Q.insertBackByOuterInnerUnordered(nonzeroCol, iQ) = tval(iQ);
|
|
568
541
|
tval(iQ) = Scalar(0.);
|
|
569
542
|
}
|
|
570
543
|
nonzeroCol++;
|
|
571
|
-
if(nonzeroCol<diagSize)
|
|
572
|
-
|
|
573
|
-
}
|
|
574
|
-
else
|
|
575
|
-
{
|
|
544
|
+
if (nonzeroCol < diagSize) m_Q.startVec(nonzeroCol);
|
|
545
|
+
} else {
|
|
576
546
|
// Zero pivot found: move implicitly this column to the end
|
|
577
|
-
for (Index j = nonzeroCol; j < n-1; j++)
|
|
578
|
-
|
|
579
|
-
|
|
547
|
+
for (Index j = nonzeroCol; j < n - 1; j++) std::swap(m_pivotperm.indices()(j), m_pivotperm.indices()[j + 1]);
|
|
548
|
+
|
|
580
549
|
// Recompute the column elimination tree
|
|
581
550
|
internal::coletree(m_pmat, m_etree, m_firstRowElt, m_pivotperm.indices().data());
|
|
582
551
|
m_isEtreeOk = false;
|
|
583
552
|
}
|
|
584
553
|
}
|
|
585
|
-
|
|
586
|
-
m_hcoeffs.tail(diagSize-nonzeroCol).setZero();
|
|
587
|
-
|
|
554
|
+
|
|
555
|
+
m_hcoeffs.tail(diagSize - nonzeroCol).setZero();
|
|
556
|
+
|
|
588
557
|
// Finalize the column pointers of the sparse matrices R and Q
|
|
589
558
|
m_Q.finalize();
|
|
590
559
|
m_Q.makeCompressed();
|
|
@@ -593,166 +562,145 @@ void SparseQR<MatrixType,OrderingType>::factorize(const MatrixType& mat)
|
|
|
593
562
|
m_isQSorted = false;
|
|
594
563
|
|
|
595
564
|
m_nonzeropivots = nonzeroCol;
|
|
596
|
-
|
|
597
|
-
if(nonzeroCol<n)
|
|
598
|
-
{
|
|
565
|
+
|
|
566
|
+
if (nonzeroCol < n) {
|
|
599
567
|
// Permute the triangular factor to put the 'dead' columns to the end
|
|
600
568
|
QRMatrixType tempR(m_R);
|
|
601
569
|
m_R = tempR * m_pivotperm;
|
|
602
|
-
|
|
570
|
+
|
|
603
571
|
// Update the column permutation
|
|
604
572
|
m_outputPerm_c = m_outputPerm_c * m_pivotperm;
|
|
605
573
|
}
|
|
606
|
-
|
|
607
|
-
m_isInitialized = true;
|
|
574
|
+
|
|
575
|
+
m_isInitialized = true;
|
|
608
576
|
m_factorizationIsok = true;
|
|
609
577
|
m_info = Success;
|
|
610
578
|
}
|
|
611
579
|
|
|
612
580
|
template <typename SparseQRType, typename Derived>
|
|
613
|
-
struct SparseQR_QProduct : ReturnByValue<SparseQR_QProduct<SparseQRType, Derived> >
|
|
614
|
-
{
|
|
581
|
+
struct SparseQR_QProduct : ReturnByValue<SparseQR_QProduct<SparseQRType, Derived> > {
|
|
615
582
|
typedef typename SparseQRType::QRMatrixType MatrixType;
|
|
616
583
|
typedef typename SparseQRType::Scalar Scalar;
|
|
617
|
-
// Get the references
|
|
618
|
-
SparseQR_QProduct(const SparseQRType& qr, const Derived& other, bool transpose)
|
|
619
|
-
|
|
584
|
+
// Get the references
|
|
585
|
+
SparseQR_QProduct(const SparseQRType& qr, const Derived& other, bool transpose)
|
|
586
|
+
: m_qr(qr), m_other(other), m_transpose(transpose) {}
|
|
620
587
|
inline Index rows() const { return m_qr.matrixQ().rows(); }
|
|
621
588
|
inline Index cols() const { return m_other.cols(); }
|
|
622
|
-
|
|
589
|
+
|
|
623
590
|
// Assign to a vector
|
|
624
|
-
template<typename DesType>
|
|
625
|
-
void evalTo(DesType& res) const
|
|
626
|
-
{
|
|
591
|
+
template <typename DesType>
|
|
592
|
+
void evalTo(DesType& res) const {
|
|
627
593
|
Index m = m_qr.rows();
|
|
628
594
|
Index n = m_qr.cols();
|
|
629
|
-
Index diagSize = (std::min)(m,n);
|
|
595
|
+
Index diagSize = (std::min)(m, n);
|
|
630
596
|
res = m_other;
|
|
631
|
-
if (m_transpose)
|
|
632
|
-
{
|
|
597
|
+
if (m_transpose) {
|
|
633
598
|
eigen_assert(m_qr.m_Q.rows() == m_other.rows() && "Non conforming object sizes");
|
|
634
|
-
//Compute res = Q' * other column by column
|
|
635
|
-
for(Index j = 0; j < res.cols(); j++){
|
|
636
|
-
for (Index k = 0; k < diagSize; k++)
|
|
637
|
-
{
|
|
599
|
+
// Compute res = Q' * other column by column
|
|
600
|
+
for (Index j = 0; j < res.cols(); j++) {
|
|
601
|
+
for (Index k = 0; k < diagSize; k++) {
|
|
638
602
|
Scalar tau = Scalar(0);
|
|
639
603
|
tau = m_qr.m_Q.col(k).dot(res.col(j));
|
|
640
|
-
if(tau==Scalar(0)) continue;
|
|
604
|
+
if (tau == Scalar(0)) continue;
|
|
641
605
|
tau = tau * m_qr.m_hcoeffs(k);
|
|
642
606
|
res.col(j) -= tau * m_qr.m_Q.col(k);
|
|
643
607
|
}
|
|
644
608
|
}
|
|
645
|
-
}
|
|
646
|
-
else
|
|
647
|
-
{
|
|
609
|
+
} else {
|
|
648
610
|
eigen_assert(m_qr.matrixQ().cols() == m_other.rows() && "Non conforming object sizes");
|
|
649
611
|
|
|
650
612
|
res.conservativeResize(rows(), cols());
|
|
651
613
|
|
|
652
614
|
// Compute res = Q * other column by column
|
|
653
|
-
for(Index j = 0; j < res.cols(); j++)
|
|
654
|
-
|
|
655
|
-
Index
|
|
656
|
-
for (Index k = start_k; k >=0; k--)
|
|
657
|
-
{
|
|
615
|
+
for (Index j = 0; j < res.cols(); j++) {
|
|
616
|
+
Index start_k = internal::is_identity<Derived>::value ? numext::mini(j, diagSize - 1) : diagSize - 1;
|
|
617
|
+
for (Index k = start_k; k >= 0; k--) {
|
|
658
618
|
Scalar tau = Scalar(0);
|
|
659
619
|
tau = m_qr.m_Q.col(k).dot(res.col(j));
|
|
660
|
-
if(tau==Scalar(0)) continue;
|
|
620
|
+
if (tau == Scalar(0)) continue;
|
|
661
621
|
tau = tau * numext::conj(m_qr.m_hcoeffs(k));
|
|
662
622
|
res.col(j) -= tau * m_qr.m_Q.col(k);
|
|
663
623
|
}
|
|
664
624
|
}
|
|
665
625
|
}
|
|
666
626
|
}
|
|
667
|
-
|
|
627
|
+
|
|
668
628
|
const SparseQRType& m_qr;
|
|
669
629
|
const Derived& m_other;
|
|
670
|
-
bool m_transpose;
|
|
630
|
+
bool m_transpose; // TODO this actually means adjoint
|
|
671
631
|
};
|
|
672
632
|
|
|
673
|
-
template<typename SparseQRType>
|
|
674
|
-
struct SparseQRMatrixQReturnType : public EigenBase<SparseQRMatrixQReturnType<SparseQRType> >
|
|
675
|
-
{
|
|
633
|
+
template <typename SparseQRType>
|
|
634
|
+
struct SparseQRMatrixQReturnType : public EigenBase<SparseQRMatrixQReturnType<SparseQRType> > {
|
|
676
635
|
typedef typename SparseQRType::Scalar Scalar;
|
|
677
|
-
typedef Matrix<Scalar,Dynamic,Dynamic> DenseMatrix;
|
|
678
|
-
enum {
|
|
679
|
-
RowsAtCompileTime = Dynamic,
|
|
680
|
-
ColsAtCompileTime = Dynamic
|
|
681
|
-
};
|
|
636
|
+
typedef Matrix<Scalar, Dynamic, Dynamic> DenseMatrix;
|
|
637
|
+
enum { RowsAtCompileTime = Dynamic, ColsAtCompileTime = Dynamic };
|
|
682
638
|
explicit SparseQRMatrixQReturnType(const SparseQRType& qr) : m_qr(qr) {}
|
|
683
|
-
template<typename Derived>
|
|
684
|
-
SparseQR_QProduct<SparseQRType, Derived> operator*(const MatrixBase<Derived>& other)
|
|
685
|
-
|
|
686
|
-
return SparseQR_QProduct<SparseQRType,Derived>(m_qr,other.derived(),false);
|
|
639
|
+
template <typename Derived>
|
|
640
|
+
SparseQR_QProduct<SparseQRType, Derived> operator*(const MatrixBase<Derived>& other) {
|
|
641
|
+
return SparseQR_QProduct<SparseQRType, Derived>(m_qr, other.derived(), false);
|
|
687
642
|
}
|
|
688
643
|
// To use for operations with the adjoint of Q
|
|
689
|
-
SparseQRMatrixQTransposeReturnType<SparseQRType> adjoint() const
|
|
690
|
-
{
|
|
644
|
+
SparseQRMatrixQTransposeReturnType<SparseQRType> adjoint() const {
|
|
691
645
|
return SparseQRMatrixQTransposeReturnType<SparseQRType>(m_qr);
|
|
692
646
|
}
|
|
693
647
|
inline Index rows() const { return m_qr.rows(); }
|
|
694
648
|
inline Index cols() const { return m_qr.rows(); }
|
|
695
649
|
// To use for operations with the transpose of Q FIXME this is the same as adjoint at the moment
|
|
696
|
-
SparseQRMatrixQTransposeReturnType<SparseQRType> transpose() const
|
|
697
|
-
{
|
|
650
|
+
SparseQRMatrixQTransposeReturnType<SparseQRType> transpose() const {
|
|
698
651
|
return SparseQRMatrixQTransposeReturnType<SparseQRType>(m_qr);
|
|
699
652
|
}
|
|
700
653
|
const SparseQRType& m_qr;
|
|
701
654
|
};
|
|
702
655
|
|
|
703
656
|
// TODO this actually represents the adjoint of Q
|
|
704
|
-
template<typename SparseQRType>
|
|
705
|
-
struct SparseQRMatrixQTransposeReturnType
|
|
706
|
-
{
|
|
657
|
+
template <typename SparseQRType>
|
|
658
|
+
struct SparseQRMatrixQTransposeReturnType {
|
|
707
659
|
explicit SparseQRMatrixQTransposeReturnType(const SparseQRType& qr) : m_qr(qr) {}
|
|
708
|
-
template<typename Derived>
|
|
709
|
-
SparseQR_QProduct<SparseQRType,Derived> operator*(const MatrixBase<Derived>& other)
|
|
710
|
-
|
|
711
|
-
return SparseQR_QProduct<SparseQRType,Derived>(m_qr,other.derived(), true);
|
|
660
|
+
template <typename Derived>
|
|
661
|
+
SparseQR_QProduct<SparseQRType, Derived> operator*(const MatrixBase<Derived>& other) {
|
|
662
|
+
return SparseQR_QProduct<SparseQRType, Derived>(m_qr, other.derived(), true);
|
|
712
663
|
}
|
|
713
664
|
const SparseQRType& m_qr;
|
|
714
665
|
};
|
|
715
666
|
|
|
716
667
|
namespace internal {
|
|
717
|
-
|
|
718
|
-
template<typename SparseQRType>
|
|
719
|
-
struct evaluator_traits<SparseQRMatrixQReturnType<SparseQRType> >
|
|
720
|
-
{
|
|
668
|
+
|
|
669
|
+
template <typename SparseQRType>
|
|
670
|
+
struct evaluator_traits<SparseQRMatrixQReturnType<SparseQRType> > {
|
|
721
671
|
typedef typename SparseQRType::MatrixType MatrixType;
|
|
722
672
|
typedef typename storage_kind_to_evaluator_kind<typename MatrixType::StorageKind>::Kind Kind;
|
|
723
673
|
typedef SparseShape Shape;
|
|
724
674
|
};
|
|
725
675
|
|
|
726
|
-
template<
|
|
727
|
-
struct Assignment<DstXprType, SparseQRMatrixQReturnType<SparseQRType>,
|
|
728
|
-
{
|
|
676
|
+
template <typename DstXprType, typename SparseQRType>
|
|
677
|
+
struct Assignment<DstXprType, SparseQRMatrixQReturnType<SparseQRType>,
|
|
678
|
+
internal::assign_op<typename DstXprType::Scalar, typename DstXprType::Scalar>, Sparse2Sparse> {
|
|
729
679
|
typedef SparseQRMatrixQReturnType<SparseQRType> SrcXprType;
|
|
730
680
|
typedef typename DstXprType::Scalar Scalar;
|
|
731
681
|
typedef typename DstXprType::StorageIndex StorageIndex;
|
|
732
|
-
static void run(DstXprType
|
|
733
|
-
{
|
|
682
|
+
static void run(DstXprType& dst, const SrcXprType& src, const internal::assign_op<Scalar, Scalar>& /*func*/) {
|
|
734
683
|
typename DstXprType::PlainObject idMat(src.rows(), src.cols());
|
|
735
684
|
idMat.setIdentity();
|
|
736
685
|
// Sort the sparse householder reflectors if needed
|
|
737
|
-
const_cast<SparseQRType
|
|
686
|
+
const_cast<SparseQRType*>(&src.m_qr)->_sort_matrix_Q();
|
|
738
687
|
dst = SparseQR_QProduct<SparseQRType, DstXprType>(src.m_qr, idMat, false);
|
|
739
688
|
}
|
|
740
689
|
};
|
|
741
690
|
|
|
742
|
-
template<
|
|
743
|
-
struct Assignment<DstXprType, SparseQRMatrixQReturnType<SparseQRType>,
|
|
744
|
-
{
|
|
691
|
+
template <typename DstXprType, typename SparseQRType>
|
|
692
|
+
struct Assignment<DstXprType, SparseQRMatrixQReturnType<SparseQRType>,
|
|
693
|
+
internal::assign_op<typename DstXprType::Scalar, typename DstXprType::Scalar>, Sparse2Dense> {
|
|
745
694
|
typedef SparseQRMatrixQReturnType<SparseQRType> SrcXprType;
|
|
746
695
|
typedef typename DstXprType::Scalar Scalar;
|
|
747
696
|
typedef typename DstXprType::StorageIndex StorageIndex;
|
|
748
|
-
static void run(DstXprType
|
|
749
|
-
{
|
|
697
|
+
static void run(DstXprType& dst, const SrcXprType& src, const internal::assign_op<Scalar, Scalar>& /*func*/) {
|
|
750
698
|
dst = src.m_qr.matrixQ() * DstXprType::Identity(src.m_qr.rows(), src.m_qr.rows());
|
|
751
699
|
}
|
|
752
700
|
};
|
|
753
701
|
|
|
754
|
-
}
|
|
702
|
+
} // end namespace internal
|
|
755
703
|
|
|
756
|
-
}
|
|
704
|
+
} // end namespace Eigen
|
|
757
705
|
|
|
758
706
|
#endif
|