umappp 0.1.2
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.
- checksums.yaml +7 -0
- data/LICENSE.txt +25 -0
- data/README.md +110 -0
- data/ext/umappp/extconf.rb +25 -0
- data/ext/umappp/numo.hpp +867 -0
- data/ext/umappp/umappp.cpp +225 -0
- data/lib/umappp/version.rb +5 -0
- data/lib/umappp.rb +41 -0
- data/vendor/Eigen/Cholesky +45 -0
- data/vendor/Eigen/CholmodSupport +48 -0
- data/vendor/Eigen/Core +384 -0
- data/vendor/Eigen/Dense +7 -0
- data/vendor/Eigen/Eigen +2 -0
- data/vendor/Eigen/Eigenvalues +60 -0
- data/vendor/Eigen/Geometry +59 -0
- data/vendor/Eigen/Householder +29 -0
- data/vendor/Eigen/IterativeLinearSolvers +48 -0
- data/vendor/Eigen/Jacobi +32 -0
- data/vendor/Eigen/KLUSupport +41 -0
- data/vendor/Eigen/LU +47 -0
- data/vendor/Eigen/MetisSupport +35 -0
- data/vendor/Eigen/OrderingMethods +70 -0
- data/vendor/Eigen/PaStiXSupport +49 -0
- data/vendor/Eigen/PardisoSupport +35 -0
- data/vendor/Eigen/QR +50 -0
- data/vendor/Eigen/QtAlignedMalloc +39 -0
- data/vendor/Eigen/SPQRSupport +34 -0
- data/vendor/Eigen/SVD +50 -0
- data/vendor/Eigen/Sparse +34 -0
- data/vendor/Eigen/SparseCholesky +37 -0
- data/vendor/Eigen/SparseCore +69 -0
- data/vendor/Eigen/SparseLU +50 -0
- data/vendor/Eigen/SparseQR +36 -0
- data/vendor/Eigen/StdDeque +27 -0
- data/vendor/Eigen/StdList +26 -0
- data/vendor/Eigen/StdVector +27 -0
- data/vendor/Eigen/SuperLUSupport +64 -0
- data/vendor/Eigen/UmfPackSupport +40 -0
- data/vendor/Eigen/src/Cholesky/LDLT.h +688 -0
- data/vendor/Eigen/src/Cholesky/LLT.h +558 -0
- data/vendor/Eigen/src/Cholesky/LLT_LAPACKE.h +99 -0
- data/vendor/Eigen/src/CholmodSupport/CholmodSupport.h +682 -0
- data/vendor/Eigen/src/Core/ArithmeticSequence.h +413 -0
- data/vendor/Eigen/src/Core/Array.h +417 -0
- data/vendor/Eigen/src/Core/ArrayBase.h +226 -0
- data/vendor/Eigen/src/Core/ArrayWrapper.h +209 -0
- data/vendor/Eigen/src/Core/Assign.h +90 -0
- data/vendor/Eigen/src/Core/AssignEvaluator.h +1010 -0
- data/vendor/Eigen/src/Core/Assign_MKL.h +178 -0
- data/vendor/Eigen/src/Core/BandMatrix.h +353 -0
- data/vendor/Eigen/src/Core/Block.h +448 -0
- data/vendor/Eigen/src/Core/BooleanRedux.h +162 -0
- data/vendor/Eigen/src/Core/CommaInitializer.h +164 -0
- data/vendor/Eigen/src/Core/ConditionEstimator.h +175 -0
- data/vendor/Eigen/src/Core/CoreEvaluators.h +1741 -0
- data/vendor/Eigen/src/Core/CoreIterators.h +132 -0
- data/vendor/Eigen/src/Core/CwiseBinaryOp.h +183 -0
- data/vendor/Eigen/src/Core/CwiseNullaryOp.h +1001 -0
- data/vendor/Eigen/src/Core/CwiseTernaryOp.h +197 -0
- data/vendor/Eigen/src/Core/CwiseUnaryOp.h +103 -0
- data/vendor/Eigen/src/Core/CwiseUnaryView.h +132 -0
- data/vendor/Eigen/src/Core/DenseBase.h +701 -0
- data/vendor/Eigen/src/Core/DenseCoeffsBase.h +685 -0
- data/vendor/Eigen/src/Core/DenseStorage.h +652 -0
- data/vendor/Eigen/src/Core/Diagonal.h +258 -0
- data/vendor/Eigen/src/Core/DiagonalMatrix.h +391 -0
- data/vendor/Eigen/src/Core/DiagonalProduct.h +28 -0
- data/vendor/Eigen/src/Core/Dot.h +318 -0
- data/vendor/Eigen/src/Core/EigenBase.h +160 -0
- data/vendor/Eigen/src/Core/ForceAlignedAccess.h +150 -0
- data/vendor/Eigen/src/Core/Fuzzy.h +155 -0
- data/vendor/Eigen/src/Core/GeneralProduct.h +465 -0
- data/vendor/Eigen/src/Core/GenericPacketMath.h +1040 -0
- data/vendor/Eigen/src/Core/GlobalFunctions.h +194 -0
- data/vendor/Eigen/src/Core/IO.h +258 -0
- data/vendor/Eigen/src/Core/IndexedView.h +237 -0
- data/vendor/Eigen/src/Core/Inverse.h +117 -0
- data/vendor/Eigen/src/Core/Map.h +171 -0
- data/vendor/Eigen/src/Core/MapBase.h +310 -0
- data/vendor/Eigen/src/Core/MathFunctions.h +2057 -0
- data/vendor/Eigen/src/Core/MathFunctionsImpl.h +200 -0
- data/vendor/Eigen/src/Core/Matrix.h +565 -0
- data/vendor/Eigen/src/Core/MatrixBase.h +547 -0
- data/vendor/Eigen/src/Core/NestByValue.h +85 -0
- data/vendor/Eigen/src/Core/NoAlias.h +109 -0
- data/vendor/Eigen/src/Core/NumTraits.h +335 -0
- data/vendor/Eigen/src/Core/PartialReduxEvaluator.h +232 -0
- data/vendor/Eigen/src/Core/PermutationMatrix.h +605 -0
- data/vendor/Eigen/src/Core/PlainObjectBase.h +1128 -0
- data/vendor/Eigen/src/Core/Product.h +191 -0
- data/vendor/Eigen/src/Core/ProductEvaluators.h +1179 -0
- data/vendor/Eigen/src/Core/Random.h +218 -0
- data/vendor/Eigen/src/Core/Redux.h +515 -0
- data/vendor/Eigen/src/Core/Ref.h +381 -0
- data/vendor/Eigen/src/Core/Replicate.h +142 -0
- data/vendor/Eigen/src/Core/Reshaped.h +454 -0
- data/vendor/Eigen/src/Core/ReturnByValue.h +119 -0
- data/vendor/Eigen/src/Core/Reverse.h +217 -0
- data/vendor/Eigen/src/Core/Select.h +164 -0
- data/vendor/Eigen/src/Core/SelfAdjointView.h +365 -0
- data/vendor/Eigen/src/Core/SelfCwiseBinaryOp.h +47 -0
- data/vendor/Eigen/src/Core/Solve.h +188 -0
- data/vendor/Eigen/src/Core/SolveTriangular.h +235 -0
- data/vendor/Eigen/src/Core/SolverBase.h +168 -0
- data/vendor/Eigen/src/Core/StableNorm.h +251 -0
- data/vendor/Eigen/src/Core/StlIterators.h +463 -0
- data/vendor/Eigen/src/Core/Stride.h +116 -0
- data/vendor/Eigen/src/Core/Swap.h +68 -0
- data/vendor/Eigen/src/Core/Transpose.h +464 -0
- data/vendor/Eigen/src/Core/Transpositions.h +386 -0
- data/vendor/Eigen/src/Core/TriangularMatrix.h +1001 -0
- data/vendor/Eigen/src/Core/VectorBlock.h +96 -0
- data/vendor/Eigen/src/Core/VectorwiseOp.h +784 -0
- data/vendor/Eigen/src/Core/Visitor.h +381 -0
- data/vendor/Eigen/src/Core/arch/AVX/Complex.h +372 -0
- data/vendor/Eigen/src/Core/arch/AVX/MathFunctions.h +228 -0
- data/vendor/Eigen/src/Core/arch/AVX/PacketMath.h +1574 -0
- data/vendor/Eigen/src/Core/arch/AVX/TypeCasting.h +115 -0
- data/vendor/Eigen/src/Core/arch/AVX512/Complex.h +422 -0
- data/vendor/Eigen/src/Core/arch/AVX512/MathFunctions.h +362 -0
- data/vendor/Eigen/src/Core/arch/AVX512/PacketMath.h +2303 -0
- data/vendor/Eigen/src/Core/arch/AVX512/TypeCasting.h +89 -0
- data/vendor/Eigen/src/Core/arch/AltiVec/Complex.h +417 -0
- data/vendor/Eigen/src/Core/arch/AltiVec/MathFunctions.h +90 -0
- data/vendor/Eigen/src/Core/arch/AltiVec/MatrixProduct.h +2937 -0
- data/vendor/Eigen/src/Core/arch/AltiVec/MatrixProductCommon.h +221 -0
- data/vendor/Eigen/src/Core/arch/AltiVec/MatrixProductMMA.h +629 -0
- data/vendor/Eigen/src/Core/arch/AltiVec/PacketMath.h +2711 -0
- data/vendor/Eigen/src/Core/arch/CUDA/Complex.h +258 -0
- data/vendor/Eigen/src/Core/arch/Default/BFloat16.h +700 -0
- data/vendor/Eigen/src/Core/arch/Default/ConjHelper.h +117 -0
- data/vendor/Eigen/src/Core/arch/Default/GenericPacketMathFunctions.h +1649 -0
- data/vendor/Eigen/src/Core/arch/Default/GenericPacketMathFunctionsFwd.h +110 -0
- data/vendor/Eigen/src/Core/arch/Default/Half.h +942 -0
- data/vendor/Eigen/src/Core/arch/Default/Settings.h +49 -0
- data/vendor/Eigen/src/Core/arch/Default/TypeCasting.h +120 -0
- data/vendor/Eigen/src/Core/arch/GPU/MathFunctions.h +103 -0
- data/vendor/Eigen/src/Core/arch/GPU/PacketMath.h +1685 -0
- data/vendor/Eigen/src/Core/arch/GPU/TypeCasting.h +80 -0
- data/vendor/Eigen/src/Core/arch/HIP/hcc/math_constants.h +23 -0
- data/vendor/Eigen/src/Core/arch/MSA/Complex.h +648 -0
- data/vendor/Eigen/src/Core/arch/MSA/MathFunctions.h +387 -0
- data/vendor/Eigen/src/Core/arch/MSA/PacketMath.h +1233 -0
- data/vendor/Eigen/src/Core/arch/NEON/Complex.h +584 -0
- data/vendor/Eigen/src/Core/arch/NEON/GeneralBlockPanelKernel.h +183 -0
- data/vendor/Eigen/src/Core/arch/NEON/MathFunctions.h +75 -0
- data/vendor/Eigen/src/Core/arch/NEON/PacketMath.h +4587 -0
- data/vendor/Eigen/src/Core/arch/NEON/TypeCasting.h +1419 -0
- data/vendor/Eigen/src/Core/arch/SSE/Complex.h +351 -0
- data/vendor/Eigen/src/Core/arch/SSE/MathFunctions.h +199 -0
- data/vendor/Eigen/src/Core/arch/SSE/PacketMath.h +1505 -0
- data/vendor/Eigen/src/Core/arch/SSE/TypeCasting.h +142 -0
- data/vendor/Eigen/src/Core/arch/SVE/MathFunctions.h +44 -0
- data/vendor/Eigen/src/Core/arch/SVE/PacketMath.h +752 -0
- data/vendor/Eigen/src/Core/arch/SVE/TypeCasting.h +49 -0
- data/vendor/Eigen/src/Core/arch/SYCL/InteropHeaders.h +232 -0
- data/vendor/Eigen/src/Core/arch/SYCL/MathFunctions.h +301 -0
- data/vendor/Eigen/src/Core/arch/SYCL/PacketMath.h +670 -0
- data/vendor/Eigen/src/Core/arch/SYCL/SyclMemoryModel.h +694 -0
- data/vendor/Eigen/src/Core/arch/SYCL/TypeCasting.h +85 -0
- data/vendor/Eigen/src/Core/arch/ZVector/Complex.h +426 -0
- data/vendor/Eigen/src/Core/arch/ZVector/MathFunctions.h +233 -0
- data/vendor/Eigen/src/Core/arch/ZVector/PacketMath.h +1060 -0
- data/vendor/Eigen/src/Core/functors/AssignmentFunctors.h +177 -0
- data/vendor/Eigen/src/Core/functors/BinaryFunctors.h +541 -0
- data/vendor/Eigen/src/Core/functors/NullaryFunctors.h +189 -0
- data/vendor/Eigen/src/Core/functors/StlFunctors.h +166 -0
- data/vendor/Eigen/src/Core/functors/TernaryFunctors.h +25 -0
- data/vendor/Eigen/src/Core/functors/UnaryFunctors.h +1131 -0
- data/vendor/Eigen/src/Core/products/GeneralBlockPanelKernel.h +2645 -0
- data/vendor/Eigen/src/Core/products/GeneralMatrixMatrix.h +517 -0
- data/vendor/Eigen/src/Core/products/GeneralMatrixMatrixTriangular.h +317 -0
- data/vendor/Eigen/src/Core/products/GeneralMatrixMatrixTriangular_BLAS.h +145 -0
- data/vendor/Eigen/src/Core/products/GeneralMatrixMatrix_BLAS.h +124 -0
- data/vendor/Eigen/src/Core/products/GeneralMatrixVector.h +518 -0
- data/vendor/Eigen/src/Core/products/GeneralMatrixVector_BLAS.h +136 -0
- data/vendor/Eigen/src/Core/products/Parallelizer.h +180 -0
- data/vendor/Eigen/src/Core/products/SelfadjointMatrixMatrix.h +544 -0
- data/vendor/Eigen/src/Core/products/SelfadjointMatrixMatrix_BLAS.h +295 -0
- data/vendor/Eigen/src/Core/products/SelfadjointMatrixVector.h +262 -0
- data/vendor/Eigen/src/Core/products/SelfadjointMatrixVector_BLAS.h +118 -0
- data/vendor/Eigen/src/Core/products/SelfadjointProduct.h +133 -0
- data/vendor/Eigen/src/Core/products/SelfadjointRank2Update.h +94 -0
- data/vendor/Eigen/src/Core/products/TriangularMatrixMatrix.h +472 -0
- data/vendor/Eigen/src/Core/products/TriangularMatrixMatrix_BLAS.h +317 -0
- data/vendor/Eigen/src/Core/products/TriangularMatrixVector.h +350 -0
- data/vendor/Eigen/src/Core/products/TriangularMatrixVector_BLAS.h +255 -0
- data/vendor/Eigen/src/Core/products/TriangularSolverMatrix.h +337 -0
- data/vendor/Eigen/src/Core/products/TriangularSolverMatrix_BLAS.h +167 -0
- data/vendor/Eigen/src/Core/products/TriangularSolverVector.h +148 -0
- data/vendor/Eigen/src/Core/util/BlasUtil.h +583 -0
- data/vendor/Eigen/src/Core/util/ConfigureVectorization.h +512 -0
- data/vendor/Eigen/src/Core/util/Constants.h +563 -0
- data/vendor/Eigen/src/Core/util/DisableStupidWarnings.h +106 -0
- data/vendor/Eigen/src/Core/util/ForwardDeclarations.h +322 -0
- data/vendor/Eigen/src/Core/util/IndexedViewHelper.h +186 -0
- data/vendor/Eigen/src/Core/util/IntegralConstant.h +272 -0
- data/vendor/Eigen/src/Core/util/MKL_support.h +137 -0
- data/vendor/Eigen/src/Core/util/Macros.h +1464 -0
- data/vendor/Eigen/src/Core/util/Memory.h +1163 -0
- data/vendor/Eigen/src/Core/util/Meta.h +812 -0
- data/vendor/Eigen/src/Core/util/NonMPL2.h +3 -0
- data/vendor/Eigen/src/Core/util/ReenableStupidWarnings.h +31 -0
- data/vendor/Eigen/src/Core/util/ReshapedHelper.h +51 -0
- data/vendor/Eigen/src/Core/util/StaticAssert.h +221 -0
- data/vendor/Eigen/src/Core/util/SymbolicIndex.h +293 -0
- data/vendor/Eigen/src/Core/util/XprHelper.h +856 -0
- data/vendor/Eigen/src/Eigenvalues/ComplexEigenSolver.h +346 -0
- data/vendor/Eigen/src/Eigenvalues/ComplexSchur.h +462 -0
- data/vendor/Eigen/src/Eigenvalues/ComplexSchur_LAPACKE.h +91 -0
- data/vendor/Eigen/src/Eigenvalues/EigenSolver.h +622 -0
- data/vendor/Eigen/src/Eigenvalues/GeneralizedEigenSolver.h +418 -0
- data/vendor/Eigen/src/Eigenvalues/GeneralizedSelfAdjointEigenSolver.h +226 -0
- data/vendor/Eigen/src/Eigenvalues/HessenbergDecomposition.h +374 -0
- data/vendor/Eigen/src/Eigenvalues/MatrixBaseEigenvalues.h +158 -0
- data/vendor/Eigen/src/Eigenvalues/RealQZ.h +657 -0
- data/vendor/Eigen/src/Eigenvalues/RealSchur.h +558 -0
- data/vendor/Eigen/src/Eigenvalues/RealSchur_LAPACKE.h +77 -0
- data/vendor/Eigen/src/Eigenvalues/SelfAdjointEigenSolver.h +904 -0
- data/vendor/Eigen/src/Eigenvalues/SelfAdjointEigenSolver_LAPACKE.h +87 -0
- data/vendor/Eigen/src/Eigenvalues/Tridiagonalization.h +561 -0
- data/vendor/Eigen/src/Geometry/AlignedBox.h +486 -0
- data/vendor/Eigen/src/Geometry/AngleAxis.h +247 -0
- data/vendor/Eigen/src/Geometry/EulerAngles.h +114 -0
- data/vendor/Eigen/src/Geometry/Homogeneous.h +501 -0
- data/vendor/Eigen/src/Geometry/Hyperplane.h +282 -0
- data/vendor/Eigen/src/Geometry/OrthoMethods.h +235 -0
- data/vendor/Eigen/src/Geometry/ParametrizedLine.h +232 -0
- data/vendor/Eigen/src/Geometry/Quaternion.h +870 -0
- data/vendor/Eigen/src/Geometry/Rotation2D.h +199 -0
- data/vendor/Eigen/src/Geometry/RotationBase.h +206 -0
- data/vendor/Eigen/src/Geometry/Scaling.h +188 -0
- data/vendor/Eigen/src/Geometry/Transform.h +1563 -0
- data/vendor/Eigen/src/Geometry/Translation.h +202 -0
- data/vendor/Eigen/src/Geometry/Umeyama.h +166 -0
- data/vendor/Eigen/src/Geometry/arch/Geometry_SIMD.h +168 -0
- data/vendor/Eigen/src/Householder/BlockHouseholder.h +110 -0
- data/vendor/Eigen/src/Householder/Householder.h +176 -0
- data/vendor/Eigen/src/Householder/HouseholderSequence.h +545 -0
- data/vendor/Eigen/src/IterativeLinearSolvers/BasicPreconditioners.h +226 -0
- data/vendor/Eigen/src/IterativeLinearSolvers/BiCGSTAB.h +212 -0
- data/vendor/Eigen/src/IterativeLinearSolvers/ConjugateGradient.h +229 -0
- data/vendor/Eigen/src/IterativeLinearSolvers/IncompleteCholesky.h +394 -0
- data/vendor/Eigen/src/IterativeLinearSolvers/IncompleteLUT.h +453 -0
- data/vendor/Eigen/src/IterativeLinearSolvers/IterativeSolverBase.h +444 -0
- data/vendor/Eigen/src/IterativeLinearSolvers/LeastSquareConjugateGradient.h +198 -0
- data/vendor/Eigen/src/IterativeLinearSolvers/SolveWithGuess.h +117 -0
- data/vendor/Eigen/src/Jacobi/Jacobi.h +483 -0
- data/vendor/Eigen/src/KLUSupport/KLUSupport.h +358 -0
- data/vendor/Eigen/src/LU/Determinant.h +117 -0
- data/vendor/Eigen/src/LU/FullPivLU.h +877 -0
- data/vendor/Eigen/src/LU/InverseImpl.h +432 -0
- data/vendor/Eigen/src/LU/PartialPivLU.h +624 -0
- data/vendor/Eigen/src/LU/PartialPivLU_LAPACKE.h +83 -0
- data/vendor/Eigen/src/LU/arch/InverseSize4.h +351 -0
- data/vendor/Eigen/src/MetisSupport/MetisSupport.h +137 -0
- data/vendor/Eigen/src/OrderingMethods/Amd.h +435 -0
- data/vendor/Eigen/src/OrderingMethods/Eigen_Colamd.h +1863 -0
- data/vendor/Eigen/src/OrderingMethods/Ordering.h +153 -0
- data/vendor/Eigen/src/PaStiXSupport/PaStiXSupport.h +678 -0
- data/vendor/Eigen/src/PardisoSupport/PardisoSupport.h +545 -0
- data/vendor/Eigen/src/QR/ColPivHouseholderQR.h +674 -0
- data/vendor/Eigen/src/QR/ColPivHouseholderQR_LAPACKE.h +97 -0
- data/vendor/Eigen/src/QR/CompleteOrthogonalDecomposition.h +635 -0
- data/vendor/Eigen/src/QR/FullPivHouseholderQR.h +713 -0
- data/vendor/Eigen/src/QR/HouseholderQR.h +434 -0
- data/vendor/Eigen/src/QR/HouseholderQR_LAPACKE.h +68 -0
- data/vendor/Eigen/src/SPQRSupport/SuiteSparseQRSupport.h +335 -0
- data/vendor/Eigen/src/SVD/BDCSVD.h +1366 -0
- data/vendor/Eigen/src/SVD/JacobiSVD.h +812 -0
- data/vendor/Eigen/src/SVD/JacobiSVD_LAPACKE.h +91 -0
- data/vendor/Eigen/src/SVD/SVDBase.h +376 -0
- data/vendor/Eigen/src/SVD/UpperBidiagonalization.h +414 -0
- data/vendor/Eigen/src/SparseCholesky/SimplicialCholesky.h +697 -0
- data/vendor/Eigen/src/SparseCholesky/SimplicialCholesky_impl.h +174 -0
- data/vendor/Eigen/src/SparseCore/AmbiVector.h +378 -0
- data/vendor/Eigen/src/SparseCore/CompressedStorage.h +274 -0
- data/vendor/Eigen/src/SparseCore/ConservativeSparseSparseProduct.h +352 -0
- data/vendor/Eigen/src/SparseCore/MappedSparseMatrix.h +67 -0
- data/vendor/Eigen/src/SparseCore/SparseAssign.h +270 -0
- data/vendor/Eigen/src/SparseCore/SparseBlock.h +571 -0
- data/vendor/Eigen/src/SparseCore/SparseColEtree.h +206 -0
- data/vendor/Eigen/src/SparseCore/SparseCompressedBase.h +370 -0
- data/vendor/Eigen/src/SparseCore/SparseCwiseBinaryOp.h +722 -0
- data/vendor/Eigen/src/SparseCore/SparseCwiseUnaryOp.h +150 -0
- data/vendor/Eigen/src/SparseCore/SparseDenseProduct.h +342 -0
- data/vendor/Eigen/src/SparseCore/SparseDiagonalProduct.h +138 -0
- data/vendor/Eigen/src/SparseCore/SparseDot.h +98 -0
- data/vendor/Eigen/src/SparseCore/SparseFuzzy.h +29 -0
- data/vendor/Eigen/src/SparseCore/SparseMap.h +305 -0
- data/vendor/Eigen/src/SparseCore/SparseMatrix.h +1518 -0
- data/vendor/Eigen/src/SparseCore/SparseMatrixBase.h +398 -0
- data/vendor/Eigen/src/SparseCore/SparsePermutation.h +178 -0
- data/vendor/Eigen/src/SparseCore/SparseProduct.h +181 -0
- data/vendor/Eigen/src/SparseCore/SparseRedux.h +49 -0
- data/vendor/Eigen/src/SparseCore/SparseRef.h +397 -0
- data/vendor/Eigen/src/SparseCore/SparseSelfAdjointView.h +659 -0
- data/vendor/Eigen/src/SparseCore/SparseSolverBase.h +124 -0
- data/vendor/Eigen/src/SparseCore/SparseSparseProductWithPruning.h +198 -0
- data/vendor/Eigen/src/SparseCore/SparseTranspose.h +92 -0
- data/vendor/Eigen/src/SparseCore/SparseTriangularView.h +189 -0
- data/vendor/Eigen/src/SparseCore/SparseUtil.h +186 -0
- data/vendor/Eigen/src/SparseCore/SparseVector.h +478 -0
- data/vendor/Eigen/src/SparseCore/SparseView.h +254 -0
- data/vendor/Eigen/src/SparseCore/TriangularSolver.h +315 -0
- data/vendor/Eigen/src/SparseLU/SparseLU.h +923 -0
- data/vendor/Eigen/src/SparseLU/SparseLUImpl.h +66 -0
- data/vendor/Eigen/src/SparseLU/SparseLU_Memory.h +226 -0
- data/vendor/Eigen/src/SparseLU/SparseLU_Structs.h +110 -0
- data/vendor/Eigen/src/SparseLU/SparseLU_SupernodalMatrix.h +375 -0
- data/vendor/Eigen/src/SparseLU/SparseLU_Utils.h +80 -0
- data/vendor/Eigen/src/SparseLU/SparseLU_column_bmod.h +181 -0
- data/vendor/Eigen/src/SparseLU/SparseLU_column_dfs.h +179 -0
- data/vendor/Eigen/src/SparseLU/SparseLU_copy_to_ucol.h +107 -0
- data/vendor/Eigen/src/SparseLU/SparseLU_gemm_kernel.h +280 -0
- data/vendor/Eigen/src/SparseLU/SparseLU_heap_relax_snode.h +126 -0
- data/vendor/Eigen/src/SparseLU/SparseLU_kernel_bmod.h +130 -0
- data/vendor/Eigen/src/SparseLU/SparseLU_panel_bmod.h +223 -0
- data/vendor/Eigen/src/SparseLU/SparseLU_panel_dfs.h +258 -0
- data/vendor/Eigen/src/SparseLU/SparseLU_pivotL.h +137 -0
- data/vendor/Eigen/src/SparseLU/SparseLU_pruneL.h +136 -0
- data/vendor/Eigen/src/SparseLU/SparseLU_relax_snode.h +83 -0
- data/vendor/Eigen/src/SparseQR/SparseQR.h +758 -0
- data/vendor/Eigen/src/StlSupport/StdDeque.h +116 -0
- data/vendor/Eigen/src/StlSupport/StdList.h +106 -0
- data/vendor/Eigen/src/StlSupport/StdVector.h +131 -0
- data/vendor/Eigen/src/StlSupport/details.h +84 -0
- data/vendor/Eigen/src/SuperLUSupport/SuperLUSupport.h +1025 -0
- data/vendor/Eigen/src/UmfPackSupport/UmfPackSupport.h +642 -0
- data/vendor/Eigen/src/misc/Image.h +82 -0
- data/vendor/Eigen/src/misc/Kernel.h +79 -0
- data/vendor/Eigen/src/misc/RealSvd2x2.h +55 -0
- data/vendor/Eigen/src/misc/blas.h +440 -0
- data/vendor/Eigen/src/misc/lapack.h +152 -0
- data/vendor/Eigen/src/misc/lapacke.h +16292 -0
- data/vendor/Eigen/src/misc/lapacke_mangling.h +17 -0
- data/vendor/Eigen/src/plugins/ArrayCwiseBinaryOps.h +358 -0
- data/vendor/Eigen/src/plugins/ArrayCwiseUnaryOps.h +696 -0
- data/vendor/Eigen/src/plugins/BlockMethods.h +1442 -0
- data/vendor/Eigen/src/plugins/CommonCwiseBinaryOps.h +115 -0
- data/vendor/Eigen/src/plugins/CommonCwiseUnaryOps.h +177 -0
- data/vendor/Eigen/src/plugins/IndexedViewMethods.h +262 -0
- data/vendor/Eigen/src/plugins/MatrixCwiseBinaryOps.h +152 -0
- data/vendor/Eigen/src/plugins/MatrixCwiseUnaryOps.h +95 -0
- data/vendor/Eigen/src/plugins/ReshapedMethods.h +149 -0
- data/vendor/aarand/aarand.hpp +114 -0
- data/vendor/annoy/annoylib.h +1495 -0
- data/vendor/annoy/kissrandom.h +120 -0
- data/vendor/annoy/mman.h +242 -0
- data/vendor/hnswlib/bruteforce.h +152 -0
- data/vendor/hnswlib/hnswalg.h +1192 -0
- data/vendor/hnswlib/hnswlib.h +108 -0
- data/vendor/hnswlib/space_ip.h +282 -0
- data/vendor/hnswlib/space_l2.h +281 -0
- data/vendor/hnswlib/visited_list_pool.h +79 -0
- data/vendor/irlba/irlba.hpp +575 -0
- data/vendor/irlba/lanczos.hpp +212 -0
- data/vendor/irlba/parallel.hpp +474 -0
- data/vendor/irlba/utils.hpp +224 -0
- data/vendor/irlba/wrappers.hpp +228 -0
- data/vendor/kmeans/Base.hpp +75 -0
- data/vendor/kmeans/Details.hpp +79 -0
- data/vendor/kmeans/HartiganWong.hpp +492 -0
- data/vendor/kmeans/InitializeKmeansPP.hpp +144 -0
- data/vendor/kmeans/InitializeNone.hpp +44 -0
- data/vendor/kmeans/InitializePCAPartition.hpp +309 -0
- data/vendor/kmeans/InitializeRandom.hpp +91 -0
- data/vendor/kmeans/Kmeans.hpp +161 -0
- data/vendor/kmeans/Lloyd.hpp +134 -0
- data/vendor/kmeans/MiniBatch.hpp +269 -0
- data/vendor/kmeans/QuickSearch.hpp +179 -0
- data/vendor/kmeans/compute_centroids.hpp +32 -0
- data/vendor/kmeans/compute_wcss.hpp +27 -0
- data/vendor/kmeans/is_edge_case.hpp +42 -0
- data/vendor/kmeans/random.hpp +55 -0
- data/vendor/knncolle/Annoy/Annoy.hpp +193 -0
- data/vendor/knncolle/BruteForce/BruteForce.hpp +120 -0
- data/vendor/knncolle/Hnsw/Hnsw.hpp +225 -0
- data/vendor/knncolle/Kmknn/Kmknn.hpp +286 -0
- data/vendor/knncolle/VpTree/VpTree.hpp +256 -0
- data/vendor/knncolle/knncolle.hpp +34 -0
- data/vendor/knncolle/utils/Base.hpp +100 -0
- data/vendor/knncolle/utils/NeighborQueue.hpp +94 -0
- data/vendor/knncolle/utils/distances.hpp +98 -0
- data/vendor/knncolle/utils/find_nearest_neighbors.hpp +112 -0
- data/vendor/powerit/PowerIterations.hpp +157 -0
- data/vendor/umappp/NeighborList.hpp +37 -0
- data/vendor/umappp/Umap.hpp +662 -0
- data/vendor/umappp/combine_neighbor_sets.hpp +95 -0
- data/vendor/umappp/find_ab.hpp +157 -0
- data/vendor/umappp/neighbor_similarities.hpp +136 -0
- data/vendor/umappp/optimize_layout.hpp +285 -0
- data/vendor/umappp/spectral_init.hpp +181 -0
- data/vendor/umappp/umappp.hpp +13 -0
- metadata +465 -0
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
#ifndef UMAPPP_COMBINE_NEIGHBOR_SETS_HPP
|
|
2
|
+
#define UMAPPP_COMBINE_NEIGHBOR_SETS_HPP
|
|
3
|
+
|
|
4
|
+
#include <vector>
|
|
5
|
+
#include <limits>
|
|
6
|
+
#include <cmath>
|
|
7
|
+
#include <algorithm>
|
|
8
|
+
#include <numeric>
|
|
9
|
+
|
|
10
|
+
#include "NeighborList.hpp"
|
|
11
|
+
|
|
12
|
+
namespace umappp {
|
|
13
|
+
|
|
14
|
+
template<typename Float>
|
|
15
|
+
void combine_neighbor_sets(NeighborList<Float>& x, Float mix_ratio = 1) {
|
|
16
|
+
std::vector<size_t> last(x.size());
|
|
17
|
+
std::vector<size_t> original(x.size());
|
|
18
|
+
|
|
19
|
+
for (size_t i = 0; i < x.size(); ++i) {
|
|
20
|
+
auto& current = x[i];
|
|
21
|
+
std::sort(current.begin(), current.end()); // sorting by ID, see below.
|
|
22
|
+
original[i] = x[i].size();
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
for (size_t first = 0; first < x.size(); ++first) {
|
|
26
|
+
auto& current = x[first];
|
|
27
|
+
const int desired = first;
|
|
28
|
+
|
|
29
|
+
// Looping through the neighbors and searching for self in each
|
|
30
|
+
// neighbor's neighbors. As each inner vector in 'x' is sorted,
|
|
31
|
+
// this should only require a single pass through the entire set of
|
|
32
|
+
// neighbors as we do not need to search previously searched hits.
|
|
33
|
+
for (auto& y : current) {
|
|
34
|
+
auto& target = x[y.first];
|
|
35
|
+
auto& curlast = last[y.first];
|
|
36
|
+
const auto& limits = original[y.first];
|
|
37
|
+
while (curlast < limits && target[curlast].first < desired) {
|
|
38
|
+
++curlast;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
if (curlast < limits && target[curlast].first == desired) {
|
|
42
|
+
if (desired < y.first) { // don't average it twice.
|
|
43
|
+
Float product = y.second * target[curlast].second;
|
|
44
|
+
Float prob_final;
|
|
45
|
+
|
|
46
|
+
if (mix_ratio == 1) {
|
|
47
|
+
prob_final = y.second + target[curlast].second - product;
|
|
48
|
+
} else if (mix_ratio == 0) {
|
|
49
|
+
prob_final = product;
|
|
50
|
+
} else {
|
|
51
|
+
prob_final = mix_ratio * (y.second + target[curlast].second - product) + (1 - mix_ratio) * product;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
y.second = prob_final;
|
|
55
|
+
target[curlast].second = prob_final;
|
|
56
|
+
}
|
|
57
|
+
} else {
|
|
58
|
+
if (mix_ratio == 1) {
|
|
59
|
+
target.emplace_back(desired, y.second);
|
|
60
|
+
} else if (mix_ratio == 0) {
|
|
61
|
+
y.second = 0; // mark for deletion.
|
|
62
|
+
} else {
|
|
63
|
+
y.second *= mix_ratio;
|
|
64
|
+
target.emplace_back(desired, y.second);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// Removing zero probabilities.
|
|
71
|
+
if (mix_ratio == 0) {
|
|
72
|
+
for (auto& current : x) {
|
|
73
|
+
typename std::remove_reference<decltype(current)>::type replacement;
|
|
74
|
+
replacement.reserve(current.size());
|
|
75
|
+
for (const auto& y : current) {
|
|
76
|
+
if (y.second) {
|
|
77
|
+
replacement.push_back(y);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
std::swap(current, replacement);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// Sorting everything by index to be more cache-friendly. Also,
|
|
85
|
+
// irlba::ParallelSparseMatrix needs increasing inserts.
|
|
86
|
+
for (auto& current : x) {
|
|
87
|
+
std::sort(current.begin(), current.end());
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
#endif
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
#ifndef UMAPPP_FIND_AB_HPP
|
|
2
|
+
#define UMAPPP_FIND_AB_HPP
|
|
3
|
+
|
|
4
|
+
#include <cmath>
|
|
5
|
+
#include <vector>
|
|
6
|
+
#include <iostream>
|
|
7
|
+
|
|
8
|
+
namespace umappp {
|
|
9
|
+
|
|
10
|
+
/*
|
|
11
|
+
* Derivatives were obtained using the following code in R:
|
|
12
|
+
*
|
|
13
|
+
* > delta <- expression((1/(1+ a * x^(2*b)) - y)^2)
|
|
14
|
+
* > D(delta, "a")
|
|
15
|
+
* > D(delta, "b")
|
|
16
|
+
* > D(D(delta, "a"), "a")
|
|
17
|
+
* > D(D(delta, "b"), "a")
|
|
18
|
+
* > D(D(delta, "b"), "b")
|
|
19
|
+
*
|
|
20
|
+
* To test, evaluate with:
|
|
21
|
+
*
|
|
22
|
+
* > a <- 1.55461
|
|
23
|
+
* > b <- 0.743147
|
|
24
|
+
* > s <- 1
|
|
25
|
+
* > m <- 0.05
|
|
26
|
+
* > x <- seq(0, 3 * s, length.out=301)[-1]
|
|
27
|
+
* > y <- pmin(1, exp(-(x - m)/s))
|
|
28
|
+
* > sum(eval(delta))
|
|
29
|
+
*/
|
|
30
|
+
|
|
31
|
+
template<typename Float>
|
|
32
|
+
std::pair<Float, Float> find_ab(Float spread, Float min_dist, Float grid = 300, Float limit = 0.5, int iter = 50, Float tol = 1e-6) {
|
|
33
|
+
Float x_half = std::log(limit) * -spread + min_dist;
|
|
34
|
+
Float d_half = limit / -spread;
|
|
35
|
+
|
|
36
|
+
// Compute the x and y coordinates of the expected distance curve.
|
|
37
|
+
std::vector<Float> grid_x(grid), grid_y(grid), log_x(grid);
|
|
38
|
+
const Float delta = spread * 3 / grid;
|
|
39
|
+
for (int g = 0; g < grid; ++g) {
|
|
40
|
+
grid_x[g] = (g + 1) * delta; // +1 to avoid meaningless least squares result at x = 0, where both curves have y = 1 (and also the derivative w.r.t. b is not defined).
|
|
41
|
+
log_x[g] = std::log(grid_x[g]);
|
|
42
|
+
grid_y[g] = (grid_x[g] <= min_dist ? 1 : std::exp(- (grid_x[g] - min_dist) / spread));
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// Starting estimates.
|
|
46
|
+
Float b = - d_half * x_half / (1 / limit - 1) / (2 * limit * limit);
|
|
47
|
+
Float a = (1 / limit - 1) / std::pow(x_half, 2 * b);
|
|
48
|
+
|
|
49
|
+
std::vector<Float> observed_y(grid), xpow(grid);
|
|
50
|
+
auto compute_ss = [&](Float A, Float B) -> Float {
|
|
51
|
+
for (int g = 0; g < grid; ++g) {
|
|
52
|
+
xpow[g] = std::pow(grid_x[g], 2 * B);
|
|
53
|
+
observed_y[g] = 1 / (1 + A * xpow[g]);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
Float ss = 0;
|
|
57
|
+
for (int g = 0; g < grid; ++g) {
|
|
58
|
+
ss += (grid_y[g] - observed_y[g]) * (grid_y[g] - observed_y[g]);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
return ss;
|
|
62
|
+
};
|
|
63
|
+
Float ss = compute_ss(a, b);
|
|
64
|
+
|
|
65
|
+
for (int it = 0; it < iter; ++it) {
|
|
66
|
+
// Computing the first and second derivatives of the sum of squared differences.
|
|
67
|
+
Float da = 0, db = 0, daa = 0, dab = 0, dbb = 0;
|
|
68
|
+
for (int g = 0; g < grid; ++g) {
|
|
69
|
+
const Float& x = grid_x[g];
|
|
70
|
+
const Float& gy = grid_y[g];
|
|
71
|
+
const Float& oy = observed_y[g];
|
|
72
|
+
|
|
73
|
+
const Float& x2b = xpow[g];
|
|
74
|
+
const Float logx2 = log_x[g] * 2;
|
|
75
|
+
const Float delta = oy - gy;
|
|
76
|
+
|
|
77
|
+
// -(2 * (x^(2 * b)/(1 + a * x^(2 * b))^2 * (1/(1 + a * x^(2 * b)) - y)))
|
|
78
|
+
da += -2 * x2b * oy * oy * delta;
|
|
79
|
+
|
|
80
|
+
// -(2 * (a * (x^(2 * b) * (log(x) * 2))/(1 + a * x^(2 * b))^2 * (1/(1 + a * x^(2 * b)) - y)))
|
|
81
|
+
db += -2 * a * x2b * logx2 * oy * oy * delta;
|
|
82
|
+
|
|
83
|
+
// 2 * (
|
|
84
|
+
// x^(2 * b)/(1 + a * x^(2 * b))^2 * (x^(2 * b)/(1 + a * x^(2 * b))^2)
|
|
85
|
+
// + x^(2 * b) * (2 * (x^(2 * b) * (1 + a * x^(2 * b))))/((1 + a * x^(2 * b))^2)^2 * (1/(1 + a * x^(2 * b)) - y)
|
|
86
|
+
// )
|
|
87
|
+
daa += 2 * (
|
|
88
|
+
x2b * oy * oy * x2b * oy * oy
|
|
89
|
+
+ x2b * 2 * x2b * oy * oy * oy * delta
|
|
90
|
+
);
|
|
91
|
+
|
|
92
|
+
//-(2 *
|
|
93
|
+
// (
|
|
94
|
+
// (
|
|
95
|
+
// (x^(2 * b) * (log(x) * 2))/(1 + a * x^(2 * b))^2
|
|
96
|
+
// - a * (x^(2 * b) * (log(x) * 2)) * (2 * (x^(2 * b) * (1 + a * x^(2 * b))))/((1 + a * x^(2 * b))^2)^2
|
|
97
|
+
// )
|
|
98
|
+
// * (1/(1 + a * x^(2 * b)) - y)
|
|
99
|
+
// - a * (x^(2 * b) * (log(x) * 2))/(1 + a * x^(2 * b))^2 * (x^(2 * b)/(1 + a * x^(2 * b))^2)
|
|
100
|
+
// )
|
|
101
|
+
//)
|
|
102
|
+
dab += -2 * (
|
|
103
|
+
(
|
|
104
|
+
x2b * logx2 * oy * oy
|
|
105
|
+
- a * x2b * logx2 * 2 * x2b * oy * oy * oy
|
|
106
|
+
) * delta
|
|
107
|
+
- a * x2b * logx2 * oy * oy * x2b * oy * oy
|
|
108
|
+
);
|
|
109
|
+
|
|
110
|
+
// -(2 *
|
|
111
|
+
// (
|
|
112
|
+
// (
|
|
113
|
+
// a * (x^(2 * b) * (log(x) * 2) * (log(x) * 2))/(1 + a * x^(2 * b))^2
|
|
114
|
+
// - a * (x^(2 * b) * (log(x) * 2)) * (2 * (a * (x^(2 * b) * (log(x) * 2)) * (1 + a * x^(2 * b))))/((1 + a * x^(2 * b))^2)^2
|
|
115
|
+
// )
|
|
116
|
+
// * (1/(1 + a * x^(2 * b)) - y)
|
|
117
|
+
// - a * (x^(2 * b) * (log(x) * 2))/(1 + a * x^(2 * b))^2 * (a * (x^(2 * b) * (log(x) * 2))/(1 + a * x^(2 * b))^2)
|
|
118
|
+
// )
|
|
119
|
+
// )
|
|
120
|
+
dbb += -2 * (
|
|
121
|
+
(
|
|
122
|
+
(a * x2b * logx2 * logx2 * oy * oy)
|
|
123
|
+
- (a * x2b * logx2 * 2 * a * x2b * logx2 * oy * oy * oy)
|
|
124
|
+
) * delta
|
|
125
|
+
- a * x2b * logx2 * oy * oy * a * x2b * logx2 * oy * oy
|
|
126
|
+
);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// Applying the Newton iterations with damping.
|
|
130
|
+
Float determinant = daa * dbb - dab * dab;
|
|
131
|
+
const Float delta_a = (da * dbb - dab * db) / determinant;
|
|
132
|
+
const Float delta_b = (- da * dab + daa * db) / determinant;
|
|
133
|
+
|
|
134
|
+
Float ss_next = 0;
|
|
135
|
+
Float factor = 1;
|
|
136
|
+
for (int inner = 0; inner < 10; ++inner, factor /= 2) {
|
|
137
|
+
ss_next = compute_ss(a - factor * delta_a, b - factor * delta_b);
|
|
138
|
+
if (ss_next < ss) {
|
|
139
|
+
break;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
if (ss && 1 - ss_next/ss > tol) {
|
|
144
|
+
a -= factor * delta_a;
|
|
145
|
+
b -= factor * delta_b;
|
|
146
|
+
ss = ss_next;
|
|
147
|
+
} else {
|
|
148
|
+
break;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
return std::make_pair(a, b);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
#endif
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
#ifndef UMAPPP_NEIGHBOR_SIMILARITIES_HPP
|
|
2
|
+
#define UMAPPP_NEIGHBOR_SIMILARITIES_HPP
|
|
3
|
+
|
|
4
|
+
#include <vector>
|
|
5
|
+
#include <limits>
|
|
6
|
+
#include <cmath>
|
|
7
|
+
#include <algorithm>
|
|
8
|
+
#include <numeric>
|
|
9
|
+
|
|
10
|
+
#include "NeighborList.hpp"
|
|
11
|
+
|
|
12
|
+
namespace umappp {
|
|
13
|
+
|
|
14
|
+
template<typename Float>
|
|
15
|
+
void neighbor_similarities(
|
|
16
|
+
NeighborList<Float>& x,
|
|
17
|
+
Float local_connectivity = 1.0,
|
|
18
|
+
Float bandwidth = 1.0,
|
|
19
|
+
int max_iter = 64,
|
|
20
|
+
Float tol = 1e-5,
|
|
21
|
+
Float min_k_dist_scale = 1e-3
|
|
22
|
+
) {
|
|
23
|
+
Float grand_mean_dist = -1;
|
|
24
|
+
constexpr Float max_val = std::numeric_limits<Float>::max();
|
|
25
|
+
|
|
26
|
+
#pragma omp parallel
|
|
27
|
+
{
|
|
28
|
+
std::vector<Float> non_zero_distances;
|
|
29
|
+
|
|
30
|
+
#pragma omp for
|
|
31
|
+
for (size_t i = 0; i < x.size(); ++i) {
|
|
32
|
+
auto& all_neighbors = x[i];
|
|
33
|
+
const int n_neighbors = all_neighbors.size();
|
|
34
|
+
|
|
35
|
+
non_zero_distances.clear();
|
|
36
|
+
for (const auto& f : all_neighbors) {
|
|
37
|
+
if (f.second) {
|
|
38
|
+
non_zero_distances.push_back(f.second);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
if (non_zero_distances.size() <= local_connectivity) {
|
|
43
|
+
// When this happens, 'rho' is just theoretically set to the
|
|
44
|
+
// maximum distance. In such cases, the weights are always just
|
|
45
|
+
// set to 1 in the remaining code, because no distance can be
|
|
46
|
+
// greater than 'rho'. If that's the case, we might as well
|
|
47
|
+
// save some time and compute it here.
|
|
48
|
+
for (int k = 0; k < n_neighbors; ++k) {
|
|
49
|
+
all_neighbors[k].second = 1;
|
|
50
|
+
}
|
|
51
|
+
continue;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// Find rho, the distance to the nearest (non-identical) neighbor,
|
|
55
|
+
// possibly with interpolation.
|
|
56
|
+
int index = std::floor(local_connectivity);
|
|
57
|
+
const Float interpolation = local_connectivity - index;
|
|
58
|
+
const Float lower = (index > 0 ? non_zero_distances[index - 1] : 0); // 'index' is 1-based, so -1.
|
|
59
|
+
const Float upper = non_zero_distances[index];
|
|
60
|
+
const Float rho = lower + interpolation * (upper - lower);
|
|
61
|
+
|
|
62
|
+
// Iterating to find a good sigma, just like how t-SNE does so for beta.
|
|
63
|
+
Float sigma = 1.0;
|
|
64
|
+
Float lo = 0.0;
|
|
65
|
+
Float hi = max_val;
|
|
66
|
+
Float sigma_best = sigma;
|
|
67
|
+
Float adiff_min = max_val;
|
|
68
|
+
const Float target = std::log2(all_neighbors.size() + 1); // include self. Dunno why, but uwot does it.
|
|
69
|
+
|
|
70
|
+
bool converged = false;
|
|
71
|
+
for (int iter = 0; iter < max_iter; ++iter) {
|
|
72
|
+
// If distance = 0, then max(distance - rho, 0) = 0 as rho >=
|
|
73
|
+
// 0. In which case, exp(-dist / sigma) is just 1 for each
|
|
74
|
+
// distance of zero, allowing us to just add these directly.
|
|
75
|
+
Float val = n_neighbors - non_zero_distances.size();
|
|
76
|
+
|
|
77
|
+
for (auto d : non_zero_distances) {
|
|
78
|
+
if (d > rho) {
|
|
79
|
+
val += std::exp(-(d - rho)/ sigma);
|
|
80
|
+
} else {
|
|
81
|
+
val += 1;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
Float adiff = std::abs(val - target);
|
|
86
|
+
if (adiff < tol) {
|
|
87
|
+
converged = true;
|
|
88
|
+
break;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// store best sigma in case binary search fails (usually in the presence
|
|
92
|
+
// of multiple degenerate distances)
|
|
93
|
+
if (adiff < adiff_min) {
|
|
94
|
+
adiff_min = adiff;
|
|
95
|
+
sigma_best = sigma;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
if (val > target) {
|
|
99
|
+
hi = sigma;
|
|
100
|
+
sigma = (lo + hi) / 2;
|
|
101
|
+
} else {
|
|
102
|
+
lo = sigma;
|
|
103
|
+
if (hi == max_val) {
|
|
104
|
+
sigma *= 2;
|
|
105
|
+
} else {
|
|
106
|
+
sigma = (lo + hi) / 2;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
if (!converged) {
|
|
112
|
+
sigma = sigma_best;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// Quickly summing over the non-zero distances, then dividing
|
|
116
|
+
// by the total number of neighbors to obtain the mean.
|
|
117
|
+
Float mean_dist = std::accumulate(non_zero_distances.begin(), non_zero_distances.end(), 0.0)/n_neighbors;
|
|
118
|
+
sigma = std::max(min_k_dist_scale * mean_dist, sigma);
|
|
119
|
+
|
|
120
|
+
for (int k = 0; k < n_neighbors; ++k) {
|
|
121
|
+
Float& dist = all_neighbors[k].second;
|
|
122
|
+
if (dist > rho) {
|
|
123
|
+
dist = std::exp(-(dist - rho) / (sigma * bandwidth));
|
|
124
|
+
} else {
|
|
125
|
+
dist = 1;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
#endif
|
|
@@ -0,0 +1,285 @@
|
|
|
1
|
+
#ifndef UMAPPP_OPTIMIZE_LAYOUT_HPP
|
|
2
|
+
#define UMAPPP_OPTIMIZE_LAYOUT_HPP
|
|
3
|
+
|
|
4
|
+
#include <vector>
|
|
5
|
+
#include <limits>
|
|
6
|
+
#include <algorithm>
|
|
7
|
+
#include <cmath>
|
|
8
|
+
|
|
9
|
+
#include "NeighborList.hpp"
|
|
10
|
+
#include "aarand/aarand.hpp"
|
|
11
|
+
|
|
12
|
+
namespace umappp {
|
|
13
|
+
|
|
14
|
+
template<typename Float>
|
|
15
|
+
struct EpochData {
|
|
16
|
+
EpochData(size_t nobs) : head(nobs) {}
|
|
17
|
+
|
|
18
|
+
int total_epochs;
|
|
19
|
+
int current_epoch = 0;
|
|
20
|
+
|
|
21
|
+
std::vector<size_t> head;
|
|
22
|
+
std::vector<int> tail;
|
|
23
|
+
std::vector<Float> epochs_per_sample;
|
|
24
|
+
|
|
25
|
+
std::vector<Float> epoch_of_next_sample;
|
|
26
|
+
std::vector<Float> epoch_of_next_negative_sample;
|
|
27
|
+
Float negative_sample_rate;
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
template<typename Float>
|
|
31
|
+
EpochData<Float> similarities_to_epochs(const NeighborList<Float>& p, int num_epochs, Float negative_sample_rate) {
|
|
32
|
+
Float maxed = 0;
|
|
33
|
+
size_t count = 0;
|
|
34
|
+
for (const auto& x : p) {
|
|
35
|
+
count += x.size();
|
|
36
|
+
for (const auto& y : x) {
|
|
37
|
+
maxed = std::max(maxed, y.second);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
EpochData<Float> output(p.size());
|
|
42
|
+
output.total_epochs = num_epochs;
|
|
43
|
+
output.tail.reserve(count);
|
|
44
|
+
output.epochs_per_sample.reserve(count);
|
|
45
|
+
const Float limit = maxed / num_epochs;
|
|
46
|
+
|
|
47
|
+
size_t last = 0;
|
|
48
|
+
for (size_t i = 0; i < p.size(); ++i) {
|
|
49
|
+
const auto& x = p[i];
|
|
50
|
+
for (const auto& y : x) {
|
|
51
|
+
if (y.second >= limit) {
|
|
52
|
+
output.tail.push_back(y.first);
|
|
53
|
+
output.epochs_per_sample.push_back(maxed / y.second);
|
|
54
|
+
++last;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
output.head[i] = last;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// Filling in some epoch-related running statistics.
|
|
61
|
+
output.epoch_of_next_sample = output.epochs_per_sample;
|
|
62
|
+
output.epoch_of_next_negative_sample = output.epochs_per_sample;
|
|
63
|
+
for (auto& e : output.epoch_of_next_negative_sample) {
|
|
64
|
+
e /= negative_sample_rate;
|
|
65
|
+
}
|
|
66
|
+
output.negative_sample_rate = negative_sample_rate;
|
|
67
|
+
|
|
68
|
+
return output;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
template<typename Float>
|
|
72
|
+
Float quick_squared_distance(const Float* left, const Float* right, int ndim) {
|
|
73
|
+
Float dist2 = 0;
|
|
74
|
+
for (int d = 0; d < ndim; ++d, ++left, ++right) {
|
|
75
|
+
dist2 += (*left - *right) * (*left - *right);
|
|
76
|
+
}
|
|
77
|
+
constexpr Float dist_eps = std::numeric_limits<Float>::epsilon();
|
|
78
|
+
return std::max(dist_eps, dist2);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
template<typename Float>
|
|
82
|
+
Float clamp(Float input) {
|
|
83
|
+
constexpr Float min_gradient = -4;
|
|
84
|
+
constexpr Float max_gradient = 4;
|
|
85
|
+
return std::min(std::max(input, min_gradient), max_gradient);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
template<bool batch, typename Float, class Setup, class Rng>
|
|
89
|
+
void optimize_sample(
|
|
90
|
+
size_t i,
|
|
91
|
+
int ndim,
|
|
92
|
+
Float* embedding,
|
|
93
|
+
Float* buffer,
|
|
94
|
+
Setup& setup,
|
|
95
|
+
Float a,
|
|
96
|
+
Float b,
|
|
97
|
+
Float gamma,
|
|
98
|
+
Float alpha,
|
|
99
|
+
Rng& rng,
|
|
100
|
+
Float epoch
|
|
101
|
+
) {
|
|
102
|
+
const auto& head = setup.head;
|
|
103
|
+
const auto& tail = setup.tail;
|
|
104
|
+
const auto& epochs_per_sample = setup.epochs_per_sample;
|
|
105
|
+
auto& epoch_of_next_sample = setup.epoch_of_next_sample;
|
|
106
|
+
auto& epoch_of_next_negative_sample = setup.epoch_of_next_negative_sample;
|
|
107
|
+
|
|
108
|
+
const size_t num_obs = head.size();
|
|
109
|
+
const Float negative_sample_rate = setup.negative_sample_rate;
|
|
110
|
+
|
|
111
|
+
size_t start = (i == 0 ? 0 : setup.head[i-1]), end = setup.head[i];
|
|
112
|
+
Float* left = embedding + i * ndim;
|
|
113
|
+
|
|
114
|
+
for (size_t j = start; j < end; ++j) {
|
|
115
|
+
if (epoch_of_next_sample[j] > epoch) {
|
|
116
|
+
continue;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
Float* right = embedding + tail[j] * ndim;
|
|
120
|
+
Float dist2 = quick_squared_distance(left, right, ndim);
|
|
121
|
+
const Float pd2b = std::pow(dist2, b);
|
|
122
|
+
const Float grad_coef = (-2 * a * b * pd2b) / (dist2 * (a * pd2b + 1.0));
|
|
123
|
+
{
|
|
124
|
+
Float* lcopy = left;
|
|
125
|
+
Float* rcopy = right;
|
|
126
|
+
|
|
127
|
+
for (int d = 0; d < ndim; ++d, ++lcopy, ++rcopy) {
|
|
128
|
+
Float gradient = alpha * clamp(grad_coef * (*lcopy - *rcopy));
|
|
129
|
+
if constexpr(!batch) {
|
|
130
|
+
*lcopy += gradient;
|
|
131
|
+
*rcopy -= gradient;
|
|
132
|
+
} else {
|
|
133
|
+
// Doubling as we'll assume symmetry from the same
|
|
134
|
+
// force applied by the right node. This allows us to
|
|
135
|
+
// avoid worrying about accounting for modifications to
|
|
136
|
+
// the right node.
|
|
137
|
+
buffer[d] += 2 * gradient;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// Here, we divide by epochs_per_negative_sample, defined as epochs_per_sample[j] / negative_sample_rate.
|
|
143
|
+
const size_t num_neg_samples = (epoch - epoch_of_next_negative_sample[j]) * negative_sample_rate / epochs_per_sample[j];
|
|
144
|
+
|
|
145
|
+
for (size_t p = 0; p < num_neg_samples; ++p) {
|
|
146
|
+
size_t sampled = aarand::discrete_uniform(rng, num_obs);
|
|
147
|
+
if (sampled == i) {
|
|
148
|
+
continue;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
Float* right = embedding + sampled * ndim;
|
|
152
|
+
Float dist2 = quick_squared_distance(left, right, ndim);
|
|
153
|
+
const Float grad_coef = 2 * gamma * b / ((0.001 + dist2) * (a * std::pow(dist2, b) + 1.0));
|
|
154
|
+
{
|
|
155
|
+
Float* lcopy = left;
|
|
156
|
+
const Float* rcopy = right;
|
|
157
|
+
for (int d = 0; d < ndim; ++d, ++lcopy, ++rcopy) {
|
|
158
|
+
Float gradient = alpha * clamp(grad_coef * (*lcopy - *rcopy));
|
|
159
|
+
if constexpr(!batch) {
|
|
160
|
+
*lcopy += gradient;
|
|
161
|
+
} else {
|
|
162
|
+
buffer[d] += gradient;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
epoch_of_next_sample[j] += epochs_per_sample[j];
|
|
169
|
+
|
|
170
|
+
// The update to epoch_of_next_negative_sample involves adding
|
|
171
|
+
// num_neg_samples * epochs_per_negative_sample, which eventually boils
|
|
172
|
+
// down to setting epoch_of_next_negative_sample to 'n'.
|
|
173
|
+
epoch_of_next_negative_sample[j] = epoch;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
template<typename Float, class Setup, class Rng>
|
|
178
|
+
void optimize_layout(
|
|
179
|
+
int ndim,
|
|
180
|
+
Float* embedding,
|
|
181
|
+
Setup& setup,
|
|
182
|
+
Float a,
|
|
183
|
+
Float b,
|
|
184
|
+
Float gamma,
|
|
185
|
+
Float initial_alpha,
|
|
186
|
+
Rng& rng,
|
|
187
|
+
int epoch_limit
|
|
188
|
+
) {
|
|
189
|
+
auto& n = setup.current_epoch;
|
|
190
|
+
auto num_epochs = setup.total_epochs;
|
|
191
|
+
auto limit_epochs = num_epochs;
|
|
192
|
+
if (epoch_limit> 0) {
|
|
193
|
+
limit_epochs = std::min(epoch_limit, num_epochs);
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
for (; n < limit_epochs; ++n) {
|
|
197
|
+
const Float epoch = n;
|
|
198
|
+
const Float alpha = initial_alpha * (1.0 - epoch / num_epochs);
|
|
199
|
+
for (size_t i = 0; i < setup.head.size(); ++i) {
|
|
200
|
+
optimize_sample<false>(i, ndim, embedding, static_cast<Float*>(NULL), setup, a, b, gamma, alpha, rng, epoch);
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
return;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
template<typename Float, class Setup, class SeedFunction, class EngineFunction>
|
|
208
|
+
inline void optimize_layout_batched(
|
|
209
|
+
int ndim,
|
|
210
|
+
Float* embedding,
|
|
211
|
+
Setup& setup,
|
|
212
|
+
Float a,
|
|
213
|
+
Float b,
|
|
214
|
+
Float gamma,
|
|
215
|
+
Float initial_alpha,
|
|
216
|
+
SeedFunction seeder,
|
|
217
|
+
EngineFunction creator,
|
|
218
|
+
int epoch_limit,
|
|
219
|
+
int nthreads
|
|
220
|
+
) {
|
|
221
|
+
auto& n = setup.current_epoch;
|
|
222
|
+
auto num_epochs = setup.total_epochs;
|
|
223
|
+
auto limit_epochs = num_epochs;
|
|
224
|
+
if (epoch_limit > 0) {
|
|
225
|
+
limit_epochs = std::min(epoch_limit, num_epochs);
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
const size_t num_obs = setup.head.size();
|
|
229
|
+
std::vector<decltype(seeder())> seeds(num_obs);
|
|
230
|
+
std::vector<Float> replace_buffer(num_obs * ndim);
|
|
231
|
+
Float* replacement = replace_buffer.data();
|
|
232
|
+
bool using_replacement = false;
|
|
233
|
+
|
|
234
|
+
for (; n < limit_epochs; ++n) {
|
|
235
|
+
const Float epoch = n;
|
|
236
|
+
const Float alpha = initial_alpha * (1.0 - epoch / num_epochs);
|
|
237
|
+
|
|
238
|
+
// Fill the seeds.
|
|
239
|
+
for (auto& s : seeds) {
|
|
240
|
+
s = seeder();
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
// Input and output alternate between epochs, to avoid the need for a
|
|
244
|
+
// copy operation on the entire embedding at the end of each epoch.
|
|
245
|
+
Float* reference = (using_replacement ? replacement : embedding);
|
|
246
|
+
Float* output = (using_replacement ? embedding : replacement);
|
|
247
|
+
using_replacement = !using_replacement;
|
|
248
|
+
|
|
249
|
+
#ifndef UMAPPP_CUSTOM_PARALLEL
|
|
250
|
+
#pragma omp parallel num_threads(nthreads)
|
|
251
|
+
{
|
|
252
|
+
std::vector<Float> buffer(ndim);
|
|
253
|
+
#pragma omp for
|
|
254
|
+
for (size_t i = 0; i < setup.head.size(); ++i) {
|
|
255
|
+
#else
|
|
256
|
+
UMAPPP_CUSTOM_PARALLEL(setup.head.size(), [&](size_t first, size_t last) -> void {
|
|
257
|
+
std::vector<Float> buffer(ndim);
|
|
258
|
+
for (size_t i = first; i < last; ++i) {
|
|
259
|
+
#endif
|
|
260
|
+
|
|
261
|
+
size_t shift = i * ndim;
|
|
262
|
+
std::copy(reference + shift, reference + shift + ndim, buffer.data());
|
|
263
|
+
auto rng = creator(seeds[i]);
|
|
264
|
+
optimize_sample<true>(i, ndim, reference, buffer.data(), setup, a, b, gamma, alpha, rng, epoch);
|
|
265
|
+
std::copy(buffer.begin(), buffer.end(), output + shift);
|
|
266
|
+
|
|
267
|
+
#ifndef UMAPPP_CUSTOM_PARALLEL
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
#else
|
|
271
|
+
}
|
|
272
|
+
}, nthreads);
|
|
273
|
+
#endif
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
if (using_replacement) {
|
|
277
|
+
std::copy(replace_buffer.begin(), replace_buffer.end(), embedding);
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
return;
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
#endif
|