umappp 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (395) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE.txt +25 -0
  3. data/README.md +110 -0
  4. data/ext/umappp/extconf.rb +25 -0
  5. data/ext/umappp/numo.hpp +867 -0
  6. data/ext/umappp/umappp.cpp +225 -0
  7. data/lib/umappp/version.rb +5 -0
  8. data/lib/umappp.rb +41 -0
  9. data/vendor/Eigen/Cholesky +45 -0
  10. data/vendor/Eigen/CholmodSupport +48 -0
  11. data/vendor/Eigen/Core +384 -0
  12. data/vendor/Eigen/Dense +7 -0
  13. data/vendor/Eigen/Eigen +2 -0
  14. data/vendor/Eigen/Eigenvalues +60 -0
  15. data/vendor/Eigen/Geometry +59 -0
  16. data/vendor/Eigen/Householder +29 -0
  17. data/vendor/Eigen/IterativeLinearSolvers +48 -0
  18. data/vendor/Eigen/Jacobi +32 -0
  19. data/vendor/Eigen/KLUSupport +41 -0
  20. data/vendor/Eigen/LU +47 -0
  21. data/vendor/Eigen/MetisSupport +35 -0
  22. data/vendor/Eigen/OrderingMethods +70 -0
  23. data/vendor/Eigen/PaStiXSupport +49 -0
  24. data/vendor/Eigen/PardisoSupport +35 -0
  25. data/vendor/Eigen/QR +50 -0
  26. data/vendor/Eigen/QtAlignedMalloc +39 -0
  27. data/vendor/Eigen/SPQRSupport +34 -0
  28. data/vendor/Eigen/SVD +50 -0
  29. data/vendor/Eigen/Sparse +34 -0
  30. data/vendor/Eigen/SparseCholesky +37 -0
  31. data/vendor/Eigen/SparseCore +69 -0
  32. data/vendor/Eigen/SparseLU +50 -0
  33. data/vendor/Eigen/SparseQR +36 -0
  34. data/vendor/Eigen/StdDeque +27 -0
  35. data/vendor/Eigen/StdList +26 -0
  36. data/vendor/Eigen/StdVector +27 -0
  37. data/vendor/Eigen/SuperLUSupport +64 -0
  38. data/vendor/Eigen/UmfPackSupport +40 -0
  39. data/vendor/Eigen/src/Cholesky/LDLT.h +688 -0
  40. data/vendor/Eigen/src/Cholesky/LLT.h +558 -0
  41. data/vendor/Eigen/src/Cholesky/LLT_LAPACKE.h +99 -0
  42. data/vendor/Eigen/src/CholmodSupport/CholmodSupport.h +682 -0
  43. data/vendor/Eigen/src/Core/ArithmeticSequence.h +413 -0
  44. data/vendor/Eigen/src/Core/Array.h +417 -0
  45. data/vendor/Eigen/src/Core/ArrayBase.h +226 -0
  46. data/vendor/Eigen/src/Core/ArrayWrapper.h +209 -0
  47. data/vendor/Eigen/src/Core/Assign.h +90 -0
  48. data/vendor/Eigen/src/Core/AssignEvaluator.h +1010 -0
  49. data/vendor/Eigen/src/Core/Assign_MKL.h +178 -0
  50. data/vendor/Eigen/src/Core/BandMatrix.h +353 -0
  51. data/vendor/Eigen/src/Core/Block.h +448 -0
  52. data/vendor/Eigen/src/Core/BooleanRedux.h +162 -0
  53. data/vendor/Eigen/src/Core/CommaInitializer.h +164 -0
  54. data/vendor/Eigen/src/Core/ConditionEstimator.h +175 -0
  55. data/vendor/Eigen/src/Core/CoreEvaluators.h +1741 -0
  56. data/vendor/Eigen/src/Core/CoreIterators.h +132 -0
  57. data/vendor/Eigen/src/Core/CwiseBinaryOp.h +183 -0
  58. data/vendor/Eigen/src/Core/CwiseNullaryOp.h +1001 -0
  59. data/vendor/Eigen/src/Core/CwiseTernaryOp.h +197 -0
  60. data/vendor/Eigen/src/Core/CwiseUnaryOp.h +103 -0
  61. data/vendor/Eigen/src/Core/CwiseUnaryView.h +132 -0
  62. data/vendor/Eigen/src/Core/DenseBase.h +701 -0
  63. data/vendor/Eigen/src/Core/DenseCoeffsBase.h +685 -0
  64. data/vendor/Eigen/src/Core/DenseStorage.h +652 -0
  65. data/vendor/Eigen/src/Core/Diagonal.h +258 -0
  66. data/vendor/Eigen/src/Core/DiagonalMatrix.h +391 -0
  67. data/vendor/Eigen/src/Core/DiagonalProduct.h +28 -0
  68. data/vendor/Eigen/src/Core/Dot.h +318 -0
  69. data/vendor/Eigen/src/Core/EigenBase.h +160 -0
  70. data/vendor/Eigen/src/Core/ForceAlignedAccess.h +150 -0
  71. data/vendor/Eigen/src/Core/Fuzzy.h +155 -0
  72. data/vendor/Eigen/src/Core/GeneralProduct.h +465 -0
  73. data/vendor/Eigen/src/Core/GenericPacketMath.h +1040 -0
  74. data/vendor/Eigen/src/Core/GlobalFunctions.h +194 -0
  75. data/vendor/Eigen/src/Core/IO.h +258 -0
  76. data/vendor/Eigen/src/Core/IndexedView.h +237 -0
  77. data/vendor/Eigen/src/Core/Inverse.h +117 -0
  78. data/vendor/Eigen/src/Core/Map.h +171 -0
  79. data/vendor/Eigen/src/Core/MapBase.h +310 -0
  80. data/vendor/Eigen/src/Core/MathFunctions.h +2057 -0
  81. data/vendor/Eigen/src/Core/MathFunctionsImpl.h +200 -0
  82. data/vendor/Eigen/src/Core/Matrix.h +565 -0
  83. data/vendor/Eigen/src/Core/MatrixBase.h +547 -0
  84. data/vendor/Eigen/src/Core/NestByValue.h +85 -0
  85. data/vendor/Eigen/src/Core/NoAlias.h +109 -0
  86. data/vendor/Eigen/src/Core/NumTraits.h +335 -0
  87. data/vendor/Eigen/src/Core/PartialReduxEvaluator.h +232 -0
  88. data/vendor/Eigen/src/Core/PermutationMatrix.h +605 -0
  89. data/vendor/Eigen/src/Core/PlainObjectBase.h +1128 -0
  90. data/vendor/Eigen/src/Core/Product.h +191 -0
  91. data/vendor/Eigen/src/Core/ProductEvaluators.h +1179 -0
  92. data/vendor/Eigen/src/Core/Random.h +218 -0
  93. data/vendor/Eigen/src/Core/Redux.h +515 -0
  94. data/vendor/Eigen/src/Core/Ref.h +381 -0
  95. data/vendor/Eigen/src/Core/Replicate.h +142 -0
  96. data/vendor/Eigen/src/Core/Reshaped.h +454 -0
  97. data/vendor/Eigen/src/Core/ReturnByValue.h +119 -0
  98. data/vendor/Eigen/src/Core/Reverse.h +217 -0
  99. data/vendor/Eigen/src/Core/Select.h +164 -0
  100. data/vendor/Eigen/src/Core/SelfAdjointView.h +365 -0
  101. data/vendor/Eigen/src/Core/SelfCwiseBinaryOp.h +47 -0
  102. data/vendor/Eigen/src/Core/Solve.h +188 -0
  103. data/vendor/Eigen/src/Core/SolveTriangular.h +235 -0
  104. data/vendor/Eigen/src/Core/SolverBase.h +168 -0
  105. data/vendor/Eigen/src/Core/StableNorm.h +251 -0
  106. data/vendor/Eigen/src/Core/StlIterators.h +463 -0
  107. data/vendor/Eigen/src/Core/Stride.h +116 -0
  108. data/vendor/Eigen/src/Core/Swap.h +68 -0
  109. data/vendor/Eigen/src/Core/Transpose.h +464 -0
  110. data/vendor/Eigen/src/Core/Transpositions.h +386 -0
  111. data/vendor/Eigen/src/Core/TriangularMatrix.h +1001 -0
  112. data/vendor/Eigen/src/Core/VectorBlock.h +96 -0
  113. data/vendor/Eigen/src/Core/VectorwiseOp.h +784 -0
  114. data/vendor/Eigen/src/Core/Visitor.h +381 -0
  115. data/vendor/Eigen/src/Core/arch/AVX/Complex.h +372 -0
  116. data/vendor/Eigen/src/Core/arch/AVX/MathFunctions.h +228 -0
  117. data/vendor/Eigen/src/Core/arch/AVX/PacketMath.h +1574 -0
  118. data/vendor/Eigen/src/Core/arch/AVX/TypeCasting.h +115 -0
  119. data/vendor/Eigen/src/Core/arch/AVX512/Complex.h +422 -0
  120. data/vendor/Eigen/src/Core/arch/AVX512/MathFunctions.h +362 -0
  121. data/vendor/Eigen/src/Core/arch/AVX512/PacketMath.h +2303 -0
  122. data/vendor/Eigen/src/Core/arch/AVX512/TypeCasting.h +89 -0
  123. data/vendor/Eigen/src/Core/arch/AltiVec/Complex.h +417 -0
  124. data/vendor/Eigen/src/Core/arch/AltiVec/MathFunctions.h +90 -0
  125. data/vendor/Eigen/src/Core/arch/AltiVec/MatrixProduct.h +2937 -0
  126. data/vendor/Eigen/src/Core/arch/AltiVec/MatrixProductCommon.h +221 -0
  127. data/vendor/Eigen/src/Core/arch/AltiVec/MatrixProductMMA.h +629 -0
  128. data/vendor/Eigen/src/Core/arch/AltiVec/PacketMath.h +2711 -0
  129. data/vendor/Eigen/src/Core/arch/CUDA/Complex.h +258 -0
  130. data/vendor/Eigen/src/Core/arch/Default/BFloat16.h +700 -0
  131. data/vendor/Eigen/src/Core/arch/Default/ConjHelper.h +117 -0
  132. data/vendor/Eigen/src/Core/arch/Default/GenericPacketMathFunctions.h +1649 -0
  133. data/vendor/Eigen/src/Core/arch/Default/GenericPacketMathFunctionsFwd.h +110 -0
  134. data/vendor/Eigen/src/Core/arch/Default/Half.h +942 -0
  135. data/vendor/Eigen/src/Core/arch/Default/Settings.h +49 -0
  136. data/vendor/Eigen/src/Core/arch/Default/TypeCasting.h +120 -0
  137. data/vendor/Eigen/src/Core/arch/GPU/MathFunctions.h +103 -0
  138. data/vendor/Eigen/src/Core/arch/GPU/PacketMath.h +1685 -0
  139. data/vendor/Eigen/src/Core/arch/GPU/TypeCasting.h +80 -0
  140. data/vendor/Eigen/src/Core/arch/HIP/hcc/math_constants.h +23 -0
  141. data/vendor/Eigen/src/Core/arch/MSA/Complex.h +648 -0
  142. data/vendor/Eigen/src/Core/arch/MSA/MathFunctions.h +387 -0
  143. data/vendor/Eigen/src/Core/arch/MSA/PacketMath.h +1233 -0
  144. data/vendor/Eigen/src/Core/arch/NEON/Complex.h +584 -0
  145. data/vendor/Eigen/src/Core/arch/NEON/GeneralBlockPanelKernel.h +183 -0
  146. data/vendor/Eigen/src/Core/arch/NEON/MathFunctions.h +75 -0
  147. data/vendor/Eigen/src/Core/arch/NEON/PacketMath.h +4587 -0
  148. data/vendor/Eigen/src/Core/arch/NEON/TypeCasting.h +1419 -0
  149. data/vendor/Eigen/src/Core/arch/SSE/Complex.h +351 -0
  150. data/vendor/Eigen/src/Core/arch/SSE/MathFunctions.h +199 -0
  151. data/vendor/Eigen/src/Core/arch/SSE/PacketMath.h +1505 -0
  152. data/vendor/Eigen/src/Core/arch/SSE/TypeCasting.h +142 -0
  153. data/vendor/Eigen/src/Core/arch/SVE/MathFunctions.h +44 -0
  154. data/vendor/Eigen/src/Core/arch/SVE/PacketMath.h +752 -0
  155. data/vendor/Eigen/src/Core/arch/SVE/TypeCasting.h +49 -0
  156. data/vendor/Eigen/src/Core/arch/SYCL/InteropHeaders.h +232 -0
  157. data/vendor/Eigen/src/Core/arch/SYCL/MathFunctions.h +301 -0
  158. data/vendor/Eigen/src/Core/arch/SYCL/PacketMath.h +670 -0
  159. data/vendor/Eigen/src/Core/arch/SYCL/SyclMemoryModel.h +694 -0
  160. data/vendor/Eigen/src/Core/arch/SYCL/TypeCasting.h +85 -0
  161. data/vendor/Eigen/src/Core/arch/ZVector/Complex.h +426 -0
  162. data/vendor/Eigen/src/Core/arch/ZVector/MathFunctions.h +233 -0
  163. data/vendor/Eigen/src/Core/arch/ZVector/PacketMath.h +1060 -0
  164. data/vendor/Eigen/src/Core/functors/AssignmentFunctors.h +177 -0
  165. data/vendor/Eigen/src/Core/functors/BinaryFunctors.h +541 -0
  166. data/vendor/Eigen/src/Core/functors/NullaryFunctors.h +189 -0
  167. data/vendor/Eigen/src/Core/functors/StlFunctors.h +166 -0
  168. data/vendor/Eigen/src/Core/functors/TernaryFunctors.h +25 -0
  169. data/vendor/Eigen/src/Core/functors/UnaryFunctors.h +1131 -0
  170. data/vendor/Eigen/src/Core/products/GeneralBlockPanelKernel.h +2645 -0
  171. data/vendor/Eigen/src/Core/products/GeneralMatrixMatrix.h +517 -0
  172. data/vendor/Eigen/src/Core/products/GeneralMatrixMatrixTriangular.h +317 -0
  173. data/vendor/Eigen/src/Core/products/GeneralMatrixMatrixTriangular_BLAS.h +145 -0
  174. data/vendor/Eigen/src/Core/products/GeneralMatrixMatrix_BLAS.h +124 -0
  175. data/vendor/Eigen/src/Core/products/GeneralMatrixVector.h +518 -0
  176. data/vendor/Eigen/src/Core/products/GeneralMatrixVector_BLAS.h +136 -0
  177. data/vendor/Eigen/src/Core/products/Parallelizer.h +180 -0
  178. data/vendor/Eigen/src/Core/products/SelfadjointMatrixMatrix.h +544 -0
  179. data/vendor/Eigen/src/Core/products/SelfadjointMatrixMatrix_BLAS.h +295 -0
  180. data/vendor/Eigen/src/Core/products/SelfadjointMatrixVector.h +262 -0
  181. data/vendor/Eigen/src/Core/products/SelfadjointMatrixVector_BLAS.h +118 -0
  182. data/vendor/Eigen/src/Core/products/SelfadjointProduct.h +133 -0
  183. data/vendor/Eigen/src/Core/products/SelfadjointRank2Update.h +94 -0
  184. data/vendor/Eigen/src/Core/products/TriangularMatrixMatrix.h +472 -0
  185. data/vendor/Eigen/src/Core/products/TriangularMatrixMatrix_BLAS.h +317 -0
  186. data/vendor/Eigen/src/Core/products/TriangularMatrixVector.h +350 -0
  187. data/vendor/Eigen/src/Core/products/TriangularMatrixVector_BLAS.h +255 -0
  188. data/vendor/Eigen/src/Core/products/TriangularSolverMatrix.h +337 -0
  189. data/vendor/Eigen/src/Core/products/TriangularSolverMatrix_BLAS.h +167 -0
  190. data/vendor/Eigen/src/Core/products/TriangularSolverVector.h +148 -0
  191. data/vendor/Eigen/src/Core/util/BlasUtil.h +583 -0
  192. data/vendor/Eigen/src/Core/util/ConfigureVectorization.h +512 -0
  193. data/vendor/Eigen/src/Core/util/Constants.h +563 -0
  194. data/vendor/Eigen/src/Core/util/DisableStupidWarnings.h +106 -0
  195. data/vendor/Eigen/src/Core/util/ForwardDeclarations.h +322 -0
  196. data/vendor/Eigen/src/Core/util/IndexedViewHelper.h +186 -0
  197. data/vendor/Eigen/src/Core/util/IntegralConstant.h +272 -0
  198. data/vendor/Eigen/src/Core/util/MKL_support.h +137 -0
  199. data/vendor/Eigen/src/Core/util/Macros.h +1464 -0
  200. data/vendor/Eigen/src/Core/util/Memory.h +1163 -0
  201. data/vendor/Eigen/src/Core/util/Meta.h +812 -0
  202. data/vendor/Eigen/src/Core/util/NonMPL2.h +3 -0
  203. data/vendor/Eigen/src/Core/util/ReenableStupidWarnings.h +31 -0
  204. data/vendor/Eigen/src/Core/util/ReshapedHelper.h +51 -0
  205. data/vendor/Eigen/src/Core/util/StaticAssert.h +221 -0
  206. data/vendor/Eigen/src/Core/util/SymbolicIndex.h +293 -0
  207. data/vendor/Eigen/src/Core/util/XprHelper.h +856 -0
  208. data/vendor/Eigen/src/Eigenvalues/ComplexEigenSolver.h +346 -0
  209. data/vendor/Eigen/src/Eigenvalues/ComplexSchur.h +462 -0
  210. data/vendor/Eigen/src/Eigenvalues/ComplexSchur_LAPACKE.h +91 -0
  211. data/vendor/Eigen/src/Eigenvalues/EigenSolver.h +622 -0
  212. data/vendor/Eigen/src/Eigenvalues/GeneralizedEigenSolver.h +418 -0
  213. data/vendor/Eigen/src/Eigenvalues/GeneralizedSelfAdjointEigenSolver.h +226 -0
  214. data/vendor/Eigen/src/Eigenvalues/HessenbergDecomposition.h +374 -0
  215. data/vendor/Eigen/src/Eigenvalues/MatrixBaseEigenvalues.h +158 -0
  216. data/vendor/Eigen/src/Eigenvalues/RealQZ.h +657 -0
  217. data/vendor/Eigen/src/Eigenvalues/RealSchur.h +558 -0
  218. data/vendor/Eigen/src/Eigenvalues/RealSchur_LAPACKE.h +77 -0
  219. data/vendor/Eigen/src/Eigenvalues/SelfAdjointEigenSolver.h +904 -0
  220. data/vendor/Eigen/src/Eigenvalues/SelfAdjointEigenSolver_LAPACKE.h +87 -0
  221. data/vendor/Eigen/src/Eigenvalues/Tridiagonalization.h +561 -0
  222. data/vendor/Eigen/src/Geometry/AlignedBox.h +486 -0
  223. data/vendor/Eigen/src/Geometry/AngleAxis.h +247 -0
  224. data/vendor/Eigen/src/Geometry/EulerAngles.h +114 -0
  225. data/vendor/Eigen/src/Geometry/Homogeneous.h +501 -0
  226. data/vendor/Eigen/src/Geometry/Hyperplane.h +282 -0
  227. data/vendor/Eigen/src/Geometry/OrthoMethods.h +235 -0
  228. data/vendor/Eigen/src/Geometry/ParametrizedLine.h +232 -0
  229. data/vendor/Eigen/src/Geometry/Quaternion.h +870 -0
  230. data/vendor/Eigen/src/Geometry/Rotation2D.h +199 -0
  231. data/vendor/Eigen/src/Geometry/RotationBase.h +206 -0
  232. data/vendor/Eigen/src/Geometry/Scaling.h +188 -0
  233. data/vendor/Eigen/src/Geometry/Transform.h +1563 -0
  234. data/vendor/Eigen/src/Geometry/Translation.h +202 -0
  235. data/vendor/Eigen/src/Geometry/Umeyama.h +166 -0
  236. data/vendor/Eigen/src/Geometry/arch/Geometry_SIMD.h +168 -0
  237. data/vendor/Eigen/src/Householder/BlockHouseholder.h +110 -0
  238. data/vendor/Eigen/src/Householder/Householder.h +176 -0
  239. data/vendor/Eigen/src/Householder/HouseholderSequence.h +545 -0
  240. data/vendor/Eigen/src/IterativeLinearSolvers/BasicPreconditioners.h +226 -0
  241. data/vendor/Eigen/src/IterativeLinearSolvers/BiCGSTAB.h +212 -0
  242. data/vendor/Eigen/src/IterativeLinearSolvers/ConjugateGradient.h +229 -0
  243. data/vendor/Eigen/src/IterativeLinearSolvers/IncompleteCholesky.h +394 -0
  244. data/vendor/Eigen/src/IterativeLinearSolvers/IncompleteLUT.h +453 -0
  245. data/vendor/Eigen/src/IterativeLinearSolvers/IterativeSolverBase.h +444 -0
  246. data/vendor/Eigen/src/IterativeLinearSolvers/LeastSquareConjugateGradient.h +198 -0
  247. data/vendor/Eigen/src/IterativeLinearSolvers/SolveWithGuess.h +117 -0
  248. data/vendor/Eigen/src/Jacobi/Jacobi.h +483 -0
  249. data/vendor/Eigen/src/KLUSupport/KLUSupport.h +358 -0
  250. data/vendor/Eigen/src/LU/Determinant.h +117 -0
  251. data/vendor/Eigen/src/LU/FullPivLU.h +877 -0
  252. data/vendor/Eigen/src/LU/InverseImpl.h +432 -0
  253. data/vendor/Eigen/src/LU/PartialPivLU.h +624 -0
  254. data/vendor/Eigen/src/LU/PartialPivLU_LAPACKE.h +83 -0
  255. data/vendor/Eigen/src/LU/arch/InverseSize4.h +351 -0
  256. data/vendor/Eigen/src/MetisSupport/MetisSupport.h +137 -0
  257. data/vendor/Eigen/src/OrderingMethods/Amd.h +435 -0
  258. data/vendor/Eigen/src/OrderingMethods/Eigen_Colamd.h +1863 -0
  259. data/vendor/Eigen/src/OrderingMethods/Ordering.h +153 -0
  260. data/vendor/Eigen/src/PaStiXSupport/PaStiXSupport.h +678 -0
  261. data/vendor/Eigen/src/PardisoSupport/PardisoSupport.h +545 -0
  262. data/vendor/Eigen/src/QR/ColPivHouseholderQR.h +674 -0
  263. data/vendor/Eigen/src/QR/ColPivHouseholderQR_LAPACKE.h +97 -0
  264. data/vendor/Eigen/src/QR/CompleteOrthogonalDecomposition.h +635 -0
  265. data/vendor/Eigen/src/QR/FullPivHouseholderQR.h +713 -0
  266. data/vendor/Eigen/src/QR/HouseholderQR.h +434 -0
  267. data/vendor/Eigen/src/QR/HouseholderQR_LAPACKE.h +68 -0
  268. data/vendor/Eigen/src/SPQRSupport/SuiteSparseQRSupport.h +335 -0
  269. data/vendor/Eigen/src/SVD/BDCSVD.h +1366 -0
  270. data/vendor/Eigen/src/SVD/JacobiSVD.h +812 -0
  271. data/vendor/Eigen/src/SVD/JacobiSVD_LAPACKE.h +91 -0
  272. data/vendor/Eigen/src/SVD/SVDBase.h +376 -0
  273. data/vendor/Eigen/src/SVD/UpperBidiagonalization.h +414 -0
  274. data/vendor/Eigen/src/SparseCholesky/SimplicialCholesky.h +697 -0
  275. data/vendor/Eigen/src/SparseCholesky/SimplicialCholesky_impl.h +174 -0
  276. data/vendor/Eigen/src/SparseCore/AmbiVector.h +378 -0
  277. data/vendor/Eigen/src/SparseCore/CompressedStorage.h +274 -0
  278. data/vendor/Eigen/src/SparseCore/ConservativeSparseSparseProduct.h +352 -0
  279. data/vendor/Eigen/src/SparseCore/MappedSparseMatrix.h +67 -0
  280. data/vendor/Eigen/src/SparseCore/SparseAssign.h +270 -0
  281. data/vendor/Eigen/src/SparseCore/SparseBlock.h +571 -0
  282. data/vendor/Eigen/src/SparseCore/SparseColEtree.h +206 -0
  283. data/vendor/Eigen/src/SparseCore/SparseCompressedBase.h +370 -0
  284. data/vendor/Eigen/src/SparseCore/SparseCwiseBinaryOp.h +722 -0
  285. data/vendor/Eigen/src/SparseCore/SparseCwiseUnaryOp.h +150 -0
  286. data/vendor/Eigen/src/SparseCore/SparseDenseProduct.h +342 -0
  287. data/vendor/Eigen/src/SparseCore/SparseDiagonalProduct.h +138 -0
  288. data/vendor/Eigen/src/SparseCore/SparseDot.h +98 -0
  289. data/vendor/Eigen/src/SparseCore/SparseFuzzy.h +29 -0
  290. data/vendor/Eigen/src/SparseCore/SparseMap.h +305 -0
  291. data/vendor/Eigen/src/SparseCore/SparseMatrix.h +1518 -0
  292. data/vendor/Eigen/src/SparseCore/SparseMatrixBase.h +398 -0
  293. data/vendor/Eigen/src/SparseCore/SparsePermutation.h +178 -0
  294. data/vendor/Eigen/src/SparseCore/SparseProduct.h +181 -0
  295. data/vendor/Eigen/src/SparseCore/SparseRedux.h +49 -0
  296. data/vendor/Eigen/src/SparseCore/SparseRef.h +397 -0
  297. data/vendor/Eigen/src/SparseCore/SparseSelfAdjointView.h +659 -0
  298. data/vendor/Eigen/src/SparseCore/SparseSolverBase.h +124 -0
  299. data/vendor/Eigen/src/SparseCore/SparseSparseProductWithPruning.h +198 -0
  300. data/vendor/Eigen/src/SparseCore/SparseTranspose.h +92 -0
  301. data/vendor/Eigen/src/SparseCore/SparseTriangularView.h +189 -0
  302. data/vendor/Eigen/src/SparseCore/SparseUtil.h +186 -0
  303. data/vendor/Eigen/src/SparseCore/SparseVector.h +478 -0
  304. data/vendor/Eigen/src/SparseCore/SparseView.h +254 -0
  305. data/vendor/Eigen/src/SparseCore/TriangularSolver.h +315 -0
  306. data/vendor/Eigen/src/SparseLU/SparseLU.h +923 -0
  307. data/vendor/Eigen/src/SparseLU/SparseLUImpl.h +66 -0
  308. data/vendor/Eigen/src/SparseLU/SparseLU_Memory.h +226 -0
  309. data/vendor/Eigen/src/SparseLU/SparseLU_Structs.h +110 -0
  310. data/vendor/Eigen/src/SparseLU/SparseLU_SupernodalMatrix.h +375 -0
  311. data/vendor/Eigen/src/SparseLU/SparseLU_Utils.h +80 -0
  312. data/vendor/Eigen/src/SparseLU/SparseLU_column_bmod.h +181 -0
  313. data/vendor/Eigen/src/SparseLU/SparseLU_column_dfs.h +179 -0
  314. data/vendor/Eigen/src/SparseLU/SparseLU_copy_to_ucol.h +107 -0
  315. data/vendor/Eigen/src/SparseLU/SparseLU_gemm_kernel.h +280 -0
  316. data/vendor/Eigen/src/SparseLU/SparseLU_heap_relax_snode.h +126 -0
  317. data/vendor/Eigen/src/SparseLU/SparseLU_kernel_bmod.h +130 -0
  318. data/vendor/Eigen/src/SparseLU/SparseLU_panel_bmod.h +223 -0
  319. data/vendor/Eigen/src/SparseLU/SparseLU_panel_dfs.h +258 -0
  320. data/vendor/Eigen/src/SparseLU/SparseLU_pivotL.h +137 -0
  321. data/vendor/Eigen/src/SparseLU/SparseLU_pruneL.h +136 -0
  322. data/vendor/Eigen/src/SparseLU/SparseLU_relax_snode.h +83 -0
  323. data/vendor/Eigen/src/SparseQR/SparseQR.h +758 -0
  324. data/vendor/Eigen/src/StlSupport/StdDeque.h +116 -0
  325. data/vendor/Eigen/src/StlSupport/StdList.h +106 -0
  326. data/vendor/Eigen/src/StlSupport/StdVector.h +131 -0
  327. data/vendor/Eigen/src/StlSupport/details.h +84 -0
  328. data/vendor/Eigen/src/SuperLUSupport/SuperLUSupport.h +1025 -0
  329. data/vendor/Eigen/src/UmfPackSupport/UmfPackSupport.h +642 -0
  330. data/vendor/Eigen/src/misc/Image.h +82 -0
  331. data/vendor/Eigen/src/misc/Kernel.h +79 -0
  332. data/vendor/Eigen/src/misc/RealSvd2x2.h +55 -0
  333. data/vendor/Eigen/src/misc/blas.h +440 -0
  334. data/vendor/Eigen/src/misc/lapack.h +152 -0
  335. data/vendor/Eigen/src/misc/lapacke.h +16292 -0
  336. data/vendor/Eigen/src/misc/lapacke_mangling.h +17 -0
  337. data/vendor/Eigen/src/plugins/ArrayCwiseBinaryOps.h +358 -0
  338. data/vendor/Eigen/src/plugins/ArrayCwiseUnaryOps.h +696 -0
  339. data/vendor/Eigen/src/plugins/BlockMethods.h +1442 -0
  340. data/vendor/Eigen/src/plugins/CommonCwiseBinaryOps.h +115 -0
  341. data/vendor/Eigen/src/plugins/CommonCwiseUnaryOps.h +177 -0
  342. data/vendor/Eigen/src/plugins/IndexedViewMethods.h +262 -0
  343. data/vendor/Eigen/src/plugins/MatrixCwiseBinaryOps.h +152 -0
  344. data/vendor/Eigen/src/plugins/MatrixCwiseUnaryOps.h +95 -0
  345. data/vendor/Eigen/src/plugins/ReshapedMethods.h +149 -0
  346. data/vendor/aarand/aarand.hpp +114 -0
  347. data/vendor/annoy/annoylib.h +1495 -0
  348. data/vendor/annoy/kissrandom.h +120 -0
  349. data/vendor/annoy/mman.h +242 -0
  350. data/vendor/hnswlib/bruteforce.h +152 -0
  351. data/vendor/hnswlib/hnswalg.h +1192 -0
  352. data/vendor/hnswlib/hnswlib.h +108 -0
  353. data/vendor/hnswlib/space_ip.h +282 -0
  354. data/vendor/hnswlib/space_l2.h +281 -0
  355. data/vendor/hnswlib/visited_list_pool.h +79 -0
  356. data/vendor/irlba/irlba.hpp +575 -0
  357. data/vendor/irlba/lanczos.hpp +212 -0
  358. data/vendor/irlba/parallel.hpp +474 -0
  359. data/vendor/irlba/utils.hpp +224 -0
  360. data/vendor/irlba/wrappers.hpp +228 -0
  361. data/vendor/kmeans/Base.hpp +75 -0
  362. data/vendor/kmeans/Details.hpp +79 -0
  363. data/vendor/kmeans/HartiganWong.hpp +492 -0
  364. data/vendor/kmeans/InitializeKmeansPP.hpp +144 -0
  365. data/vendor/kmeans/InitializeNone.hpp +44 -0
  366. data/vendor/kmeans/InitializePCAPartition.hpp +309 -0
  367. data/vendor/kmeans/InitializeRandom.hpp +91 -0
  368. data/vendor/kmeans/Kmeans.hpp +161 -0
  369. data/vendor/kmeans/Lloyd.hpp +134 -0
  370. data/vendor/kmeans/MiniBatch.hpp +269 -0
  371. data/vendor/kmeans/QuickSearch.hpp +179 -0
  372. data/vendor/kmeans/compute_centroids.hpp +32 -0
  373. data/vendor/kmeans/compute_wcss.hpp +27 -0
  374. data/vendor/kmeans/is_edge_case.hpp +42 -0
  375. data/vendor/kmeans/random.hpp +55 -0
  376. data/vendor/knncolle/Annoy/Annoy.hpp +193 -0
  377. data/vendor/knncolle/BruteForce/BruteForce.hpp +120 -0
  378. data/vendor/knncolle/Hnsw/Hnsw.hpp +225 -0
  379. data/vendor/knncolle/Kmknn/Kmknn.hpp +286 -0
  380. data/vendor/knncolle/VpTree/VpTree.hpp +256 -0
  381. data/vendor/knncolle/knncolle.hpp +34 -0
  382. data/vendor/knncolle/utils/Base.hpp +100 -0
  383. data/vendor/knncolle/utils/NeighborQueue.hpp +94 -0
  384. data/vendor/knncolle/utils/distances.hpp +98 -0
  385. data/vendor/knncolle/utils/find_nearest_neighbors.hpp +112 -0
  386. data/vendor/powerit/PowerIterations.hpp +157 -0
  387. data/vendor/umappp/NeighborList.hpp +37 -0
  388. data/vendor/umappp/Umap.hpp +662 -0
  389. data/vendor/umappp/combine_neighbor_sets.hpp +95 -0
  390. data/vendor/umappp/find_ab.hpp +157 -0
  391. data/vendor/umappp/neighbor_similarities.hpp +136 -0
  392. data/vendor/umappp/optimize_layout.hpp +285 -0
  393. data/vendor/umappp/spectral_init.hpp +181 -0
  394. data/vendor/umappp/umappp.hpp +13 -0
  395. metadata +465 -0
@@ -0,0 +1,1495 @@
1
+ // Copyright (c) 2013 Spotify AB
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License"); you may not
4
+ // use this file except in compliance with the License. You may obtain a copy of
5
+ // the License at
6
+ //
7
+ // http://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11
+ // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12
+ // License for the specific language governing permissions and limitations under
13
+ // the License.
14
+
15
+
16
+ #ifndef ANNOY_ANNOYLIB_H
17
+ #define ANNOY_ANNOYLIB_H
18
+
19
+ #include <stdio.h>
20
+ #include <sys/stat.h>
21
+ #ifndef _MSC_VER
22
+ #include <unistd.h>
23
+ #endif
24
+ #include <stdio.h>
25
+ #include <stdlib.h>
26
+ #include <sys/types.h>
27
+ #include <fcntl.h>
28
+ #include <stddef.h>
29
+
30
+ #if defined(_MSC_VER) && _MSC_VER == 1500
31
+ typedef unsigned char uint8_t;
32
+ typedef signed __int32 int32_t;
33
+ typedef unsigned __int64 uint64_t;
34
+ typedef signed __int64 int64_t;
35
+ #else
36
+ #include <stdint.h>
37
+ #endif
38
+
39
+ #if defined(_MSC_VER) || defined(__MINGW32__)
40
+ // a bit hacky, but override some definitions to support 64 bit
41
+ #define off_t int64_t
42
+ #define lseek_getsize(fd) _lseeki64(fd, 0, SEEK_END)
43
+ #ifndef NOMINMAX
44
+ #define NOMINMAX
45
+ #endif
46
+ #include "mman.h"
47
+ #include <windows.h>
48
+ #else
49
+ #include <sys/mman.h>
50
+ #define lseek_getsize(fd) lseek(fd, 0, SEEK_END)
51
+ #endif
52
+
53
+ #include <cerrno>
54
+ #include <string.h>
55
+ #include <math.h>
56
+ #include <vector>
57
+ #include <algorithm>
58
+ #include <queue>
59
+ #include <limits>
60
+
61
+ #if __cplusplus >= 201103L
62
+ #include <type_traits>
63
+ #endif
64
+
65
+ #ifdef ANNOYLIB_MULTITHREADED_BUILD
66
+ #include <thread>
67
+ #include <mutex>
68
+ #include <shared_mutex>
69
+ #endif
70
+
71
+ #ifdef _MSC_VER
72
+ // Needed for Visual Studio to disable runtime checks for mempcy
73
+ #pragma runtime_checks("s", off)
74
+ #endif
75
+
76
+ // This allows others to supply their own logger / error printer without
77
+ // requiring Annoy to import their headers. See RcppAnnoy for a use case.
78
+ #ifndef __ERROR_PRINTER_OVERRIDE__
79
+ #define annoylib_showUpdate(...) { fprintf(stderr, __VA_ARGS__ ); }
80
+ #else
81
+ #define annoylib_showUpdate(...) { __ERROR_PRINTER_OVERRIDE__( __VA_ARGS__ ); }
82
+ #endif
83
+
84
+ // Portable alloc definition, cf Writing R Extensions, Section 1.6.4
85
+ #ifdef __GNUC__
86
+ // Includes GCC, clang and Intel compilers
87
+ # undef alloca
88
+ # define alloca(x) __builtin_alloca((x))
89
+ #elif defined(__sun) || defined(_AIX)
90
+ // this is necessary (and sufficient) for Solaris 10 and AIX 6:
91
+ # include <alloca.h>
92
+ #endif
93
+
94
+ // We let the v array in the Node struct take whatever space is needed, so this is a mostly insignificant number.
95
+ // Compilers need *some* size defined for the v array, and some memory checking tools will flag for buffer overruns if this is set too low.
96
+ #define ANNOYLIB_V_ARRAY_SIZE 65536
97
+
98
+ #ifndef _MSC_VER
99
+ #define annoylib_popcount __builtin_popcountll
100
+ #else // See #293, #358
101
+ #define annoylib_popcount cole_popcount
102
+ #endif
103
+
104
+ #if !defined(NO_MANUAL_VECTORIZATION) && defined(__GNUC__) && (__GNUC__ >6) && defined(__AVX512F__) // See #402
105
+ #define ANNOYLIB_USE_AVX512
106
+ #elif !defined(NO_MANUAL_VECTORIZATION) && defined(__AVX__) && defined (__SSE__) && defined(__SSE2__) && defined(__SSE3__)
107
+ #define ANNOYLIB_USE_AVX
108
+ #else
109
+ #endif
110
+
111
+ #if defined(ANNOYLIB_USE_AVX) || defined(ANNOYLIB_USE_AVX512)
112
+ #if defined(_MSC_VER)
113
+ #include <intrin.h>
114
+ #elif defined(__GNUC__)
115
+ #include <x86intrin.h>
116
+ #endif
117
+ #endif
118
+
119
+ #if !defined(__MINGW32__)
120
+ #define ANNOYLIB_FTRUNCATE_SIZE(x) static_cast<int64_t>(x)
121
+ #else
122
+ #define ANNOYLIB_FTRUNCATE_SIZE(x) (x)
123
+ #endif
124
+
125
+ namespace Annoy {
126
+
127
+ inline void set_error_from_errno(char **error, const char* msg) {
128
+ annoylib_showUpdate("%s: %s (%d)\n", msg, strerror(errno), errno);
129
+ if (error) {
130
+ *error = (char *)malloc(256); // TODO: win doesn't support snprintf
131
+ sprintf(*error, "%s: %s (%d)", msg, strerror(errno), errno);
132
+ }
133
+ }
134
+
135
+ inline void set_error_from_string(char **error, const char* msg) {
136
+ annoylib_showUpdate("%s\n", msg);
137
+ if (error) {
138
+ *error = (char *)malloc(strlen(msg) + 1);
139
+ strcpy(*error, msg);
140
+ }
141
+ }
142
+
143
+
144
+ using std::vector;
145
+ using std::pair;
146
+ using std::numeric_limits;
147
+ using std::make_pair;
148
+
149
+ inline bool remap_memory_and_truncate(void** _ptr, int _fd, size_t old_size, size_t new_size) {
150
+ #ifdef __linux__
151
+ *_ptr = mremap(*_ptr, old_size, new_size, MREMAP_MAYMOVE);
152
+ bool ok = ftruncate(_fd, new_size) != -1;
153
+ #else
154
+ munmap(*_ptr, old_size);
155
+ bool ok = ftruncate(_fd, ANNOYLIB_FTRUNCATE_SIZE(new_size)) != -1;
156
+ #ifdef MAP_POPULATE
157
+ *_ptr = mmap(*_ptr, new_size, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_POPULATE, _fd, 0);
158
+ #else
159
+ *_ptr = mmap(*_ptr, new_size, PROT_READ | PROT_WRITE, MAP_SHARED, _fd, 0);
160
+ #endif
161
+ #endif
162
+ return ok;
163
+ }
164
+
165
+ namespace {
166
+
167
+ template<typename S, typename Node>
168
+ inline Node* get_node_ptr(const void* _nodes, const size_t _s, const S i) {
169
+ return (Node*)((uint8_t *)_nodes + (_s * i));
170
+ }
171
+
172
+ template<typename T>
173
+ inline T dot(const T* x, const T* y, int f) {
174
+ T s = 0;
175
+ for (int z = 0; z < f; z++) {
176
+ s += (*x) * (*y);
177
+ x++;
178
+ y++;
179
+ }
180
+ return s;
181
+ }
182
+
183
+ template<typename T>
184
+ inline T manhattan_distance(const T* x, const T* y, int f) {
185
+ T d = 0.0;
186
+ for (int i = 0; i < f; i++)
187
+ d += fabs(x[i] - y[i]);
188
+ return d;
189
+ }
190
+
191
+ template<typename T>
192
+ inline T euclidean_distance(const T* x, const T* y, int f) {
193
+ // Don't use dot-product: avoid catastrophic cancellation in #314.
194
+ T d = 0.0;
195
+ for (int i = 0; i < f; ++i) {
196
+ const T tmp=*x - *y;
197
+ d += tmp * tmp;
198
+ ++x;
199
+ ++y;
200
+ }
201
+ return d;
202
+ }
203
+
204
+ #ifdef ANNOYLIB_USE_AVX
205
+ // Horizontal single sum of 256bit vector.
206
+ inline float hsum256_ps_avx(__m256 v) {
207
+ const __m128 x128 = _mm_add_ps(_mm256_extractf128_ps(v, 1), _mm256_castps256_ps128(v));
208
+ const __m128 x64 = _mm_add_ps(x128, _mm_movehl_ps(x128, x128));
209
+ const __m128 x32 = _mm_add_ss(x64, _mm_shuffle_ps(x64, x64, 0x55));
210
+ return _mm_cvtss_f32(x32);
211
+ }
212
+
213
+ template<>
214
+ inline float dot<float>(const float* x, const float *y, int f) {
215
+ float result = 0;
216
+ if (f > 7) {
217
+ __m256 d = _mm256_setzero_ps();
218
+ for (; f > 7; f -= 8) {
219
+ d = _mm256_add_ps(d, _mm256_mul_ps(_mm256_loadu_ps(x), _mm256_loadu_ps(y)));
220
+ x += 8;
221
+ y += 8;
222
+ }
223
+ // Sum all floats in dot register.
224
+ result += hsum256_ps_avx(d);
225
+ }
226
+ // Don't forget the remaining values.
227
+ for (; f > 0; f--) {
228
+ result += *x * *y;
229
+ x++;
230
+ y++;
231
+ }
232
+ return result;
233
+ }
234
+
235
+ template<>
236
+ inline float manhattan_distance<float>(const float* x, const float* y, int f) {
237
+ float result = 0;
238
+ int i = f;
239
+ if (f > 7) {
240
+ __m256 manhattan = _mm256_setzero_ps();
241
+ __m256 minus_zero = _mm256_set1_ps(-0.0f);
242
+ for (; i > 7; i -= 8) {
243
+ const __m256 x_minus_y = _mm256_sub_ps(_mm256_loadu_ps(x), _mm256_loadu_ps(y));
244
+ const __m256 distance = _mm256_andnot_ps(minus_zero, x_minus_y); // Absolute value of x_minus_y (forces sign bit to zero)
245
+ manhattan = _mm256_add_ps(manhattan, distance);
246
+ x += 8;
247
+ y += 8;
248
+ }
249
+ // Sum all floats in manhattan register.
250
+ result = hsum256_ps_avx(manhattan);
251
+ }
252
+ // Don't forget the remaining values.
253
+ for (; i > 0; i--) {
254
+ result += fabsf(*x - *y);
255
+ x++;
256
+ y++;
257
+ }
258
+ return result;
259
+ }
260
+
261
+ template<>
262
+ inline float euclidean_distance<float>(const float* x, const float* y, int f) {
263
+ float result=0;
264
+ if (f > 7) {
265
+ __m256 d = _mm256_setzero_ps();
266
+ for (; f > 7; f -= 8) {
267
+ const __m256 diff = _mm256_sub_ps(_mm256_loadu_ps(x), _mm256_loadu_ps(y));
268
+ d = _mm256_add_ps(d, _mm256_mul_ps(diff, diff)); // no support for fmadd in AVX...
269
+ x += 8;
270
+ y += 8;
271
+ }
272
+ // Sum all floats in dot register.
273
+ result = hsum256_ps_avx(d);
274
+ }
275
+ // Don't forget the remaining values.
276
+ for (; f > 0; f--) {
277
+ float tmp = *x - *y;
278
+ result += tmp * tmp;
279
+ x++;
280
+ y++;
281
+ }
282
+ return result;
283
+ }
284
+
285
+ #endif
286
+
287
+ #ifdef ANNOYLIB_USE_AVX512
288
+ template<>
289
+ inline float dot<float>(const float* x, const float *y, int f) {
290
+ float result = 0;
291
+ if (f > 15) {
292
+ __m512 d = _mm512_setzero_ps();
293
+ for (; f > 15; f -= 16) {
294
+ //AVX512F includes FMA
295
+ d = _mm512_fmadd_ps(_mm512_loadu_ps(x), _mm512_loadu_ps(y), d);
296
+ x += 16;
297
+ y += 16;
298
+ }
299
+ // Sum all floats in dot register.
300
+ result += _mm512_reduce_add_ps(d);
301
+ }
302
+ // Don't forget the remaining values.
303
+ for (; f > 0; f--) {
304
+ result += *x * *y;
305
+ x++;
306
+ y++;
307
+ }
308
+ return result;
309
+ }
310
+
311
+ template<>
312
+ inline float manhattan_distance<float>(const float* x, const float* y, int f) {
313
+ float result = 0;
314
+ int i = f;
315
+ if (f > 15) {
316
+ __m512 manhattan = _mm512_setzero_ps();
317
+ for (; i > 15; i -= 16) {
318
+ const __m512 x_minus_y = _mm512_sub_ps(_mm512_loadu_ps(x), _mm512_loadu_ps(y));
319
+ manhattan = _mm512_add_ps(manhattan, _mm512_abs_ps(x_minus_y));
320
+ x += 16;
321
+ y += 16;
322
+ }
323
+ // Sum all floats in manhattan register.
324
+ result = _mm512_reduce_add_ps(manhattan);
325
+ }
326
+ // Don't forget the remaining values.
327
+ for (; i > 0; i--) {
328
+ result += fabsf(*x - *y);
329
+ x++;
330
+ y++;
331
+ }
332
+ return result;
333
+ }
334
+
335
+ template<>
336
+ inline float euclidean_distance<float>(const float* x, const float* y, int f) {
337
+ float result=0;
338
+ if (f > 15) {
339
+ __m512 d = _mm512_setzero_ps();
340
+ for (; f > 15; f -= 16) {
341
+ const __m512 diff = _mm512_sub_ps(_mm512_loadu_ps(x), _mm512_loadu_ps(y));
342
+ d = _mm512_fmadd_ps(diff, diff, d);
343
+ x += 16;
344
+ y += 16;
345
+ }
346
+ // Sum all floats in dot register.
347
+ result = _mm512_reduce_add_ps(d);
348
+ }
349
+ // Don't forget the remaining values.
350
+ for (; f > 0; f--) {
351
+ float tmp = *x - *y;
352
+ result += tmp * tmp;
353
+ x++;
354
+ y++;
355
+ }
356
+ return result;
357
+ }
358
+
359
+ #endif
360
+
361
+
362
+ template<typename T>
363
+ inline T get_norm(T* v, int f) {
364
+ return sqrt(dot(v, v, f));
365
+ }
366
+
367
+ template<typename T, typename Random, typename Distance, typename Node>
368
+ inline void two_means(const vector<Node*>& nodes, int f, Random& random, bool cosine, Node* p, Node* q) {
369
+ /*
370
+ This algorithm is a huge heuristic. Empirically it works really well, but I
371
+ can't motivate it well. The basic idea is to keep two centroids and assign
372
+ points to either one of them. We weight each centroid by the number of points
373
+ assigned to it, so to balance it.
374
+ */
375
+ static int iteration_steps = 200;
376
+ size_t count = nodes.size();
377
+
378
+ size_t i = random.index(count);
379
+ size_t j = random.index(count-1);
380
+ j += (j >= i); // ensure that i != j
381
+
382
+ Distance::template copy_node<T, Node>(p, nodes[i], f);
383
+ Distance::template copy_node<T, Node>(q, nodes[j], f);
384
+
385
+ if (cosine) { Distance::template normalize<T, Node>(p, f); Distance::template normalize<T, Node>(q, f); }
386
+ Distance::init_node(p, f);
387
+ Distance::init_node(q, f);
388
+
389
+ int ic = 1, jc = 1;
390
+ for (int l = 0; l < iteration_steps; l++) {
391
+ size_t k = random.index(count);
392
+ T di = ic * Distance::distance(p, nodes[k], f),
393
+ dj = jc * Distance::distance(q, nodes[k], f);
394
+ T norm = cosine ? get_norm(nodes[k]->v, f) : 1;
395
+ if (!(norm > T(0))) {
396
+ continue;
397
+ }
398
+ if (di < dj) {
399
+ for (int z = 0; z < f; z++)
400
+ p->v[z] = (p->v[z] * ic + nodes[k]->v[z] / norm) / (ic + 1);
401
+ Distance::init_node(p, f);
402
+ ic++;
403
+ } else if (dj < di) {
404
+ for (int z = 0; z < f; z++)
405
+ q->v[z] = (q->v[z] * jc + nodes[k]->v[z] / norm) / (jc + 1);
406
+ Distance::init_node(q, f);
407
+ jc++;
408
+ }
409
+ }
410
+ }
411
+ } // namespace
412
+
413
+ struct Base {
414
+ template<typename T, typename S, typename Node>
415
+ static inline void preprocess(void* nodes, size_t _s, const S node_count, const int f) {
416
+ // Override this in specific metric structs below if you need to do any pre-processing
417
+ // on the entire set of nodes passed into this index.
418
+ }
419
+
420
+ template<typename Node>
421
+ static inline void zero_value(Node* dest) {
422
+ // Initialize any fields that require sane defaults within this node.
423
+ }
424
+
425
+ template<typename T, typename Node>
426
+ static inline void copy_node(Node* dest, const Node* source, const int f) {
427
+ memcpy(dest->v, source->v, f * sizeof(T));
428
+ }
429
+
430
+ template<typename T, typename Node>
431
+ static inline void normalize(Node* node, int f) {
432
+ T norm = get_norm(node->v, f);
433
+ if (norm > 0) {
434
+ for (int z = 0; z < f; z++)
435
+ node->v[z] /= norm;
436
+ }
437
+ }
438
+ };
439
+
440
+ struct Angular : Base {
441
+ template<typename S, typename T>
442
+ struct Node {
443
+ /*
444
+ * We store a binary tree where each node has two things
445
+ * - A vector associated with it
446
+ * - Two children
447
+ * All nodes occupy the same amount of memory
448
+ * All nodes with n_descendants == 1 are leaf nodes.
449
+ * A memory optimization is that for nodes with 2 <= n_descendants <= K,
450
+ * we skip the vector. Instead we store a list of all descendants. K is
451
+ * determined by the number of items that fits in the space of the vector.
452
+ * For nodes with n_descendants == 1 the vector is a data point.
453
+ * For nodes with n_descendants > K the vector is the normal of the split plane.
454
+ * Note that we can't really do sizeof(node<T>) because we cheat and allocate
455
+ * more memory to be able to fit the vector outside
456
+ */
457
+ S n_descendants;
458
+ union {
459
+ S children[2]; // Will possibly store more than 2
460
+ T norm;
461
+ };
462
+ T v[ANNOYLIB_V_ARRAY_SIZE];
463
+ };
464
+ template<typename S, typename T>
465
+ static inline T distance(const Node<S, T>* x, const Node<S, T>* y, int f) {
466
+ // want to calculate (a/|a| - b/|b|)^2
467
+ // = a^2 / a^2 + b^2 / b^2 - 2ab/|a||b|
468
+ // = 2 - 2cos
469
+ T pp = x->norm ? x->norm : dot(x->v, x->v, f); // For backwards compatibility reasons, we need to fall back and compute the norm here
470
+ T qq = y->norm ? y->norm : dot(y->v, y->v, f);
471
+ T pq = dot(x->v, y->v, f);
472
+ T ppqq = pp * qq;
473
+ if (ppqq > 0) return 2.0 - 2.0 * pq / sqrt(ppqq);
474
+ else return 2.0; // cos is 0
475
+ }
476
+ template<typename S, typename T>
477
+ static inline T margin(const Node<S, T>* n, const T* y, int f) {
478
+ return dot(n->v, y, f);
479
+ }
480
+ template<typename S, typename T, typename Random>
481
+ static inline bool side(const Node<S, T>* n, const T* y, int f, Random& random) {
482
+ T dot = margin(n, y, f);
483
+ if (dot != 0)
484
+ return (dot > 0);
485
+ else
486
+ return (bool)random.flip();
487
+ }
488
+ template<typename S, typename T, typename Random>
489
+ static inline void create_split(const vector<Node<S, T>*>& nodes, int f, size_t s, Random& random, Node<S, T>* n) {
490
+ Node<S, T>* p = (Node<S, T>*)alloca(s);
491
+ Node<S, T>* q = (Node<S, T>*)alloca(s);
492
+ two_means<T, Random, Angular, Node<S, T> >(nodes, f, random, true, p, q);
493
+ for (int z = 0; z < f; z++)
494
+ n->v[z] = p->v[z] - q->v[z];
495
+ Base::normalize<T, Node<S, T> >(n, f);
496
+ }
497
+ template<typename T>
498
+ static inline T normalized_distance(T distance) {
499
+ // Used when requesting distances from Python layer
500
+ // Turns out sometimes the squared distance is -0.0
501
+ // so we have to make sure it's a positive number.
502
+ return sqrt(std::max(distance, T(0)));
503
+ }
504
+ template<typename T>
505
+ static inline T pq_distance(T distance, T margin, int child_nr) {
506
+ if (child_nr == 0)
507
+ margin = -margin;
508
+ return std::min(distance, margin);
509
+ }
510
+ template<typename T>
511
+ static inline T pq_initial_value() {
512
+ return numeric_limits<T>::infinity();
513
+ }
514
+ template<typename S, typename T>
515
+ static inline void init_node(Node<S, T>* n, int f) {
516
+ n->norm = dot(n->v, n->v, f);
517
+ }
518
+ static const char* name() {
519
+ return "angular";
520
+ }
521
+ };
522
+
523
+
524
+ struct DotProduct : Angular {
525
+ template<typename S, typename T>
526
+ struct Node {
527
+ /*
528
+ * This is an extension of the Angular node with an extra attribute for the scaled norm.
529
+ */
530
+ S n_descendants;
531
+ S children[2]; // Will possibly store more than 2
532
+ T dot_factor;
533
+ T v[ANNOYLIB_V_ARRAY_SIZE];
534
+ };
535
+
536
+ static const char* name() {
537
+ return "dot";
538
+ }
539
+ template<typename S, typename T>
540
+ static inline T distance(const Node<S, T>* x, const Node<S, T>* y, int f) {
541
+ return -dot(x->v, y->v, f);
542
+ }
543
+
544
+ template<typename Node>
545
+ static inline void zero_value(Node* dest) {
546
+ dest->dot_factor = 0;
547
+ }
548
+
549
+ template<typename S, typename T>
550
+ static inline void init_node(Node<S, T>* n, int f) {
551
+ }
552
+
553
+ template<typename T, typename Node>
554
+ static inline void copy_node(Node* dest, const Node* source, const int f) {
555
+ memcpy(dest->v, source->v, f * sizeof(T));
556
+ dest->dot_factor = source->dot_factor;
557
+ }
558
+
559
+ template<typename S, typename T, typename Random>
560
+ static inline void create_split(const vector<Node<S, T>*>& nodes, int f, size_t s, Random& random, Node<S, T>* n) {
561
+ Node<S, T>* p = (Node<S, T>*)alloca(s);
562
+ Node<S, T>* q = (Node<S, T>*)alloca(s);
563
+ DotProduct::zero_value(p);
564
+ DotProduct::zero_value(q);
565
+ two_means<T, Random, DotProduct, Node<S, T> >(nodes, f, random, true, p, q);
566
+ for (int z = 0; z < f; z++)
567
+ n->v[z] = p->v[z] - q->v[z];
568
+ n->dot_factor = p->dot_factor - q->dot_factor;
569
+ DotProduct::normalize<T, Node<S, T> >(n, f);
570
+ }
571
+
572
+ template<typename T, typename Node>
573
+ static inline void normalize(Node* node, int f) {
574
+ T norm = sqrt(dot(node->v, node->v, f) + pow(node->dot_factor, 2));
575
+ if (norm > 0) {
576
+ for (int z = 0; z < f; z++)
577
+ node->v[z] /= norm;
578
+ node->dot_factor /= norm;
579
+ }
580
+ }
581
+
582
+ template<typename S, typename T>
583
+ static inline T margin(const Node<S, T>* n, const T* y, int f) {
584
+ return dot(n->v, y, f) + (n->dot_factor * n->dot_factor);
585
+ }
586
+
587
+ template<typename S, typename T, typename Random>
588
+ static inline bool side(const Node<S, T>* n, const T* y, int f, Random& random) {
589
+ T dot = margin(n, y, f);
590
+ if (dot != 0)
591
+ return (dot > 0);
592
+ else
593
+ return (bool)random.flip();
594
+ }
595
+
596
+ template<typename T>
597
+ static inline T normalized_distance(T distance) {
598
+ return -distance;
599
+ }
600
+
601
+ template<typename T, typename S, typename Node>
602
+ static inline void preprocess(void* nodes, size_t _s, const S node_count, const int f) {
603
+ // This uses a method from Microsoft Research for transforming inner product spaces to cosine/angular-compatible spaces.
604
+ // (Bachrach et al., 2014, see https://www.microsoft.com/en-us/research/wp-content/uploads/2016/02/XboxInnerProduct.pdf)
605
+
606
+ // Step one: compute the norm of each vector and store that in its extra dimension (f-1)
607
+ for (S i = 0; i < node_count; i++) {
608
+ Node* node = get_node_ptr<S, Node>(nodes, _s, i);
609
+ T d = dot(node->v, node->v, f);
610
+ T norm = d < 0 ? 0 : sqrt(d);
611
+ node->dot_factor = norm;
612
+ }
613
+
614
+ // Step two: find the maximum norm
615
+ T max_norm = 0;
616
+ for (S i = 0; i < node_count; i++) {
617
+ Node* node = get_node_ptr<S, Node>(nodes, _s, i);
618
+ if (node->dot_factor > max_norm) {
619
+ max_norm = node->dot_factor;
620
+ }
621
+ }
622
+
623
+ // Step three: set each vector's extra dimension to sqrt(max_norm^2 - norm^2)
624
+ for (S i = 0; i < node_count; i++) {
625
+ Node* node = get_node_ptr<S, Node>(nodes, _s, i);
626
+ T node_norm = node->dot_factor;
627
+ T squared_norm_diff = pow(max_norm, static_cast<T>(2.0)) - pow(node_norm, static_cast<T>(2.0));
628
+ T dot_factor = squared_norm_diff < 0 ? 0 : sqrt(squared_norm_diff);
629
+
630
+ node->dot_factor = dot_factor;
631
+ }
632
+ }
633
+ };
634
+
635
+ struct Hamming : Base {
636
+ template<typename S, typename T>
637
+ struct Node {
638
+ S n_descendants;
639
+ S children[2];
640
+ T v[ANNOYLIB_V_ARRAY_SIZE];
641
+ };
642
+
643
+ static const size_t max_iterations = 20;
644
+
645
+ template<typename T>
646
+ static inline T pq_distance(T distance, T margin, int child_nr) {
647
+ return distance - (margin != (unsigned int) child_nr);
648
+ }
649
+
650
+ template<typename T>
651
+ static inline T pq_initial_value() {
652
+ return numeric_limits<T>::max();
653
+ }
654
+ template<typename T>
655
+ static inline int cole_popcount(T v) {
656
+ // Note: Only used with MSVC 9, which lacks intrinsics and fails to
657
+ // calculate std::bitset::count for v > 32bit. Uses the generalized
658
+ // approach by Eric Cole.
659
+ // See https://graphics.stanford.edu/~seander/bithacks.html#CountBitsSet64
660
+ v = v - ((v >> 1) & (T)~(T)0/3);
661
+ v = (v & (T)~(T)0/15*3) + ((v >> 2) & (T)~(T)0/15*3);
662
+ v = (v + (v >> 4)) & (T)~(T)0/255*15;
663
+ return (T)(v * ((T)~(T)0/255)) >> (sizeof(T) - 1) * 8;
664
+ }
665
+ template<typename S, typename T>
666
+ static inline T distance(const Node<S, T>* x, const Node<S, T>* y, int f) {
667
+ size_t dist = 0;
668
+ for (int i = 0; i < f; i++) {
669
+ dist += annoylib_popcount(x->v[i] ^ y->v[i]);
670
+ }
671
+ return dist;
672
+ }
673
+ template<typename S, typename T>
674
+ static inline bool margin(const Node<S, T>* n, const T* y, int f) {
675
+ static const size_t n_bits = sizeof(T) * 8;
676
+ T chunk = n->v[0] / n_bits;
677
+ return (y[chunk] & (static_cast<T>(1) << (n_bits - 1 - (n->v[0] % n_bits)))) != 0;
678
+ }
679
+ template<typename S, typename T, typename Random>
680
+ static inline bool side(const Node<S, T>* n, const T* y, int f, Random& random) {
681
+ return margin(n, y, f);
682
+ }
683
+ template<typename S, typename T, typename Random>
684
+ static inline void create_split(const vector<Node<S, T>*>& nodes, int f, size_t s, Random& random, Node<S, T>* n) {
685
+ size_t cur_size = 0;
686
+ size_t i = 0;
687
+ int dim = f * 8 * sizeof(T);
688
+ for (; i < max_iterations; i++) {
689
+ // choose random position to split at
690
+ n->v[0] = random.index(dim);
691
+ cur_size = 0;
692
+ for (typename vector<Node<S, T>*>::const_iterator it = nodes.begin(); it != nodes.end(); ++it) {
693
+ if (margin(n, (*it)->v, f)) {
694
+ cur_size++;
695
+ }
696
+ }
697
+ if (cur_size > 0 && cur_size < nodes.size()) {
698
+ break;
699
+ }
700
+ }
701
+ // brute-force search for splitting coordinate
702
+ if (i == max_iterations) {
703
+ int j = 0;
704
+ for (; j < dim; j++) {
705
+ n->v[0] = j;
706
+ cur_size = 0;
707
+ for (typename vector<Node<S, T>*>::const_iterator it = nodes.begin(); it != nodes.end(); ++it) {
708
+ if (margin(n, (*it)->v, f)) {
709
+ cur_size++;
710
+ }
711
+ }
712
+ if (cur_size > 0 && cur_size < nodes.size()) {
713
+ break;
714
+ }
715
+ }
716
+ }
717
+ }
718
+ template<typename T>
719
+ static inline T normalized_distance(T distance) {
720
+ return distance;
721
+ }
722
+ template<typename S, typename T>
723
+ static inline void init_node(Node<S, T>* n, int f) {
724
+ }
725
+ static const char* name() {
726
+ return "hamming";
727
+ }
728
+ };
729
+
730
+
731
+ struct Minkowski : Base {
732
+ template<typename S, typename T>
733
+ struct Node {
734
+ S n_descendants;
735
+ T a; // need an extra constant term to determine the offset of the plane
736
+ S children[2];
737
+ T v[ANNOYLIB_V_ARRAY_SIZE];
738
+ };
739
+ template<typename S, typename T>
740
+ static inline T margin(const Node<S, T>* n, const T* y, int f) {
741
+ return n->a + dot(n->v, y, f);
742
+ }
743
+ template<typename S, typename T, typename Random>
744
+ static inline bool side(const Node<S, T>* n, const T* y, int f, Random& random) {
745
+ T dot = margin(n, y, f);
746
+ if (dot != 0)
747
+ return (dot > 0);
748
+ else
749
+ return (bool)random.flip();
750
+ }
751
+ template<typename T>
752
+ static inline T pq_distance(T distance, T margin, int child_nr) {
753
+ if (child_nr == 0)
754
+ margin = -margin;
755
+ return std::min(distance, margin);
756
+ }
757
+ template<typename T>
758
+ static inline T pq_initial_value() {
759
+ return numeric_limits<T>::infinity();
760
+ }
761
+ };
762
+
763
+
764
+ struct Euclidean : Minkowski {
765
+ template<typename S, typename T>
766
+ static inline T distance(const Node<S, T>* x, const Node<S, T>* y, int f) {
767
+ return euclidean_distance(x->v, y->v, f);
768
+ }
769
+ template<typename S, typename T, typename Random>
770
+ static inline void create_split(const vector<Node<S, T>*>& nodes, int f, size_t s, Random& random, Node<S, T>* n) {
771
+ Node<S, T>* p = (Node<S, T>*)alloca(s);
772
+ Node<S, T>* q = (Node<S, T>*)alloca(s);
773
+ two_means<T, Random, Euclidean, Node<S, T> >(nodes, f, random, false, p, q);
774
+
775
+ for (int z = 0; z < f; z++)
776
+ n->v[z] = p->v[z] - q->v[z];
777
+ Base::normalize<T, Node<S, T> >(n, f);
778
+ n->a = 0.0;
779
+ for (int z = 0; z < f; z++)
780
+ n->a += -n->v[z] * (p->v[z] + q->v[z]) / 2;
781
+ }
782
+ template<typename T>
783
+ static inline T normalized_distance(T distance) {
784
+ return sqrt(std::max(distance, T(0)));
785
+ }
786
+ template<typename S, typename T>
787
+ static inline void init_node(Node<S, T>* n, int f) {
788
+ }
789
+ static const char* name() {
790
+ return "euclidean";
791
+ }
792
+
793
+ };
794
+
795
+ struct Manhattan : Minkowski {
796
+ template<typename S, typename T>
797
+ static inline T distance(const Node<S, T>* x, const Node<S, T>* y, int f) {
798
+ return manhattan_distance(x->v, y->v, f);
799
+ }
800
+ template<typename S, typename T, typename Random>
801
+ static inline void create_split(const vector<Node<S, T>*>& nodes, int f, size_t s, Random& random, Node<S, T>* n) {
802
+ Node<S, T>* p = (Node<S, T>*)alloca(s);
803
+ Node<S, T>* q = (Node<S, T>*)alloca(s);
804
+ two_means<T, Random, Manhattan, Node<S, T> >(nodes, f, random, false, p, q);
805
+
806
+ for (int z = 0; z < f; z++)
807
+ n->v[z] = p->v[z] - q->v[z];
808
+ Base::normalize<T, Node<S, T> >(n, f);
809
+ n->a = 0.0;
810
+ for (int z = 0; z < f; z++)
811
+ n->a += -n->v[z] * (p->v[z] + q->v[z]) / 2;
812
+ }
813
+ template<typename T>
814
+ static inline T normalized_distance(T distance) {
815
+ return std::max(distance, T(0));
816
+ }
817
+ template<typename S, typename T>
818
+ static inline void init_node(Node<S, T>* n, int f) {
819
+ }
820
+ static const char* name() {
821
+ return "manhattan";
822
+ }
823
+ };
824
+
825
+ template<typename S, typename T, typename R = uint64_t>
826
+ class AnnoyIndexInterface {
827
+ public:
828
+ // Note that the methods with an **error argument will allocate memory and write the pointer to that string if error is non-NULL
829
+ virtual ~AnnoyIndexInterface() {};
830
+ virtual bool add_item(S item, const T* w, char** error=NULL) = 0;
831
+ virtual bool build(int q, int n_threads=-1, char** error=NULL) = 0;
832
+ virtual bool unbuild(char** error=NULL) = 0;
833
+ virtual bool save(const char* filename, bool prefault=false, char** error=NULL) = 0;
834
+ virtual void unload() = 0;
835
+ virtual bool load(const char* filename, bool prefault=false, char** error=NULL) = 0;
836
+ virtual T get_distance(S i, S j) const = 0;
837
+ virtual void get_nns_by_item(S item, size_t n, int search_k, vector<S>* result, vector<T>* distances) const = 0;
838
+ virtual void get_nns_by_vector(const T* w, size_t n, int search_k, vector<S>* result, vector<T>* distances) const = 0;
839
+ virtual S get_n_items() const = 0;
840
+ virtual S get_n_trees() const = 0;
841
+ virtual void verbose(bool v) = 0;
842
+ virtual void get_item(S item, T* v) const = 0;
843
+ virtual void set_seed(R q) = 0;
844
+ virtual bool on_disk_build(const char* filename, char** error=NULL) = 0;
845
+ };
846
+
847
+ template<typename S, typename T, typename Distance, typename Random, class ThreadedBuildPolicy>
848
+ class AnnoyIndex : public AnnoyIndexInterface<S, T,
849
+ #if __cplusplus >= 201103L
850
+ typename std::remove_const<decltype(Random::default_seed)>::type
851
+ #else
852
+ typename Random::seed_type
853
+ #endif
854
+ > {
855
+ /*
856
+ * We use random projection to build a forest of binary trees of all items.
857
+ * Basically just split the hyperspace into two sides by a hyperplane,
858
+ * then recursively split each of those subtrees etc.
859
+ * We create a tree like this q times. The default q is determined automatically
860
+ * in such a way that we at most use 2x as much memory as the vectors take.
861
+ */
862
+ public:
863
+ typedef Distance D;
864
+ typedef typename D::template Node<S, T> Node;
865
+ #if __cplusplus >= 201103L
866
+ typedef typename std::remove_const<decltype(Random::default_seed)>::type R;
867
+ #else
868
+ typedef typename Random::seed_type R;
869
+ #endif
870
+
871
+ protected:
872
+ const int _f;
873
+ size_t _s;
874
+ S _n_items;
875
+ void* _nodes; // Could either be mmapped, or point to a memory buffer that we reallocate
876
+ S _n_nodes;
877
+ S _nodes_size;
878
+ vector<S> _roots;
879
+ S _K;
880
+ R _seed;
881
+ bool _loaded;
882
+ bool _verbose;
883
+ int _fd;
884
+ bool _on_disk;
885
+ bool _built;
886
+ public:
887
+
888
+ AnnoyIndex(int f) : _f(f), _seed(Random::default_seed) {
889
+ _s = offsetof(Node, v) + _f * sizeof(T); // Size of each node
890
+ _verbose = false;
891
+ _built = false;
892
+ _K = (S) (((size_t) (_s - offsetof(Node, children))) / sizeof(S)); // Max number of descendants to fit into node
893
+ reinitialize(); // Reset everything
894
+ }
895
+ ~AnnoyIndex() {
896
+ unload();
897
+ }
898
+
899
+ int get_f() const {
900
+ return _f;
901
+ }
902
+
903
+ bool add_item(S item, const T* w, char** error=NULL) {
904
+ return add_item_impl(item, w, error);
905
+ }
906
+
907
+ template<typename W>
908
+ bool add_item_impl(S item, const W& w, char** error=NULL) {
909
+ if (_loaded) {
910
+ set_error_from_string(error, "You can't add an item to a loaded index");
911
+ return false;
912
+ }
913
+ _allocate_size(item + 1);
914
+ Node* n = _get(item);
915
+
916
+ D::zero_value(n);
917
+
918
+ n->children[0] = 0;
919
+ n->children[1] = 0;
920
+ n->n_descendants = 1;
921
+
922
+ for (int z = 0; z < _f; z++)
923
+ n->v[z] = w[z];
924
+
925
+ D::init_node(n, _f);
926
+
927
+ if (item >= _n_items)
928
+ _n_items = item + 1;
929
+
930
+ return true;
931
+ }
932
+
933
+ bool on_disk_build(const char* file, char** error=NULL) {
934
+ _on_disk = true;
935
+ _fd = open(file, O_RDWR | O_CREAT | O_TRUNC, (int) 0600);
936
+ if (_fd == -1) {
937
+ set_error_from_errno(error, "Unable to open");
938
+ _fd = 0;
939
+ return false;
940
+ }
941
+ _nodes_size = 1;
942
+ if (ftruncate(_fd, ANNOYLIB_FTRUNCATE_SIZE(_s) * ANNOYLIB_FTRUNCATE_SIZE(_nodes_size)) == -1) {
943
+ set_error_from_errno(error, "Unable to truncate");
944
+ return false;
945
+ }
946
+ #ifdef MAP_POPULATE
947
+ _nodes = (Node*) mmap(0, _s * _nodes_size, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_POPULATE, _fd, 0);
948
+ #else
949
+ _nodes = (Node*) mmap(0, _s * _nodes_size, PROT_READ | PROT_WRITE, MAP_SHARED, _fd, 0);
950
+ #endif
951
+ return true;
952
+ }
953
+
954
+ bool build(int q, int n_threads=-1, char** error=NULL) {
955
+ if (_loaded) {
956
+ set_error_from_string(error, "You can't build a loaded index");
957
+ return false;
958
+ }
959
+
960
+ if (_built) {
961
+ set_error_from_string(error, "You can't build a built index");
962
+ return false;
963
+ }
964
+
965
+ D::template preprocess<T, S, Node>(_nodes, _s, _n_items, _f);
966
+
967
+ _n_nodes = _n_items;
968
+
969
+ ThreadedBuildPolicy::template build<S, T>(this, q, n_threads);
970
+
971
+ // Also, copy the roots into the last segment of the array
972
+ // This way we can load them faster without reading the whole file
973
+ _allocate_size(_n_nodes + (S)_roots.size());
974
+ for (size_t i = 0; i < _roots.size(); i++)
975
+ memcpy(_get(_n_nodes + (S)i), _get(_roots[i]), _s);
976
+ _n_nodes += _roots.size();
977
+
978
+ if (_verbose) annoylib_showUpdate("has %d nodes\n", _n_nodes);
979
+
980
+ if (_on_disk) {
981
+ if (!remap_memory_and_truncate(&_nodes, _fd,
982
+ static_cast<size_t>(_s) * static_cast<size_t>(_nodes_size),
983
+ static_cast<size_t>(_s) * static_cast<size_t>(_n_nodes))) {
984
+ // TODO: this probably creates an index in a corrupt state... not sure what to do
985
+ set_error_from_errno(error, "Unable to truncate");
986
+ return false;
987
+ }
988
+ _nodes_size = _n_nodes;
989
+ }
990
+ _built = true;
991
+ return true;
992
+ }
993
+
994
+ bool unbuild(char** error=NULL) {
995
+ if (_loaded) {
996
+ set_error_from_string(error, "You can't unbuild a loaded index");
997
+ return false;
998
+ }
999
+
1000
+ _roots.clear();
1001
+ _n_nodes = _n_items;
1002
+ _built = false;
1003
+
1004
+ return true;
1005
+ }
1006
+
1007
+ bool save(const char* filename, bool prefault=false, char** error=NULL) {
1008
+ if (!_built) {
1009
+ set_error_from_string(error, "You can't save an index that hasn't been built");
1010
+ return false;
1011
+ }
1012
+ if (_on_disk) {
1013
+ return true;
1014
+ } else {
1015
+ // Delete file if it already exists (See issue #335)
1016
+ unlink(filename);
1017
+
1018
+ FILE *f = fopen(filename, "wb");
1019
+ if (f == NULL) {
1020
+ set_error_from_errno(error, "Unable to open");
1021
+ return false;
1022
+ }
1023
+
1024
+ if (fwrite(_nodes, _s, _n_nodes, f) != (size_t) _n_nodes) {
1025
+ set_error_from_errno(error, "Unable to write");
1026
+ return false;
1027
+ }
1028
+
1029
+ if (fclose(f) == EOF) {
1030
+ set_error_from_errno(error, "Unable to close");
1031
+ return false;
1032
+ }
1033
+
1034
+ unload();
1035
+ return load(filename, prefault, error);
1036
+ }
1037
+ }
1038
+
1039
+ void reinitialize() {
1040
+ _fd = 0;
1041
+ _nodes = NULL;
1042
+ _loaded = false;
1043
+ _n_items = 0;
1044
+ _n_nodes = 0;
1045
+ _nodes_size = 0;
1046
+ _on_disk = false;
1047
+ _seed = Random::default_seed;
1048
+ _roots.clear();
1049
+ }
1050
+
1051
+ void unload() {
1052
+ if (_on_disk && _fd) {
1053
+ close(_fd);
1054
+ munmap(_nodes, _s * _nodes_size);
1055
+ } else {
1056
+ if (_fd) {
1057
+ // we have mmapped data
1058
+ close(_fd);
1059
+ munmap(_nodes, _n_nodes * _s);
1060
+ } else if (_nodes) {
1061
+ // We have heap allocated data
1062
+ free(_nodes);
1063
+ }
1064
+ }
1065
+ reinitialize();
1066
+ if (_verbose) annoylib_showUpdate("unloaded\n");
1067
+ }
1068
+
1069
+ bool load(const char* filename, bool prefault=false, char** error=NULL) {
1070
+ _fd = open(filename, O_RDONLY, (int)0400);
1071
+ if (_fd == -1) {
1072
+ set_error_from_errno(error, "Unable to open");
1073
+ _fd = 0;
1074
+ return false;
1075
+ }
1076
+ off_t size = lseek_getsize(_fd);
1077
+ if (size == -1) {
1078
+ set_error_from_errno(error, "Unable to get size");
1079
+ return false;
1080
+ } else if (size == 0) {
1081
+ set_error_from_errno(error, "Size of file is zero");
1082
+ return false;
1083
+ } else if (size % _s) {
1084
+ // Something is fishy with this index!
1085
+ set_error_from_errno(error, "Index size is not a multiple of vector size. Ensure you are opening using the same metric you used to create the index.");
1086
+ return false;
1087
+ }
1088
+
1089
+ int flags = MAP_SHARED;
1090
+ if (prefault) {
1091
+ #ifdef MAP_POPULATE
1092
+ flags |= MAP_POPULATE;
1093
+ #else
1094
+ annoylib_showUpdate("prefault is set to true, but MAP_POPULATE is not defined on this platform");
1095
+ #endif
1096
+ }
1097
+ _nodes = (Node*)mmap(0, size, PROT_READ, flags, _fd, 0);
1098
+ _n_nodes = (S)(size / _s);
1099
+
1100
+ // Find the roots by scanning the end of the file and taking the nodes with most descendants
1101
+ _roots.clear();
1102
+ S m = -1;
1103
+ for (S i = _n_nodes - 1; i >= 0; i--) {
1104
+ S k = _get(i)->n_descendants;
1105
+ if (m == -1 || k == m) {
1106
+ _roots.push_back(i);
1107
+ m = k;
1108
+ } else {
1109
+ break;
1110
+ }
1111
+ }
1112
+ // hacky fix: since the last root precedes the copy of all roots, delete it
1113
+ if (_roots.size() > 1 && _get(_roots.front())->children[0] == _get(_roots.back())->children[0])
1114
+ _roots.pop_back();
1115
+ _loaded = true;
1116
+ _built = true;
1117
+ _n_items = m;
1118
+ if (_verbose) annoylib_showUpdate("found %lu roots with degree %d\n", _roots.size(), m);
1119
+ return true;
1120
+ }
1121
+
1122
+ T get_distance(S i, S j) const {
1123
+ return D::normalized_distance(D::distance(_get(i), _get(j), _f));
1124
+ }
1125
+
1126
+ void get_nns_by_item(S item, size_t n, int search_k, vector<S>* result, vector<T>* distances) const {
1127
+ // TODO: handle OOB
1128
+ const Node* m = _get(item);
1129
+ _get_all_nns(m->v, n, search_k, result, distances);
1130
+ }
1131
+
1132
+ void get_nns_by_vector(const T* w, size_t n, int search_k, vector<S>* result, vector<T>* distances) const {
1133
+ _get_all_nns(w, n, search_k, result, distances);
1134
+ }
1135
+
1136
+ S get_n_items() const {
1137
+ return _n_items;
1138
+ }
1139
+
1140
+ S get_n_trees() const {
1141
+ return (S)_roots.size();
1142
+ }
1143
+
1144
+ void verbose(bool v) {
1145
+ _verbose = v;
1146
+ }
1147
+
1148
+ void get_item(S item, T* v) const {
1149
+ // TODO: handle OOB
1150
+ Node* m = _get(item);
1151
+ memcpy(v, m->v, (_f) * sizeof(T));
1152
+ }
1153
+
1154
+ void set_seed(R seed) {
1155
+ _seed = seed;
1156
+ }
1157
+
1158
+ void thread_build(int q, int thread_idx, ThreadedBuildPolicy& threaded_build_policy) {
1159
+ // Each thread needs its own seed, otherwise each thread would be building the same tree(s)
1160
+ Random _random(_seed + thread_idx);
1161
+
1162
+ vector<S> thread_roots;
1163
+ while (1) {
1164
+ if (q == -1) {
1165
+ threaded_build_policy.lock_n_nodes();
1166
+ if (_n_nodes >= 2 * _n_items) {
1167
+ threaded_build_policy.unlock_n_nodes();
1168
+ break;
1169
+ }
1170
+ threaded_build_policy.unlock_n_nodes();
1171
+ } else {
1172
+ if (thread_roots.size() >= (size_t)q) {
1173
+ break;
1174
+ }
1175
+ }
1176
+
1177
+ if (_verbose) annoylib_showUpdate("pass %zd...\n", thread_roots.size());
1178
+
1179
+ vector<S> indices;
1180
+ threaded_build_policy.lock_shared_nodes();
1181
+ for (S i = 0; i < _n_items; i++) {
1182
+ if (_get(i)->n_descendants >= 1) { // Issue #223
1183
+ indices.push_back(i);
1184
+ }
1185
+ }
1186
+ threaded_build_policy.unlock_shared_nodes();
1187
+
1188
+ thread_roots.push_back(_make_tree(indices, true, _random, threaded_build_policy));
1189
+ }
1190
+
1191
+ threaded_build_policy.lock_roots();
1192
+ _roots.insert(_roots.end(), thread_roots.begin(), thread_roots.end());
1193
+ threaded_build_policy.unlock_roots();
1194
+ }
1195
+
1196
+ protected:
1197
+ void _reallocate_nodes(S n) {
1198
+ const double reallocation_factor = 1.3;
1199
+ S new_nodes_size = std::max(n, (S) ((_nodes_size + 1) * reallocation_factor));
1200
+ void *old = _nodes;
1201
+
1202
+ if (_on_disk) {
1203
+ if (!remap_memory_and_truncate(&_nodes, _fd,
1204
+ static_cast<size_t>(_s) * static_cast<size_t>(_nodes_size),
1205
+ static_cast<size_t>(_s) * static_cast<size_t>(new_nodes_size)) &&
1206
+ _verbose)
1207
+ annoylib_showUpdate("File truncation error\n");
1208
+ } else {
1209
+ _nodes = realloc(_nodes, _s * new_nodes_size);
1210
+ memset((char *) _nodes + (_nodes_size * _s) / sizeof(char), 0, (new_nodes_size - _nodes_size) * _s);
1211
+ }
1212
+
1213
+ _nodes_size = new_nodes_size;
1214
+ if (_verbose) annoylib_showUpdate("Reallocating to %d nodes: old_address=%p, new_address=%p\n", new_nodes_size, old, _nodes);
1215
+ }
1216
+
1217
+ void _allocate_size(S n, ThreadedBuildPolicy& threaded_build_policy) {
1218
+ if (n > _nodes_size) {
1219
+ threaded_build_policy.lock_nodes();
1220
+ _reallocate_nodes(n);
1221
+ threaded_build_policy.unlock_nodes();
1222
+ }
1223
+ }
1224
+
1225
+ void _allocate_size(S n) {
1226
+ if (n > _nodes_size) {
1227
+ _reallocate_nodes(n);
1228
+ }
1229
+ }
1230
+
1231
+ Node* _get(const S i) const {
1232
+ return get_node_ptr<S, Node>(_nodes, _s, i);
1233
+ }
1234
+
1235
+ double _split_imbalance(const vector<S>& left_indices, const vector<S>& right_indices) {
1236
+ double ls = (float)left_indices.size();
1237
+ double rs = (float)right_indices.size();
1238
+ float f = ls / (ls + rs + 1e-9); // Avoid 0/0
1239
+ return std::max(f, 1-f);
1240
+ }
1241
+
1242
+ S _make_tree(const vector<S>& indices, bool is_root, Random& _random, ThreadedBuildPolicy& threaded_build_policy) {
1243
+ // The basic rule is that if we have <= _K items, then it's a leaf node, otherwise it's a split node.
1244
+ // There's some regrettable complications caused by the problem that root nodes have to be "special":
1245
+ // 1. We identify root nodes by the arguable logic that _n_items == n->n_descendants, regardless of how many descendants they actually have
1246
+ // 2. Root nodes with only 1 child need to be a "dummy" parent
1247
+ // 3. Due to the _n_items "hack", we need to be careful with the cases where _n_items <= _K or _n_items > _K
1248
+ if (indices.size() == 1 && !is_root)
1249
+ return indices[0];
1250
+
1251
+ if (indices.size() <= (size_t)_K && (!is_root || (size_t)_n_items <= (size_t)_K || indices.size() == 1)) {
1252
+ threaded_build_policy.lock_n_nodes();
1253
+ _allocate_size(_n_nodes + 1, threaded_build_policy);
1254
+ S item = _n_nodes++;
1255
+ threaded_build_policy.unlock_n_nodes();
1256
+
1257
+ threaded_build_policy.lock_shared_nodes();
1258
+ Node* m = _get(item);
1259
+ m->n_descendants = is_root ? _n_items : (S)indices.size();
1260
+
1261
+ // Using std::copy instead of a loop seems to resolve issues #3 and #13,
1262
+ // probably because gcc 4.8 goes overboard with optimizations.
1263
+ // Using memcpy instead of std::copy for MSVC compatibility. #235
1264
+ // Only copy when necessary to avoid crash in MSVC 9. #293
1265
+ if (!indices.empty())
1266
+ memcpy(m->children, &indices[0], indices.size() * sizeof(S));
1267
+
1268
+ threaded_build_policy.unlock_shared_nodes();
1269
+ return item;
1270
+ }
1271
+
1272
+ threaded_build_policy.lock_shared_nodes();
1273
+ vector<Node*> children;
1274
+ for (size_t i = 0; i < indices.size(); i++) {
1275
+ S j = indices[i];
1276
+ Node* n = _get(j);
1277
+ if (n)
1278
+ children.push_back(n);
1279
+ }
1280
+
1281
+ vector<S> children_indices[2];
1282
+ Node* m = (Node*)alloca(_s);
1283
+
1284
+ for (int attempt = 0; attempt < 3; attempt++) {
1285
+ children_indices[0].clear();
1286
+ children_indices[1].clear();
1287
+ D::create_split(children, _f, _s, _random, m);
1288
+
1289
+ for (size_t i = 0; i < indices.size(); i++) {
1290
+ S j = indices[i];
1291
+ Node* n = _get(j);
1292
+ if (n) {
1293
+ bool side = D::side(m, n->v, _f, _random);
1294
+ children_indices[side].push_back(j);
1295
+ } else {
1296
+ annoylib_showUpdate("No node for index %d?\n", j);
1297
+ }
1298
+ }
1299
+
1300
+ if (_split_imbalance(children_indices[0], children_indices[1]) < 0.95)
1301
+ break;
1302
+ }
1303
+ threaded_build_policy.unlock_shared_nodes();
1304
+
1305
+ // If we didn't find a hyperplane, just randomize sides as a last option
1306
+ while (_split_imbalance(children_indices[0], children_indices[1]) > 0.99) {
1307
+ if (_verbose)
1308
+ annoylib_showUpdate("\tNo hyperplane found (left has %ld children, right has %ld children)\n",
1309
+ children_indices[0].size(), children_indices[1].size());
1310
+
1311
+ children_indices[0].clear();
1312
+ children_indices[1].clear();
1313
+
1314
+ // Set the vector to 0.0
1315
+ for (int z = 0; z < _f; z++)
1316
+ m->v[z] = 0;
1317
+
1318
+ for (size_t i = 0; i < indices.size(); i++) {
1319
+ S j = indices[i];
1320
+ // Just randomize...
1321
+ children_indices[_random.flip()].push_back(j);
1322
+ }
1323
+ }
1324
+
1325
+ int flip = (children_indices[0].size() > children_indices[1].size());
1326
+
1327
+ m->n_descendants = is_root ? _n_items : (S)indices.size();
1328
+ for (int side = 0; side < 2; side++) {
1329
+ // run _make_tree for the smallest child first (for cache locality)
1330
+ m->children[side^flip] = _make_tree(children_indices[side^flip], false, _random, threaded_build_policy);
1331
+ }
1332
+
1333
+ threaded_build_policy.lock_n_nodes();
1334
+ _allocate_size(_n_nodes + 1, threaded_build_policy);
1335
+ S item = _n_nodes++;
1336
+ threaded_build_policy.unlock_n_nodes();
1337
+
1338
+ threaded_build_policy.lock_shared_nodes();
1339
+ memcpy(_get(item), m, _s);
1340
+ threaded_build_policy.unlock_shared_nodes();
1341
+
1342
+ return item;
1343
+ }
1344
+
1345
+ void _get_all_nns(const T* v, size_t n, int search_k, vector<S>* result, vector<T>* distances) const {
1346
+ Node* v_node = (Node *)alloca(_s);
1347
+ D::template zero_value<Node>(v_node);
1348
+ memcpy(v_node->v, v, sizeof(T) * _f);
1349
+ D::init_node(v_node, _f);
1350
+
1351
+ std::priority_queue<pair<T, S> > q;
1352
+
1353
+ if (search_k == -1) {
1354
+ search_k = n * _roots.size();
1355
+ }
1356
+
1357
+ for (size_t i = 0; i < _roots.size(); i++) {
1358
+ q.push(make_pair(Distance::template pq_initial_value<T>(), _roots[i]));
1359
+ }
1360
+
1361
+ std::vector<S> nns;
1362
+ while (nns.size() < (size_t)search_k && !q.empty()) {
1363
+ const pair<T, S>& top = q.top();
1364
+ T d = top.first;
1365
+ S i = top.second;
1366
+ Node* nd = _get(i);
1367
+ q.pop();
1368
+ if (nd->n_descendants == 1 && i < _n_items) {
1369
+ nns.push_back(i);
1370
+ } else if (nd->n_descendants <= _K) {
1371
+ const S* dst = nd->children;
1372
+ nns.insert(nns.end(), dst, &dst[nd->n_descendants]);
1373
+ } else {
1374
+ T margin = D::margin(nd, v, _f);
1375
+ q.push(make_pair(D::pq_distance(d, margin, 1), static_cast<S>(nd->children[1])));
1376
+ q.push(make_pair(D::pq_distance(d, margin, 0), static_cast<S>(nd->children[0])));
1377
+ }
1378
+ }
1379
+
1380
+ // Get distances for all items
1381
+ // To avoid calculating distance multiple times for any items, sort by id
1382
+ std::sort(nns.begin(), nns.end());
1383
+ vector<pair<T, S> > nns_dist;
1384
+ S last = -1;
1385
+ for (size_t i = 0; i < nns.size(); i++) {
1386
+ S j = nns[i];
1387
+ if (j == last)
1388
+ continue;
1389
+ last = j;
1390
+ if (_get(j)->n_descendants == 1) // This is only to guard a really obscure case, #284
1391
+ nns_dist.push_back(make_pair(D::distance(v_node, _get(j), _f), j));
1392
+ }
1393
+
1394
+ size_t m = nns_dist.size();
1395
+ size_t p = n < m ? n : m; // Return this many items
1396
+ std::partial_sort(nns_dist.begin(), nns_dist.begin() + p, nns_dist.end());
1397
+ for (size_t i = 0; i < p; i++) {
1398
+ if (distances)
1399
+ distances->push_back(D::normalized_distance(nns_dist[i].first));
1400
+ result->push_back(nns_dist[i].second);
1401
+ }
1402
+ }
1403
+ };
1404
+
1405
+ class AnnoyIndexSingleThreadedBuildPolicy {
1406
+ public:
1407
+ template<typename S, typename T, typename D, typename Random>
1408
+ static void build(AnnoyIndex<S, T, D, Random, AnnoyIndexSingleThreadedBuildPolicy>* annoy, int q, int n_threads) {
1409
+ AnnoyIndexSingleThreadedBuildPolicy threaded_build_policy;
1410
+ annoy->thread_build(q, 0, threaded_build_policy);
1411
+ }
1412
+
1413
+ void lock_n_nodes() {}
1414
+ void unlock_n_nodes() {}
1415
+
1416
+ void lock_nodes() {}
1417
+ void unlock_nodes() {}
1418
+
1419
+ void lock_shared_nodes() {}
1420
+ void unlock_shared_nodes() {}
1421
+
1422
+ void lock_roots() {}
1423
+ void unlock_roots() {}
1424
+ };
1425
+
1426
+ #ifdef ANNOYLIB_MULTITHREADED_BUILD
1427
+ class AnnoyIndexMultiThreadedBuildPolicy {
1428
+ private:
1429
+ std::shared_timed_mutex nodes_mutex;
1430
+ std::mutex n_nodes_mutex;
1431
+ std::mutex roots_mutex;
1432
+
1433
+ public:
1434
+ template<typename S, typename T, typename D, typename Random>
1435
+ static void build(AnnoyIndex<S, T, D, Random, AnnoyIndexMultiThreadedBuildPolicy>* annoy, int q, int n_threads) {
1436
+ AnnoyIndexMultiThreadedBuildPolicy threaded_build_policy;
1437
+ if (n_threads == -1) {
1438
+ // If the hardware_concurrency() value is not well defined or not computable, it returns 0.
1439
+ // We guard against this by using at least 1 thread.
1440
+ n_threads = std::max(1, (int)std::thread::hardware_concurrency());
1441
+ }
1442
+
1443
+ vector<std::thread> threads(n_threads);
1444
+
1445
+ for (int thread_idx = 0; thread_idx < n_threads; thread_idx++) {
1446
+ int trees_per_thread = q == -1 ? -1 : (int)floor((q + thread_idx) / n_threads);
1447
+
1448
+ threads[thread_idx] = std::thread(
1449
+ &AnnoyIndex<S, T, D, Random, AnnoyIndexMultiThreadedBuildPolicy>::thread_build,
1450
+ annoy,
1451
+ trees_per_thread,
1452
+ thread_idx,
1453
+ std::ref(threaded_build_policy)
1454
+ );
1455
+ }
1456
+
1457
+ for (auto& thread : threads) {
1458
+ thread.join();
1459
+ }
1460
+ }
1461
+
1462
+ void lock_n_nodes() {
1463
+ n_nodes_mutex.lock();
1464
+ }
1465
+ void unlock_n_nodes() {
1466
+ n_nodes_mutex.unlock();
1467
+ }
1468
+
1469
+ void lock_nodes() {
1470
+ nodes_mutex.lock();
1471
+ }
1472
+ void unlock_nodes() {
1473
+ nodes_mutex.unlock();
1474
+ }
1475
+
1476
+ void lock_shared_nodes() {
1477
+ nodes_mutex.lock_shared();
1478
+ }
1479
+ void unlock_shared_nodes() {
1480
+ nodes_mutex.unlock_shared();
1481
+ }
1482
+
1483
+ void lock_roots() {
1484
+ roots_mutex.lock();
1485
+ }
1486
+ void unlock_roots() {
1487
+ roots_mutex.unlock();
1488
+ }
1489
+ };
1490
+ #endif
1491
+
1492
+ }
1493
+
1494
+ #endif
1495
+ // vim: tabstop=2 shiftwidth=2