@smake/eigen 1.0.2 → 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 -21
- package/eigen/Eigen/CholmodSupport +28 -28
- package/eigen/Eigen/Core +235 -326
- package/eigen/Eigen/Eigenvalues +16 -14
- package/eigen/Eigen/Geometry +21 -24
- package/eigen/Eigen/Householder +9 -8
- package/eigen/Eigen/IterativeLinearSolvers +8 -4
- package/eigen/Eigen/Jacobi +14 -14
- package/eigen/Eigen/KLUSupport +43 -0
- package/eigen/Eigen/LU +16 -20
- package/eigen/Eigen/MetisSupport +12 -12
- package/eigen/Eigen/OrderingMethods +54 -54
- package/eigen/Eigen/PaStiXSupport +23 -20
- package/eigen/Eigen/PardisoSupport +17 -14
- package/eigen/Eigen/QR +18 -21
- package/eigen/Eigen/QtAlignedMalloc +5 -13
- package/eigen/Eigen/SPQRSupport +21 -14
- package/eigen/Eigen/SVD +23 -18
- package/eigen/Eigen/Sparse +1 -4
- package/eigen/Eigen/SparseCholesky +18 -23
- package/eigen/Eigen/SparseCore +18 -17
- package/eigen/Eigen/SparseLU +12 -8
- 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 +377 -401
- package/eigen/Eigen/src/Cholesky/LLT.h +332 -360
- package/eigen/Eigen/src/Cholesky/LLT_LAPACKE.h +81 -56
- package/eigen/Eigen/src/CholmodSupport/CholmodSupport.h +620 -521
- package/eigen/Eigen/src/CholmodSupport/InternalHeaderCheck.h +3 -0
- package/eigen/Eigen/src/Core/ArithmeticSequence.h +239 -0
- package/eigen/Eigen/src/Core/Array.h +341 -294
- package/eigen/Eigen/src/Core/ArrayBase.h +190 -203
- package/eigen/Eigen/src/Core/ArrayWrapper.h +127 -171
- package/eigen/Eigen/src/Core/Assign.h +30 -40
- package/eigen/Eigen/src/Core/AssignEvaluator.h +711 -589
- package/eigen/Eigen/src/Core/Assign_MKL.h +130 -125
- package/eigen/Eigen/src/Core/BandMatrix.h +268 -283
- package/eigen/Eigen/src/Core/Block.h +375 -398
- package/eigen/Eigen/src/Core/CommaInitializer.h +86 -97
- package/eigen/Eigen/src/Core/ConditionEstimator.h +51 -53
- package/eigen/Eigen/src/Core/CoreEvaluators.h +1356 -1026
- package/eigen/Eigen/src/Core/CoreIterators.h +73 -59
- package/eigen/Eigen/src/Core/CwiseBinaryOp.h +114 -132
- package/eigen/Eigen/src/Core/CwiseNullaryOp.h +726 -617
- package/eigen/Eigen/src/Core/CwiseTernaryOp.h +77 -103
- package/eigen/Eigen/src/Core/CwiseUnaryOp.h +56 -68
- package/eigen/Eigen/src/Core/CwiseUnaryView.h +132 -95
- package/eigen/Eigen/src/Core/DenseBase.h +632 -571
- package/eigen/Eigen/src/Core/DenseCoeffsBase.h +511 -624
- package/eigen/Eigen/src/Core/DenseStorage.h +512 -509
- package/eigen/Eigen/src/Core/DeviceWrapper.h +153 -0
- package/eigen/Eigen/src/Core/Diagonal.h +169 -210
- package/eigen/Eigen/src/Core/DiagonalMatrix.h +351 -274
- package/eigen/Eigen/src/Core/DiagonalProduct.h +12 -10
- package/eigen/Eigen/src/Core/Dot.h +172 -222
- package/eigen/Eigen/src/Core/EigenBase.h +75 -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 -109
- package/eigen/Eigen/src/Core/Fuzzy.h +82 -105
- package/eigen/Eigen/src/Core/GeneralProduct.h +327 -263
- package/eigen/Eigen/src/Core/GenericPacketMath.h +1472 -360
- package/eigen/Eigen/src/Core/GlobalFunctions.h +194 -151
- package/eigen/Eigen/src/Core/IO.h +147 -139
- package/eigen/Eigen/src/Core/IndexedView.h +321 -0
- 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 +56 -66
- package/eigen/Eigen/src/Core/Map.h +124 -142
- package/eigen/Eigen/src/Core/MapBase.h +256 -281
- package/eigen/Eigen/src/Core/MathFunctions.h +1620 -938
- package/eigen/Eigen/src/Core/MathFunctionsImpl.h +233 -71
- package/eigen/Eigen/src/Core/Matrix.h +491 -416
- package/eigen/Eigen/src/Core/MatrixBase.h +468 -453
- package/eigen/Eigen/src/Core/NestByValue.h +66 -85
- package/eigen/Eigen/src/Core/NoAlias.h +79 -85
- package/eigen/Eigen/src/Core/NumTraits.h +235 -148
- package/eigen/Eigen/src/Core/PartialReduxEvaluator.h +253 -0
- package/eigen/Eigen/src/Core/PermutationMatrix.h +461 -511
- package/eigen/Eigen/src/Core/PlainObjectBase.h +871 -894
- package/eigen/Eigen/src/Core/Product.h +260 -139
- package/eigen/Eigen/src/Core/ProductEvaluators.h +863 -714
- package/eigen/Eigen/src/Core/Random.h +161 -136
- 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 +366 -336
- package/eigen/Eigen/src/Core/Ref.h +308 -209
- package/eigen/Eigen/src/Core/Replicate.h +94 -106
- package/eigen/Eigen/src/Core/Reshaped.h +398 -0
- package/eigen/Eigen/src/Core/ReturnByValue.h +49 -55
- package/eigen/Eigen/src/Core/Reverse.h +136 -145
- package/eigen/Eigen/src/Core/Select.h +70 -140
- package/eigen/Eigen/src/Core/SelfAdjointView.h +262 -285
- 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 +97 -111
- package/eigen/Eigen/src/Core/SolveTriangular.h +131 -129
- package/eigen/Eigen/src/Core/SolverBase.h +138 -101
- package/eigen/Eigen/src/Core/StableNorm.h +156 -160
- package/eigen/Eigen/src/Core/StlIterators.h +619 -0
- package/eigen/Eigen/src/Core/Stride.h +91 -88
- package/eigen/Eigen/src/Core/Swap.h +70 -38
- package/eigen/Eigen/src/Core/Transpose.h +295 -273
- package/eigen/Eigen/src/Core/Transpositions.h +272 -317
- package/eigen/Eigen/src/Core/TriangularMatrix.h +670 -755
- package/eigen/Eigen/src/Core/VectorBlock.h +59 -72
- package/eigen/Eigen/src/Core/VectorwiseOp.h +668 -630
- package/eigen/Eigen/src/Core/Visitor.h +480 -216
- package/eigen/Eigen/src/Core/arch/AVX/Complex.h +407 -293
- package/eigen/Eigen/src/Core/arch/AVX/MathFunctions.h +79 -388
- package/eigen/Eigen/src/Core/arch/AVX/PacketMath.h +2935 -491
- package/eigen/Eigen/src/Core/arch/AVX/Reductions.h +353 -0
- package/eigen/Eigen/src/Core/arch/AVX/TypeCasting.h +279 -22
- package/eigen/Eigen/src/Core/arch/AVX512/Complex.h +472 -0
- package/eigen/Eigen/src/Core/arch/AVX512/GemmKernel.h +1245 -0
- package/eigen/Eigen/src/Core/arch/AVX512/MathFunctions.h +85 -333
- package/eigen/Eigen/src/Core/arch/AVX512/MathFunctionsFP16.h +75 -0
- package/eigen/Eigen/src/Core/arch/AVX512/PacketMath.h +2490 -649
- 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 +277 -0
- package/eigen/Eigen/src/Core/arch/AVX512/TypeCastingFP16.h +130 -0
- package/eigen/Eigen/src/Core/arch/AltiVec/Complex.h +521 -298
- package/eigen/Eigen/src/Core/arch/AltiVec/MathFunctions.h +39 -280
- package/eigen/Eigen/src/Core/arch/AltiVec/MatrixProduct.h +3686 -0
- package/eigen/Eigen/src/Core/arch/AltiVec/MatrixProductCommon.h +205 -0
- package/eigen/Eigen/src/Core/arch/AltiVec/MatrixProductMMA.h +901 -0
- 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 +3391 -723
- package/eigen/Eigen/src/Core/arch/AltiVec/TypeCasting.h +153 -0
- package/eigen/Eigen/src/Core/arch/Default/BFloat16.h +866 -0
- package/eigen/Eigen/src/Core/arch/Default/ConjHelper.h +113 -14
- package/eigen/Eigen/src/Core/arch/Default/GenericPacketMathFunctions.h +2634 -0
- package/eigen/Eigen/src/Core/arch/Default/GenericPacketMathFunctionsFwd.h +227 -0
- package/eigen/Eigen/src/Core/arch/Default/Half.h +1091 -0
- package/eigen/Eigen/src/Core/arch/Default/Settings.h +11 -13
- package/eigen/Eigen/src/Core/arch/GPU/Complex.h +244 -0
- package/eigen/Eigen/src/Core/arch/GPU/MathFunctions.h +104 -0
- package/eigen/Eigen/src/Core/arch/GPU/PacketMath.h +1712 -0
- package/eigen/Eigen/src/Core/arch/GPU/Tuple.h +268 -0
- package/eigen/Eigen/src/Core/arch/GPU/TypeCasting.h +77 -0
- package/eigen/Eigen/src/Core/arch/HIP/hcc/math_constants.h +23 -0
- 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 +620 -0
- package/eigen/Eigen/src/Core/arch/MSA/MathFunctions.h +379 -0
- package/eigen/Eigen/src/Core/arch/MSA/PacketMath.h +1237 -0
- package/eigen/Eigen/src/Core/arch/NEON/Complex.h +531 -289
- package/eigen/Eigen/src/Core/arch/NEON/GeneralBlockPanelKernel.h +243 -0
- package/eigen/Eigen/src/Core/arch/NEON/MathFunctions.h +50 -73
- package/eigen/Eigen/src/Core/arch/NEON/PacketMath.h +5915 -579
- package/eigen/Eigen/src/Core/arch/NEON/TypeCasting.h +1642 -0
- package/eigen/Eigen/src/Core/arch/NEON/UnaryFunctors.h +57 -0
- package/eigen/Eigen/src/Core/arch/SSE/Complex.h +366 -334
- package/eigen/Eigen/src/Core/arch/SSE/MathFunctions.h +40 -514
- package/eigen/Eigen/src/Core/arch/SSE/PacketMath.h +2164 -675
- package/eigen/Eigen/src/Core/arch/SSE/Reductions.h +324 -0
- package/eigen/Eigen/src/Core/arch/SSE/TypeCasting.h +188 -35
- package/eigen/Eigen/src/Core/arch/SVE/MathFunctions.h +48 -0
- package/eigen/Eigen/src/Core/arch/SVE/PacketMath.h +674 -0
- package/eigen/Eigen/src/Core/arch/SVE/TypeCasting.h +52 -0
- package/eigen/Eigen/src/Core/arch/SYCL/InteropHeaders.h +227 -0
- package/eigen/Eigen/src/Core/arch/SYCL/MathFunctions.h +303 -0
- package/eigen/Eigen/src/Core/arch/SYCL/PacketMath.h +576 -0
- package/eigen/Eigen/src/Core/arch/SYCL/TypeCasting.h +83 -0
- package/eigen/Eigen/src/Core/arch/ZVector/Complex.h +434 -261
- package/eigen/Eigen/src/Core/arch/ZVector/MathFunctions.h +160 -53
- package/eigen/Eigen/src/Core/arch/ZVector/PacketMath.h +1073 -605
- package/eigen/Eigen/src/Core/functors/AssignmentFunctors.h +123 -117
- package/eigen/Eigen/src/Core/functors/BinaryFunctors.h +594 -322
- package/eigen/Eigen/src/Core/functors/NullaryFunctors.h +204 -118
- package/eigen/Eigen/src/Core/functors/StlFunctors.h +110 -97
- package/eigen/Eigen/src/Core/functors/TernaryFunctors.h +34 -7
- package/eigen/Eigen/src/Core/functors/UnaryFunctors.h +1158 -530
- package/eigen/Eigen/src/Core/products/GeneralBlockPanelKernel.h +2329 -1333
- package/eigen/Eigen/src/Core/products/GeneralMatrixMatrix.h +328 -364
- package/eigen/Eigen/src/Core/products/GeneralMatrixMatrixTriangular.h +191 -178
- package/eigen/Eigen/src/Core/products/GeneralMatrixMatrixTriangular_BLAS.h +85 -82
- package/eigen/Eigen/src/Core/products/GeneralMatrixMatrix_BLAS.h +154 -73
- package/eigen/Eigen/src/Core/products/GeneralMatrixVector.h +396 -542
- package/eigen/Eigen/src/Core/products/GeneralMatrixVector_BLAS.h +80 -77
- package/eigen/Eigen/src/Core/products/Parallelizer.h +208 -92
- package/eigen/Eigen/src/Core/products/SelfadjointMatrixMatrix.h +331 -375
- package/eigen/Eigen/src/Core/products/SelfadjointMatrixMatrix_BLAS.h +206 -224
- package/eigen/Eigen/src/Core/products/SelfadjointMatrixVector.h +139 -146
- 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 -46
- 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 -275
- package/eigen/Eigen/src/Core/products/TriangularSolverMatrix_BLAS.h +108 -109
- package/eigen/Eigen/src/Core/products/TriangularSolverVector.h +70 -93
- package/eigen/Eigen/src/Core/util/Assert.h +158 -0
- package/eigen/Eigen/src/Core/util/BlasUtil.h +413 -290
- package/eigen/Eigen/src/Core/util/ConfigureVectorization.h +543 -0
- package/eigen/Eigen/src/Core/util/Constants.h +314 -263
- package/eigen/Eigen/src/Core/util/DisableStupidWarnings.h +130 -78
- package/eigen/Eigen/src/Core/util/EmulateArray.h +270 -0
- package/eigen/Eigen/src/Core/util/ForwardDeclarations.h +450 -224
- 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 +487 -0
- package/eigen/Eigen/src/Core/util/IntegralConstant.h +279 -0
- package/eigen/Eigen/src/Core/util/MKL_support.h +39 -30
- package/eigen/Eigen/src/Core/util/Macros.h +939 -646
- package/eigen/Eigen/src/Core/util/MaxSizeVector.h +139 -0
- package/eigen/Eigen/src/Core/util/Memory.h +1042 -650
- package/eigen/Eigen/src/Core/util/Meta.h +618 -426
- 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 +51 -0
- package/eigen/Eigen/src/Core/util/Serializer.h +209 -0
- package/eigen/Eigen/src/Core/util/StaticAssert.h +51 -164
- package/eigen/Eigen/src/Core/util/SymbolicIndex.h +445 -0
- package/eigen/Eigen/src/Core/util/XprHelper.h +793 -538
- 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 +91 -107
- package/eigen/Eigen/src/Eigenvalues/RealQZ.h +539 -606
- package/eigen/Eigen/src/Eigenvalues/RealSchur.h +348 -382
- package/eigen/Eigen/src/Eigenvalues/RealSchur_LAPACKE.h +41 -35
- package/eigen/Eigen/src/Eigenvalues/SelfAdjointEigenSolver.h +579 -600
- package/eigen/Eigen/src/Eigenvalues/SelfAdjointEigenSolver_LAPACKE.h +47 -44
- package/eigen/Eigen/src/Eigenvalues/Tridiagonalization.h +434 -461
- package/eigen/Eigen/src/Geometry/AlignedBox.h +307 -214
- package/eigen/Eigen/src/Geometry/AngleAxis.h +135 -137
- package/eigen/Eigen/src/Geometry/EulerAngles.h +163 -74
- package/eigen/Eigen/src/Geometry/Homogeneous.h +289 -333
- package/eigen/Eigen/src/Geometry/Hyperplane.h +152 -161
- package/eigen/Eigen/src/Geometry/InternalHeaderCheck.h +3 -0
- package/eigen/Eigen/src/Geometry/OrthoMethods.h +168 -145
- package/eigen/Eigen/src/Geometry/ParametrizedLine.h +141 -104
- package/eigen/Eigen/src/Geometry/Quaternion.h +595 -497
- package/eigen/Eigen/src/Geometry/Rotation2D.h +110 -108
- package/eigen/Eigen/src/Geometry/RotationBase.h +148 -145
- package/eigen/Eigen/src/Geometry/Scaling.h +115 -90
- package/eigen/Eigen/src/Geometry/Transform.h +896 -953
- package/eigen/Eigen/src/Geometry/Translation.h +100 -98
- package/eigen/Eigen/src/Geometry/Umeyama.h +79 -84
- package/eigen/Eigen/src/Geometry/arch/Geometry_SIMD.h +154 -0
- package/eigen/Eigen/src/Householder/BlockHouseholder.h +54 -42
- package/eigen/Eigen/src/Householder/Householder.h +104 -122
- package/eigen/Eigen/src/Householder/HouseholderSequence.h +416 -382
- package/eigen/Eigen/src/Householder/InternalHeaderCheck.h +3 -0
- package/eigen/Eigen/src/IterativeLinearSolvers/BasicPreconditioners.h +153 -166
- package/eigen/Eigen/src/IterativeLinearSolvers/BiCGSTAB.h +127 -138
- package/eigen/Eigen/src/IterativeLinearSolvers/ConjugateGradient.h +95 -124
- package/eigen/Eigen/src/IterativeLinearSolvers/IncompleteCholesky.h +269 -267
- package/eigen/Eigen/src/IterativeLinearSolvers/IncompleteLUT.h +246 -259
- package/eigen/Eigen/src/IterativeLinearSolvers/InternalHeaderCheck.h +3 -0
- package/eigen/Eigen/src/IterativeLinearSolvers/IterativeSolverBase.h +218 -217
- package/eigen/Eigen/src/IterativeLinearSolvers/LeastSquareConjugateGradient.h +80 -103
- package/eigen/Eigen/src/IterativeLinearSolvers/SolveWithGuess.h +59 -63
- package/eigen/Eigen/src/Jacobi/InternalHeaderCheck.h +3 -0
- package/eigen/Eigen/src/Jacobi/Jacobi.h +256 -291
- package/eigen/Eigen/src/KLUSupport/InternalHeaderCheck.h +3 -0
- package/eigen/Eigen/src/KLUSupport/KLUSupport.h +339 -0
- package/eigen/Eigen/src/LU/Determinant.h +60 -63
- package/eigen/Eigen/src/LU/FullPivLU.h +561 -626
- package/eigen/Eigen/src/LU/InternalHeaderCheck.h +3 -0
- package/eigen/Eigen/src/LU/InverseImpl.h +213 -275
- package/eigen/Eigen/src/LU/PartialPivLU.h +407 -435
- package/eigen/Eigen/src/LU/PartialPivLU_LAPACKE.h +54 -40
- package/eigen/Eigen/src/LU/arch/InverseSize4.h +353 -0
- 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 +250 -282
- package/eigen/Eigen/src/OrderingMethods/Eigen_Colamd.h +950 -1103
- package/eigen/Eigen/src/OrderingMethods/InternalHeaderCheck.h +3 -0
- package/eigen/Eigen/src/OrderingMethods/Ordering.h +111 -122
- 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 -429
- package/eigen/Eigen/src/QR/ColPivHouseholderQR.h +494 -473
- package/eigen/Eigen/src/QR/ColPivHouseholderQR_LAPACKE.h +120 -56
- package/eigen/Eigen/src/QR/CompleteOrthogonalDecomposition.h +223 -137
- package/eigen/Eigen/src/QR/FullPivHouseholderQR.h +517 -460
- package/eigen/Eigen/src/QR/HouseholderQR.h +412 -278
- 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 +263 -261
- package/eigen/Eigen/src/SVD/BDCSVD.h +872 -679
- 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 +585 -543
- package/eigen/Eigen/src/SVD/JacobiSVD_LAPACKE.h +85 -49
- package/eigen/Eigen/src/SVD/SVDBase.h +281 -160
- package/eigen/Eigen/src/SVD/UpperBidiagonalization.h +202 -237
- package/eigen/Eigen/src/SparseCholesky/InternalHeaderCheck.h +3 -0
- package/eigen/Eigen/src/SparseCholesky/SimplicialCholesky.h +769 -590
- package/eigen/Eigen/src/SparseCholesky/SimplicialCholesky_impl.h +318 -129
- package/eigen/Eigen/src/SparseCore/AmbiVector.h +202 -251
- package/eigen/Eigen/src/SparseCore/CompressedStorage.h +184 -236
- package/eigen/Eigen/src/SparseCore/ConservativeSparseSparseProduct.h +140 -184
- package/eigen/Eigen/src/SparseCore/InternalHeaderCheck.h +3 -0
- package/eigen/Eigen/src/SparseCore/SparseAssign.h +174 -111
- package/eigen/Eigen/src/SparseCore/SparseBlock.h +408 -477
- package/eigen/Eigen/src/SparseCore/SparseColEtree.h +100 -112
- package/eigen/Eigen/src/SparseCore/SparseCompressedBase.h +531 -280
- package/eigen/Eigen/src/SparseCore/SparseCwiseBinaryOp.h +559 -347
- package/eigen/Eigen/src/SparseCore/SparseCwiseUnaryOp.h +100 -108
- package/eigen/Eigen/src/SparseCore/SparseDenseProduct.h +185 -191
- 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 +1614 -1142
- package/eigen/Eigen/src/SparseCore/SparseMatrixBase.h +403 -357
- package/eigen/Eigen/src/SparseCore/SparsePermutation.h +186 -115
- package/eigen/Eigen/src/SparseCore/SparseProduct.h +100 -91
- 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 +371 -414
- 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 +146 -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 +814 -618
- 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 +273 -255
- 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 +90 -101
- 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 +125 -133
- 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 +451 -490
- package/eigen/Eigen/src/StlSupport/StdDeque.h +28 -105
- 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 -732
- 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 +480 -380
- 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 +9976 -16182
- 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.inc +1370 -0
- package/eigen/Eigen/src/plugins/CommonCwiseBinaryOps.inc +116 -0
- package/eigen/Eigen/src/plugins/CommonCwiseUnaryOps.inc +167 -0
- 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/lib/LibEigen.d.ts +4 -0
- package/lib/LibEigen.js +14 -0
- package/lib/index.d.ts +1 -1
- package/lib/index.js +7 -3
- package/package.json +2 -10
- package/eigen/Eigen/CMakeLists.txt +0 -19
- package/eigen/Eigen/src/Core/BooleanRedux.h +0 -164
- package/eigen/Eigen/src/Core/arch/CUDA/Complex.h +0 -103
- package/eigen/Eigen/src/Core/arch/CUDA/Half.h +0 -675
- package/eigen/Eigen/src/Core/arch/CUDA/MathFunctions.h +0 -91
- package/eigen/Eigen/src/Core/arch/CUDA/PacketMath.h +0 -333
- package/eigen/Eigen/src/Core/arch/CUDA/PacketMathHalf.h +0 -1124
- package/eigen/Eigen/src/Core/arch/CUDA/TypeCasting.h +0 -212
- package/eigen/Eigen/src/Core/util/NonMPL2.h +0 -3
- package/eigen/Eigen/src/Geometry/arch/Geometry_SSE.h +0 -161
- package/eigen/Eigen/src/LU/arch/Inverse_SSE.h +0 -338
- 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 -332
- package/eigen/Eigen/src/plugins/ArrayCwiseUnaryOps.h +0 -552
- package/eigen/Eigen/src/plugins/BlockMethods.h +0 -1058
- package/eigen/Eigen/src/plugins/CommonCwiseBinaryOps.h +0 -115
- package/eigen/Eigen/src/plugins/CommonCwiseUnaryOps.h +0 -163
- package/eigen/Eigen/src/plugins/MatrixCwiseBinaryOps.h +0 -152
- package/eigen/Eigen/src/plugins/MatrixCwiseUnaryOps.h +0 -85
- package/lib/eigen.d.ts +0 -2
- package/lib/eigen.js +0 -15
|
@@ -13,115 +13,111 @@
|
|
|
13
13
|
// Davis (davis@cise.ufl.edu), University of Florida. The algorithm was
|
|
14
14
|
// developed in collaboration with John Gilbert, Xerox PARC, and Esmond
|
|
15
15
|
// Ng, Oak Ridge National Laboratory.
|
|
16
|
-
//
|
|
16
|
+
//
|
|
17
17
|
// Date:
|
|
18
|
-
//
|
|
18
|
+
//
|
|
19
19
|
// September 8, 2003. Version 2.3.
|
|
20
|
-
//
|
|
20
|
+
//
|
|
21
21
|
// Acknowledgements:
|
|
22
|
-
//
|
|
22
|
+
//
|
|
23
23
|
// This work was supported by the National Science Foundation, under
|
|
24
24
|
// grants DMS-9504974 and DMS-9803599.
|
|
25
|
-
//
|
|
25
|
+
//
|
|
26
26
|
// Notice:
|
|
27
|
-
//
|
|
27
|
+
//
|
|
28
28
|
// Copyright (c) 1998-2003 by the University of Florida.
|
|
29
29
|
// All Rights Reserved.
|
|
30
|
-
//
|
|
30
|
+
//
|
|
31
31
|
// THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
|
|
32
32
|
// EXPRESSED OR IMPLIED. ANY USE IS AT YOUR OWN RISK.
|
|
33
|
-
//
|
|
33
|
+
//
|
|
34
34
|
// Permission is hereby granted to use, copy, modify, and/or distribute
|
|
35
35
|
// this program, provided that the Copyright, this License, and the
|
|
36
36
|
// Availability of the original version is retained on all copies and made
|
|
37
37
|
// accessible to the end-user of any code or package that includes COLAMD
|
|
38
|
-
// or any modified version of COLAMD.
|
|
39
|
-
//
|
|
38
|
+
// or any modified version of COLAMD.
|
|
39
|
+
//
|
|
40
40
|
// Availability:
|
|
41
|
-
//
|
|
41
|
+
//
|
|
42
42
|
// The colamd/symamd library is available at
|
|
43
|
-
//
|
|
43
|
+
//
|
|
44
44
|
// http://www.suitesparse.com
|
|
45
45
|
|
|
46
|
-
|
|
47
46
|
#ifndef EIGEN_COLAMD_H
|
|
48
47
|
#define EIGEN_COLAMD_H
|
|
49
48
|
|
|
49
|
+
namespace Eigen {
|
|
50
50
|
namespace internal {
|
|
51
|
+
namespace Colamd {
|
|
52
|
+
|
|
51
53
|
/* Ensure that debugging is turned off: */
|
|
52
54
|
#ifndef COLAMD_NDEBUG
|
|
53
55
|
#define COLAMD_NDEBUG
|
|
54
56
|
#endif /* NDEBUG */
|
|
57
|
+
|
|
55
58
|
/* ========================================================================== */
|
|
56
59
|
/* === Knob and statistics definitions ====================================== */
|
|
57
60
|
/* ========================================================================== */
|
|
58
61
|
|
|
59
62
|
/* size of the knobs [ ] array. Only knobs [0..1] are currently used. */
|
|
60
|
-
|
|
63
|
+
const int NKnobs = 20;
|
|
61
64
|
|
|
62
65
|
/* number of output statistics. Only stats [0..6] are currently used. */
|
|
63
|
-
|
|
66
|
+
const int NStats = 20;
|
|
64
67
|
|
|
65
|
-
/* knobs
|
|
66
|
-
|
|
68
|
+
/* Indices into knobs and stats array. */
|
|
69
|
+
enum KnobsStatsIndex {
|
|
70
|
+
/* knobs [0] and stats [0]: dense row knob and output statistic. */
|
|
71
|
+
DenseRow = 0,
|
|
67
72
|
|
|
68
|
-
/* knobs [1] and stats [1]: dense column knob and output statistic. */
|
|
69
|
-
|
|
73
|
+
/* knobs [1] and stats [1]: dense column knob and output statistic. */
|
|
74
|
+
DenseCol = 1,
|
|
70
75
|
|
|
71
|
-
/* stats [2]: memory defragmentation count output statistic */
|
|
72
|
-
|
|
76
|
+
/* stats [2]: memory defragmentation count output statistic */
|
|
77
|
+
DefragCount = 2,
|
|
73
78
|
|
|
74
|
-
/* stats [3]: colamd status: zero OK, > 0 warning or notice, < 0 error */
|
|
75
|
-
|
|
79
|
+
/* stats [3]: colamd status: zero OK, > 0 warning or notice, < 0 error */
|
|
80
|
+
Status = 3,
|
|
76
81
|
|
|
77
|
-
/* stats [4..6]: error info, or info on jumbled columns */
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
82
|
+
/* stats [4..6]: error info, or info on jumbled columns */
|
|
83
|
+
Info1 = 4,
|
|
84
|
+
Info2 = 5,
|
|
85
|
+
Info3 = 6
|
|
86
|
+
};
|
|
81
87
|
|
|
82
88
|
/* error codes returned in stats [3]: */
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
89
|
+
enum Status {
|
|
90
|
+
Ok = 0,
|
|
91
|
+
OkButJumbled = 1,
|
|
92
|
+
ErrorANotPresent = -1,
|
|
93
|
+
ErrorPNotPresent = -2,
|
|
94
|
+
ErrorNrowNegative = -3,
|
|
95
|
+
ErrorNcolNegative = -4,
|
|
96
|
+
ErrorNnzNegative = -5,
|
|
97
|
+
ErrorP0Nonzero = -6,
|
|
98
|
+
ErrorATooSmall = -7,
|
|
99
|
+
ErrorColLengthNegative = -8,
|
|
100
|
+
ErrorRowIndexOutOfBounds = -9,
|
|
101
|
+
ErrorOutOfMemory = -10,
|
|
102
|
+
ErrorInternalError = -999
|
|
103
|
+
};
|
|
97
104
|
/* ========================================================================== */
|
|
98
105
|
/* === Definitions ========================================================== */
|
|
99
106
|
/* ========================================================================== */
|
|
100
107
|
|
|
101
|
-
|
|
108
|
+
template <typename IndexType>
|
|
109
|
+
IndexType ones_complement(const IndexType r) {
|
|
110
|
+
return (-(r)-1);
|
|
111
|
+
}
|
|
102
112
|
|
|
103
113
|
/* -------------------------------------------------------------------------- */
|
|
104
|
-
|
|
105
|
-
#define COLAMD_EMPTY (-1)
|
|
114
|
+
const int Empty = -1;
|
|
106
115
|
|
|
107
116
|
/* Row and column status */
|
|
108
|
-
|
|
109
|
-
#define DEAD (-1)
|
|
117
|
+
enum RowColumnStatus { Alive = 0, Dead = -1 };
|
|
110
118
|
|
|
111
119
|
/* Column status */
|
|
112
|
-
|
|
113
|
-
#define DEAD_NON_PRINCIPAL (-2)
|
|
114
|
-
|
|
115
|
-
/* Macros for row and column status update and checking. */
|
|
116
|
-
#define ROW_IS_DEAD(r) ROW_IS_MARKED_DEAD (Row[r].shared2.mark)
|
|
117
|
-
#define ROW_IS_MARKED_DEAD(row_mark) (row_mark < ALIVE)
|
|
118
|
-
#define ROW_IS_ALIVE(r) (Row [r].shared2.mark >= ALIVE)
|
|
119
|
-
#define COL_IS_DEAD(c) (Col [c].start < ALIVE)
|
|
120
|
-
#define COL_IS_ALIVE(c) (Col [c].start >= ALIVE)
|
|
121
|
-
#define COL_IS_DEAD_PRINCIPAL(c) (Col [c].start == DEAD_PRINCIPAL)
|
|
122
|
-
#define KILL_ROW(r) { Row [r].shared2.mark = DEAD ; }
|
|
123
|
-
#define KILL_PRINCIPAL_COL(c) { Col [c].start = DEAD_PRINCIPAL ; }
|
|
124
|
-
#define KILL_NON_PRINCIPAL_COL(c) { Col [c].start = DEAD_NON_PRINCIPAL ; }
|
|
120
|
+
enum ColumnStatus { DeadPrincipal = -1, DeadNonPrincipal = -2 };
|
|
125
121
|
|
|
126
122
|
/* ========================================================================== */
|
|
127
123
|
/* === Colamd reporting mechanism =========================================== */
|
|
@@ -129,61 +125,67 @@ namespace internal {
|
|
|
129
125
|
|
|
130
126
|
// == Row and Column structures ==
|
|
131
127
|
template <typename IndexType>
|
|
132
|
-
struct
|
|
133
|
-
|
|
134
|
-
IndexType start ; /* index for A of first row in this column, or DEAD */
|
|
128
|
+
struct ColStructure {
|
|
129
|
+
IndexType start; /* index for A of first row in this column, or Dead */
|
|
135
130
|
/* if column is dead */
|
|
136
|
-
IndexType length
|
|
137
|
-
union
|
|
138
|
-
|
|
139
|
-
IndexType thickness ; /* number of original columns represented by this */
|
|
131
|
+
IndexType length; /* number of rows in this column */
|
|
132
|
+
union {
|
|
133
|
+
IndexType thickness; /* number of original columns represented by this */
|
|
140
134
|
/* col, if the column is alive */
|
|
141
|
-
IndexType parent
|
|
135
|
+
IndexType parent; /* parent in parent tree super-column structure, if */
|
|
142
136
|
/* the column is dead */
|
|
143
|
-
} shared1
|
|
144
|
-
union
|
|
145
|
-
|
|
146
|
-
IndexType
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
{
|
|
151
|
-
IndexType headhash ; /* head of a hash bucket, if col is at the head of */
|
|
137
|
+
} shared1;
|
|
138
|
+
union {
|
|
139
|
+
IndexType score; /* the score used to maintain heap, if col is alive */
|
|
140
|
+
IndexType order; /* pivot ordering of this column, if col is dead */
|
|
141
|
+
} shared2;
|
|
142
|
+
union {
|
|
143
|
+
IndexType headhash; /* head of a hash bucket, if col is at the head of */
|
|
152
144
|
/* a degree list */
|
|
153
|
-
IndexType hash
|
|
154
|
-
IndexType prev
|
|
145
|
+
IndexType hash; /* hash value, if col is not in a degree list */
|
|
146
|
+
IndexType prev; /* previous column in degree list, if col is in a */
|
|
155
147
|
/* degree list (but not at the head of a degree list) */
|
|
156
|
-
} shared3
|
|
157
|
-
union
|
|
158
|
-
|
|
159
|
-
IndexType
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
148
|
+
} shared3;
|
|
149
|
+
union {
|
|
150
|
+
IndexType degree_next; /* next column, if col is in a degree list */
|
|
151
|
+
IndexType hash_next; /* next column, if col is in a hash list */
|
|
152
|
+
} shared4;
|
|
153
|
+
|
|
154
|
+
inline bool is_dead() const { return start < Alive; }
|
|
155
|
+
|
|
156
|
+
inline bool is_alive() const { return start >= Alive; }
|
|
157
|
+
|
|
158
|
+
inline bool is_dead_principal() const { return start == DeadPrincipal; }
|
|
159
|
+
|
|
160
|
+
inline void kill_principal() { start = DeadPrincipal; }
|
|
161
|
+
|
|
162
|
+
inline void kill_non_principal() { start = DeadNonPrincipal; }
|
|
163
163
|
};
|
|
164
|
-
|
|
164
|
+
|
|
165
165
|
template <typename IndexType>
|
|
166
|
-
struct
|
|
167
|
-
|
|
168
|
-
IndexType
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
166
|
+
struct RowStructure {
|
|
167
|
+
IndexType start; /* index for A of first col in this row */
|
|
168
|
+
IndexType length; /* number of principal columns in this row */
|
|
169
|
+
union {
|
|
170
|
+
IndexType degree; /* number of principal & non-principal columns in row */
|
|
171
|
+
IndexType p; /* used as a row pointer in init_rows_cols () */
|
|
172
|
+
} shared1;
|
|
173
|
+
union {
|
|
174
|
+
IndexType mark; /* for computing set differences and marking dead rows*/
|
|
175
|
+
IndexType first_column; /* first column in row (used in garbage collection) */
|
|
176
|
+
} shared2;
|
|
177
|
+
|
|
178
|
+
inline bool is_dead() const { return shared2.mark < Alive; }
|
|
179
|
+
|
|
180
|
+
inline bool is_alive() const { return shared2.mark >= Alive; }
|
|
181
|
+
|
|
182
|
+
inline void kill() { shared2.mark = Dead; }
|
|
181
183
|
};
|
|
182
|
-
|
|
184
|
+
|
|
183
185
|
/* ========================================================================== */
|
|
184
186
|
/* === Colamd recommended memory size ======================================= */
|
|
185
187
|
/* ========================================================================== */
|
|
186
|
-
|
|
188
|
+
|
|
187
189
|
/*
|
|
188
190
|
The recommended length Alen of the array A passed to colamd is given by
|
|
189
191
|
the COLAMD_RECOMMENDED (nnz, n_row, n_col) macro. It returns -1 if any
|
|
@@ -192,41 +194,50 @@ struct Colamd_Row
|
|
|
192
194
|
required for the Col and Row arrays, respectively, which are internal to
|
|
193
195
|
colamd. An additional n_col space is the minimal amount of "elbow room",
|
|
194
196
|
and nnz/5 more space is recommended for run time efficiency.
|
|
195
|
-
|
|
197
|
+
|
|
196
198
|
This macro is not needed when using symamd.
|
|
197
|
-
|
|
199
|
+
|
|
198
200
|
Explicit typecast to IndexType added Sept. 23, 2002, COLAMD version 2.2, to avoid
|
|
199
201
|
gcc -pedantic warning messages.
|
|
200
202
|
*/
|
|
201
203
|
template <typename IndexType>
|
|
202
|
-
inline IndexType colamd_c(IndexType n_col)
|
|
203
|
-
|
|
204
|
+
inline IndexType colamd_c(IndexType n_col) {
|
|
205
|
+
return IndexType(((n_col) + 1) * sizeof(ColStructure<IndexType>) / sizeof(IndexType));
|
|
206
|
+
}
|
|
204
207
|
|
|
205
208
|
template <typename IndexType>
|
|
206
|
-
inline IndexType
|
|
207
|
-
|
|
209
|
+
inline IndexType colamd_r(IndexType n_row) {
|
|
210
|
+
return IndexType(((n_row) + 1) * sizeof(RowStructure<IndexType>) / sizeof(IndexType));
|
|
211
|
+
}
|
|
208
212
|
|
|
209
213
|
// Prototypes of non-user callable routines
|
|
210
214
|
template <typename IndexType>
|
|
211
|
-
static IndexType init_rows_cols
|
|
215
|
+
static IndexType init_rows_cols(IndexType n_row, IndexType n_col, RowStructure<IndexType> Row[],
|
|
216
|
+
ColStructure<IndexType> col[], IndexType A[], IndexType p[], IndexType stats[NStats]);
|
|
212
217
|
|
|
213
218
|
template <typename IndexType>
|
|
214
|
-
static void init_scoring
|
|
219
|
+
static void init_scoring(IndexType n_row, IndexType n_col, RowStructure<IndexType> Row[], ColStructure<IndexType> Col[],
|
|
220
|
+
IndexType A[], IndexType head[], double knobs[NKnobs], IndexType *p_n_row2,
|
|
221
|
+
IndexType *p_n_col2, IndexType *p_max_deg);
|
|
215
222
|
|
|
216
223
|
template <typename IndexType>
|
|
217
|
-
static IndexType find_ordering
|
|
224
|
+
static IndexType find_ordering(IndexType n_row, IndexType n_col, IndexType Alen, RowStructure<IndexType> Row[],
|
|
225
|
+
ColStructure<IndexType> Col[], IndexType A[], IndexType head[], IndexType n_col2,
|
|
226
|
+
IndexType max_deg, IndexType pfree);
|
|
218
227
|
|
|
219
228
|
template <typename IndexType>
|
|
220
|
-
static void order_children
|
|
229
|
+
static void order_children(IndexType n_col, ColStructure<IndexType> Col[], IndexType p[]);
|
|
221
230
|
|
|
222
231
|
template <typename IndexType>
|
|
223
|
-
static void detect_super_cols
|
|
232
|
+
static void detect_super_cols(ColStructure<IndexType> Col[], IndexType A[], IndexType head[], IndexType row_start,
|
|
233
|
+
IndexType row_length);
|
|
224
234
|
|
|
225
235
|
template <typename IndexType>
|
|
226
|
-
static IndexType garbage_collection
|
|
236
|
+
static IndexType garbage_collection(IndexType n_row, IndexType n_col, RowStructure<IndexType> Row[],
|
|
237
|
+
ColStructure<IndexType> Col[], IndexType A[], IndexType *pfree);
|
|
227
238
|
|
|
228
239
|
template <typename IndexType>
|
|
229
|
-
static inline
|
|
240
|
+
static inline IndexType clear_mark(IndexType n_row, RowStructure<IndexType> Row[]);
|
|
230
241
|
|
|
231
242
|
/* === No debugging ========================================================= */
|
|
232
243
|
|
|
@@ -236,41 +247,39 @@ static inline IndexType clear_mark (IndexType n_row, Colamd_Row<IndexType> Row
|
|
|
236
247
|
#define COLAMD_DEBUG3(params) ;
|
|
237
248
|
#define COLAMD_DEBUG4(params) ;
|
|
238
249
|
|
|
239
|
-
#define COLAMD_ASSERT(expression) ((void)
|
|
240
|
-
|
|
250
|
+
#define COLAMD_ASSERT(expression) ((void)0)
|
|
241
251
|
|
|
242
252
|
/**
|
|
243
|
-
* \brief Returns the recommended value of Alen
|
|
244
|
-
*
|
|
245
|
-
* Returns recommended value of Alen for use by colamd.
|
|
246
|
-
* Returns -1 if any input argument is negative.
|
|
247
|
-
* The use of this routine or macro is optional.
|
|
248
|
-
* Note that the macro uses its arguments more than once,
|
|
249
|
-
* so be careful for side effects, if you pass expressions as arguments to COLAMD_RECOMMENDED.
|
|
250
|
-
*
|
|
253
|
+
* \brief Returns the recommended value of Alen
|
|
254
|
+
*
|
|
255
|
+
* Returns recommended value of Alen for use by colamd.
|
|
256
|
+
* Returns -1 if any input argument is negative.
|
|
257
|
+
* The use of this routine or macro is optional.
|
|
258
|
+
* Note that the macro uses its arguments more than once,
|
|
259
|
+
* so be careful for side effects, if you pass expressions as arguments to COLAMD_RECOMMENDED.
|
|
260
|
+
*
|
|
251
261
|
* \param nnz nonzeros in A
|
|
252
262
|
* \param n_row number of rows in A
|
|
253
263
|
* \param n_col number of columns in A
|
|
254
264
|
* \return recommended value of Alen for use by colamd
|
|
255
265
|
*/
|
|
256
266
|
template <typename IndexType>
|
|
257
|
-
inline IndexType
|
|
258
|
-
{
|
|
267
|
+
inline IndexType recommended(IndexType nnz, IndexType n_row, IndexType n_col) {
|
|
259
268
|
if ((nnz) < 0 || (n_row) < 0 || (n_col) < 0)
|
|
260
269
|
return (-1);
|
|
261
270
|
else
|
|
262
|
-
return (2 * (nnz) + colamd_c
|
|
271
|
+
return (2 * (nnz) + colamd_c(n_col) + colamd_r(n_row) + (n_col) + ((nnz) / 5));
|
|
263
272
|
}
|
|
264
273
|
|
|
265
274
|
/**
|
|
266
275
|
* \brief set default parameters The use of this routine is optional.
|
|
267
|
-
*
|
|
268
|
-
* Colamd: rows with more than (knobs [
|
|
276
|
+
*
|
|
277
|
+
* Colamd: rows with more than (knobs [DenseRow] * n_col)
|
|
269
278
|
* entries are removed prior to ordering. Columns with more than
|
|
270
|
-
* (knobs [
|
|
271
|
-
* ordering, and placed last in the output column ordering.
|
|
279
|
+
* (knobs [DenseCol] * n_row) entries are removed prior to
|
|
280
|
+
* ordering, and placed last in the output column ordering.
|
|
272
281
|
*
|
|
273
|
-
*
|
|
282
|
+
* DenseRow and DenseCol are defined as 0 and 1,
|
|
274
283
|
* respectively, in colamd.h. Default values of these two knobs
|
|
275
284
|
* are both 0.5. Currently, only knobs [0] and knobs [1] are
|
|
276
285
|
* used, but future versions may use more knobs. If so, they will
|
|
@@ -279,184 +288,172 @@ inline IndexType colamd_recommended ( IndexType nnz, IndexType n_row, IndexType
|
|
|
279
288
|
* not need to change, assuming that you either use
|
|
280
289
|
* colamd_set_defaults, or pass a (double *) NULL pointer as the
|
|
281
290
|
* knobs array to colamd or symamd.
|
|
282
|
-
*
|
|
291
|
+
*
|
|
283
292
|
* \param knobs parameter settings for colamd
|
|
284
293
|
*/
|
|
285
294
|
|
|
286
|
-
static inline void
|
|
287
|
-
{
|
|
295
|
+
static inline void set_defaults(double knobs[NKnobs]) {
|
|
288
296
|
/* === Local variables ================================================== */
|
|
289
|
-
|
|
290
|
-
int i ;
|
|
291
297
|
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
298
|
+
int i;
|
|
299
|
+
|
|
300
|
+
if (!knobs) {
|
|
301
|
+
return; /* no knobs to initialize */
|
|
295
302
|
}
|
|
296
|
-
for (i = 0
|
|
297
|
-
|
|
298
|
-
knobs [i] = 0 ;
|
|
303
|
+
for (i = 0; i < NKnobs; i++) {
|
|
304
|
+
knobs[i] = 0;
|
|
299
305
|
}
|
|
300
|
-
knobs
|
|
301
|
-
knobs
|
|
306
|
+
knobs[Colamd::DenseRow] = 0.5; /* ignore rows over 50% dense */
|
|
307
|
+
knobs[Colamd::DenseCol] = 0.5; /* ignore columns over 50% dense */
|
|
302
308
|
}
|
|
303
309
|
|
|
304
|
-
/**
|
|
310
|
+
/**
|
|
305
311
|
* \brief Computes a column ordering using the column approximate minimum degree ordering
|
|
306
|
-
*
|
|
312
|
+
*
|
|
307
313
|
* Computes a column ordering (Q) of A such that P(AQ)=LU or
|
|
308
314
|
* (AQ)'AQ=LL' have less fill-in and require fewer floating point
|
|
309
315
|
* operations than factorizing the unpermuted matrix A or A'A,
|
|
310
316
|
* respectively.
|
|
311
|
-
*
|
|
312
|
-
*
|
|
317
|
+
*
|
|
318
|
+
*
|
|
313
319
|
* \param n_row number of rows in A
|
|
314
320
|
* \param n_col number of columns in A
|
|
315
|
-
* \param Alen
|
|
321
|
+
* \param Alen size of the array A
|
|
316
322
|
* \param A row indices of the matrix, of size ALen
|
|
317
323
|
* \param p column pointers of A, of size n_col+1
|
|
318
324
|
* \param knobs parameter settings for colamd
|
|
319
325
|
* \param stats colamd output statistics and error codes
|
|
320
326
|
*/
|
|
321
327
|
template <typename IndexType>
|
|
322
|
-
static bool
|
|
323
|
-
{
|
|
328
|
+
static bool compute_ordering(IndexType n_row, IndexType n_col, IndexType Alen, IndexType *A, IndexType *p,
|
|
329
|
+
double knobs[NKnobs], IndexType stats[NStats]) {
|
|
324
330
|
/* === Local variables ================================================== */
|
|
325
|
-
|
|
326
|
-
IndexType i
|
|
327
|
-
IndexType nnz
|
|
328
|
-
IndexType Row_size
|
|
329
|
-
IndexType Col_size
|
|
330
|
-
IndexType need
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
IndexType n_col2
|
|
334
|
-
IndexType n_row2
|
|
335
|
-
IndexType ngarbage
|
|
336
|
-
IndexType max_deg
|
|
337
|
-
double default_knobs
|
|
338
|
-
|
|
339
|
-
|
|
331
|
+
|
|
332
|
+
IndexType i; /* loop index */
|
|
333
|
+
IndexType nnz; /* nonzeros in A */
|
|
334
|
+
IndexType Row_size; /* size of Row [], in integers */
|
|
335
|
+
IndexType Col_size; /* size of Col [], in integers */
|
|
336
|
+
IndexType need; /* minimum required length of A */
|
|
337
|
+
Colamd::RowStructure<IndexType> *Row; /* pointer into A of Row [0..n_row] array */
|
|
338
|
+
Colamd::ColStructure<IndexType> *Col; /* pointer into A of Col [0..n_col] array */
|
|
339
|
+
IndexType n_col2; /* number of non-dense, non-empty columns */
|
|
340
|
+
IndexType n_row2; /* number of non-dense, non-empty rows */
|
|
341
|
+
IndexType ngarbage; /* number of garbage collections performed */
|
|
342
|
+
IndexType max_deg; /* maximum row degree */
|
|
343
|
+
double default_knobs[NKnobs]; /* default knobs array */
|
|
344
|
+
|
|
340
345
|
/* === Check the input arguments ======================================== */
|
|
341
|
-
|
|
342
|
-
if (!stats)
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
return (false) ;
|
|
346
|
+
|
|
347
|
+
if (!stats) {
|
|
348
|
+
COLAMD_DEBUG0(("colamd: stats not present\n"));
|
|
349
|
+
return (false);
|
|
346
350
|
}
|
|
347
|
-
for (i = 0
|
|
348
|
-
|
|
349
|
-
stats [i] = 0 ;
|
|
351
|
+
for (i = 0; i < NStats; i++) {
|
|
352
|
+
stats[i] = 0;
|
|
350
353
|
}
|
|
351
|
-
stats
|
|
352
|
-
stats
|
|
353
|
-
stats
|
|
354
|
-
|
|
355
|
-
if (!A)
|
|
354
|
+
stats[Colamd::Status] = Colamd::Ok;
|
|
355
|
+
stats[Colamd::Info1] = -1;
|
|
356
|
+
stats[Colamd::Info2] = -1;
|
|
357
|
+
|
|
358
|
+
if (!A) /* A is not present */
|
|
356
359
|
{
|
|
357
|
-
stats
|
|
358
|
-
COLAMD_DEBUG0
|
|
359
|
-
return (false)
|
|
360
|
+
stats[Colamd::Status] = Colamd::ErrorANotPresent;
|
|
361
|
+
COLAMD_DEBUG0(("colamd: A not present\n"));
|
|
362
|
+
return (false);
|
|
360
363
|
}
|
|
361
|
-
|
|
362
|
-
if (!p)
|
|
364
|
+
|
|
365
|
+
if (!p) /* p is not present */
|
|
363
366
|
{
|
|
364
|
-
stats
|
|
365
|
-
COLAMD_DEBUG0
|
|
366
|
-
return (false)
|
|
367
|
+
stats[Colamd::Status] = Colamd::ErrorPNotPresent;
|
|
368
|
+
COLAMD_DEBUG0(("colamd: p not present\n"));
|
|
369
|
+
return (false);
|
|
367
370
|
}
|
|
368
|
-
|
|
369
|
-
if (n_row < 0)
|
|
371
|
+
|
|
372
|
+
if (n_row < 0) /* n_row must be >= 0 */
|
|
370
373
|
{
|
|
371
|
-
stats
|
|
372
|
-
stats
|
|
373
|
-
COLAMD_DEBUG0
|
|
374
|
-
return (false)
|
|
374
|
+
stats[Colamd::Status] = Colamd::ErrorNrowNegative;
|
|
375
|
+
stats[Colamd::Info1] = n_row;
|
|
376
|
+
COLAMD_DEBUG0(("colamd: nrow negative %d\n", n_row));
|
|
377
|
+
return (false);
|
|
375
378
|
}
|
|
376
|
-
|
|
377
|
-
if (n_col < 0)
|
|
379
|
+
|
|
380
|
+
if (n_col < 0) /* n_col must be >= 0 */
|
|
378
381
|
{
|
|
379
|
-
stats
|
|
380
|
-
stats
|
|
381
|
-
COLAMD_DEBUG0
|
|
382
|
-
return (false)
|
|
382
|
+
stats[Colamd::Status] = Colamd::ErrorNcolNegative;
|
|
383
|
+
stats[Colamd::Info1] = n_col;
|
|
384
|
+
COLAMD_DEBUG0(("colamd: ncol negative %d\n", n_col));
|
|
385
|
+
return (false);
|
|
383
386
|
}
|
|
384
|
-
|
|
385
|
-
nnz = p
|
|
386
|
-
if (nnz < 0)
|
|
387
|
+
|
|
388
|
+
nnz = p[n_col];
|
|
389
|
+
if (nnz < 0) /* nnz must be >= 0 */
|
|
387
390
|
{
|
|
388
|
-
stats
|
|
389
|
-
stats
|
|
390
|
-
COLAMD_DEBUG0
|
|
391
|
-
return (false)
|
|
391
|
+
stats[Colamd::Status] = Colamd::ErrorNnzNegative;
|
|
392
|
+
stats[Colamd::Info1] = nnz;
|
|
393
|
+
COLAMD_DEBUG0(("colamd: number of entries negative %d\n", nnz));
|
|
394
|
+
return (false);
|
|
392
395
|
}
|
|
393
|
-
|
|
394
|
-
if (p
|
|
395
|
-
|
|
396
|
-
stats
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
return (false) ;
|
|
396
|
+
|
|
397
|
+
if (p[0] != 0) {
|
|
398
|
+
stats[Colamd::Status] = Colamd::ErrorP0Nonzero;
|
|
399
|
+
stats[Colamd::Info1] = p[0];
|
|
400
|
+
COLAMD_DEBUG0(("colamd: p[0] not zero %d\n", p[0]));
|
|
401
|
+
return (false);
|
|
400
402
|
}
|
|
401
|
-
|
|
403
|
+
|
|
402
404
|
/* === If no knobs, set default knobs =================================== */
|
|
403
|
-
|
|
404
|
-
if (!knobs)
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
knobs = default_knobs ;
|
|
405
|
+
|
|
406
|
+
if (!knobs) {
|
|
407
|
+
set_defaults(default_knobs);
|
|
408
|
+
knobs = default_knobs;
|
|
408
409
|
}
|
|
409
|
-
|
|
410
|
+
|
|
410
411
|
/* === Allocate the Row and Col arrays from array A ===================== */
|
|
411
|
-
|
|
412
|
-
Col_size = colamd_c
|
|
413
|
-
Row_size = colamd_r
|
|
414
|
-
need = 2*nnz + n_col + Col_size + Row_size
|
|
415
|
-
|
|
416
|
-
if (need > Alen)
|
|
417
|
-
{
|
|
412
|
+
|
|
413
|
+
Col_size = colamd_c(n_col);
|
|
414
|
+
Row_size = colamd_r(n_row);
|
|
415
|
+
need = 2 * nnz + n_col + Col_size + Row_size;
|
|
416
|
+
|
|
417
|
+
if (need > Alen) {
|
|
418
418
|
/* not enough space in array A to perform the ordering */
|
|
419
|
-
stats
|
|
420
|
-
stats
|
|
421
|
-
stats
|
|
422
|
-
COLAMD_DEBUG0
|
|
423
|
-
return (false)
|
|
419
|
+
stats[Colamd::Status] = Colamd::ErrorATooSmall;
|
|
420
|
+
stats[Colamd::Info1] = need;
|
|
421
|
+
stats[Colamd::Info2] = Alen;
|
|
422
|
+
COLAMD_DEBUG0(("colamd: Need Alen >= %d, given only Alen = %d\n", need, Alen));
|
|
423
|
+
return (false);
|
|
424
424
|
}
|
|
425
|
-
|
|
426
|
-
Alen -= Col_size + Row_size
|
|
427
|
-
Col = (
|
|
428
|
-
Row = (
|
|
425
|
+
|
|
426
|
+
Alen -= Col_size + Row_size;
|
|
427
|
+
Col = (ColStructure<IndexType> *)&A[Alen];
|
|
428
|
+
Row = (RowStructure<IndexType> *)&A[Alen + Col_size];
|
|
429
429
|
|
|
430
430
|
/* === Construct the row and column data structures ===================== */
|
|
431
|
-
|
|
432
|
-
if (!
|
|
433
|
-
{
|
|
431
|
+
|
|
432
|
+
if (!Colamd::init_rows_cols(n_row, n_col, Row, Col, A, p, stats)) {
|
|
434
433
|
/* input matrix is invalid */
|
|
435
|
-
COLAMD_DEBUG0
|
|
436
|
-
return (false)
|
|
434
|
+
COLAMD_DEBUG0(("colamd: Matrix invalid\n"));
|
|
435
|
+
return (false);
|
|
437
436
|
}
|
|
438
|
-
|
|
437
|
+
|
|
439
438
|
/* === Initialize scores, kill dense rows/columns ======================= */
|
|
440
439
|
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
440
|
+
Colamd::init_scoring(n_row, n_col, Row, Col, A, p, knobs, &n_row2, &n_col2, &max_deg);
|
|
441
|
+
|
|
444
442
|
/* === Order the supercolumns =========================================== */
|
|
445
|
-
|
|
446
|
-
ngarbage =
|
|
447
|
-
|
|
448
|
-
|
|
443
|
+
|
|
444
|
+
ngarbage = Colamd::find_ordering(n_row, n_col, Alen, Row, Col, A, p, n_col2, max_deg, 2 * nnz);
|
|
445
|
+
|
|
449
446
|
/* === Order the non-principal columns ================================== */
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
447
|
+
|
|
448
|
+
Colamd::order_children(n_col, Col, p);
|
|
449
|
+
|
|
453
450
|
/* === Return statistics in stats ======================================= */
|
|
454
|
-
|
|
455
|
-
stats
|
|
456
|
-
stats
|
|
457
|
-
stats
|
|
458
|
-
COLAMD_DEBUG0
|
|
459
|
-
return (true)
|
|
451
|
+
|
|
452
|
+
stats[Colamd::DenseRow] = n_row - n_row2;
|
|
453
|
+
stats[Colamd::DenseCol] = n_col - n_col2;
|
|
454
|
+
stats[Colamd::DefragCount] = ngarbage;
|
|
455
|
+
COLAMD_DEBUG0(("colamd: done.\n"));
|
|
456
|
+
return (true);
|
|
460
457
|
}
|
|
461
458
|
|
|
462
459
|
/* ========================================================================== */
|
|
@@ -465,7 +462,6 @@ static bool colamd(IndexType n_row, IndexType n_col, IndexType Alen, IndexType *
|
|
|
465
462
|
|
|
466
463
|
/* There are no user-callable routines beyond this point in the file */
|
|
467
464
|
|
|
468
|
-
|
|
469
465
|
/* ========================================================================== */
|
|
470
466
|
/* === init_rows_cols ======================================================= */
|
|
471
467
|
/* ========================================================================== */
|
|
@@ -479,112 +475,102 @@ static bool colamd(IndexType n_row, IndexType n_col, IndexType Alen, IndexType *
|
|
|
479
475
|
true otherwise. Not user-callable.
|
|
480
476
|
*/
|
|
481
477
|
template <typename IndexType>
|
|
482
|
-
static IndexType init_rows_cols
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
)
|
|
494
|
-
{
|
|
478
|
+
static IndexType init_rows_cols /* returns true if OK, or false otherwise */
|
|
479
|
+
(
|
|
480
|
+
/* === Parameters ======================================================= */
|
|
481
|
+
|
|
482
|
+
IndexType n_row, /* number of rows of A */
|
|
483
|
+
IndexType n_col, /* number of columns of A */
|
|
484
|
+
RowStructure<IndexType> Row[], /* of size n_row+1 */
|
|
485
|
+
ColStructure<IndexType> Col[], /* of size n_col+1 */
|
|
486
|
+
IndexType A[], /* row indices of A, of size Alen */
|
|
487
|
+
IndexType p[], /* pointers to columns in A, of size n_col+1 */
|
|
488
|
+
IndexType stats[NStats] /* colamd statistics */
|
|
489
|
+
) {
|
|
495
490
|
/* === Local variables ================================================== */
|
|
496
491
|
|
|
497
|
-
IndexType col
|
|
498
|
-
IndexType row
|
|
499
|
-
IndexType *cp
|
|
500
|
-
IndexType *cp_end
|
|
501
|
-
IndexType *rp
|
|
502
|
-
IndexType *rp_end
|
|
503
|
-
IndexType last_row
|
|
492
|
+
IndexType col; /* a column index */
|
|
493
|
+
IndexType row; /* a row index */
|
|
494
|
+
IndexType *cp; /* a column pointer */
|
|
495
|
+
IndexType *cp_end; /* a pointer to the end of a column */
|
|
496
|
+
IndexType *rp; /* a row pointer */
|
|
497
|
+
IndexType *rp_end; /* a pointer to the end of a row */
|
|
498
|
+
IndexType last_row; /* previous row */
|
|
504
499
|
|
|
505
500
|
/* === Initialize columns, and check column pointers ==================== */
|
|
506
501
|
|
|
507
|
-
for (col = 0
|
|
508
|
-
|
|
509
|
-
Col
|
|
510
|
-
Col [col].length = p [col+1] - p [col] ;
|
|
502
|
+
for (col = 0; col < n_col; col++) {
|
|
503
|
+
Col[col].start = p[col];
|
|
504
|
+
Col[col].length = p[col + 1] - p[col];
|
|
511
505
|
|
|
512
|
-
if ((Col
|
|
506
|
+
if ((Col[col].length) < 0) // extra parentheses to work-around gcc bug 10200
|
|
513
507
|
{
|
|
514
508
|
/* column pointers must be non-decreasing */
|
|
515
|
-
stats
|
|
516
|
-
stats
|
|
517
|
-
stats
|
|
518
|
-
COLAMD_DEBUG0
|
|
519
|
-
return (false)
|
|
509
|
+
stats[Colamd::Status] = Colamd::ErrorColLengthNegative;
|
|
510
|
+
stats[Colamd::Info1] = col;
|
|
511
|
+
stats[Colamd::Info2] = Col[col].length;
|
|
512
|
+
COLAMD_DEBUG0(("colamd: col %d length %d < 0\n", col, Col[col].length));
|
|
513
|
+
return (false);
|
|
520
514
|
}
|
|
521
515
|
|
|
522
|
-
Col
|
|
523
|
-
Col
|
|
524
|
-
Col
|
|
525
|
-
Col
|
|
516
|
+
Col[col].shared1.thickness = 1;
|
|
517
|
+
Col[col].shared2.score = 0;
|
|
518
|
+
Col[col].shared3.prev = Empty;
|
|
519
|
+
Col[col].shared4.degree_next = Empty;
|
|
526
520
|
}
|
|
527
521
|
|
|
528
522
|
/* p [0..n_col] no longer needed, used as "head" in subsequent routines */
|
|
529
523
|
|
|
530
524
|
/* === Scan columns, compute row degrees, and check row indices ========= */
|
|
531
525
|
|
|
532
|
-
stats
|
|
526
|
+
stats[Info3] = 0; /* number of duplicate or unsorted row indices*/
|
|
533
527
|
|
|
534
|
-
for (row = 0
|
|
535
|
-
|
|
536
|
-
Row
|
|
537
|
-
Row [row].shared2.mark = -1 ;
|
|
528
|
+
for (row = 0; row < n_row; row++) {
|
|
529
|
+
Row[row].length = 0;
|
|
530
|
+
Row[row].shared2.mark = -1;
|
|
538
531
|
}
|
|
539
532
|
|
|
540
|
-
for (col = 0
|
|
541
|
-
|
|
542
|
-
last_row = -1 ;
|
|
533
|
+
for (col = 0; col < n_col; col++) {
|
|
534
|
+
last_row = -1;
|
|
543
535
|
|
|
544
|
-
cp = &A
|
|
545
|
-
cp_end = &A
|
|
536
|
+
cp = &A[p[col]];
|
|
537
|
+
cp_end = &A[p[col + 1]];
|
|
546
538
|
|
|
547
|
-
while (cp < cp_end)
|
|
548
|
-
|
|
549
|
-
row = *cp++ ;
|
|
539
|
+
while (cp < cp_end) {
|
|
540
|
+
row = *cp++;
|
|
550
541
|
|
|
551
542
|
/* make sure row indices within range */
|
|
552
|
-
if (row < 0 || row >= n_row)
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
return (false) ;
|
|
543
|
+
if (row < 0 || row >= n_row) {
|
|
544
|
+
stats[Colamd::Status] = Colamd::ErrorRowIndexOutOfBounds;
|
|
545
|
+
stats[Colamd::Info1] = col;
|
|
546
|
+
stats[Colamd::Info2] = row;
|
|
547
|
+
stats[Colamd::Info3] = n_row;
|
|
548
|
+
COLAMD_DEBUG0(("colamd: row %d col %d out of bounds\n", row, col));
|
|
549
|
+
return (false);
|
|
560
550
|
}
|
|
561
551
|
|
|
562
|
-
if (row <= last_row || Row
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
COLAMD_DEBUG1 (("colamd: row %d col %d unsorted/duplicate\n",row,col));
|
|
552
|
+
if (row <= last_row || Row[row].shared2.mark == col) {
|
|
553
|
+
/* row index are unsorted or repeated (or both), thus col */
|
|
554
|
+
/* is jumbled. This is a notice, not an error condition. */
|
|
555
|
+
stats[Colamd::Status] = Colamd::OkButJumbled;
|
|
556
|
+
stats[Colamd::Info1] = col;
|
|
557
|
+
stats[Colamd::Info2] = row;
|
|
558
|
+
(stats[Colamd::Info3])++;
|
|
559
|
+
COLAMD_DEBUG1(("colamd: row %d col %d unsorted/duplicate\n", row, col));
|
|
571
560
|
}
|
|
572
561
|
|
|
573
|
-
if (Row
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
/* this is a repeated entry in the column, */
|
|
580
|
-
/* it will be removed */
|
|
581
|
-
Col [col].length-- ;
|
|
562
|
+
if (Row[row].shared2.mark != col) {
|
|
563
|
+
Row[row].length++;
|
|
564
|
+
} else {
|
|
565
|
+
/* this is a repeated entry in the column, */
|
|
566
|
+
/* it will be removed */
|
|
567
|
+
Col[col].length--;
|
|
582
568
|
}
|
|
583
569
|
|
|
584
570
|
/* mark the row as having been seen in this column */
|
|
585
|
-
Row
|
|
571
|
+
Row[row].shared2.mark = col;
|
|
586
572
|
|
|
587
|
-
last_row = row
|
|
573
|
+
last_row = row;
|
|
588
574
|
}
|
|
589
575
|
}
|
|
590
576
|
|
|
@@ -592,64 +578,52 @@ static IndexType init_rows_cols /* returns true if OK, or false otherwise */
|
|
|
592
578
|
|
|
593
579
|
/* row form of the matrix starts directly after the column */
|
|
594
580
|
/* form of matrix in A */
|
|
595
|
-
Row
|
|
596
|
-
Row
|
|
597
|
-
Row
|
|
598
|
-
for (row = 1
|
|
599
|
-
|
|
600
|
-
Row
|
|
601
|
-
Row
|
|
602
|
-
Row [row].shared2.mark = -1 ;
|
|
581
|
+
Row[0].start = p[n_col];
|
|
582
|
+
Row[0].shared1.p = Row[0].start;
|
|
583
|
+
Row[0].shared2.mark = -1;
|
|
584
|
+
for (row = 1; row < n_row; row++) {
|
|
585
|
+
Row[row].start = Row[row - 1].start + Row[row - 1].length;
|
|
586
|
+
Row[row].shared1.p = Row[row].start;
|
|
587
|
+
Row[row].shared2.mark = -1;
|
|
603
588
|
}
|
|
604
589
|
|
|
605
590
|
/* === Create row form ================================================== */
|
|
606
591
|
|
|
607
|
-
if (stats
|
|
608
|
-
{
|
|
592
|
+
if (stats[Status] == OkButJumbled) {
|
|
609
593
|
/* if cols jumbled, watch for repeated row indices */
|
|
610
|
-
for (col = 0
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
A [(Row [row].shared1.p)++] = col ;
|
|
620
|
-
Row [row].shared2.mark = col ;
|
|
621
|
-
}
|
|
594
|
+
for (col = 0; col < n_col; col++) {
|
|
595
|
+
cp = &A[p[col]];
|
|
596
|
+
cp_end = &A[p[col + 1]];
|
|
597
|
+
while (cp < cp_end) {
|
|
598
|
+
row = *cp++;
|
|
599
|
+
if (Row[row].shared2.mark != col) {
|
|
600
|
+
A[(Row[row].shared1.p)++] = col;
|
|
601
|
+
Row[row].shared2.mark = col;
|
|
602
|
+
}
|
|
622
603
|
}
|
|
623
604
|
}
|
|
624
|
-
}
|
|
625
|
-
else
|
|
626
|
-
{
|
|
605
|
+
} else {
|
|
627
606
|
/* if cols not jumbled, we don't need the mark (this is faster) */
|
|
628
|
-
for (col = 0
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
{
|
|
634
|
-
A [(Row [*cp++].shared1.p)++] = col ;
|
|
607
|
+
for (col = 0; col < n_col; col++) {
|
|
608
|
+
cp = &A[p[col]];
|
|
609
|
+
cp_end = &A[p[col + 1]];
|
|
610
|
+
while (cp < cp_end) {
|
|
611
|
+
A[(Row[*cp++].shared1.p)++] = col;
|
|
635
612
|
}
|
|
636
613
|
}
|
|
637
614
|
}
|
|
638
615
|
|
|
639
616
|
/* === Clear the row marks and set row degrees ========================== */
|
|
640
617
|
|
|
641
|
-
for (row = 0
|
|
642
|
-
|
|
643
|
-
Row
|
|
644
|
-
Row [row].shared1.degree = Row [row].length ;
|
|
618
|
+
for (row = 0; row < n_row; row++) {
|
|
619
|
+
Row[row].shared2.mark = 0;
|
|
620
|
+
Row[row].shared1.degree = Row[row].length;
|
|
645
621
|
}
|
|
646
622
|
|
|
647
623
|
/* === See if we need to re-create columns ============================== */
|
|
648
624
|
|
|
649
|
-
if (stats
|
|
650
|
-
|
|
651
|
-
COLAMD_DEBUG0 (("colamd: reconstructing column form, matrix jumbled\n")) ;
|
|
652
|
-
|
|
625
|
+
if (stats[Status] == OkButJumbled) {
|
|
626
|
+
COLAMD_DEBUG0(("colamd: reconstructing column form, matrix jumbled\n"));
|
|
653
627
|
|
|
654
628
|
/* === Compute col pointers ========================================= */
|
|
655
629
|
|
|
@@ -657,35 +631,31 @@ static IndexType init_rows_cols /* returns true if OK, or false otherwise */
|
|
|
657
631
|
/* Note, we may have a gap between the col form and the row */
|
|
658
632
|
/* form if there were duplicate entries, if so, it will be */
|
|
659
633
|
/* removed upon the first garbage collection */
|
|
660
|
-
Col
|
|
661
|
-
p
|
|
662
|
-
for (col = 1
|
|
663
|
-
{
|
|
634
|
+
Col[0].start = 0;
|
|
635
|
+
p[0] = Col[0].start;
|
|
636
|
+
for (col = 1; col < n_col; col++) {
|
|
664
637
|
/* note that the lengths here are for pruned columns, i.e. */
|
|
665
638
|
/* no duplicate row indices will exist for these columns */
|
|
666
|
-
Col
|
|
667
|
-
p
|
|
639
|
+
Col[col].start = Col[col - 1].start + Col[col - 1].length;
|
|
640
|
+
p[col] = Col[col].start;
|
|
668
641
|
}
|
|
669
642
|
|
|
670
643
|
/* === Re-create col form =========================================== */
|
|
671
644
|
|
|
672
|
-
for (row = 0
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
{
|
|
678
|
-
A [(p [*rp++])++] = row ;
|
|
645
|
+
for (row = 0; row < n_row; row++) {
|
|
646
|
+
rp = &A[Row[row].start];
|
|
647
|
+
rp_end = rp + Row[row].length;
|
|
648
|
+
while (rp < rp_end) {
|
|
649
|
+
A[(p[*rp++])++] = row;
|
|
679
650
|
}
|
|
680
651
|
}
|
|
681
652
|
}
|
|
682
653
|
|
|
683
654
|
/* === Done. Matrix is not (or no longer) jumbled ====================== */
|
|
684
655
|
|
|
685
|
-
return (true)
|
|
656
|
+
return (true);
|
|
686
657
|
}
|
|
687
658
|
|
|
688
|
-
|
|
689
659
|
/* ========================================================================== */
|
|
690
660
|
/* === init_scoring ========================================================= */
|
|
691
661
|
/* ========================================================================== */
|
|
@@ -695,112 +665,99 @@ static IndexType init_rows_cols /* returns true if OK, or false otherwise */
|
|
|
695
665
|
each column, and places all columns in the degree lists. Not user-callable.
|
|
696
666
|
*/
|
|
697
667
|
template <typename IndexType>
|
|
698
|
-
static void init_scoring
|
|
699
|
-
(
|
|
668
|
+
static void init_scoring(
|
|
700
669
|
/* === Parameters ======================================================= */
|
|
701
670
|
|
|
702
|
-
IndexType n_row,
|
|
703
|
-
IndexType n_col,
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
IndexType A
|
|
707
|
-
IndexType head
|
|
708
|
-
double knobs
|
|
709
|
-
IndexType *p_n_row2,
|
|
710
|
-
IndexType *p_n_col2,
|
|
711
|
-
IndexType *p_max_deg
|
|
712
|
-
|
|
713
|
-
{
|
|
671
|
+
IndexType n_row, /* number of rows of A */
|
|
672
|
+
IndexType n_col, /* number of columns of A */
|
|
673
|
+
RowStructure<IndexType> Row[], /* of size n_row+1 */
|
|
674
|
+
ColStructure<IndexType> Col[], /* of size n_col+1 */
|
|
675
|
+
IndexType A[], /* column form and row form of A */
|
|
676
|
+
IndexType head[], /* of size n_col+1 */
|
|
677
|
+
double knobs[NKnobs], /* parameters */
|
|
678
|
+
IndexType *p_n_row2, /* number of non-dense, non-empty rows */
|
|
679
|
+
IndexType *p_n_col2, /* number of non-dense, non-empty columns */
|
|
680
|
+
IndexType *p_max_deg /* maximum row degree */
|
|
681
|
+
) {
|
|
714
682
|
/* === Local variables ================================================== */
|
|
715
683
|
|
|
716
|
-
IndexType c
|
|
717
|
-
IndexType r, row
|
|
718
|
-
IndexType *cp
|
|
719
|
-
IndexType deg
|
|
720
|
-
IndexType *cp_end
|
|
721
|
-
IndexType *new_cp
|
|
722
|
-
IndexType col_length
|
|
723
|
-
IndexType score
|
|
724
|
-
IndexType n_col2
|
|
725
|
-
IndexType n_row2
|
|
726
|
-
IndexType dense_row_count
|
|
727
|
-
IndexType dense_col_count
|
|
728
|
-
IndexType min_score
|
|
729
|
-
IndexType max_deg
|
|
730
|
-
IndexType next_col
|
|
731
|
-
|
|
684
|
+
IndexType c; /* a column index */
|
|
685
|
+
IndexType r, row; /* a row index */
|
|
686
|
+
IndexType *cp; /* a column pointer */
|
|
687
|
+
IndexType deg; /* degree of a row or column */
|
|
688
|
+
IndexType *cp_end; /* a pointer to the end of a column */
|
|
689
|
+
IndexType *new_cp; /* new column pointer */
|
|
690
|
+
IndexType col_length; /* length of pruned column */
|
|
691
|
+
IndexType score; /* current column score */
|
|
692
|
+
IndexType n_col2; /* number of non-dense, non-empty columns */
|
|
693
|
+
IndexType n_row2; /* number of non-dense, non-empty rows */
|
|
694
|
+
IndexType dense_row_count; /* remove rows with more entries than this */
|
|
695
|
+
IndexType dense_col_count; /* remove cols with more entries than this */
|
|
696
|
+
IndexType min_score; /* smallest column score */
|
|
697
|
+
IndexType max_deg; /* maximum row degree */
|
|
698
|
+
IndexType next_col; /* Used to add to degree list.*/
|
|
732
699
|
|
|
733
700
|
/* === Extract knobs ==================================================== */
|
|
734
701
|
|
|
735
|
-
dense_row_count = numext::maxi(IndexType(0), numext::mini(IndexType(knobs
|
|
736
|
-
dense_col_count = numext::maxi(IndexType(0), numext::mini(IndexType(knobs
|
|
737
|
-
COLAMD_DEBUG1
|
|
738
|
-
max_deg = 0
|
|
739
|
-
n_col2 = n_col
|
|
740
|
-
n_row2 = n_row
|
|
702
|
+
dense_row_count = numext::maxi(IndexType(0), numext::mini(IndexType(knobs[Colamd::DenseRow] * n_col), n_col));
|
|
703
|
+
dense_col_count = numext::maxi(IndexType(0), numext::mini(IndexType(knobs[Colamd::DenseCol] * n_row), n_row));
|
|
704
|
+
COLAMD_DEBUG1(("colamd: densecount: %d %d\n", dense_row_count, dense_col_count));
|
|
705
|
+
max_deg = 0;
|
|
706
|
+
n_col2 = n_col;
|
|
707
|
+
n_row2 = n_row;
|
|
741
708
|
|
|
742
709
|
/* === Kill empty columns =============================================== */
|
|
743
710
|
|
|
744
711
|
/* Put the empty columns at the end in their natural order, so that LU */
|
|
745
712
|
/* factorization can proceed as far as possible. */
|
|
746
|
-
for (c = n_col-1
|
|
747
|
-
|
|
748
|
-
deg
|
|
749
|
-
if (deg == 0)
|
|
750
|
-
{
|
|
713
|
+
for (c = n_col - 1; c >= 0; c--) {
|
|
714
|
+
deg = Col[c].length;
|
|
715
|
+
if (deg == 0) {
|
|
751
716
|
/* this is a empty column, kill and order it last */
|
|
752
|
-
Col
|
|
753
|
-
|
|
717
|
+
Col[c].shared2.order = --n_col2;
|
|
718
|
+
Col[c].kill_principal();
|
|
754
719
|
}
|
|
755
720
|
}
|
|
756
|
-
COLAMD_DEBUG1
|
|
721
|
+
COLAMD_DEBUG1(("colamd: null columns killed: %d\n", n_col - n_col2));
|
|
757
722
|
|
|
758
723
|
/* === Kill dense columns =============================================== */
|
|
759
724
|
|
|
760
725
|
/* Put the dense columns at the end, in their natural order */
|
|
761
|
-
for (c = n_col-1
|
|
762
|
-
{
|
|
726
|
+
for (c = n_col - 1; c >= 0; c--) {
|
|
763
727
|
/* skip any dead columns */
|
|
764
|
-
if (
|
|
765
|
-
|
|
766
|
-
continue ;
|
|
728
|
+
if (Col[c].is_dead()) {
|
|
729
|
+
continue;
|
|
767
730
|
}
|
|
768
|
-
deg = Col
|
|
769
|
-
if (deg > dense_col_count)
|
|
770
|
-
{
|
|
731
|
+
deg = Col[c].length;
|
|
732
|
+
if (deg > dense_col_count) {
|
|
771
733
|
/* this is a dense column, kill and order it last */
|
|
772
|
-
Col
|
|
734
|
+
Col[c].shared2.order = --n_col2;
|
|
773
735
|
/* decrement the row degrees */
|
|
774
|
-
cp = &A
|
|
775
|
-
cp_end = cp + Col
|
|
776
|
-
while (cp < cp_end)
|
|
777
|
-
|
|
778
|
-
Row [*cp++].shared1.degree-- ;
|
|
736
|
+
cp = &A[Col[c].start];
|
|
737
|
+
cp_end = cp + Col[c].length;
|
|
738
|
+
while (cp < cp_end) {
|
|
739
|
+
Row[*cp++].shared1.degree--;
|
|
779
740
|
}
|
|
780
|
-
|
|
741
|
+
Col[c].kill_principal();
|
|
781
742
|
}
|
|
782
743
|
}
|
|
783
|
-
COLAMD_DEBUG1
|
|
744
|
+
COLAMD_DEBUG1(("colamd: Dense and null columns killed: %d\n", n_col - n_col2));
|
|
784
745
|
|
|
785
746
|
/* === Kill dense and empty rows ======================================== */
|
|
786
747
|
|
|
787
|
-
for (r = 0
|
|
788
|
-
|
|
789
|
-
deg
|
|
790
|
-
|
|
791
|
-
if (deg > dense_row_count || deg == 0)
|
|
792
|
-
{
|
|
748
|
+
for (r = 0; r < n_row; r++) {
|
|
749
|
+
deg = Row[r].shared1.degree;
|
|
750
|
+
COLAMD_ASSERT(deg >= 0 && deg <= n_col);
|
|
751
|
+
if (deg > dense_row_count || deg == 0) {
|
|
793
752
|
/* kill a dense or empty row */
|
|
794
|
-
|
|
795
|
-
--n_row2
|
|
796
|
-
}
|
|
797
|
-
else
|
|
798
|
-
{
|
|
753
|
+
Row[r].kill();
|
|
754
|
+
--n_row2;
|
|
755
|
+
} else {
|
|
799
756
|
/* keep track of max degree of remaining rows */
|
|
800
|
-
max_deg = numext::maxi(max_deg, deg)
|
|
757
|
+
max_deg = numext::maxi(max_deg, deg);
|
|
801
758
|
}
|
|
802
759
|
}
|
|
803
|
-
COLAMD_DEBUG1
|
|
760
|
+
COLAMD_DEBUG1(("colamd: Dense and null rows killed: %d\n", n_row - n_row2));
|
|
804
761
|
|
|
805
762
|
/* === Compute initial column scores ==================================== */
|
|
806
763
|
|
|
@@ -810,54 +767,46 @@ static void init_scoring
|
|
|
810
767
|
/* pruned in the code below. */
|
|
811
768
|
|
|
812
769
|
/* now find the initial matlab score for each column */
|
|
813
|
-
for (c = n_col-1
|
|
814
|
-
{
|
|
770
|
+
for (c = n_col - 1; c >= 0; c--) {
|
|
815
771
|
/* skip dead column */
|
|
816
|
-
if (
|
|
817
|
-
|
|
818
|
-
continue ;
|
|
772
|
+
if (Col[c].is_dead()) {
|
|
773
|
+
continue;
|
|
819
774
|
}
|
|
820
|
-
score = 0
|
|
821
|
-
cp = &A
|
|
822
|
-
new_cp = cp
|
|
823
|
-
cp_end = cp + Col
|
|
824
|
-
while (cp < cp_end)
|
|
825
|
-
{
|
|
775
|
+
score = 0;
|
|
776
|
+
cp = &A[Col[c].start];
|
|
777
|
+
new_cp = cp;
|
|
778
|
+
cp_end = cp + Col[c].length;
|
|
779
|
+
while (cp < cp_end) {
|
|
826
780
|
/* get a row */
|
|
827
|
-
row = *cp
|
|
781
|
+
row = *cp++;
|
|
828
782
|
/* skip if dead */
|
|
829
|
-
if (
|
|
830
|
-
|
|
831
|
-
continue ;
|
|
783
|
+
if (Row[row].is_dead()) {
|
|
784
|
+
continue;
|
|
832
785
|
}
|
|
833
786
|
/* compact the column */
|
|
834
|
-
*new_cp++ = row
|
|
787
|
+
*new_cp++ = row;
|
|
835
788
|
/* add row's external degree */
|
|
836
|
-
score += Row
|
|
789
|
+
score += Row[row].shared1.degree - 1;
|
|
837
790
|
/* guard against integer overflow */
|
|
838
|
-
score = numext::mini(score, n_col)
|
|
791
|
+
score = numext::mini(score, n_col);
|
|
839
792
|
}
|
|
840
793
|
/* determine pruned column length */
|
|
841
|
-
col_length = (IndexType)
|
|
842
|
-
if (col_length == 0)
|
|
843
|
-
{
|
|
794
|
+
col_length = (IndexType)(new_cp - &A[Col[c].start]);
|
|
795
|
+
if (col_length == 0) {
|
|
844
796
|
/* a newly-made null column (all rows in this col are "dense" */
|
|
845
797
|
/* and have already been killed) */
|
|
846
|
-
COLAMD_DEBUG2
|
|
847
|
-
Col
|
|
848
|
-
|
|
849
|
-
}
|
|
850
|
-
else
|
|
851
|
-
{
|
|
798
|
+
COLAMD_DEBUG2(("Newly null killed: %d\n", c));
|
|
799
|
+
Col[c].shared2.order = --n_col2;
|
|
800
|
+
Col[c].kill_principal();
|
|
801
|
+
} else {
|
|
852
802
|
/* set column length and set score */
|
|
853
|
-
COLAMD_ASSERT
|
|
854
|
-
COLAMD_ASSERT
|
|
855
|
-
Col
|
|
856
|
-
Col
|
|
803
|
+
COLAMD_ASSERT(score >= 0);
|
|
804
|
+
COLAMD_ASSERT(score <= n_col);
|
|
805
|
+
Col[c].length = col_length;
|
|
806
|
+
Col[c].shared2.score = score;
|
|
857
807
|
}
|
|
858
808
|
}
|
|
859
|
-
COLAMD_DEBUG1
|
|
860
|
-
n_col-n_col2)) ;
|
|
809
|
+
COLAMD_DEBUG1(("colamd: Dense, null, and newly-null columns killed: %d\n", n_col - n_col2));
|
|
861
810
|
|
|
862
811
|
/* At this point, all empty rows and columns are dead. All live columns */
|
|
863
812
|
/* are "clean" (containing no dead rows) and simplicial (no supercolumns */
|
|
@@ -866,62 +815,52 @@ static void init_scoring
|
|
|
866
815
|
|
|
867
816
|
/* === Initialize degree lists ========================================== */
|
|
868
817
|
|
|
869
|
-
|
|
870
818
|
/* clear the hash buckets */
|
|
871
|
-
for (c = 0
|
|
872
|
-
|
|
873
|
-
head [c] = COLAMD_EMPTY ;
|
|
819
|
+
for (c = 0; c <= n_col; c++) {
|
|
820
|
+
head[c] = Empty;
|
|
874
821
|
}
|
|
875
|
-
min_score = n_col
|
|
822
|
+
min_score = n_col;
|
|
876
823
|
/* place in reverse order, so low column indices are at the front */
|
|
877
824
|
/* of the lists. This is to encourage natural tie-breaking */
|
|
878
|
-
for (c = n_col-1
|
|
879
|
-
{
|
|
825
|
+
for (c = n_col - 1; c >= 0; c--) {
|
|
880
826
|
/* only add principal columns to degree lists */
|
|
881
|
-
if (
|
|
882
|
-
|
|
883
|
-
COLAMD_DEBUG4 (("place %d score %d minscore %d ncol %d\n",
|
|
884
|
-
c, Col [c].shared2.score, min_score, n_col)) ;
|
|
827
|
+
if (Col[c].is_alive()) {
|
|
828
|
+
COLAMD_DEBUG4(("place %d score %d minscore %d ncol %d\n", c, Col[c].shared2.score, min_score, n_col));
|
|
885
829
|
|
|
886
830
|
/* === Add columns score to DList =============================== */
|
|
887
831
|
|
|
888
|
-
score = Col
|
|
832
|
+
score = Col[c].shared2.score;
|
|
889
833
|
|
|
890
|
-
COLAMD_ASSERT
|
|
891
|
-
COLAMD_ASSERT
|
|
892
|
-
COLAMD_ASSERT
|
|
893
|
-
COLAMD_ASSERT
|
|
894
|
-
COLAMD_ASSERT
|
|
834
|
+
COLAMD_ASSERT(min_score >= 0);
|
|
835
|
+
COLAMD_ASSERT(min_score <= n_col);
|
|
836
|
+
COLAMD_ASSERT(score >= 0);
|
|
837
|
+
COLAMD_ASSERT(score <= n_col);
|
|
838
|
+
COLAMD_ASSERT(head[score] >= Empty);
|
|
895
839
|
|
|
896
840
|
/* now add this column to dList at proper score location */
|
|
897
|
-
next_col = head
|
|
898
|
-
Col
|
|
899
|
-
Col
|
|
841
|
+
next_col = head[score];
|
|
842
|
+
Col[c].shared3.prev = Empty;
|
|
843
|
+
Col[c].shared4.degree_next = next_col;
|
|
900
844
|
|
|
901
845
|
/* if there already was a column with the same score, set its */
|
|
902
846
|
/* previous pointer to this new column */
|
|
903
|
-
if (next_col !=
|
|
904
|
-
|
|
905
|
-
Col [next_col].shared3.prev = c ;
|
|
847
|
+
if (next_col != Empty) {
|
|
848
|
+
Col[next_col].shared3.prev = c;
|
|
906
849
|
}
|
|
907
|
-
head
|
|
850
|
+
head[score] = c;
|
|
908
851
|
|
|
909
852
|
/* see if this score is less than current min */
|
|
910
|
-
min_score = numext::mini(min_score, score)
|
|
911
|
-
|
|
912
|
-
|
|
853
|
+
min_score = numext::mini(min_score, score);
|
|
913
854
|
}
|
|
914
855
|
}
|
|
915
856
|
|
|
916
|
-
|
|
917
857
|
/* === Return number of remaining columns, and max row degree =========== */
|
|
918
858
|
|
|
919
|
-
*p_n_col2 = n_col2
|
|
920
|
-
*p_n_row2 = n_row2
|
|
921
|
-
*p_max_deg = max_deg
|
|
859
|
+
*p_n_col2 = n_col2;
|
|
860
|
+
*p_n_row2 = n_row2;
|
|
861
|
+
*p_max_deg = max_deg;
|
|
922
862
|
}
|
|
923
863
|
|
|
924
|
-
|
|
925
864
|
/* ========================================================================== */
|
|
926
865
|
/* === find_ordering ======================================================== */
|
|
927
866
|
/* ========================================================================== */
|
|
@@ -933,197 +872,180 @@ static void init_scoring
|
|
|
933
872
|
*/
|
|
934
873
|
template <typename IndexType>
|
|
935
874
|
static IndexType find_ordering /* return the number of garbage collections */
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
)
|
|
950
|
-
{
|
|
875
|
+
(
|
|
876
|
+
/* === Parameters ======================================================= */
|
|
877
|
+
|
|
878
|
+
IndexType n_row, /* number of rows of A */
|
|
879
|
+
IndexType n_col, /* number of columns of A */
|
|
880
|
+
IndexType Alen, /* size of A, 2*nnz + n_col or larger */
|
|
881
|
+
RowStructure<IndexType> Row[], /* of size n_row+1 */
|
|
882
|
+
ColStructure<IndexType> Col[], /* of size n_col+1 */
|
|
883
|
+
IndexType A[], /* column form and row form of A */
|
|
884
|
+
IndexType head[], /* of size n_col+1 */
|
|
885
|
+
IndexType n_col2, /* Remaining columns to order */
|
|
886
|
+
IndexType max_deg, /* Maximum row degree */
|
|
887
|
+
IndexType pfree /* index of first free slot (2*nnz on entry) */
|
|
888
|
+
) {
|
|
951
889
|
/* === Local variables ================================================== */
|
|
952
890
|
|
|
953
|
-
IndexType k
|
|
954
|
-
IndexType pivot_col
|
|
955
|
-
IndexType *cp
|
|
956
|
-
IndexType *rp
|
|
957
|
-
IndexType pivot_row
|
|
958
|
-
IndexType *new_cp
|
|
959
|
-
IndexType *new_rp
|
|
960
|
-
IndexType pivot_row_start
|
|
961
|
-
IndexType pivot_row_degree
|
|
962
|
-
IndexType pivot_row_length
|
|
963
|
-
IndexType pivot_col_score
|
|
964
|
-
IndexType needed_memory
|
|
965
|
-
IndexType *cp_end
|
|
966
|
-
IndexType *rp_end
|
|
967
|
-
IndexType row
|
|
968
|
-
IndexType col
|
|
969
|
-
IndexType max_score
|
|
970
|
-
IndexType cur_score
|
|
971
|
-
unsigned int hash
|
|
972
|
-
IndexType head_column
|
|
973
|
-
IndexType first_col
|
|
974
|
-
IndexType tag_mark
|
|
975
|
-
IndexType row_mark
|
|
976
|
-
IndexType set_difference
|
|
977
|
-
IndexType min_score
|
|
978
|
-
IndexType col_thickness
|
|
979
|
-
IndexType max_mark
|
|
980
|
-
IndexType pivot_col_thickness
|
|
981
|
-
IndexType prev_col
|
|
982
|
-
IndexType next_col
|
|
983
|
-
IndexType ngarbage
|
|
984
|
-
|
|
891
|
+
IndexType k; /* current pivot ordering step */
|
|
892
|
+
IndexType pivot_col; /* current pivot column */
|
|
893
|
+
IndexType *cp; /* a column pointer */
|
|
894
|
+
IndexType *rp; /* a row pointer */
|
|
895
|
+
IndexType pivot_row; /* current pivot row */
|
|
896
|
+
IndexType *new_cp; /* modified column pointer */
|
|
897
|
+
IndexType *new_rp; /* modified row pointer */
|
|
898
|
+
IndexType pivot_row_start; /* pointer to start of pivot row */
|
|
899
|
+
IndexType pivot_row_degree; /* number of columns in pivot row */
|
|
900
|
+
IndexType pivot_row_length; /* number of supercolumns in pivot row */
|
|
901
|
+
IndexType pivot_col_score; /* score of pivot column */
|
|
902
|
+
IndexType needed_memory; /* free space needed for pivot row */
|
|
903
|
+
IndexType *cp_end; /* pointer to the end of a column */
|
|
904
|
+
IndexType *rp_end; /* pointer to the end of a row */
|
|
905
|
+
IndexType row; /* a row index */
|
|
906
|
+
IndexType col; /* a column index */
|
|
907
|
+
IndexType max_score; /* maximum possible score */
|
|
908
|
+
IndexType cur_score; /* score of current column */
|
|
909
|
+
unsigned int hash; /* hash value for supernode detection */
|
|
910
|
+
IndexType head_column; /* head of hash bucket */
|
|
911
|
+
IndexType first_col; /* first column in hash bucket */
|
|
912
|
+
IndexType tag_mark; /* marker value for mark array */
|
|
913
|
+
IndexType row_mark; /* Row [row].shared2.mark */
|
|
914
|
+
IndexType set_difference; /* set difference size of row with pivot row */
|
|
915
|
+
IndexType min_score; /* smallest column score */
|
|
916
|
+
IndexType col_thickness; /* "thickness" (no. of columns in a supercol) */
|
|
917
|
+
IndexType max_mark; /* maximum value of tag_mark */
|
|
918
|
+
IndexType pivot_col_thickness; /* number of columns represented by pivot col */
|
|
919
|
+
IndexType prev_col; /* Used by Dlist operations. */
|
|
920
|
+
IndexType next_col; /* Used by Dlist operations. */
|
|
921
|
+
IndexType ngarbage; /* number of garbage collections performed */
|
|
985
922
|
|
|
986
923
|
/* === Initialization and clear mark ==================================== */
|
|
987
924
|
|
|
988
|
-
max_mark = INT_MAX - n_col
|
|
989
|
-
tag_mark =
|
|
990
|
-
min_score = 0
|
|
991
|
-
ngarbage = 0
|
|
992
|
-
COLAMD_DEBUG1
|
|
925
|
+
max_mark = INT_MAX - n_col; /* INT_MAX defined in <limits.h> */
|
|
926
|
+
tag_mark = Colamd::clear_mark(n_row, Row);
|
|
927
|
+
min_score = 0;
|
|
928
|
+
ngarbage = 0;
|
|
929
|
+
COLAMD_DEBUG1(("colamd: Ordering, n_col2=%d\n", n_col2));
|
|
993
930
|
|
|
994
931
|
/* === Order the columns ================================================ */
|
|
995
932
|
|
|
996
|
-
for (k = 0
|
|
997
|
-
{
|
|
998
|
-
|
|
933
|
+
for (k = 0; k < n_col2; /* 'k' is incremented below */) {
|
|
999
934
|
/* === Select pivot column, and order it ============================ */
|
|
1000
935
|
|
|
1001
936
|
/* make sure degree list isn't empty */
|
|
1002
|
-
COLAMD_ASSERT
|
|
1003
|
-
COLAMD_ASSERT
|
|
1004
|
-
COLAMD_ASSERT
|
|
937
|
+
COLAMD_ASSERT(min_score >= 0);
|
|
938
|
+
COLAMD_ASSERT(min_score <= n_col);
|
|
939
|
+
COLAMD_ASSERT(head[min_score] >= Empty);
|
|
1005
940
|
|
|
1006
941
|
/* get pivot column from head of minimum degree list */
|
|
1007
|
-
while (min_score < n_col && head
|
|
1008
|
-
|
|
1009
|
-
min_score++ ;
|
|
942
|
+
while (min_score < n_col && head[min_score] == Empty) {
|
|
943
|
+
min_score++;
|
|
1010
944
|
}
|
|
1011
|
-
pivot_col = head
|
|
1012
|
-
COLAMD_ASSERT
|
|
1013
|
-
next_col = Col
|
|
1014
|
-
head
|
|
1015
|
-
if (next_col !=
|
|
1016
|
-
|
|
1017
|
-
Col [next_col].shared3.prev = COLAMD_EMPTY ;
|
|
945
|
+
pivot_col = head[min_score];
|
|
946
|
+
COLAMD_ASSERT(pivot_col >= 0 && pivot_col <= n_col);
|
|
947
|
+
next_col = Col[pivot_col].shared4.degree_next;
|
|
948
|
+
head[min_score] = next_col;
|
|
949
|
+
if (next_col != Empty) {
|
|
950
|
+
Col[next_col].shared3.prev = Empty;
|
|
1018
951
|
}
|
|
1019
952
|
|
|
1020
|
-
COLAMD_ASSERT
|
|
1021
|
-
COLAMD_DEBUG3
|
|
953
|
+
COLAMD_ASSERT(Col[pivot_col].is_alive());
|
|
954
|
+
COLAMD_DEBUG3(("Pivot col: %d\n", pivot_col));
|
|
1022
955
|
|
|
1023
956
|
/* remember score for defrag check */
|
|
1024
|
-
pivot_col_score = Col
|
|
957
|
+
pivot_col_score = Col[pivot_col].shared2.score;
|
|
1025
958
|
|
|
1026
959
|
/* the pivot column is the kth column in the pivot order */
|
|
1027
|
-
Col
|
|
960
|
+
Col[pivot_col].shared2.order = k;
|
|
1028
961
|
|
|
1029
962
|
/* increment order count by column thickness */
|
|
1030
|
-
pivot_col_thickness = Col
|
|
1031
|
-
k += pivot_col_thickness
|
|
1032
|
-
COLAMD_ASSERT
|
|
963
|
+
pivot_col_thickness = Col[pivot_col].shared1.thickness;
|
|
964
|
+
k += pivot_col_thickness;
|
|
965
|
+
COLAMD_ASSERT(pivot_col_thickness > 0);
|
|
1033
966
|
|
|
1034
967
|
/* === Garbage_collection, if necessary ============================= */
|
|
1035
968
|
|
|
1036
|
-
needed_memory = numext::mini(pivot_col_score, n_col - k)
|
|
1037
|
-
if (pfree + needed_memory >= Alen)
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
ngarbage++ ;
|
|
969
|
+
needed_memory = numext::mini(pivot_col_score, n_col - k);
|
|
970
|
+
if (pfree + needed_memory >= Alen) {
|
|
971
|
+
pfree = Colamd::garbage_collection(n_row, n_col, Row, Col, A, &A[pfree]);
|
|
972
|
+
ngarbage++;
|
|
1041
973
|
/* after garbage collection we will have enough */
|
|
1042
|
-
COLAMD_ASSERT
|
|
974
|
+
COLAMD_ASSERT(pfree + needed_memory < Alen);
|
|
1043
975
|
/* garbage collection has wiped out the Row[].shared2.mark array */
|
|
1044
|
-
tag_mark =
|
|
1045
|
-
|
|
976
|
+
tag_mark = Colamd::clear_mark(n_row, Row);
|
|
1046
977
|
}
|
|
1047
978
|
|
|
1048
979
|
/* === Compute pivot row pattern ==================================== */
|
|
1049
980
|
|
|
1050
981
|
/* get starting location for this new merged row */
|
|
1051
|
-
pivot_row_start = pfree
|
|
982
|
+
pivot_row_start = pfree;
|
|
1052
983
|
|
|
1053
984
|
/* initialize new row counts to zero */
|
|
1054
|
-
pivot_row_degree = 0
|
|
985
|
+
pivot_row_degree = 0;
|
|
1055
986
|
|
|
1056
987
|
/* tag pivot column as having been visited so it isn't included */
|
|
1057
988
|
/* in merged pivot row */
|
|
1058
|
-
Col
|
|
989
|
+
Col[pivot_col].shared1.thickness = -pivot_col_thickness;
|
|
1059
990
|
|
|
1060
991
|
/* pivot row is the union of all rows in the pivot column pattern */
|
|
1061
|
-
cp = &A
|
|
1062
|
-
cp_end = cp + Col
|
|
1063
|
-
while (cp < cp_end)
|
|
1064
|
-
{
|
|
992
|
+
cp = &A[Col[pivot_col].start];
|
|
993
|
+
cp_end = cp + Col[pivot_col].length;
|
|
994
|
+
while (cp < cp_end) {
|
|
1065
995
|
/* get a row */
|
|
1066
|
-
row = *cp
|
|
1067
|
-
COLAMD_DEBUG4
|
|
996
|
+
row = *cp++;
|
|
997
|
+
COLAMD_DEBUG4(("Pivot col pattern %d %d\n", Row[row].is_alive(), row));
|
|
1068
998
|
/* skip if row is dead */
|
|
1069
|
-
if (
|
|
1070
|
-
|
|
1071
|
-
continue ;
|
|
999
|
+
if (Row[row].is_dead()) {
|
|
1000
|
+
continue;
|
|
1072
1001
|
}
|
|
1073
|
-
rp = &A
|
|
1074
|
-
rp_end = rp + Row
|
|
1075
|
-
while (rp < rp_end)
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
pivot_row_degree += col_thickness ;
|
|
1089
|
-
}
|
|
1002
|
+
rp = &A[Row[row].start];
|
|
1003
|
+
rp_end = rp + Row[row].length;
|
|
1004
|
+
while (rp < rp_end) {
|
|
1005
|
+
/* get a column */
|
|
1006
|
+
col = *rp++;
|
|
1007
|
+
/* add the column, if alive and untagged */
|
|
1008
|
+
col_thickness = Col[col].shared1.thickness;
|
|
1009
|
+
if (col_thickness > 0 && Col[col].is_alive()) {
|
|
1010
|
+
/* tag column in pivot row */
|
|
1011
|
+
Col[col].shared1.thickness = -col_thickness;
|
|
1012
|
+
COLAMD_ASSERT(pfree < Alen);
|
|
1013
|
+
/* place column in pivot row */
|
|
1014
|
+
A[pfree++] = col;
|
|
1015
|
+
pivot_row_degree += col_thickness;
|
|
1016
|
+
}
|
|
1090
1017
|
}
|
|
1091
1018
|
}
|
|
1092
1019
|
|
|
1093
1020
|
/* clear tag on pivot column */
|
|
1094
|
-
Col
|
|
1095
|
-
max_deg = numext::maxi(max_deg, pivot_row_degree)
|
|
1096
|
-
|
|
1021
|
+
Col[pivot_col].shared1.thickness = pivot_col_thickness;
|
|
1022
|
+
max_deg = numext::maxi(max_deg, pivot_row_degree);
|
|
1097
1023
|
|
|
1098
1024
|
/* === Kill all rows used to construct pivot row ==================== */
|
|
1099
1025
|
|
|
1100
1026
|
/* also kill pivot row, temporarily */
|
|
1101
|
-
cp = &A
|
|
1102
|
-
cp_end = cp + Col
|
|
1103
|
-
while (cp < cp_end)
|
|
1104
|
-
{
|
|
1027
|
+
cp = &A[Col[pivot_col].start];
|
|
1028
|
+
cp_end = cp + Col[pivot_col].length;
|
|
1029
|
+
while (cp < cp_end) {
|
|
1105
1030
|
/* may be killing an already dead row */
|
|
1106
|
-
row = *cp
|
|
1107
|
-
COLAMD_DEBUG3
|
|
1108
|
-
|
|
1031
|
+
row = *cp++;
|
|
1032
|
+
COLAMD_DEBUG3(("Kill row in pivot col: %d\n", row));
|
|
1033
|
+
Row[row].kill();
|
|
1109
1034
|
}
|
|
1110
1035
|
|
|
1111
1036
|
/* === Select a row index to use as the new pivot row =============== */
|
|
1112
1037
|
|
|
1113
|
-
pivot_row_length = pfree - pivot_row_start
|
|
1114
|
-
if (pivot_row_length > 0)
|
|
1115
|
-
{
|
|
1038
|
+
pivot_row_length = pfree - pivot_row_start;
|
|
1039
|
+
if (pivot_row_length > 0) {
|
|
1116
1040
|
/* pick the "pivot" row arbitrarily (first row in col) */
|
|
1117
|
-
pivot_row = A
|
|
1118
|
-
COLAMD_DEBUG3
|
|
1119
|
-
}
|
|
1120
|
-
else
|
|
1121
|
-
{
|
|
1041
|
+
pivot_row = A[Col[pivot_col].start];
|
|
1042
|
+
COLAMD_DEBUG3(("Pivotal row is %d\n", pivot_row));
|
|
1043
|
+
} else {
|
|
1122
1044
|
/* there is no pivot row, since it is of zero length */
|
|
1123
|
-
pivot_row =
|
|
1124
|
-
COLAMD_ASSERT
|
|
1045
|
+
pivot_row = Empty;
|
|
1046
|
+
COLAMD_ASSERT(pivot_row_length == 0);
|
|
1125
1047
|
}
|
|
1126
|
-
COLAMD_ASSERT
|
|
1048
|
+
COLAMD_ASSERT(Col[pivot_col].length > 0 || pivot_row_length == 0);
|
|
1127
1049
|
|
|
1128
1050
|
/* === Approximate degree computation =============================== */
|
|
1129
1051
|
|
|
@@ -1146,180 +1068,159 @@ static IndexType find_ordering /* return the number of garbage collections */
|
|
|
1146
1068
|
|
|
1147
1069
|
/* === Compute set differences ====================================== */
|
|
1148
1070
|
|
|
1149
|
-
COLAMD_DEBUG3
|
|
1071
|
+
COLAMD_DEBUG3(("** Computing set differences phase. **\n"));
|
|
1150
1072
|
|
|
1151
1073
|
/* pivot row is currently dead - it will be revived later. */
|
|
1152
1074
|
|
|
1153
|
-
COLAMD_DEBUG3
|
|
1075
|
+
COLAMD_DEBUG3(("Pivot row: "));
|
|
1154
1076
|
/* for each column in pivot row */
|
|
1155
|
-
rp = &A
|
|
1156
|
-
rp_end = rp + pivot_row_length
|
|
1157
|
-
while (rp < rp_end)
|
|
1158
|
-
|
|
1159
|
-
col
|
|
1160
|
-
|
|
1161
|
-
COLAMD_DEBUG3 (("Col: %d\n", col)) ;
|
|
1077
|
+
rp = &A[pivot_row_start];
|
|
1078
|
+
rp_end = rp + pivot_row_length;
|
|
1079
|
+
while (rp < rp_end) {
|
|
1080
|
+
col = *rp++;
|
|
1081
|
+
COLAMD_ASSERT(Col[col].is_alive() && col != pivot_col);
|
|
1082
|
+
COLAMD_DEBUG3(("Col: %d\n", col));
|
|
1162
1083
|
|
|
1163
1084
|
/* clear tags used to construct pivot row pattern */
|
|
1164
|
-
col_thickness = -Col
|
|
1165
|
-
COLAMD_ASSERT
|
|
1166
|
-
Col
|
|
1085
|
+
col_thickness = -Col[col].shared1.thickness;
|
|
1086
|
+
COLAMD_ASSERT(col_thickness > 0);
|
|
1087
|
+
Col[col].shared1.thickness = col_thickness;
|
|
1167
1088
|
|
|
1168
1089
|
/* === Remove column from degree list =========================== */
|
|
1169
1090
|
|
|
1170
|
-
cur_score = Col
|
|
1171
|
-
prev_col = Col
|
|
1172
|
-
next_col = Col
|
|
1173
|
-
COLAMD_ASSERT
|
|
1174
|
-
COLAMD_ASSERT
|
|
1175
|
-
COLAMD_ASSERT
|
|
1176
|
-
if (prev_col ==
|
|
1177
|
-
|
|
1178
|
-
|
|
1091
|
+
cur_score = Col[col].shared2.score;
|
|
1092
|
+
prev_col = Col[col].shared3.prev;
|
|
1093
|
+
next_col = Col[col].shared4.degree_next;
|
|
1094
|
+
COLAMD_ASSERT(cur_score >= 0);
|
|
1095
|
+
COLAMD_ASSERT(cur_score <= n_col);
|
|
1096
|
+
COLAMD_ASSERT(cur_score >= Empty);
|
|
1097
|
+
if (prev_col == Empty) {
|
|
1098
|
+
head[cur_score] = next_col;
|
|
1099
|
+
} else {
|
|
1100
|
+
Col[prev_col].shared4.degree_next = next_col;
|
|
1179
1101
|
}
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
Col [prev_col].shared4.degree_next = next_col ;
|
|
1183
|
-
}
|
|
1184
|
-
if (next_col != COLAMD_EMPTY)
|
|
1185
|
-
{
|
|
1186
|
-
Col [next_col].shared3.prev = prev_col ;
|
|
1102
|
+
if (next_col != Empty) {
|
|
1103
|
+
Col[next_col].shared3.prev = prev_col;
|
|
1187
1104
|
}
|
|
1188
1105
|
|
|
1189
1106
|
/* === Scan the column ========================================== */
|
|
1190
1107
|
|
|
1191
|
-
cp = &A
|
|
1192
|
-
cp_end = cp + Col
|
|
1193
|
-
while (cp < cp_end)
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
}
|
|
1220
|
-
else
|
|
1221
|
-
{
|
|
1222
|
-
/* save the new mark */
|
|
1223
|
-
Row [row].shared2.mark = set_difference + tag_mark ;
|
|
1224
|
-
}
|
|
1108
|
+
cp = &A[Col[col].start];
|
|
1109
|
+
cp_end = cp + Col[col].length;
|
|
1110
|
+
while (cp < cp_end) {
|
|
1111
|
+
/* get a row */
|
|
1112
|
+
row = *cp++;
|
|
1113
|
+
/* skip if dead */
|
|
1114
|
+
if (Row[row].is_dead()) {
|
|
1115
|
+
continue;
|
|
1116
|
+
}
|
|
1117
|
+
row_mark = Row[row].shared2.mark;
|
|
1118
|
+
COLAMD_ASSERT(row != pivot_row);
|
|
1119
|
+
set_difference = row_mark - tag_mark;
|
|
1120
|
+
/* check if the row has been seen yet */
|
|
1121
|
+
if (set_difference < 0) {
|
|
1122
|
+
COLAMD_ASSERT(Row[row].shared1.degree <= max_deg);
|
|
1123
|
+
set_difference = Row[row].shared1.degree;
|
|
1124
|
+
}
|
|
1125
|
+
/* subtract column thickness from this row's set difference */
|
|
1126
|
+
set_difference -= col_thickness;
|
|
1127
|
+
COLAMD_ASSERT(set_difference >= 0);
|
|
1128
|
+
/* absorb this row if the set difference becomes zero */
|
|
1129
|
+
if (set_difference == 0) {
|
|
1130
|
+
COLAMD_DEBUG3(("aggressive absorption. Row: %d\n", row));
|
|
1131
|
+
Row[row].kill();
|
|
1132
|
+
} else {
|
|
1133
|
+
/* save the new mark */
|
|
1134
|
+
Row[row].shared2.mark = set_difference + tag_mark;
|
|
1135
|
+
}
|
|
1225
1136
|
}
|
|
1226
1137
|
}
|
|
1227
1138
|
|
|
1228
|
-
|
|
1229
1139
|
/* === Add up set differences for each column ======================= */
|
|
1230
1140
|
|
|
1231
|
-
COLAMD_DEBUG3
|
|
1141
|
+
COLAMD_DEBUG3(("** Adding set differences phase. **\n"));
|
|
1232
1142
|
|
|
1233
1143
|
/* for each column in pivot row */
|
|
1234
|
-
rp = &A
|
|
1235
|
-
rp_end = rp + pivot_row_length
|
|
1236
|
-
while (rp < rp_end)
|
|
1237
|
-
{
|
|
1144
|
+
rp = &A[pivot_row_start];
|
|
1145
|
+
rp_end = rp + pivot_row_length;
|
|
1146
|
+
while (rp < rp_end) {
|
|
1238
1147
|
/* get a column */
|
|
1239
|
-
col = *rp
|
|
1240
|
-
COLAMD_ASSERT
|
|
1241
|
-
hash = 0
|
|
1242
|
-
cur_score = 0
|
|
1243
|
-
cp = &A
|
|
1148
|
+
col = *rp++;
|
|
1149
|
+
COLAMD_ASSERT(Col[col].is_alive() && col != pivot_col);
|
|
1150
|
+
hash = 0;
|
|
1151
|
+
cur_score = 0;
|
|
1152
|
+
cp = &A[Col[col].start];
|
|
1244
1153
|
/* compact the column */
|
|
1245
|
-
new_cp = cp
|
|
1246
|
-
cp_end = cp + Col
|
|
1247
|
-
|
|
1248
|
-
COLAMD_DEBUG4
|
|
1249
|
-
|
|
1250
|
-
while (cp < cp_end)
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
/* integer overflow... */
|
|
1269
|
-
cur_score = numext::mini(cur_score, n_col) ;
|
|
1154
|
+
new_cp = cp;
|
|
1155
|
+
cp_end = cp + Col[col].length;
|
|
1156
|
+
|
|
1157
|
+
COLAMD_DEBUG4(("Adding set diffs for Col: %d.\n", col));
|
|
1158
|
+
|
|
1159
|
+
while (cp < cp_end) {
|
|
1160
|
+
/* get a row */
|
|
1161
|
+
row = *cp++;
|
|
1162
|
+
COLAMD_ASSERT(row >= 0 && row < n_row);
|
|
1163
|
+
/* skip if dead */
|
|
1164
|
+
if (Row[row].is_dead()) {
|
|
1165
|
+
continue;
|
|
1166
|
+
}
|
|
1167
|
+
row_mark = Row[row].shared2.mark;
|
|
1168
|
+
COLAMD_ASSERT(row_mark > tag_mark);
|
|
1169
|
+
/* compact the column */
|
|
1170
|
+
*new_cp++ = row;
|
|
1171
|
+
/* compute hash function */
|
|
1172
|
+
hash += row;
|
|
1173
|
+
/* add set difference */
|
|
1174
|
+
cur_score += row_mark - tag_mark;
|
|
1175
|
+
/* integer overflow... */
|
|
1176
|
+
cur_score = numext::mini(cur_score, n_col);
|
|
1270
1177
|
}
|
|
1271
1178
|
|
|
1272
1179
|
/* recompute the column's length */
|
|
1273
|
-
Col
|
|
1180
|
+
Col[col].length = (IndexType)(new_cp - &A[Col[col].start]);
|
|
1274
1181
|
|
|
1275
1182
|
/* === Further mass elimination ================================= */
|
|
1276
1183
|
|
|
1277
|
-
if (Col
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
}
|
|
1318
|
-
Col [col].shared4.hash_next = first_col ;
|
|
1319
|
-
|
|
1320
|
-
/* save hash function in Col [col].shared3.hash */
|
|
1321
|
-
Col [col].shared3.hash = (IndexType) hash ;
|
|
1322
|
-
COLAMD_ASSERT (COL_IS_ALIVE (col)) ;
|
|
1184
|
+
if (Col[col].length == 0) {
|
|
1185
|
+
COLAMD_DEBUG4(("further mass elimination. Col: %d\n", col));
|
|
1186
|
+
/* nothing left but the pivot row in this column */
|
|
1187
|
+
Col[col].kill_principal();
|
|
1188
|
+
pivot_row_degree -= Col[col].shared1.thickness;
|
|
1189
|
+
COLAMD_ASSERT(pivot_row_degree >= 0);
|
|
1190
|
+
/* order it */
|
|
1191
|
+
Col[col].shared2.order = k;
|
|
1192
|
+
/* increment order count by column thickness */
|
|
1193
|
+
k += Col[col].shared1.thickness;
|
|
1194
|
+
} else {
|
|
1195
|
+
/* === Prepare for supercolumn detection ==================== */
|
|
1196
|
+
|
|
1197
|
+
COLAMD_DEBUG4(("Preparing supercol detection for Col: %d.\n", col));
|
|
1198
|
+
|
|
1199
|
+
/* save score so far */
|
|
1200
|
+
Col[col].shared2.score = cur_score;
|
|
1201
|
+
|
|
1202
|
+
/* add column to hash table, for supercolumn detection */
|
|
1203
|
+
hash %= n_col + 1;
|
|
1204
|
+
|
|
1205
|
+
COLAMD_DEBUG4((" Hash = %d, n_col = %d.\n", hash, n_col));
|
|
1206
|
+
COLAMD_ASSERT(hash <= n_col);
|
|
1207
|
+
|
|
1208
|
+
head_column = head[hash];
|
|
1209
|
+
if (head_column > Empty) {
|
|
1210
|
+
/* degree list "hash" is non-empty, use prev (shared3) of */
|
|
1211
|
+
/* first column in degree list as head of hash bucket */
|
|
1212
|
+
first_col = Col[head_column].shared3.headhash;
|
|
1213
|
+
Col[head_column].shared3.headhash = col;
|
|
1214
|
+
} else {
|
|
1215
|
+
/* degree list "hash" is empty, use head as hash bucket */
|
|
1216
|
+
first_col = -(head_column + 2);
|
|
1217
|
+
head[hash] = -(col + 2);
|
|
1218
|
+
}
|
|
1219
|
+
Col[col].shared4.hash_next = first_col;
|
|
1220
|
+
|
|
1221
|
+
/* save hash function in Col [col].shared3.hash */
|
|
1222
|
+
Col[col].shared3.hash = (IndexType)hash;
|
|
1223
|
+
COLAMD_ASSERT(Col[col].is_alive());
|
|
1323
1224
|
}
|
|
1324
1225
|
}
|
|
1325
1226
|
|
|
@@ -1327,105 +1228,98 @@ static IndexType find_ordering /* return the number of garbage collections */
|
|
|
1327
1228
|
|
|
1328
1229
|
/* === Supercolumn detection ======================================== */
|
|
1329
1230
|
|
|
1330
|
-
COLAMD_DEBUG3
|
|
1231
|
+
COLAMD_DEBUG3(("** Supercolumn detection phase. **\n"));
|
|
1331
1232
|
|
|
1332
|
-
|
|
1233
|
+
Colamd::detect_super_cols(Col, A, head, pivot_row_start, pivot_row_length);
|
|
1333
1234
|
|
|
1334
1235
|
/* === Kill the pivotal column ====================================== */
|
|
1335
1236
|
|
|
1336
|
-
|
|
1237
|
+
Col[pivot_col].kill_principal();
|
|
1337
1238
|
|
|
1338
1239
|
/* === Clear mark =================================================== */
|
|
1339
1240
|
|
|
1340
|
-
tag_mark += (max_deg + 1)
|
|
1341
|
-
if (tag_mark >= max_mark)
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
tag_mark = Eigen::internal::clear_mark (n_row, Row) ;
|
|
1241
|
+
tag_mark += (max_deg + 1);
|
|
1242
|
+
if (tag_mark >= max_mark) {
|
|
1243
|
+
COLAMD_DEBUG2(("clearing tag_mark\n"));
|
|
1244
|
+
tag_mark = Colamd::clear_mark(n_row, Row);
|
|
1345
1245
|
}
|
|
1346
1246
|
|
|
1347
1247
|
/* === Finalize the new pivot row, and column scores ================ */
|
|
1348
1248
|
|
|
1349
|
-
COLAMD_DEBUG3
|
|
1249
|
+
COLAMD_DEBUG3(("** Finalize scores phase. **\n"));
|
|
1350
1250
|
|
|
1351
1251
|
/* for each column in pivot row */
|
|
1352
|
-
rp = &A
|
|
1252
|
+
rp = &A[pivot_row_start];
|
|
1353
1253
|
/* compact the pivot row */
|
|
1354
|
-
new_rp = rp
|
|
1355
|
-
rp_end = rp + pivot_row_length
|
|
1356
|
-
while (rp < rp_end)
|
|
1357
|
-
|
|
1358
|
-
col = *rp++ ;
|
|
1254
|
+
new_rp = rp;
|
|
1255
|
+
rp_end = rp + pivot_row_length;
|
|
1256
|
+
while (rp < rp_end) {
|
|
1257
|
+
col = *rp++;
|
|
1359
1258
|
/* skip dead columns */
|
|
1360
|
-
if (
|
|
1361
|
-
|
|
1362
|
-
continue ;
|
|
1259
|
+
if (Col[col].is_dead()) {
|
|
1260
|
+
continue;
|
|
1363
1261
|
}
|
|
1364
|
-
*new_rp++ = col
|
|
1262
|
+
*new_rp++ = col;
|
|
1365
1263
|
/* add new pivot row to column */
|
|
1366
|
-
A
|
|
1264
|
+
A[Col[col].start + (Col[col].length++)] = pivot_row;
|
|
1367
1265
|
|
|
1368
1266
|
/* retrieve score so far and add on pivot row's degree. */
|
|
1369
1267
|
/* (we wait until here for this in case the pivot */
|
|
1370
1268
|
/* row's degree was reduced due to mass elimination). */
|
|
1371
|
-
cur_score = Col
|
|
1269
|
+
cur_score = Col[col].shared2.score + pivot_row_degree;
|
|
1372
1270
|
|
|
1373
1271
|
/* calculate the max possible score as the number of */
|
|
1374
1272
|
/* external columns minus the 'k' value minus the */
|
|
1375
1273
|
/* columns thickness */
|
|
1376
|
-
max_score = n_col - k - Col
|
|
1274
|
+
max_score = n_col - k - Col[col].shared1.thickness;
|
|
1377
1275
|
|
|
1378
1276
|
/* make the score the external degree of the union-of-rows */
|
|
1379
|
-
cur_score -= Col
|
|
1277
|
+
cur_score -= Col[col].shared1.thickness;
|
|
1380
1278
|
|
|
1381
1279
|
/* make sure score is less or equal than the max score */
|
|
1382
|
-
cur_score = numext::mini(cur_score, max_score)
|
|
1383
|
-
COLAMD_ASSERT
|
|
1280
|
+
cur_score = numext::mini(cur_score, max_score);
|
|
1281
|
+
COLAMD_ASSERT(cur_score >= 0);
|
|
1384
1282
|
|
|
1385
1283
|
/* store updated score */
|
|
1386
|
-
Col
|
|
1284
|
+
Col[col].shared2.score = cur_score;
|
|
1387
1285
|
|
|
1388
1286
|
/* === Place column back in degree list ========================= */
|
|
1389
1287
|
|
|
1390
|
-
COLAMD_ASSERT
|
|
1391
|
-
COLAMD_ASSERT
|
|
1392
|
-
COLAMD_ASSERT
|
|
1393
|
-
COLAMD_ASSERT
|
|
1394
|
-
COLAMD_ASSERT
|
|
1395
|
-
next_col = head
|
|
1396
|
-
Col
|
|
1397
|
-
Col
|
|
1398
|
-
if (next_col !=
|
|
1399
|
-
|
|
1400
|
-
Col [next_col].shared3.prev = col ;
|
|
1288
|
+
COLAMD_ASSERT(min_score >= 0);
|
|
1289
|
+
COLAMD_ASSERT(min_score <= n_col);
|
|
1290
|
+
COLAMD_ASSERT(cur_score >= 0);
|
|
1291
|
+
COLAMD_ASSERT(cur_score <= n_col);
|
|
1292
|
+
COLAMD_ASSERT(head[cur_score] >= Empty);
|
|
1293
|
+
next_col = head[cur_score];
|
|
1294
|
+
Col[col].shared4.degree_next = next_col;
|
|
1295
|
+
Col[col].shared3.prev = Empty;
|
|
1296
|
+
if (next_col != Empty) {
|
|
1297
|
+
Col[next_col].shared3.prev = col;
|
|
1401
1298
|
}
|
|
1402
|
-
head
|
|
1299
|
+
head[cur_score] = col;
|
|
1403
1300
|
|
|
1404
1301
|
/* see if this score is less than current min */
|
|
1405
|
-
min_score = numext::mini(min_score, cur_score)
|
|
1406
|
-
|
|
1302
|
+
min_score = numext::mini(min_score, cur_score);
|
|
1407
1303
|
}
|
|
1408
1304
|
|
|
1409
1305
|
/* === Resurrect the new pivot row ================================== */
|
|
1410
1306
|
|
|
1411
|
-
if (pivot_row_degree > 0)
|
|
1412
|
-
{
|
|
1307
|
+
if (pivot_row_degree > 0) {
|
|
1413
1308
|
/* update pivot row length to reflect any cols that were killed */
|
|
1414
1309
|
/* during super-col detection and mass elimination */
|
|
1415
|
-
Row
|
|
1416
|
-
Row
|
|
1417
|
-
Row
|
|
1418
|
-
Row
|
|
1310
|
+
Row[pivot_row].start = pivot_row_start;
|
|
1311
|
+
Row[pivot_row].length = (IndexType)(new_rp - &A[pivot_row_start]);
|
|
1312
|
+
Row[pivot_row].shared1.degree = pivot_row_degree;
|
|
1313
|
+
Row[pivot_row].shared2.mark = 0;
|
|
1419
1314
|
/* pivot row is no longer dead */
|
|
1420
1315
|
}
|
|
1421
1316
|
}
|
|
1422
1317
|
|
|
1423
1318
|
/* === All principal columns have now been ordered ====================== */
|
|
1424
1319
|
|
|
1425
|
-
return (ngarbage)
|
|
1320
|
+
return (ngarbage);
|
|
1426
1321
|
}
|
|
1427
1322
|
|
|
1428
|
-
|
|
1429
1323
|
/* ========================================================================== */
|
|
1430
1324
|
/* === order_children ======================================================= */
|
|
1431
1325
|
/* ========================================================================== */
|
|
@@ -1443,74 +1337,66 @@ static IndexType find_ordering /* return the number of garbage collections */
|
|
|
1443
1337
|
columns. Not user-callable.
|
|
1444
1338
|
*/
|
|
1445
1339
|
template <typename IndexType>
|
|
1446
|
-
static inline
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
)
|
|
1454
|
-
{
|
|
1340
|
+
static inline void order_children(
|
|
1341
|
+
/* === Parameters ======================================================= */
|
|
1342
|
+
|
|
1343
|
+
IndexType n_col, /* number of columns of A */
|
|
1344
|
+
ColStructure<IndexType> Col[], /* of size n_col+1 */
|
|
1345
|
+
IndexType p[] /* p [0 ... n_col-1] is the column permutation*/
|
|
1346
|
+
) {
|
|
1455
1347
|
/* === Local variables ================================================== */
|
|
1456
1348
|
|
|
1457
|
-
IndexType i
|
|
1458
|
-
IndexType c
|
|
1459
|
-
IndexType parent
|
|
1460
|
-
IndexType order
|
|
1349
|
+
IndexType i; /* loop counter for all columns */
|
|
1350
|
+
IndexType c; /* column index */
|
|
1351
|
+
IndexType parent; /* index of column's parent */
|
|
1352
|
+
IndexType order; /* column's order */
|
|
1461
1353
|
|
|
1462
1354
|
/* === Order each non-principal column ================================== */
|
|
1463
1355
|
|
|
1464
|
-
for (i = 0
|
|
1465
|
-
{
|
|
1356
|
+
for (i = 0; i < n_col; i++) {
|
|
1466
1357
|
/* find an un-ordered non-principal column */
|
|
1467
|
-
COLAMD_ASSERT
|
|
1468
|
-
if (!
|
|
1469
|
-
|
|
1470
|
-
parent = i ;
|
|
1358
|
+
COLAMD_ASSERT(col_is_dead(Col, i));
|
|
1359
|
+
if (!Col[i].is_dead_principal() && Col[i].shared2.order == Empty) {
|
|
1360
|
+
parent = i;
|
|
1471
1361
|
/* once found, find its principal parent */
|
|
1472
|
-
do
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
} while (!COL_IS_DEAD_PRINCIPAL (parent)) ;
|
|
1362
|
+
do {
|
|
1363
|
+
parent = Col[parent].shared1.parent;
|
|
1364
|
+
} while (!Col[parent].is_dead_principal());
|
|
1476
1365
|
|
|
1477
1366
|
/* now, order all un-ordered non-principal columns along path */
|
|
1478
1367
|
/* to this parent. collapse tree at the same time */
|
|
1479
|
-
c = i
|
|
1368
|
+
c = i;
|
|
1480
1369
|
/* get order of parent */
|
|
1481
|
-
order = Col
|
|
1370
|
+
order = Col[parent].shared2.order;
|
|
1482
1371
|
|
|
1483
|
-
do
|
|
1484
|
-
|
|
1485
|
-
COLAMD_ASSERT (Col [c].shared2.order == COLAMD_EMPTY) ;
|
|
1372
|
+
do {
|
|
1373
|
+
COLAMD_ASSERT(Col[c].shared2.order == Empty);
|
|
1486
1374
|
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1375
|
+
/* order this column */
|
|
1376
|
+
Col[c].shared2.order = order++;
|
|
1377
|
+
/* collapse tree */
|
|
1378
|
+
Col[c].shared1.parent = parent;
|
|
1491
1379
|
|
|
1492
|
-
|
|
1493
|
-
|
|
1380
|
+
/* get immediate parent of this column */
|
|
1381
|
+
c = Col[c].shared1.parent;
|
|
1494
1382
|
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
} while (Col
|
|
1383
|
+
/* continue until we hit an ordered column. There are */
|
|
1384
|
+
/* guaranteed not to be anymore unordered columns */
|
|
1385
|
+
/* above an ordered column */
|
|
1386
|
+
} while (Col[c].shared2.order == Empty);
|
|
1499
1387
|
|
|
1500
1388
|
/* re-order the super_col parent to largest order for this group */
|
|
1501
|
-
Col
|
|
1389
|
+
Col[parent].shared2.order = order;
|
|
1502
1390
|
}
|
|
1503
1391
|
}
|
|
1504
1392
|
|
|
1505
1393
|
/* === Generate the permutation ========================================= */
|
|
1506
1394
|
|
|
1507
|
-
for (c = 0
|
|
1508
|
-
|
|
1509
|
-
p [Col [c].shared2.order] = c ;
|
|
1395
|
+
for (c = 0; c < n_col; c++) {
|
|
1396
|
+
p[Col[c].shared2.order] = c;
|
|
1510
1397
|
}
|
|
1511
1398
|
}
|
|
1512
1399
|
|
|
1513
|
-
|
|
1514
1400
|
/* ========================================================================== */
|
|
1515
1401
|
/* === detect_super_cols ==================================================== */
|
|
1516
1402
|
/* ========================================================================== */
|
|
@@ -1544,269 +1430,232 @@ static inline void order_children
|
|
|
1544
1430
|
Not user-callable.
|
|
1545
1431
|
*/
|
|
1546
1432
|
template <typename IndexType>
|
|
1547
|
-
static void detect_super_cols
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
)
|
|
1557
|
-
{
|
|
1433
|
+
static void detect_super_cols(
|
|
1434
|
+
/* === Parameters ======================================================= */
|
|
1435
|
+
|
|
1436
|
+
ColStructure<IndexType> Col[], /* of size n_col+1 */
|
|
1437
|
+
IndexType A[], /* row indices of A */
|
|
1438
|
+
IndexType head[], /* head of degree lists and hash buckets */
|
|
1439
|
+
IndexType row_start, /* pointer to set of columns to check */
|
|
1440
|
+
IndexType row_length /* number of columns to check */
|
|
1441
|
+
) {
|
|
1558
1442
|
/* === Local variables ================================================== */
|
|
1559
1443
|
|
|
1560
|
-
IndexType hash
|
|
1561
|
-
IndexType *rp
|
|
1562
|
-
IndexType c
|
|
1563
|
-
IndexType super_c
|
|
1564
|
-
IndexType *cp1
|
|
1565
|
-
IndexType *cp2
|
|
1566
|
-
IndexType length
|
|
1567
|
-
IndexType prev_c
|
|
1568
|
-
IndexType i
|
|
1569
|
-
IndexType *rp_end
|
|
1570
|
-
IndexType col
|
|
1571
|
-
IndexType head_column
|
|
1572
|
-
IndexType first_col
|
|
1444
|
+
IndexType hash; /* hash value for a column */
|
|
1445
|
+
IndexType *rp; /* pointer to a row */
|
|
1446
|
+
IndexType c; /* a column index */
|
|
1447
|
+
IndexType super_c; /* column index of the column to absorb into */
|
|
1448
|
+
IndexType *cp1; /* column pointer for column super_c */
|
|
1449
|
+
IndexType *cp2; /* column pointer for column c */
|
|
1450
|
+
IndexType length; /* length of column super_c */
|
|
1451
|
+
IndexType prev_c; /* column preceding c in hash bucket */
|
|
1452
|
+
IndexType i; /* loop counter */
|
|
1453
|
+
IndexType *rp_end; /* pointer to the end of the row */
|
|
1454
|
+
IndexType col; /* a column index in the row to check */
|
|
1455
|
+
IndexType head_column; /* first column in hash bucket or degree list */
|
|
1456
|
+
IndexType first_col; /* first column in hash bucket */
|
|
1573
1457
|
|
|
1574
1458
|
/* === Consider each column in the row ================================== */
|
|
1575
1459
|
|
|
1576
|
-
rp = &A
|
|
1577
|
-
rp_end = rp + row_length
|
|
1578
|
-
while (rp < rp_end)
|
|
1579
|
-
|
|
1580
|
-
col
|
|
1581
|
-
|
|
1582
|
-
{
|
|
1583
|
-
continue ;
|
|
1460
|
+
rp = &A[row_start];
|
|
1461
|
+
rp_end = rp + row_length;
|
|
1462
|
+
while (rp < rp_end) {
|
|
1463
|
+
col = *rp++;
|
|
1464
|
+
if (Col[col].is_dead()) {
|
|
1465
|
+
continue;
|
|
1584
1466
|
}
|
|
1585
1467
|
|
|
1586
1468
|
/* get hash number for this column */
|
|
1587
|
-
hash = Col
|
|
1588
|
-
COLAMD_ASSERT
|
|
1469
|
+
hash = Col[col].shared3.hash;
|
|
1470
|
+
COLAMD_ASSERT(hash <= n_col);
|
|
1589
1471
|
|
|
1590
1472
|
/* === Get the first column in this hash bucket ===================== */
|
|
1591
1473
|
|
|
1592
|
-
head_column = head
|
|
1593
|
-
if (head_column >
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
else
|
|
1598
|
-
{
|
|
1599
|
-
first_col = - (head_column + 2) ;
|
|
1474
|
+
head_column = head[hash];
|
|
1475
|
+
if (head_column > Empty) {
|
|
1476
|
+
first_col = Col[head_column].shared3.headhash;
|
|
1477
|
+
} else {
|
|
1478
|
+
first_col = -(head_column + 2);
|
|
1600
1479
|
}
|
|
1601
1480
|
|
|
1602
1481
|
/* === Consider each column in the hash bucket ====================== */
|
|
1603
1482
|
|
|
1604
|
-
for (super_c = first_col
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
COLAMD_ASSERT (Col [super_c].shared3.hash == hash) ;
|
|
1609
|
-
length = Col [super_c].length ;
|
|
1483
|
+
for (super_c = first_col; super_c != Empty; super_c = Col[super_c].shared4.hash_next) {
|
|
1484
|
+
COLAMD_ASSERT(Col[super_c].is_alive());
|
|
1485
|
+
COLAMD_ASSERT(Col[super_c].shared3.hash == hash);
|
|
1486
|
+
length = Col[super_c].length;
|
|
1610
1487
|
|
|
1611
1488
|
/* prev_c is the column preceding column c in the hash bucket */
|
|
1612
|
-
prev_c = super_c
|
|
1489
|
+
prev_c = super_c;
|
|
1613
1490
|
|
|
1614
1491
|
/* === Compare super_c with all columns after it ================ */
|
|
1615
1492
|
|
|
1616
|
-
for (c = Col
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
|
|
1655
|
-
|
|
1656
|
-
|
|
1657
|
-
|
|
1658
|
-
|
|
1659
|
-
Col [super_c].shared1.thickness += Col [c].shared1.thickness ;
|
|
1660
|
-
Col [c].shared1.parent = super_c ;
|
|
1661
|
-
KILL_NON_PRINCIPAL_COL (c) ;
|
|
1662
|
-
/* order c later, in order_children() */
|
|
1663
|
-
Col [c].shared2.order = COLAMD_EMPTY ;
|
|
1664
|
-
/* remove c from hash bucket */
|
|
1665
|
-
Col [prev_c].shared4.hash_next = Col [c].shared4.hash_next ;
|
|
1493
|
+
for (c = Col[super_c].shared4.hash_next; c != Empty; c = Col[c].shared4.hash_next) {
|
|
1494
|
+
COLAMD_ASSERT(c != super_c);
|
|
1495
|
+
COLAMD_ASSERT(Col[c].is_alive());
|
|
1496
|
+
COLAMD_ASSERT(Col[c].shared3.hash == hash);
|
|
1497
|
+
|
|
1498
|
+
/* not identical if lengths or scores are different */
|
|
1499
|
+
if (Col[c].length != length || Col[c].shared2.score != Col[super_c].shared2.score) {
|
|
1500
|
+
prev_c = c;
|
|
1501
|
+
continue;
|
|
1502
|
+
}
|
|
1503
|
+
|
|
1504
|
+
/* compare the two columns */
|
|
1505
|
+
cp1 = &A[Col[super_c].start];
|
|
1506
|
+
cp2 = &A[Col[c].start];
|
|
1507
|
+
|
|
1508
|
+
for (i = 0; i < length; i++) {
|
|
1509
|
+
/* the columns are "clean" (no dead rows) */
|
|
1510
|
+
COLAMD_ASSERT(cp1->is_alive());
|
|
1511
|
+
COLAMD_ASSERT(cp2->is_alive());
|
|
1512
|
+
/* row indices will same order for both supercols, */
|
|
1513
|
+
/* no gather scatter necessary */
|
|
1514
|
+
if (*cp1++ != *cp2++) {
|
|
1515
|
+
break;
|
|
1516
|
+
}
|
|
1517
|
+
}
|
|
1518
|
+
|
|
1519
|
+
/* the two columns are different if the for-loop "broke" */
|
|
1520
|
+
if (i != length) {
|
|
1521
|
+
prev_c = c;
|
|
1522
|
+
continue;
|
|
1523
|
+
}
|
|
1524
|
+
|
|
1525
|
+
/* === Got it! two columns are identical =================== */
|
|
1526
|
+
|
|
1527
|
+
COLAMD_ASSERT(Col[c].shared2.score == Col[super_c].shared2.score);
|
|
1528
|
+
|
|
1529
|
+
Col[super_c].shared1.thickness += Col[c].shared1.thickness;
|
|
1530
|
+
Col[c].shared1.parent = super_c;
|
|
1531
|
+
Col[c].kill_non_principal();
|
|
1532
|
+
/* order c later, in order_children() */
|
|
1533
|
+
Col[c].shared2.order = Empty;
|
|
1534
|
+
/* remove c from hash bucket */
|
|
1535
|
+
Col[prev_c].shared4.hash_next = Col[c].shared4.hash_next;
|
|
1666
1536
|
}
|
|
1667
1537
|
}
|
|
1668
1538
|
|
|
1669
1539
|
/* === Empty this hash bucket ======================================= */
|
|
1670
1540
|
|
|
1671
|
-
if (head_column >
|
|
1672
|
-
{
|
|
1541
|
+
if (head_column > Empty) {
|
|
1673
1542
|
/* corresponding degree list "hash" is not empty */
|
|
1674
|
-
Col
|
|
1675
|
-
}
|
|
1676
|
-
else
|
|
1677
|
-
{
|
|
1543
|
+
Col[head_column].shared3.headhash = Empty;
|
|
1544
|
+
} else {
|
|
1678
1545
|
/* corresponding degree list "hash" is empty */
|
|
1679
|
-
head
|
|
1546
|
+
head[hash] = Empty;
|
|
1680
1547
|
}
|
|
1681
1548
|
}
|
|
1682
1549
|
}
|
|
1683
1550
|
|
|
1684
|
-
|
|
1685
1551
|
/* ========================================================================== */
|
|
1686
1552
|
/* === garbage_collection =================================================== */
|
|
1687
1553
|
/* ========================================================================== */
|
|
1688
1554
|
|
|
1689
1555
|
/*
|
|
1690
1556
|
Defragments and compacts columns and rows in the workspace A. Used when
|
|
1691
|
-
all
|
|
1557
|
+
all available memory has been used while performing row merging. Returns
|
|
1692
1558
|
the index of the first free position in A, after garbage collection. The
|
|
1693
1559
|
time taken by this routine is linear is the size of the array A, which is
|
|
1694
1560
|
itself linear in the number of nonzeros in the input matrix.
|
|
1695
1561
|
Not user-callable.
|
|
1696
1562
|
*/
|
|
1697
1563
|
template <typename IndexType>
|
|
1698
|
-
static IndexType garbage_collection
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
|
|
1702
|
-
|
|
1703
|
-
|
|
1704
|
-
|
|
1705
|
-
|
|
1706
|
-
|
|
1707
|
-
|
|
1708
|
-
)
|
|
1709
|
-
{
|
|
1564
|
+
static IndexType garbage_collection /* returns the new value of pfree */
|
|
1565
|
+
(
|
|
1566
|
+
/* === Parameters ======================================================= */
|
|
1567
|
+
|
|
1568
|
+
IndexType n_row, /* number of rows */
|
|
1569
|
+
IndexType n_col, /* number of columns */
|
|
1570
|
+
RowStructure<IndexType> Row[], /* row info */
|
|
1571
|
+
ColStructure<IndexType> Col[], /* column info */
|
|
1572
|
+
IndexType A[], /* A [0 ... Alen-1] holds the matrix */
|
|
1573
|
+
IndexType *pfree /* &A [0] ... pfree is in use */
|
|
1574
|
+
) {
|
|
1710
1575
|
/* === Local variables ================================================== */
|
|
1711
1576
|
|
|
1712
|
-
IndexType *psrc
|
|
1713
|
-
IndexType *pdest
|
|
1714
|
-
IndexType j
|
|
1715
|
-
IndexType r
|
|
1716
|
-
IndexType c
|
|
1717
|
-
IndexType length
|
|
1577
|
+
IndexType *psrc; /* source pointer */
|
|
1578
|
+
IndexType *pdest; /* destination pointer */
|
|
1579
|
+
IndexType j; /* counter */
|
|
1580
|
+
IndexType r; /* a row index */
|
|
1581
|
+
IndexType c; /* a column index */
|
|
1582
|
+
IndexType length; /* length of a row or column */
|
|
1718
1583
|
|
|
1719
1584
|
/* === Defragment the columns =========================================== */
|
|
1720
1585
|
|
|
1721
|
-
pdest = &A[0]
|
|
1722
|
-
for (c = 0
|
|
1723
|
-
|
|
1724
|
-
|
|
1725
|
-
{
|
|
1726
|
-
psrc = &A [Col [c].start] ;
|
|
1586
|
+
pdest = &A[0];
|
|
1587
|
+
for (c = 0; c < n_col; c++) {
|
|
1588
|
+
if (Col[c].is_alive()) {
|
|
1589
|
+
psrc = &A[Col[c].start];
|
|
1727
1590
|
|
|
1728
1591
|
/* move and compact the column */
|
|
1729
|
-
COLAMD_ASSERT
|
|
1730
|
-
Col
|
|
1731
|
-
length = Col
|
|
1732
|
-
for (j = 0
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
*pdest++ = r ;
|
|
1738
|
-
}
|
|
1592
|
+
COLAMD_ASSERT(pdest <= psrc);
|
|
1593
|
+
Col[c].start = (IndexType)(pdest - &A[0]);
|
|
1594
|
+
length = Col[c].length;
|
|
1595
|
+
for (j = 0; j < length; j++) {
|
|
1596
|
+
r = *psrc++;
|
|
1597
|
+
if (Row[r].is_alive()) {
|
|
1598
|
+
*pdest++ = r;
|
|
1599
|
+
}
|
|
1739
1600
|
}
|
|
1740
|
-
Col
|
|
1601
|
+
Col[c].length = (IndexType)(pdest - &A[Col[c].start]);
|
|
1741
1602
|
}
|
|
1742
1603
|
}
|
|
1743
1604
|
|
|
1744
1605
|
/* === Prepare to defragment the rows =================================== */
|
|
1745
1606
|
|
|
1746
|
-
for (r = 0
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
|
|
1755
|
-
|
|
1756
|
-
|
|
1757
|
-
|
|
1758
|
-
|
|
1759
|
-
psrc = &A [Row [r].start] ;
|
|
1760
|
-
Row [r].shared2.first_column = *psrc ;
|
|
1761
|
-
COLAMD_ASSERT (ROW_IS_ALIVE (r)) ;
|
|
1762
|
-
/* flag the start of the row with the one's complement of row */
|
|
1763
|
-
*psrc = ONES_COMPLEMENT (r) ;
|
|
1764
|
-
|
|
1607
|
+
for (r = 0; r < n_row; r++) {
|
|
1608
|
+
if (Row[r].is_alive()) {
|
|
1609
|
+
if (Row[r].length == 0) {
|
|
1610
|
+
/* this row is of zero length. cannot compact it, so kill it */
|
|
1611
|
+
COLAMD_DEBUG3(("Defrag row kill\n"));
|
|
1612
|
+
Row[r].kill();
|
|
1613
|
+
} else {
|
|
1614
|
+
/* save first column index in Row [r].shared2.first_column */
|
|
1615
|
+
psrc = &A[Row[r].start];
|
|
1616
|
+
Row[r].shared2.first_column = *psrc;
|
|
1617
|
+
COLAMD_ASSERT(Row[r].is_alive());
|
|
1618
|
+
/* flag the start of the row with the one's complement of row */
|
|
1619
|
+
*psrc = ones_complement(r);
|
|
1765
1620
|
}
|
|
1766
1621
|
}
|
|
1767
1622
|
}
|
|
1768
1623
|
|
|
1769
1624
|
/* === Defragment the rows ============================================== */
|
|
1770
1625
|
|
|
1771
|
-
psrc = pdest
|
|
1772
|
-
while (psrc < pfree)
|
|
1773
|
-
{
|
|
1626
|
+
psrc = pdest;
|
|
1627
|
+
while (psrc < pfree) {
|
|
1774
1628
|
/* find a negative number ... the start of a row */
|
|
1775
|
-
if (*psrc++ < 0)
|
|
1776
|
-
|
|
1777
|
-
psrc-- ;
|
|
1629
|
+
if (*psrc++ < 0) {
|
|
1630
|
+
psrc--;
|
|
1778
1631
|
/* get the row index */
|
|
1779
|
-
r =
|
|
1780
|
-
COLAMD_ASSERT
|
|
1632
|
+
r = ones_complement(*psrc);
|
|
1633
|
+
COLAMD_ASSERT(r >= 0 && r < n_row);
|
|
1781
1634
|
/* restore first column index */
|
|
1782
|
-
*psrc = Row
|
|
1783
|
-
COLAMD_ASSERT
|
|
1635
|
+
*psrc = Row[r].shared2.first_column;
|
|
1636
|
+
COLAMD_ASSERT(Row[r].is_alive());
|
|
1784
1637
|
|
|
1785
1638
|
/* move and compact the row */
|
|
1786
|
-
COLAMD_ASSERT
|
|
1787
|
-
Row
|
|
1788
|
-
length = Row
|
|
1789
|
-
for (j = 0
|
|
1790
|
-
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
|
|
1794
|
-
*pdest++ = c ;
|
|
1795
|
-
}
|
|
1639
|
+
COLAMD_ASSERT(pdest <= psrc);
|
|
1640
|
+
Row[r].start = (IndexType)(pdest - &A[0]);
|
|
1641
|
+
length = Row[r].length;
|
|
1642
|
+
for (j = 0; j < length; j++) {
|
|
1643
|
+
c = *psrc++;
|
|
1644
|
+
if (Col[c].is_alive()) {
|
|
1645
|
+
*pdest++ = c;
|
|
1646
|
+
}
|
|
1796
1647
|
}
|
|
1797
|
-
Row
|
|
1798
|
-
|
|
1648
|
+
Row[r].length = (IndexType)(pdest - &A[Row[r].start]);
|
|
1799
1649
|
}
|
|
1800
1650
|
}
|
|
1801
1651
|
/* ensure we found all the rows */
|
|
1802
|
-
COLAMD_ASSERT
|
|
1652
|
+
COLAMD_ASSERT(debug_rows == 0);
|
|
1803
1653
|
|
|
1804
1654
|
/* === Return the new value of pfree ==================================== */
|
|
1805
1655
|
|
|
1806
|
-
return ((IndexType)
|
|
1656
|
+
return ((IndexType)(pdest - &A[0]));
|
|
1807
1657
|
}
|
|
1808
1658
|
|
|
1809
|
-
|
|
1810
1659
|
/* ========================================================================== */
|
|
1811
1660
|
/* === clear_mark =========================================================== */
|
|
1812
1661
|
/* ========================================================================== */
|
|
@@ -1816,28 +1665,26 @@ static IndexType garbage_collection /* returns the new value of pfree */
|
|
|
1816
1665
|
Return value is the new tag_mark. Not user-callable.
|
|
1817
1666
|
*/
|
|
1818
1667
|
template <typename IndexType>
|
|
1819
|
-
static inline
|
|
1820
|
-
|
|
1821
|
-
|
|
1822
|
-
|
|
1823
|
-
|
|
1824
|
-
|
|
1825
|
-
)
|
|
1826
|
-
{
|
|
1668
|
+
static inline IndexType clear_mark /* return the new value for tag_mark */
|
|
1669
|
+
(
|
|
1670
|
+
/* === Parameters ======================================================= */
|
|
1671
|
+
|
|
1672
|
+
IndexType n_row, /* number of rows in A */
|
|
1673
|
+
RowStructure<IndexType> Row[] /* Row [0 ... n_row-1].shared2.mark is set to zero */
|
|
1674
|
+
) {
|
|
1827
1675
|
/* === Local variables ================================================== */
|
|
1828
1676
|
|
|
1829
|
-
IndexType r
|
|
1677
|
+
IndexType r;
|
|
1830
1678
|
|
|
1831
|
-
for (r = 0
|
|
1832
|
-
|
|
1833
|
-
|
|
1834
|
-
{
|
|
1835
|
-
Row [r].shared2.mark = 0 ;
|
|
1679
|
+
for (r = 0; r < n_row; r++) {
|
|
1680
|
+
if (Row[r].is_alive()) {
|
|
1681
|
+
Row[r].shared2.mark = 0;
|
|
1836
1682
|
}
|
|
1837
1683
|
}
|
|
1838
|
-
return (1)
|
|
1684
|
+
return (1);
|
|
1839
1685
|
}
|
|
1840
1686
|
|
|
1841
|
-
|
|
1842
|
-
}
|
|
1687
|
+
} // namespace Colamd
|
|
1688
|
+
} // namespace internal
|
|
1689
|
+
} // namespace Eigen
|
|
1843
1690
|
#endif
|