usearch 2.21.4 → 2.25.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (604) hide show
  1. package/README.md +65 -69
  2. package/binding.gyp +15 -37
  3. package/c/CMakeLists.txt +4 -5
  4. package/c/README.md +8 -8
  5. package/c/lib.cpp +32 -14
  6. package/c/test.c +124 -1
  7. package/c/usearch.h +24 -3
  8. package/cpp/CMakeLists.txt +4 -0
  9. package/cpp/README.md +5 -5
  10. package/cpp/bench.cpp +97 -116
  11. package/cpp/test.cpp +117 -20
  12. package/include/usearch/index.hpp +224 -48
  13. package/include/usearch/index_dense.hpp +105 -40
  14. package/include/usearch/index_plugins.hpp +1387 -204
  15. package/javascript/README.md +1 -1
  16. package/javascript/dist/cjs/usearch.d.ts +8 -3
  17. package/javascript/dist/cjs/usearch.js +12 -4
  18. package/javascript/dist/esm/usearch.d.ts +8 -3
  19. package/javascript/dist/esm/usearch.js +12 -4
  20. package/javascript/lib.cpp +17 -0
  21. package/javascript/usearch.test.js +117 -94
  22. package/javascript/usearch.ts +14 -6
  23. package/numkong/.clang-tidy +30 -0
  24. package/{simsimd → numkong}/.cmake-format.py +18 -0
  25. package/numkong/.editorconfig +12 -0
  26. package/numkong/.git-blame-ignore-revs +123 -0
  27. package/numkong/.mailmap +15 -0
  28. package/numkong/.spi.yml +11 -0
  29. package/numkong/.swift-format +14 -0
  30. package/numkong/CITATION.cff +81 -0
  31. package/numkong/CONTRIBUTING.md +500 -0
  32. package/numkong/Cargo.toml +54 -0
  33. package/numkong/MANIFEST.in +8 -0
  34. package/numkong/Package.swift +84 -0
  35. package/numkong/README.md +569 -0
  36. package/numkong/bench/README.md +217 -0
  37. package/numkong/bench/bench-browser.html +323 -0
  38. package/numkong/bench/bench.cpp +344 -0
  39. package/numkong/bench/bench.hpp +816 -0
  40. package/numkong/bench/bench.js +148 -0
  41. package/numkong/bench/bench.mjs +616 -0
  42. package/numkong/bench/bench_attention.cpp +113 -0
  43. package/numkong/bench/bench_cast.cpp +264 -0
  44. package/numkong/bench/bench_cross_amx.cpp +62 -0
  45. package/numkong/bench/bench_cross_arm.cpp +245 -0
  46. package/numkong/bench/bench_cross_blas.cpp +309 -0
  47. package/numkong/bench/bench_cross_loongarch.cpp +106 -0
  48. package/numkong/bench/bench_cross_power.cpp +84 -0
  49. package/numkong/bench/bench_cross_rvv.cpp +121 -0
  50. package/numkong/bench/bench_cross_serial.cpp +151 -0
  51. package/numkong/bench/bench_cross_sme.cpp +163 -0
  52. package/numkong/bench/bench_cross_wasm.cpp +142 -0
  53. package/numkong/bench/bench_cross_x86.cpp +455 -0
  54. package/numkong/bench/bench_curved.cpp +210 -0
  55. package/numkong/bench/bench_dot.cpp +315 -0
  56. package/numkong/bench/bench_each.cpp +503 -0
  57. package/numkong/bench/bench_geospatial.cpp +112 -0
  58. package/numkong/bench/bench_maxsim.cpp +154 -0
  59. package/numkong/bench/bench_mesh.cpp +148 -0
  60. package/numkong/bench/bench_probability.cpp +60 -0
  61. package/numkong/bench/bench_reduce.cpp +371 -0
  62. package/numkong/bench/bench_set.cpp +73 -0
  63. package/numkong/bench/bench_sparse.cpp +198 -0
  64. package/numkong/bench/bench_spatial.cpp +347 -0
  65. package/numkong/bench/bench_trigonometry.cpp +137 -0
  66. package/numkong/bench/swift/Bench.swift +506 -0
  67. package/numkong/binding.gyp +169 -0
  68. package/numkong/build.rs +484 -0
  69. package/numkong/c/dispatch.h +512 -0
  70. package/numkong/c/dispatch_bf16.c +447 -0
  71. package/numkong/c/dispatch_bf16c.c +52 -0
  72. package/numkong/c/dispatch_e2m3.c +296 -0
  73. package/numkong/c/dispatch_e3m2.c +284 -0
  74. package/numkong/c/dispatch_e4m3.c +318 -0
  75. package/numkong/c/dispatch_e5m2.c +316 -0
  76. package/numkong/c/dispatch_f16.c +452 -0
  77. package/numkong/c/dispatch_f16c.c +58 -0
  78. package/numkong/c/dispatch_f32.c +434 -0
  79. package/numkong/c/dispatch_f32c.c +99 -0
  80. package/numkong/c/dispatch_f64.c +348 -0
  81. package/numkong/c/dispatch_f64c.c +98 -0
  82. package/numkong/c/dispatch_i16.c +96 -0
  83. package/numkong/c/dispatch_i32.c +89 -0
  84. package/numkong/c/dispatch_i4.c +153 -0
  85. package/numkong/c/dispatch_i64.c +86 -0
  86. package/numkong/c/dispatch_i8.c +348 -0
  87. package/numkong/c/dispatch_other.c +348 -0
  88. package/numkong/c/dispatch_u1.c +193 -0
  89. package/numkong/c/dispatch_u16.c +124 -0
  90. package/numkong/c/dispatch_u32.c +118 -0
  91. package/numkong/c/dispatch_u4.c +153 -0
  92. package/numkong/c/dispatch_u64.c +102 -0
  93. package/numkong/c/dispatch_u8.c +364 -0
  94. package/numkong/c/numkong.c +940 -0
  95. package/numkong/cmake/nk_arm_isa_probes.cmake +61 -0
  96. package/numkong/cmake/nk_isa_probe.cmake +90 -0
  97. package/numkong/cmake/nk_loongarch_isa_probes.cmake +15 -0
  98. package/numkong/cmake/nk_math_lib.cmake +46 -0
  99. package/numkong/cmake/nk_power_isa_probes.cmake +15 -0
  100. package/numkong/cmake/nk_riscv_isa_probes.cmake +19 -0
  101. package/numkong/cmake/nk_x86_isa_probes.cmake +35 -0
  102. package/numkong/cmake/toolchain-aarch64-gnu.cmake +86 -0
  103. package/numkong/cmake/toolchain-android-arm64.cmake +25 -0
  104. package/numkong/cmake/toolchain-android-armv7.cmake +25 -0
  105. package/numkong/cmake/toolchain-loongarch64-gnu.cmake +68 -0
  106. package/numkong/cmake/toolchain-ppc64le-gnu.cmake +74 -0
  107. package/numkong/cmake/toolchain-riscv64-gnu.cmake +107 -0
  108. package/numkong/cmake/toolchain-riscv64-llvm.cmake +114 -0
  109. package/numkong/cmake/toolchain-wasi.cmake +77 -0
  110. package/numkong/cmake/toolchain-wasm.cmake +70 -0
  111. package/numkong/cmake/toolchain-wasm64.cmake +62 -0
  112. package/numkong/cmake/toolchain-x86_64-llvm.cmake +47 -0
  113. package/numkong/include/README.md +643 -0
  114. package/numkong/include/module.modulemap +129 -0
  115. package/numkong/include/numkong/attention/sapphireamx.h +1363 -0
  116. package/numkong/include/numkong/attention/sme.h +2075 -0
  117. package/numkong/include/numkong/attention.h +49 -0
  118. package/numkong/include/numkong/capabilities.h +930 -0
  119. package/numkong/include/numkong/cast/README.md +262 -0
  120. package/numkong/include/numkong/cast/diamond.h +64 -0
  121. package/numkong/include/numkong/cast/haswell.h +823 -0
  122. package/numkong/include/numkong/cast/icelake.h +475 -0
  123. package/numkong/include/numkong/cast/loongsonasx.h +252 -0
  124. package/numkong/include/numkong/cast/neon.h +1174 -0
  125. package/numkong/include/numkong/cast/powervsx.h +449 -0
  126. package/numkong/include/numkong/cast/rvv.h +970 -0
  127. package/numkong/include/numkong/cast/sapphire.h +262 -0
  128. package/numkong/include/numkong/cast/serial.h +2336 -0
  129. package/numkong/include/numkong/cast/skylake.h +915 -0
  130. package/numkong/include/numkong/cast/v128relaxed.h +537 -0
  131. package/numkong/include/numkong/cast.h +254 -0
  132. package/numkong/include/numkong/cast.hpp +44 -0
  133. package/numkong/include/numkong/curved/README.md +223 -0
  134. package/numkong/include/numkong/curved/genoa.h +182 -0
  135. package/numkong/include/numkong/curved/haswell.h +276 -0
  136. package/numkong/include/numkong/curved/neon.h +329 -0
  137. package/numkong/include/numkong/curved/neonbfdot.h +211 -0
  138. package/numkong/include/numkong/curved/rvv.h +305 -0
  139. package/numkong/include/numkong/curved/serial.h +207 -0
  140. package/numkong/include/numkong/curved/skylake.h +457 -0
  141. package/numkong/include/numkong/curved/smef64.h +530 -0
  142. package/numkong/include/numkong/curved.h +513 -0
  143. package/numkong/include/numkong/curved.hpp +144 -0
  144. package/numkong/include/numkong/dot/README.md +442 -0
  145. package/numkong/include/numkong/dot/alder.h +563 -0
  146. package/numkong/include/numkong/dot/diamond.h +158 -0
  147. package/numkong/include/numkong/dot/genoa.h +289 -0
  148. package/numkong/include/numkong/dot/haswell.h +1723 -0
  149. package/numkong/include/numkong/dot/icelake.h +997 -0
  150. package/numkong/include/numkong/dot/loongsonasx.h +671 -0
  151. package/numkong/include/numkong/dot/neon.h +869 -0
  152. package/numkong/include/numkong/dot/neonbfdot.h +243 -0
  153. package/numkong/include/numkong/dot/neonfhm.h +358 -0
  154. package/numkong/include/numkong/dot/neonfp8.h +323 -0
  155. package/numkong/include/numkong/dot/neonsdot.h +622 -0
  156. package/numkong/include/numkong/dot/powervsx.h +752 -0
  157. package/numkong/include/numkong/dot/rvv.h +722 -0
  158. package/numkong/include/numkong/dot/rvvbb.h +72 -0
  159. package/numkong/include/numkong/dot/rvvbf16.h +123 -0
  160. package/numkong/include/numkong/dot/rvvhalf.h +129 -0
  161. package/numkong/include/numkong/dot/sapphire.h +141 -0
  162. package/numkong/include/numkong/dot/serial.h +874 -0
  163. package/numkong/include/numkong/dot/sierra.h +405 -0
  164. package/numkong/include/numkong/dot/skylake.h +1116 -0
  165. package/numkong/include/numkong/dot/sve.h +420 -0
  166. package/numkong/include/numkong/dot/svebfdot.h +75 -0
  167. package/numkong/include/numkong/dot/svehalf.h +168 -0
  168. package/numkong/include/numkong/dot/svesdot.h +90 -0
  169. package/numkong/include/numkong/dot/v128relaxed.h +1293 -0
  170. package/numkong/include/numkong/dot.h +1136 -0
  171. package/numkong/include/numkong/dot.hpp +94 -0
  172. package/numkong/include/numkong/dots/README.md +496 -0
  173. package/numkong/include/numkong/dots/alder.h +117 -0
  174. package/numkong/include/numkong/dots/diamond.h +86 -0
  175. package/numkong/include/numkong/dots/genoa.h +100 -0
  176. package/numkong/include/numkong/dots/graniteamx.h +733 -0
  177. package/numkong/include/numkong/dots/haswell.h +310 -0
  178. package/numkong/include/numkong/dots/icelake.h +180 -0
  179. package/numkong/include/numkong/dots/loongsonasx.h +176 -0
  180. package/numkong/include/numkong/dots/neon.h +123 -0
  181. package/numkong/include/numkong/dots/neonbfdot.h +59 -0
  182. package/numkong/include/numkong/dots/neonfhm.h +96 -0
  183. package/numkong/include/numkong/dots/neonfp8.h +99 -0
  184. package/numkong/include/numkong/dots/neonsdot.h +144 -0
  185. package/numkong/include/numkong/dots/powervsx.h +194 -0
  186. package/numkong/include/numkong/dots/rvv.h +2593 -0
  187. package/numkong/include/numkong/dots/sapphireamx.h +4017 -0
  188. package/numkong/include/numkong/dots/serial.h +2867 -0
  189. package/numkong/include/numkong/dots/sierra.h +100 -0
  190. package/numkong/include/numkong/dots/skylake.h +207 -0
  191. package/numkong/include/numkong/dots/sme.h +5041 -0
  192. package/numkong/include/numkong/dots/smebi32.h +477 -0
  193. package/numkong/include/numkong/dots/smef64.h +1328 -0
  194. package/numkong/include/numkong/dots/smehalf.h +47 -0
  195. package/numkong/include/numkong/dots/v128relaxed.h +317 -0
  196. package/numkong/include/numkong/dots.h +3110 -0
  197. package/numkong/include/numkong/dots.hpp +641 -0
  198. package/numkong/include/numkong/each/README.md +465 -0
  199. package/numkong/include/numkong/each/haswell.h +1658 -0
  200. package/numkong/include/numkong/each/icelake.h +272 -0
  201. package/numkong/include/numkong/each/neon.h +1138 -0
  202. package/numkong/include/numkong/each/neonbfdot.h +211 -0
  203. package/numkong/include/numkong/each/neonhalf.h +318 -0
  204. package/numkong/include/numkong/each/rvv.h +1121 -0
  205. package/numkong/include/numkong/each/sapphire.h +343 -0
  206. package/numkong/include/numkong/each/serial.h +282 -0
  207. package/numkong/include/numkong/each/skylake.h +1562 -0
  208. package/numkong/include/numkong/each/v128relaxed.h +562 -0
  209. package/numkong/include/numkong/each.h +2232 -0
  210. package/numkong/include/numkong/each.hpp +434 -0
  211. package/numkong/include/numkong/geospatial/README.md +147 -0
  212. package/numkong/include/numkong/geospatial/haswell.h +633 -0
  213. package/numkong/include/numkong/geospatial/neon.h +615 -0
  214. package/numkong/include/numkong/geospatial/rvv.h +701 -0
  215. package/numkong/include/numkong/geospatial/serial.h +309 -0
  216. package/numkong/include/numkong/geospatial/skylake.h +613 -0
  217. package/numkong/include/numkong/geospatial/v128relaxed.h +652 -0
  218. package/numkong/include/numkong/geospatial.h +453 -0
  219. package/numkong/include/numkong/geospatial.hpp +235 -0
  220. package/numkong/include/numkong/matrix.hpp +336 -0
  221. package/numkong/include/numkong/maxsim/README.md +187 -0
  222. package/numkong/include/numkong/maxsim/alder.h +511 -0
  223. package/numkong/include/numkong/maxsim/genoa.h +115 -0
  224. package/numkong/include/numkong/maxsim/haswell.h +553 -0
  225. package/numkong/include/numkong/maxsim/icelake.h +480 -0
  226. package/numkong/include/numkong/maxsim/neonsdot.h +394 -0
  227. package/numkong/include/numkong/maxsim/sapphireamx.h +877 -0
  228. package/numkong/include/numkong/maxsim/serial.h +490 -0
  229. package/numkong/include/numkong/maxsim/sme.h +993 -0
  230. package/numkong/include/numkong/maxsim/v128relaxed.h +280 -0
  231. package/numkong/include/numkong/maxsim.h +571 -0
  232. package/numkong/include/numkong/maxsim.hpp +133 -0
  233. package/numkong/include/numkong/mesh/README.md +219 -0
  234. package/numkong/include/numkong/mesh/haswell.h +2013 -0
  235. package/numkong/include/numkong/mesh/neon.h +1821 -0
  236. package/numkong/include/numkong/mesh/neonbfdot.h +771 -0
  237. package/numkong/include/numkong/mesh/rvv.h +936 -0
  238. package/numkong/include/numkong/mesh/serial.h +721 -0
  239. package/numkong/include/numkong/mesh/skylake.h +2344 -0
  240. package/numkong/include/numkong/mesh/v128relaxed.h +1081 -0
  241. package/numkong/include/numkong/mesh.h +666 -0
  242. package/numkong/include/numkong/mesh.hpp +701 -0
  243. package/numkong/include/numkong/numkong.h +78 -0
  244. package/numkong/include/numkong/numkong.hpp +58 -0
  245. package/numkong/include/numkong/probability/README.md +177 -0
  246. package/numkong/include/numkong/probability/haswell.h +267 -0
  247. package/numkong/include/numkong/probability/neon.h +255 -0
  248. package/numkong/include/numkong/probability/rvv.h +414 -0
  249. package/numkong/include/numkong/probability/serial.h +181 -0
  250. package/numkong/include/numkong/probability/skylake.h +324 -0
  251. package/numkong/include/numkong/probability.h +380 -0
  252. package/numkong/include/numkong/probability.hpp +120 -0
  253. package/numkong/include/numkong/random.h +50 -0
  254. package/numkong/include/numkong/random.hpp +285 -0
  255. package/numkong/include/numkong/reduce/README.md +552 -0
  256. package/numkong/include/numkong/reduce/alder.h +636 -0
  257. package/numkong/include/numkong/reduce/genoa.h +201 -0
  258. package/numkong/include/numkong/reduce/haswell.h +3785 -0
  259. package/numkong/include/numkong/reduce/icelake.h +549 -0
  260. package/numkong/include/numkong/reduce/neon.h +3980 -0
  261. package/numkong/include/numkong/reduce/neonbfdot.h +142 -0
  262. package/numkong/include/numkong/reduce/neonfhm.h +293 -0
  263. package/numkong/include/numkong/reduce/neonsdot.h +357 -0
  264. package/numkong/include/numkong/reduce/rvv.h +3533 -0
  265. package/numkong/include/numkong/reduce/serial.h +753 -0
  266. package/numkong/include/numkong/reduce/sierra.h +338 -0
  267. package/numkong/include/numkong/reduce/skylake.h +3794 -0
  268. package/numkong/include/numkong/reduce/sve.h +52 -0
  269. package/numkong/include/numkong/reduce/v128relaxed.h +2302 -0
  270. package/numkong/include/numkong/reduce.h +1582 -0
  271. package/numkong/include/numkong/reduce.hpp +778 -0
  272. package/numkong/include/numkong/scalar/README.md +89 -0
  273. package/numkong/include/numkong/scalar/haswell.h +122 -0
  274. package/numkong/include/numkong/scalar/loongsonasx.h +74 -0
  275. package/numkong/include/numkong/scalar/neon.h +122 -0
  276. package/numkong/include/numkong/scalar/neonhalf.h +70 -0
  277. package/numkong/include/numkong/scalar/powervsx.h +96 -0
  278. package/numkong/include/numkong/scalar/rvv.h +211 -0
  279. package/numkong/include/numkong/scalar/sapphire.h +74 -0
  280. package/numkong/include/numkong/scalar/serial.h +332 -0
  281. package/numkong/include/numkong/scalar/v128relaxed.h +56 -0
  282. package/numkong/include/numkong/scalar.h +696 -0
  283. package/numkong/include/numkong/set/README.md +179 -0
  284. package/numkong/include/numkong/set/haswell.h +334 -0
  285. package/numkong/include/numkong/set/icelake.h +485 -0
  286. package/numkong/include/numkong/set/loongsonasx.h +181 -0
  287. package/numkong/include/numkong/set/neon.h +363 -0
  288. package/numkong/include/numkong/set/powervsx.h +326 -0
  289. package/numkong/include/numkong/set/rvv.h +226 -0
  290. package/numkong/include/numkong/set/rvvbb.h +117 -0
  291. package/numkong/include/numkong/set/serial.h +174 -0
  292. package/numkong/include/numkong/set/sve.h +187 -0
  293. package/numkong/include/numkong/set/v128relaxed.h +240 -0
  294. package/numkong/include/numkong/set.h +471 -0
  295. package/numkong/include/numkong/set.hpp +114 -0
  296. package/numkong/include/numkong/sets/README.md +149 -0
  297. package/numkong/include/numkong/sets/haswell.h +63 -0
  298. package/numkong/include/numkong/sets/icelake.h +66 -0
  299. package/numkong/include/numkong/sets/loongsonasx.h +52 -0
  300. package/numkong/include/numkong/sets/neon.h +61 -0
  301. package/numkong/include/numkong/sets/powervsx.h +65 -0
  302. package/numkong/include/numkong/sets/serial.h +43 -0
  303. package/numkong/include/numkong/sets/smebi32.h +1135 -0
  304. package/numkong/include/numkong/sets/v128relaxed.h +58 -0
  305. package/numkong/include/numkong/sets.h +382 -0
  306. package/numkong/include/numkong/sparse/README.md +156 -0
  307. package/numkong/include/numkong/sparse/icelake.h +463 -0
  308. package/numkong/include/numkong/sparse/neon.h +288 -0
  309. package/numkong/include/numkong/sparse/serial.h +117 -0
  310. package/numkong/include/numkong/sparse/sve2.h +504 -0
  311. package/numkong/include/numkong/sparse/turin.h +322 -0
  312. package/numkong/include/numkong/sparse.h +363 -0
  313. package/numkong/include/numkong/sparse.hpp +113 -0
  314. package/numkong/include/numkong/spatial/README.md +439 -0
  315. package/numkong/include/numkong/spatial/alder.h +604 -0
  316. package/numkong/include/numkong/spatial/diamond.h +240 -0
  317. package/numkong/include/numkong/spatial/genoa.h +222 -0
  318. package/numkong/include/numkong/spatial/haswell.h +979 -0
  319. package/numkong/include/numkong/spatial/icelake.h +1067 -0
  320. package/numkong/include/numkong/spatial/loongsonasx.h +483 -0
  321. package/numkong/include/numkong/spatial/neon.h +846 -0
  322. package/numkong/include/numkong/spatial/neonbfdot.h +164 -0
  323. package/numkong/include/numkong/spatial/neonfp8.h +258 -0
  324. package/numkong/include/numkong/spatial/neonsdot.h +429 -0
  325. package/numkong/include/numkong/spatial/powervsx.h +738 -0
  326. package/numkong/include/numkong/spatial/rvv.h +991 -0
  327. package/numkong/include/numkong/spatial/rvvbf16.h +128 -0
  328. package/numkong/include/numkong/spatial/rvvhalf.h +120 -0
  329. package/numkong/include/numkong/spatial/serial.h +347 -0
  330. package/numkong/include/numkong/spatial/sierra.h +516 -0
  331. package/numkong/include/numkong/spatial/skylake.h +605 -0
  332. package/numkong/include/numkong/spatial/sve.h +246 -0
  333. package/numkong/include/numkong/spatial/svebfdot.h +125 -0
  334. package/numkong/include/numkong/spatial/svehalf.h +136 -0
  335. package/numkong/include/numkong/spatial/svesdot.h +143 -0
  336. package/numkong/include/numkong/spatial/v128relaxed.h +969 -0
  337. package/numkong/include/numkong/spatial.h +1681 -0
  338. package/numkong/include/numkong/spatial.hpp +183 -0
  339. package/numkong/include/numkong/spatials/README.md +580 -0
  340. package/numkong/include/numkong/spatials/alder.h +94 -0
  341. package/numkong/include/numkong/spatials/diamond.h +82 -0
  342. package/numkong/include/numkong/spatials/genoa.h +94 -0
  343. package/numkong/include/numkong/spatials/graniteamx.h +173 -0
  344. package/numkong/include/numkong/spatials/haswell.h +219 -0
  345. package/numkong/include/numkong/spatials/icelake.h +113 -0
  346. package/numkong/include/numkong/spatials/loongsonasx.h +153 -0
  347. package/numkong/include/numkong/spatials/neon.h +109 -0
  348. package/numkong/include/numkong/spatials/neonbfdot.h +60 -0
  349. package/numkong/include/numkong/spatials/neonfhm.h +92 -0
  350. package/numkong/include/numkong/spatials/neonfp8.h +111 -0
  351. package/numkong/include/numkong/spatials/neonsdot.h +143 -0
  352. package/numkong/include/numkong/spatials/powervsx.h +153 -0
  353. package/numkong/include/numkong/spatials/rvv.h +1976 -0
  354. package/numkong/include/numkong/spatials/sapphireamx.h +1149 -0
  355. package/numkong/include/numkong/spatials/serial.h +248 -0
  356. package/numkong/include/numkong/spatials/sierra.h +96 -0
  357. package/numkong/include/numkong/spatials/skylake.h +184 -0
  358. package/numkong/include/numkong/spatials/sme.h +1927 -0
  359. package/numkong/include/numkong/spatials/smef64.h +483 -0
  360. package/numkong/include/numkong/spatials/v128relaxed.h +240 -0
  361. package/numkong/include/numkong/spatials.h +3374 -0
  362. package/numkong/include/numkong/spatials.hpp +509 -0
  363. package/numkong/include/numkong/tensor.hpp +1981 -0
  364. package/numkong/include/numkong/trigonometry/README.md +184 -0
  365. package/numkong/include/numkong/trigonometry/haswell.h +653 -0
  366. package/numkong/include/numkong/trigonometry/neon.h +638 -0
  367. package/numkong/include/numkong/trigonometry/rvv.h +700 -0
  368. package/numkong/include/numkong/trigonometry/serial.h +703 -0
  369. package/numkong/include/numkong/trigonometry/skylake.h +725 -0
  370. package/numkong/include/numkong/trigonometry/v128relaxed.h +667 -0
  371. package/numkong/include/numkong/trigonometry.h +467 -0
  372. package/numkong/include/numkong/trigonometry.hpp +166 -0
  373. package/numkong/include/numkong/types.h +1695 -0
  374. package/numkong/include/numkong/types.hpp +6027 -0
  375. package/numkong/include/numkong/vector.hpp +766 -0
  376. package/numkong/javascript/@numkong-darwin-arm64/package.json +26 -0
  377. package/numkong/javascript/@numkong-darwin-x64/package.json +26 -0
  378. package/numkong/javascript/@numkong-linux-arm64/package.json +25 -0
  379. package/numkong/javascript/@numkong-linux-x64/package.json +25 -0
  380. package/numkong/javascript/@numkong-win32-arm64/package.json +25 -0
  381. package/numkong/javascript/@numkong-win32-x64/package.json +25 -0
  382. package/numkong/javascript/README.md +254 -0
  383. package/numkong/javascript/node-gyp-build.d.ts +4 -0
  384. package/numkong/javascript/numkong-browser.ts +40 -0
  385. package/numkong/javascript/numkong-wasm.ts +750 -0
  386. package/numkong/javascript/numkong.c +712 -0
  387. package/numkong/javascript/numkong.ts +613 -0
  388. package/{simsimd → numkong}/javascript/tsconfig-base.json +6 -3
  389. package/numkong/javascript/tsconfig-cjs.json +13 -0
  390. package/{simsimd → numkong}/javascript/tsconfig-esm.json +1 -1
  391. package/numkong/javascript/types.ts +784 -0
  392. package/numkong/numkong.gypi +104 -0
  393. package/numkong/package.json +108 -0
  394. package/numkong/probes/arm_neon.c +8 -0
  395. package/numkong/probes/arm_neon_bfdot.c +9 -0
  396. package/numkong/probes/arm_neon_fhm.c +9 -0
  397. package/numkong/probes/arm_neon_half.c +8 -0
  398. package/numkong/probes/arm_neon_sdot.c +9 -0
  399. package/numkong/probes/arm_neonfp8.c +9 -0
  400. package/numkong/probes/arm_sme.c +16 -0
  401. package/numkong/probes/arm_sme2.c +16 -0
  402. package/numkong/probes/arm_sme2p1.c +16 -0
  403. package/numkong/probes/arm_sme_bf16.c +16 -0
  404. package/numkong/probes/arm_sme_bi32.c +16 -0
  405. package/numkong/probes/arm_sme_f64.c +16 -0
  406. package/numkong/probes/arm_sme_fa64.c +14 -0
  407. package/numkong/probes/arm_sme_half.c +16 -0
  408. package/numkong/probes/arm_sme_lut2.c +15 -0
  409. package/numkong/probes/arm_sve.c +18 -0
  410. package/numkong/probes/arm_sve2.c +20 -0
  411. package/numkong/probes/arm_sve2p1.c +18 -0
  412. package/numkong/probes/arm_sve_bfdot.c +20 -0
  413. package/numkong/probes/arm_sve_half.c +18 -0
  414. package/numkong/probes/arm_sve_sdot.c +21 -0
  415. package/numkong/probes/loongarch_lasx.c +12 -0
  416. package/numkong/probes/power_vsx.c +12 -0
  417. package/numkong/probes/probe.js +127 -0
  418. package/numkong/probes/riscv_rvv.c +14 -0
  419. package/numkong/probes/riscv_rvv_bb.c +15 -0
  420. package/numkong/probes/riscv_rvv_bf16.c +17 -0
  421. package/numkong/probes/riscv_rvv_half.c +14 -0
  422. package/numkong/probes/wasm_v128relaxed.c +11 -0
  423. package/numkong/probes/x86_alder.c +17 -0
  424. package/numkong/probes/x86_diamond.c +17 -0
  425. package/numkong/probes/x86_genoa.c +17 -0
  426. package/numkong/probes/x86_graniteamx.c +19 -0
  427. package/numkong/probes/x86_haswell.c +11 -0
  428. package/numkong/probes/x86_icelake.c +17 -0
  429. package/numkong/probes/x86_sapphire.c +16 -0
  430. package/numkong/probes/x86_sapphireamx.c +18 -0
  431. package/numkong/probes/x86_sierra.c +17 -0
  432. package/numkong/probes/x86_skylake.c +15 -0
  433. package/numkong/probes/x86_turin.c +17 -0
  434. package/numkong/rust/README.md +698 -0
  435. package/numkong/rust/capabilities.rs +96 -0
  436. package/numkong/rust/cast.rs +314 -0
  437. package/numkong/rust/curved.rs +391 -0
  438. package/numkong/rust/each.rs +2721 -0
  439. package/numkong/rust/geospatial.rs +343 -0
  440. package/numkong/rust/matrix.rs +5424 -0
  441. package/numkong/rust/maxsim.rs +540 -0
  442. package/numkong/rust/mesh.rs +837 -0
  443. package/numkong/rust/numkong.rs +409 -0
  444. package/numkong/rust/probability.rs +272 -0
  445. package/numkong/rust/reduce.rs +1249 -0
  446. package/numkong/rust/set.rs +194 -0
  447. package/numkong/rust/sparse.rs +513 -0
  448. package/numkong/rust/spatial.rs +1815 -0
  449. package/numkong/rust/tensor.rs +7565 -0
  450. package/numkong/rust/types.rs +3666 -0
  451. package/numkong/rust/vector.rs +1899 -0
  452. package/numkong/rustfmt.toml +2 -0
  453. package/numkong/swift/Matrix.swift +1388 -0
  454. package/numkong/swift/MaxSim.swift +151 -0
  455. package/numkong/swift/NumKong.swift +283 -0
  456. package/numkong/swift/Numerics.swift +329 -0
  457. package/numkong/swift/README.md +433 -0
  458. package/numkong/swift/Scalar.swift +741 -0
  459. package/numkong/swift/Tensor.swift +209 -0
  460. package/numkong/test/README.md +315 -0
  461. package/numkong/test/playwright.config.ts +16 -0
  462. package/numkong/test/swift/Test.swift +534 -0
  463. package/numkong/test/test-browser-bundle-runner.mjs +36 -0
  464. package/numkong/test/test-browser-bundle.html +188 -0
  465. package/numkong/test/test-browser-runner.mjs +43 -0
  466. package/numkong/test/test-browser.html +305 -0
  467. package/numkong/test/test-dtypes.mjs +453 -0
  468. package/numkong/test/test-wasm.mjs +267 -0
  469. package/numkong/test/test.cpp +442 -0
  470. package/numkong/test/test.hpp +580 -0
  471. package/numkong/test/test.mjs +363 -0
  472. package/numkong/test/test_base.py +1041 -0
  473. package/numkong/test/test_cast.cpp +242 -0
  474. package/numkong/test/test_cross.hpp +551 -0
  475. package/numkong/test/test_cross.py +467 -0
  476. package/numkong/test/test_cross_amx.cpp +50 -0
  477. package/numkong/test/test_cross_arm.cpp +225 -0
  478. package/numkong/test/test_cross_blas.cpp +354 -0
  479. package/numkong/test/test_cross_loongarch.cpp +90 -0
  480. package/numkong/test/test_cross_power.cpp +73 -0
  481. package/numkong/test/test_cross_rvv.cpp +109 -0
  482. package/numkong/test/test_cross_serial.cpp +181 -0
  483. package/numkong/test/test_cross_sme.cpp +148 -0
  484. package/numkong/test/test_cross_wasm.cpp +141 -0
  485. package/numkong/test/test_cross_x86.cpp +442 -0
  486. package/numkong/test/test_curved.cpp +182 -0
  487. package/numkong/test/test_curved.py +207 -0
  488. package/numkong/test/test_dot.cpp +353 -0
  489. package/numkong/test/test_dot.py +296 -0
  490. package/numkong/test/test_each.cpp +437 -0
  491. package/numkong/test/test_each.py +756 -0
  492. package/numkong/test/test_geospatial.cpp +155 -0
  493. package/numkong/test/test_geospatial.py +241 -0
  494. package/numkong/test/test_maxsim.cpp +138 -0
  495. package/numkong/test/test_maxsim.py +209 -0
  496. package/numkong/test/test_mesh.cpp +203 -0
  497. package/numkong/test/test_mesh.py +394 -0
  498. package/numkong/test/test_probability.cpp +136 -0
  499. package/numkong/test/test_probability.py +166 -0
  500. package/numkong/test/test_reduce.cpp +563 -0
  501. package/numkong/test/test_reduce.py +781 -0
  502. package/numkong/test/test_set.cpp +151 -0
  503. package/numkong/test/test_set.py +120 -0
  504. package/numkong/test/test_similarities.py +579 -0
  505. package/numkong/test/test_sparse.cpp +121 -0
  506. package/numkong/test/test_sparse.py +118 -0
  507. package/numkong/test/test_spatial.cpp +518 -0
  508. package/numkong/test/test_spatial.py +269 -0
  509. package/numkong/test/test_tensor.cpp +884 -0
  510. package/numkong/test/test_tensor.py +1417 -0
  511. package/numkong/test/test_trigonometry.cpp +156 -0
  512. package/numkong/test/test_trigonometry.py +180 -0
  513. package/package.json +7 -8
  514. package/prebuilds/darwin-arm64+x64/usearch.node +0 -0
  515. package/prebuilds/linux-arm64/usearch.node +0 -0
  516. package/prebuilds/linux-x64/usearch.node +0 -0
  517. package/fp16/CMakeLists.txt +0 -176
  518. package/fp16/LICENSE +0 -11
  519. package/fp16/README.md +0 -20
  520. package/fp16/bench/alt-element.cc +0 -89
  521. package/fp16/bench/from-alt-array.cc +0 -175
  522. package/fp16/bench/from-ieee-array.cc +0 -399
  523. package/fp16/bench/ieee-element.cc +0 -272
  524. package/fp16/bench/to-alt-array.cc +0 -91
  525. package/fp16/bench/to-ieee-array.cc +0 -303
  526. package/fp16/cmake/DownloadGoogleBenchmark.cmake +0 -15
  527. package/fp16/cmake/DownloadGoogleTest.cmake +0 -15
  528. package/fp16/cmake/DownloadPSimd.cmake +0 -15
  529. package/fp16/configure.py +0 -65
  530. package/fp16/confu.yaml +0 -8
  531. package/fp16/include/fp16/__init__.py +0 -0
  532. package/fp16/include/fp16/avx.py +0 -50
  533. package/fp16/include/fp16/avx2.py +0 -53
  534. package/fp16/include/fp16/bitcasts.h +0 -92
  535. package/fp16/include/fp16/fp16.h +0 -451
  536. package/fp16/include/fp16/psimd.h +0 -131
  537. package/fp16/include/fp16.h +0 -11
  538. package/fp16/jni/Android.mk +0 -6
  539. package/fp16/jni/Application.mk +0 -4
  540. package/fp16/test/alt-from-fp32-value.cc +0 -498
  541. package/fp16/test/alt-to-fp32-bits.cc +0 -263
  542. package/fp16/test/alt-to-fp32-psimd.cc +0 -145
  543. package/fp16/test/alt-to-fp32-value.cc +0 -348
  544. package/fp16/test/alt-to-fp32x2-psimd.cc +0 -245
  545. package/fp16/test/bitcasts.cc +0 -56
  546. package/fp16/test/ieee-from-fp32-value.cc +0 -523
  547. package/fp16/test/ieee-to-fp32-bits.cc +0 -333
  548. package/fp16/test/ieee-to-fp32-psimd.cc +0 -312
  549. package/fp16/test/ieee-to-fp32-value.cc +0 -420
  550. package/fp16/test/ieee-to-fp32x2-psimd.cc +0 -541
  551. package/fp16/test/peachpy/alt-xmm-to-fp32-xmm-avx.cc +0 -96
  552. package/fp16/test/peachpy/alt-xmm-to-fp32-ymm-avx2.cc +0 -96
  553. package/fp16/test/peachpy/stubs.py +0 -38
  554. package/fp16/test/tables.cc +0 -530
  555. package/fp16/test/tables.h +0 -13
  556. package/fp16/third-party/THHalf.h +0 -92
  557. package/fp16/third-party/eigen-half.h +0 -170
  558. package/fp16/third-party/float16-compressor.h +0 -80
  559. package/fp16/third-party/half.hpp +0 -2916
  560. package/fp16/third-party/npy-halffloat.h +0 -328
  561. package/simsimd/.git-blame-ignore-revs +0 -2
  562. package/simsimd/CONTRIBUTING.md +0 -321
  563. package/simsimd/Cargo.toml +0 -49
  564. package/simsimd/MANIFEST.in +0 -4
  565. package/simsimd/Package.swift +0 -28
  566. package/simsimd/README.md +0 -1493
  567. package/simsimd/binding.gyp +0 -35
  568. package/simsimd/build.rs +0 -70
  569. package/simsimd/c/lib.c +0 -374
  570. package/simsimd/include/module.modulemap +0 -4
  571. package/simsimd/include/simsimd/binary.h +0 -486
  572. package/simsimd/include/simsimd/curved.h +0 -1541
  573. package/simsimd/include/simsimd/dot.h +0 -1853
  574. package/simsimd/include/simsimd/elementwise.h +0 -2465
  575. package/simsimd/include/simsimd/geospatial.h +0 -43
  576. package/simsimd/include/simsimd/mesh.h +0 -69
  577. package/simsimd/include/simsimd/probability.h +0 -606
  578. package/simsimd/include/simsimd/simsimd.h +0 -2567
  579. package/simsimd/include/simsimd/sparse.h +0 -1384
  580. package/simsimd/include/simsimd/spatial.h +0 -2335
  581. package/simsimd/include/simsimd/types.h +0 -666
  582. package/simsimd/javascript/fallback.ts +0 -233
  583. package/simsimd/javascript/lib.c +0 -125
  584. package/simsimd/javascript/node-gyp-build.d.ts +0 -1
  585. package/simsimd/javascript/simsimd.ts +0 -179
  586. package/simsimd/javascript/tsconfig-cjs.json +0 -8
  587. package/simsimd/package-lock.json +0 -1761
  588. package/simsimd/package.json +0 -61
  589. package/simsimd/rust/lib.rs +0 -1821
  590. package/simsimd/scripts/bench.cxx +0 -1170
  591. package/simsimd/scripts/bench.ipynb +0 -187
  592. package/simsimd/scripts/bench.js +0 -127
  593. package/simsimd/scripts/bench.rs +0 -876
  594. package/simsimd/scripts/bench_vectors.py +0 -734
  595. package/simsimd/scripts/bench_vectors_live.py +0 -213
  596. package/simsimd/scripts/test.c +0 -187
  597. package/simsimd/scripts/test.mjs +0 -220
  598. package/simsimd/scripts/test.py +0 -1505
  599. package/simsimd/swift/SimSIMD.swift +0 -149
  600. package/simsimd/swift/Test.swift +0 -128
  601. /package/{simsimd → numkong}/CODE_OF_CONDUCT.md +0 -0
  602. /package/{simsimd → numkong}/LICENSE +0 -0
  603. /package/{simsimd → numkong}/javascript/dist-package-cjs.json +0 -0
  604. /package/{simsimd → numkong}/javascript/dist-package-esm.json +0 -0
@@ -0,0 +1,380 @@
1
+ /**
2
+ * @brief SIMD-accelerated Similarity Measures for Probability Distributions.
3
+ * @file include/numkong/probability.h
4
+ * @author Ash Vardanian
5
+ * @date October 20, 2023
6
+ *
7
+ * Contains following similarity measures:
8
+ *
9
+ * - Kullback-Leibler Divergence (KLD)
10
+ * - Jensen-Shannon Distance (JSD)
11
+ *
12
+ * For dtypes:
13
+ *
14
+ * - 64-bit floating point numbers → 64-bit
15
+ * - 32-bit floating point numbers → 64-bit
16
+ * - 16-bit floating point numbers → 32-bit
17
+ * - 16-bit brain-floating point numbers → 32-bit
18
+ *
19
+ * Precision policy:
20
+ *
21
+ * - For `f32` inputs, the per-element vertical path stays in `f32` to preserve the fast ratio/log
22
+ * approximations and SIMD throughput.
23
+ * - The horizontal reduction over those per-element contributions widens to `f64`, and public
24
+ * `f32` results are exposed as `f64`.
25
+ * - For `f64` inputs, both the vertical path and the horizontal reduction stay in `f64`, with
26
+ * stable summation in the serial kernels.
27
+ * - For `f16` and `bf16` inputs, the kernels still widen to `f32`.
28
+ *
29
+ * For hardware architectures:
30
+ *
31
+ * - Arm: NEON
32
+ * - x86: Haswell, Skylake, Sapphire
33
+ *
34
+ * @section x86_instructions Relevant x86 Instructions
35
+ *
36
+ * KL/JS divergence requires log2(x) which decomposes into exponent extraction (VGETEXP) plus
37
+ * mantissa polynomial (using VGETMANT + FMA chain). This approach is faster than scalar log()
38
+ * calls. Division (for p/q ratio) uses either VDIVPS directly or VRCP14PS with Newton-Raphson
39
+ * refinement when ~14-bit precision suffices. Genoa's VGETEXP/VGETMANT are 25% faster than Ice.
40
+ *
41
+ * Intrinsic Instruction Icelake Genoa
42
+ * _mm512_getexp_ps VGETEXPPS (ZMM, ZMM) 4cy @ p0 3cy @ p23
43
+ * _mm512_getexp_pd VGETEXPPD (ZMM, ZMM) 4cy @ p0 3cy @ p23
44
+ * _mm512_getmant_ps VGETMANTPS (ZMM, ZMM, I8) 4cy @ p0 3cy @ p23
45
+ * _mm512_getmant_pd VGETMANTPD (ZMM, ZMM, I8) 4cy @ p0 3cy @ p23
46
+ * _mm512_rcp14_ps VRCP14PS (ZMM, ZMM) 7cy @ p0+p0+p05 5cy @ p01
47
+ * _mm512_div_ps VDIVPS (ZMM, ZMM, ZMM) 17cy @ p0+p0+p05 11cy @ p01
48
+ * _mm512_fmadd_ps VFMADD231PS (ZMM, ZMM, ZMM) 4cy @ p0 4cy @ p01
49
+ *
50
+ * @section arm_instructions Relevant ARM NEON/SVE Instructions
51
+ *
52
+ * ARM lacks direct exponent/mantissa extraction, so log2 uses integer reinterpretation of the
53
+ * float bits followed by polynomial refinement. FRECPE provides ~8-bit reciprocal approximation
54
+ * for division, refined with FRECPS Newton-Raphson steps to ~22-bit precision.
55
+ *
56
+ * Intrinsic Instruction M1 Firestorm Graviton 3 Graviton 4
57
+ * vfmaq_f32 FMLA.S (vec) 4cy @ V0123 4cy @ V0123 4cy @ V0123
58
+ * vrecpeq_f32 FRECPE.S 3cy @ V02 3cy @ V02 3cy @ V02
59
+ * vrecpsq_f32 FRECPS.S 4cy @ V0123 4cy @ V0123 4cy @ V0123
60
+ *
61
+ * @section references References
62
+ *
63
+ * - x86 intrinsics: https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html
64
+ * - Arm intrinsics: https://developer.arm.com/architectures/instruction-sets/intrinsics/
65
+ *
66
+ */
67
+ #ifndef NK_PROBABILITY_H
68
+ #define NK_PROBABILITY_H
69
+
70
+ #include "numkong/types.h"
71
+ #include "numkong/reduce.h" // For horizontal reduction helpers
72
+
73
+ #if defined(__cplusplus)
74
+ extern "C" {
75
+ #endif
76
+
77
+ /**
78
+ * @brief Kullback-Leibler divergence between two discrete probability distributions.
79
+ *
80
+ * @param[in] a The first discrete probability distribution.
81
+ * @param[in] b The second discrete probability distribution.
82
+ * @param[in] n The number of elements in the distributions.
83
+ * @param[out] result The output divergence value.
84
+ *
85
+ * @note The distributions are assumed to be normalized.
86
+ * @note The output divergence value is non-negative.
87
+ * @note The output divergence value is zero if and only if the two distributions are identical.
88
+ */
89
+ NK_DYNAMIC void nk_kld_f16(nk_f16_t const *a, nk_f16_t const *b, nk_size_t n, nk_f32_t *result);
90
+ /**
91
+ * @brief Kullback-Leibler divergence between two discrete probability distributions.
92
+ *
93
+ * @param[in] a The first discrete probability distribution.
94
+ * @param[in] b The second discrete probability distribution.
95
+ * @param[in] n The number of elements in the distributions.
96
+ * @param[out] result The output divergence value.
97
+ *
98
+ * @note The distributions are assumed to be normalized.
99
+ * @note The output divergence value is non-negative.
100
+ * @note The output divergence value is zero if and only if the two distributions are identical.
101
+ */
102
+ NK_DYNAMIC void nk_kld_bf16(nk_bf16_t const *a, nk_bf16_t const *b, nk_size_t n, nk_f32_t *result);
103
+ /**
104
+ * @brief Kullback-Leibler divergence between two discrete probability distributions.
105
+ *
106
+ * @param[in] a The first discrete probability distribution.
107
+ * @param[in] b The second discrete probability distribution.
108
+ * @param[in] n The number of elements in the distributions.
109
+ * @param[out] result The output divergence value.
110
+ *
111
+ * @note The distributions are assumed to be normalized.
112
+ * @note The output divergence value is non-negative.
113
+ * @note The output divergence value is zero if and only if the two distributions are identical.
114
+ */
115
+ NK_DYNAMIC void nk_kld_f32(nk_f32_t const *a, nk_f32_t const *b, nk_size_t n, nk_f64_t *result);
116
+ /**
117
+ * @brief Kullback-Leibler divergence between two discrete probability distributions.
118
+ *
119
+ * @param[in] a The first discrete probability distribution.
120
+ * @param[in] b The second discrete probability distribution.
121
+ * @param[in] n The number of elements in the distributions.
122
+ * @param[out] result The output divergence value.
123
+ *
124
+ * @note The distributions are assumed to be normalized.
125
+ * @note The output divergence value is non-negative.
126
+ * @note The output divergence value is zero if and only if the two distributions are identical.
127
+ */
128
+ NK_DYNAMIC void nk_kld_f64(nk_f64_t const *a, nk_f64_t const *b, nk_size_t n, nk_f64_t *result);
129
+ /**
130
+ * @brief Jensen-Shannon distance between two discrete probability distributions.
131
+ *
132
+ * @param[in] a The first discrete probability distribution.
133
+ * @param[in] b The second discrete probability distribution.
134
+ * @param[in] n The number of elements in the distributions.
135
+ * @param[out] result The output distance value.
136
+ *
137
+ * @note The distributions are assumed to be normalized.
138
+ * @note The output distance value is non-negative.
139
+ * @note The output distance value is zero if and only if the two distributions are identical.
140
+ */
141
+ NK_DYNAMIC void nk_jsd_f16(nk_f16_t const *a, nk_f16_t const *b, nk_size_t n, nk_f32_t *result);
142
+ /**
143
+ * @brief Jensen-Shannon distance between two discrete probability distributions.
144
+ *
145
+ * @param[in] a The first discrete probability distribution.
146
+ * @param[in] b The second discrete probability distribution.
147
+ * @param[in] n The number of elements in the distributions.
148
+ * @param[out] result The output distance value.
149
+ *
150
+ * @note The distributions are assumed to be normalized.
151
+ * @note The output distance value is non-negative.
152
+ * @note The output distance value is zero if and only if the two distributions are identical.
153
+ */
154
+ NK_DYNAMIC void nk_jsd_bf16(nk_bf16_t const *a, nk_bf16_t const *b, nk_size_t n, nk_f32_t *result);
155
+ /**
156
+ * @brief Jensen-Shannon distance between two discrete probability distributions.
157
+ *
158
+ * @param[in] a The first discrete probability distribution.
159
+ * @param[in] b The second discrete probability distribution.
160
+ * @param[in] n The number of elements in the distributions.
161
+ * @param[out] result The output distance value.
162
+ *
163
+ * @note The distributions are assumed to be normalized.
164
+ * @note The output distance value is non-negative.
165
+ * @note The output distance value is zero if and only if the two distributions are identical.
166
+ */
167
+ NK_DYNAMIC void nk_jsd_f32(nk_f32_t const *a, nk_f32_t const *b, nk_size_t n, nk_f64_t *result);
168
+ /**
169
+ * @brief Jensen-Shannon distance between two discrete probability distributions.
170
+ *
171
+ * @param[in] a The first discrete probability distribution.
172
+ * @param[in] b The second discrete probability distribution.
173
+ * @param[in] n The number of elements in the distributions.
174
+ * @param[out] result The output distance value.
175
+ *
176
+ * @note The distributions are assumed to be normalized.
177
+ * @note The output distance value is non-negative.
178
+ * @note The output distance value is zero if and only if the two distributions are identical.
179
+ */
180
+ NK_DYNAMIC void nk_jsd_f64(nk_f64_t const *a, nk_f64_t const *b, nk_size_t n, nk_f64_t *result);
181
+
182
+ /** @copydoc nk_kld_f64 */
183
+ NK_PUBLIC void nk_kld_f64_serial(nk_f64_t const *a, nk_f64_t const *b, nk_size_t n, nk_f64_t *result);
184
+ /** @copydoc nk_jsd_f64 */
185
+ NK_PUBLIC void nk_jsd_f64_serial(nk_f64_t const *a, nk_f64_t const *b, nk_size_t n, nk_f64_t *result);
186
+ /** @copydoc nk_kld_f32 */
187
+ NK_PUBLIC void nk_kld_f32_serial(nk_f32_t const *a, nk_f32_t const *b, nk_size_t n, nk_f64_t *result);
188
+ /** @copydoc nk_jsd_f32 */
189
+ NK_PUBLIC void nk_jsd_f32_serial(nk_f32_t const *a, nk_f32_t const *b, nk_size_t n, nk_f64_t *result);
190
+ /** @copydoc nk_kld_f16 */
191
+ NK_PUBLIC void nk_kld_f16_serial(nk_f16_t const *a, nk_f16_t const *b, nk_size_t n, nk_f32_t *result);
192
+ /** @copydoc nk_jsd_f16 */
193
+ NK_PUBLIC void nk_jsd_f16_serial(nk_f16_t const *a, nk_f16_t const *b, nk_size_t n, nk_f32_t *result);
194
+ /** @copydoc nk_kld_bf16 */
195
+ NK_PUBLIC void nk_kld_bf16_serial(nk_bf16_t const *a, nk_bf16_t const *b, nk_size_t n, nk_f32_t *result);
196
+ /** @copydoc nk_jsd_bf16 */
197
+ NK_PUBLIC void nk_jsd_bf16_serial(nk_bf16_t const *a, nk_bf16_t const *b, nk_size_t n, nk_f32_t *result);
198
+
199
+ #if NK_TARGET_NEON
200
+ /** @copydoc nk_kld_f32 */
201
+ NK_PUBLIC void nk_kld_f32_neon(nk_f32_t const *a, nk_f32_t const *b, nk_size_t n, nk_f64_t *result);
202
+ /** @copydoc nk_jsd_f32 */
203
+ NK_PUBLIC void nk_jsd_f32_neon(nk_f32_t const *a, nk_f32_t const *b, nk_size_t n, nk_f64_t *result);
204
+ /** @copydoc nk_kld_f16 */
205
+ NK_PUBLIC void nk_kld_f16_neon(nk_f16_t const *a, nk_f16_t const *b, nk_size_t n, nk_f32_t *result);
206
+ /** @copydoc nk_jsd_f16 */
207
+ NK_PUBLIC void nk_jsd_f16_neon(nk_f16_t const *a, nk_f16_t const *b, nk_size_t n, nk_f32_t *result);
208
+ #endif // NK_TARGET_NEON
209
+
210
+ #if NK_TARGET_HASWELL
211
+ /** @copydoc nk_kld_f64 */
212
+ NK_PUBLIC void nk_kld_f64_haswell(nk_f64_t const *a, nk_f64_t const *b, nk_size_t n, nk_f64_t *result);
213
+ /** @copydoc nk_jsd_f64 */
214
+ NK_PUBLIC void nk_jsd_f64_haswell(nk_f64_t const *a, nk_f64_t const *b, nk_size_t n, nk_f64_t *result);
215
+ /** @copydoc nk_kld_f16 */
216
+ NK_PUBLIC void nk_kld_f16_haswell(nk_f16_t const *a, nk_f16_t const *b, nk_size_t n, nk_f32_t *result);
217
+ /** @copydoc nk_jsd_f16 */
218
+ NK_PUBLIC void nk_jsd_f16_haswell(nk_f16_t const *a, nk_f16_t const *b, nk_size_t n, nk_f32_t *result);
219
+ #endif // NK_TARGET_HASWELL
220
+
221
+ #if NK_TARGET_SKYLAKE
222
+ /** @copydoc nk_kld_f64 */
223
+ NK_PUBLIC void nk_kld_f64_skylake(nk_f64_t const *a, nk_f64_t const *b, nk_size_t n, nk_f64_t *result);
224
+ /** @copydoc nk_jsd_f64 */
225
+ NK_PUBLIC void nk_jsd_f64_skylake(nk_f64_t const *a, nk_f64_t const *b, nk_size_t n, nk_f64_t *result);
226
+ /** @copydoc nk_kld_f32 */
227
+ NK_PUBLIC void nk_kld_f32_skylake(nk_f32_t const *a, nk_f32_t const *b, nk_size_t n, nk_f64_t *result);
228
+ /** @copydoc nk_jsd_f32 */
229
+ NK_PUBLIC void nk_jsd_f32_skylake(nk_f32_t const *a, nk_f32_t const *b, nk_size_t n, nk_f64_t *result);
230
+ /** @copydoc nk_kld_f16 */
231
+ NK_PUBLIC void nk_kld_f16_skylake(nk_f16_t const *a, nk_f16_t const *b, nk_size_t n, nk_f32_t *result);
232
+ /** @copydoc nk_jsd_f16 */
233
+ NK_PUBLIC void nk_jsd_f16_skylake(nk_f16_t const *a, nk_f16_t const *b, nk_size_t n, nk_f32_t *result);
234
+ #endif // NK_TARGET_SKYLAKE
235
+
236
+ #if NK_TARGET_RVV
237
+ /** @copydoc nk_kld_f32 */
238
+ NK_PUBLIC void nk_kld_f32_rvv(nk_f32_t const *a, nk_f32_t const *b, nk_size_t n, nk_f64_t *result);
239
+ /** @copydoc nk_jsd_f32 */
240
+ NK_PUBLIC void nk_jsd_f32_rvv(nk_f32_t const *a, nk_f32_t const *b, nk_size_t n, nk_f64_t *result);
241
+ /** @copydoc nk_kld_f64 */
242
+ NK_PUBLIC void nk_kld_f64_rvv(nk_f64_t const *a, nk_f64_t const *b, nk_size_t n, nk_f64_t *result);
243
+ /** @copydoc nk_jsd_f64 */
244
+ NK_PUBLIC void nk_jsd_f64_rvv(nk_f64_t const *a, nk_f64_t const *b, nk_size_t n, nk_f64_t *result);
245
+ /** @copydoc nk_kld_f16 */
246
+ NK_PUBLIC void nk_kld_f16_rvv(nk_f16_t const *a, nk_f16_t const *b, nk_size_t n, nk_f32_t *result);
247
+ /** @copydoc nk_jsd_f16 */
248
+ NK_PUBLIC void nk_jsd_f16_rvv(nk_f16_t const *a, nk_f16_t const *b, nk_size_t n, nk_f32_t *result);
249
+ /** @copydoc nk_kld_bf16 */
250
+ NK_PUBLIC void nk_kld_bf16_rvv(nk_bf16_t const *a, nk_bf16_t const *b, nk_size_t n, nk_f32_t *result);
251
+ /** @copydoc nk_jsd_bf16 */
252
+ NK_PUBLIC void nk_jsd_bf16_rvv(nk_bf16_t const *a, nk_bf16_t const *b, nk_size_t n, nk_f32_t *result);
253
+ #endif // NK_TARGET_RVV
254
+
255
+ /** @brief Returns the output dtype for probability measures (KLD, JSD). */
256
+ NK_INTERNAL nk_dtype_t nk_probability_output_dtype(nk_dtype_t dtype) {
257
+ switch (dtype) {
258
+ case nk_f64_k: return nk_f64_k;
259
+ case nk_f32_k: return nk_f64_k;
260
+ case nk_f16_k: return nk_f32_k;
261
+ case nk_bf16_k: return nk_f32_k;
262
+ default: return nk_dtype_unknown_k;
263
+ }
264
+ }
265
+
266
+ #if defined(__cplusplus)
267
+ } // extern "C"
268
+ #endif
269
+
270
+ #include "numkong/probability/serial.h"
271
+ #include "numkong/probability/neon.h"
272
+ #include "numkong/probability/haswell.h"
273
+ #include "numkong/probability/skylake.h"
274
+ #include "numkong/probability/rvv.h"
275
+
276
+ #if defined(__cplusplus)
277
+ extern "C" {
278
+ #endif
279
+
280
+ #if !NK_DYNAMIC_DISPATCH
281
+
282
+ NK_PUBLIC void nk_kld_f16(nk_f16_t const *a, nk_f16_t const *b, nk_size_t n, nk_f32_t *result) {
283
+ #if NK_TARGET_NEON
284
+ nk_kld_f16_neon(a, b, n, result);
285
+ #elif NK_TARGET_SKYLAKE
286
+ nk_kld_f16_skylake(a, b, n, result);
287
+ #elif NK_TARGET_HASWELL
288
+ nk_kld_f16_haswell(a, b, n, result);
289
+ #elif NK_TARGET_RVV
290
+ nk_kld_f16_rvv(a, b, n, result);
291
+ #else
292
+ nk_kld_f16_serial(a, b, n, result);
293
+ #endif
294
+ }
295
+
296
+ NK_PUBLIC void nk_kld_bf16(nk_bf16_t const *a, nk_bf16_t const *b, nk_size_t n, nk_f32_t *result) {
297
+ #if NK_TARGET_RVV
298
+ nk_kld_bf16_rvv(a, b, n, result);
299
+ #else
300
+ nk_kld_bf16_serial(a, b, n, result);
301
+ #endif
302
+ }
303
+
304
+ NK_PUBLIC void nk_kld_f32(nk_f32_t const *a, nk_f32_t const *b, nk_size_t n, nk_f64_t *result) {
305
+ #if NK_TARGET_NEON
306
+ nk_kld_f32_neon(a, b, n, result);
307
+ #elif NK_TARGET_SKYLAKE
308
+ nk_kld_f32_skylake(a, b, n, result);
309
+ #elif NK_TARGET_RVV
310
+ nk_kld_f32_rvv(a, b, n, result);
311
+ #else
312
+ nk_kld_f32_serial(a, b, n, result);
313
+ #endif
314
+ }
315
+
316
+ NK_PUBLIC void nk_kld_f64(nk_f64_t const *a, nk_f64_t const *b, nk_size_t n, nk_f64_t *result) {
317
+ #if NK_TARGET_SKYLAKE
318
+ nk_kld_f64_skylake(a, b, n, result);
319
+ #elif NK_TARGET_HASWELL
320
+ nk_kld_f64_haswell(a, b, n, result);
321
+ #elif NK_TARGET_RVV
322
+ nk_kld_f64_rvv(a, b, n, result);
323
+ #else
324
+ nk_kld_f64_serial(a, b, n, result);
325
+ #endif
326
+ }
327
+
328
+ NK_PUBLIC void nk_jsd_f16(nk_f16_t const *a, nk_f16_t const *b, nk_size_t n, nk_f32_t *result) {
329
+ #if NK_TARGET_NEON
330
+ nk_jsd_f16_neon(a, b, n, result);
331
+ #elif NK_TARGET_SKYLAKE
332
+ nk_jsd_f16_skylake(a, b, n, result);
333
+ #elif NK_TARGET_HASWELL
334
+ nk_jsd_f16_haswell(a, b, n, result);
335
+ #elif NK_TARGET_RVV
336
+ nk_jsd_f16_rvv(a, b, n, result);
337
+ #else
338
+ nk_jsd_f16_serial(a, b, n, result);
339
+ #endif
340
+ }
341
+
342
+ NK_PUBLIC void nk_jsd_bf16(nk_bf16_t const *a, nk_bf16_t const *b, nk_size_t n, nk_f32_t *result) {
343
+ #if NK_TARGET_RVV
344
+ nk_jsd_bf16_rvv(a, b, n, result);
345
+ #else
346
+ nk_jsd_bf16_serial(a, b, n, result);
347
+ #endif
348
+ }
349
+
350
+ NK_PUBLIC void nk_jsd_f32(nk_f32_t const *a, nk_f32_t const *b, nk_size_t n, nk_f64_t *result) {
351
+ #if NK_TARGET_NEON
352
+ nk_jsd_f32_neon(a, b, n, result);
353
+ #elif NK_TARGET_SKYLAKE
354
+ nk_jsd_f32_skylake(a, b, n, result);
355
+ #elif NK_TARGET_RVV
356
+ nk_jsd_f32_rvv(a, b, n, result);
357
+ #else
358
+ nk_jsd_f32_serial(a, b, n, result);
359
+ #endif
360
+ }
361
+
362
+ NK_PUBLIC void nk_jsd_f64(nk_f64_t const *a, nk_f64_t const *b, nk_size_t n, nk_f64_t *result) {
363
+ #if NK_TARGET_SKYLAKE
364
+ nk_jsd_f64_skylake(a, b, n, result);
365
+ #elif NK_TARGET_HASWELL
366
+ nk_jsd_f64_haswell(a, b, n, result);
367
+ #elif NK_TARGET_RVV
368
+ nk_jsd_f64_rvv(a, b, n, result);
369
+ #else
370
+ nk_jsd_f64_serial(a, b, n, result);
371
+ #endif
372
+ }
373
+
374
+ #endif // !NK_DYNAMIC_DISPATCH
375
+
376
+ #if defined(__cplusplus)
377
+ } // extern "C"
378
+ #endif
379
+
380
+ #endif
@@ -0,0 +1,120 @@
1
+ /**
2
+ * @brief C++ wrappers for SIMD-accelerated Similarity Measures for Probability Distributions.
3
+ * @file include/numkong/probability.hpp
4
+ * @author Ash Vardanian
5
+ * @date February 5, 2026
6
+ */
7
+ #ifndef NK_PROBABILITY_HPP
8
+ #define NK_PROBABILITY_HPP
9
+
10
+ #include <cstdint>
11
+ #include <type_traits>
12
+
13
+ #include "numkong/probability.h"
14
+
15
+ #include "numkong/types.hpp"
16
+
17
+ namespace ashvardanian::numkong {
18
+
19
+ /**
20
+ * @brief Kullback-Leibler divergence: Σ pᵢ × log(pᵢ / qᵢ)
21
+ * @param[in] p,q First and second probability distributions
22
+ * @param[in] d Number of dimensions in input vectors
23
+ * @param[out] r Pointer to output divergence value
24
+ *
25
+ * @tparam in_type_ Input distribution type (probability vectors)
26
+ * @tparam result_type_ Result type, defaults to `in_type_::probability_result_t`
27
+ * @tparam allow_simd_ Enable SIMD kernel dispatch when `prefer_simd_k`
28
+ */
29
+ template <numeric_dtype in_type_, numeric_dtype result_type_ = typename in_type_::probability_result_t,
30
+ allow_simd_t allow_simd_ = prefer_simd_k>
31
+ void kld(in_type_ const *p, in_type_ const *q, std::size_t d, result_type_ *r) noexcept {
32
+ constexpr bool simd = allow_simd_ == prefer_simd_k &&
33
+ std::is_same_v<result_type_, typename in_type_::probability_result_t>;
34
+
35
+ if constexpr (std::is_same_v<in_type_, f64_t> && simd) nk_kld_f64(&p->raw_, &q->raw_, d, &r->raw_);
36
+ else if constexpr (std::is_same_v<in_type_, f32_t> && simd) nk_kld_f32(&p->raw_, &q->raw_, d, &r->raw_);
37
+ else if constexpr (std::is_same_v<in_type_, f16_t> && simd) nk_kld_f16(&p->raw_, &q->raw_, d, &r->raw_);
38
+ else if constexpr (std::is_same_v<in_type_, bf16_t> && simd) nk_kld_bf16(&p->raw_, &q->raw_, d, &r->raw_);
39
+ // Scalar fallback
40
+ else {
41
+ result_type_ sum {};
42
+ for (std::size_t i = 0; i < d; i++) {
43
+ result_type_ pi(p[i]), qi(q[i]);
44
+ if (pi > result_type_(0)) sum = sum + pi * (pi / qi).log();
45
+ }
46
+ *r = sum;
47
+ }
48
+ }
49
+
50
+ /**
51
+ * @brief Jensen-Shannon distance: √(½ × (KL(p‖m) + KL(q‖m))), where m = (p + q) / 2
52
+ * @param[in] p,q First and second probability distributions
53
+ * @param[in] d Number of dimensions in input vectors
54
+ * @param[out] r Pointer to output distance value
55
+ *
56
+ * @tparam in_type_ Input distribution type (probability vectors)
57
+ * @tparam result_type_ Result type, defaults to `in_type_::probability_result_t`
58
+ * @tparam allow_simd_ Enable SIMD kernel dispatch when `prefer_simd_k`
59
+ */
60
+ template <numeric_dtype in_type_, numeric_dtype result_type_ = typename in_type_::probability_result_t,
61
+ allow_simd_t allow_simd_ = prefer_simd_k>
62
+ void jsd(in_type_ const *p, in_type_ const *q, std::size_t d, result_type_ *r) noexcept {
63
+ constexpr bool simd = allow_simd_ == prefer_simd_k &&
64
+ std::is_same_v<result_type_, typename in_type_::probability_result_t>;
65
+
66
+ if constexpr (std::is_same_v<in_type_, f64_t> && simd) nk_jsd_f64(&p->raw_, &q->raw_, d, &r->raw_);
67
+ else if constexpr (std::is_same_v<in_type_, f32_t> && simd) nk_jsd_f32(&p->raw_, &q->raw_, d, &r->raw_);
68
+ else if constexpr (std::is_same_v<in_type_, f16_t> && simd) nk_jsd_f16(&p->raw_, &q->raw_, d, &r->raw_);
69
+ else if constexpr (std::is_same_v<in_type_, bf16_t> && simd) nk_jsd_bf16(&p->raw_, &q->raw_, d, &r->raw_);
70
+ // Scalar fallback
71
+ else {
72
+ result_type_ sum {};
73
+ result_type_ half(0.5);
74
+ for (std::size_t i = 0; i < d; i++) {
75
+ result_type_ pi(p[i]), qi(q[i]);
76
+ result_type_ mi = half * (pi + qi);
77
+ if (pi > result_type_(0)) sum = sum + pi * (pi / mi).log();
78
+ if (qi > result_type_(0)) sum = sum + qi * (qi / mi).log();
79
+ }
80
+ // JSD distance = sqrt(divergence / 2), clamped to non-negative
81
+ result_type_ divergence = half * sum;
82
+ *r = divergence > result_type_(0) ? divergence.sqrt() : result_type_(0);
83
+ }
84
+ }
85
+
86
+ } // namespace ashvardanian::numkong
87
+
88
+ #include "numkong/tensor.hpp"
89
+
90
+ namespace ashvardanian::numkong {
91
+
92
+ template <numeric_dtype in_type_, numeric_dtype result_type_ = typename in_type_::probability_result_t,
93
+ allow_simd_t allow_simd_ = prefer_simd_k, std::size_t max_rank_a_, std::size_t max_rank_b_>
94
+ void kld(tensor_view<in_type_, max_rank_a_> p, tensor_view<in_type_, max_rank_b_> q, std::size_t d,
95
+ result_type_ *r) noexcept {
96
+ kld<in_type_, result_type_, allow_simd_>(p.data(), q.data(), d, r);
97
+ }
98
+
99
+ template <numeric_dtype in_type_, numeric_dtype result_type_ = typename in_type_::probability_result_t,
100
+ allow_simd_t allow_simd_ = prefer_simd_k>
101
+ void kld(vector_view<in_type_> p, vector_view<in_type_> q, std::size_t d, result_type_ *r) noexcept {
102
+ kld<in_type_, result_type_, allow_simd_>(p.data(), q.data(), d, r);
103
+ }
104
+
105
+ template <numeric_dtype in_type_, numeric_dtype result_type_ = typename in_type_::probability_result_t,
106
+ allow_simd_t allow_simd_ = prefer_simd_k, std::size_t max_rank_a_, std::size_t max_rank_b_>
107
+ void jsd(tensor_view<in_type_, max_rank_a_> p, tensor_view<in_type_, max_rank_b_> q, std::size_t d,
108
+ result_type_ *r) noexcept {
109
+ jsd<in_type_, result_type_, allow_simd_>(p.data(), q.data(), d, r);
110
+ }
111
+
112
+ template <numeric_dtype in_type_, numeric_dtype result_type_ = typename in_type_::probability_result_t,
113
+ allow_simd_t allow_simd_ = prefer_simd_k>
114
+ void jsd(vector_view<in_type_> p, vector_view<in_type_> q, std::size_t d, result_type_ *r) noexcept {
115
+ jsd<in_type_, result_type_, allow_simd_>(p.data(), q.data(), d, r);
116
+ }
117
+
118
+ } // namespace ashvardanian::numkong
119
+
120
+ #endif // NK_PROBABILITY_HPP
@@ -0,0 +1,50 @@
1
+ /**
2
+ * @brief SIMD-accelerated Pseudo-Random Number Generators.
3
+ * @file include/numkong/random.h
4
+ * @author Ash Vardanian
5
+ * @date January 11, 2026
6
+ *
7
+ * Implements following statistical distributions
8
+ *
9
+ * - Uniform Distribution
10
+ * - Gaussian (Normal) Distribution
11
+ *
12
+ * For dtypes:
13
+ *
14
+ * - 64-bit floating point numbers
15
+ * - 32-bit floating point numbers
16
+ * - 16-bit floating point numbers
17
+ * - 16-bit brain-floating point numbers
18
+ * - 8-bit floating point numbers
19
+ * - 8-bit integers
20
+ *
21
+ * For hardware architectures:
22
+ *
23
+ * - Arm: NEON, SSVE
24
+ * - x86: Haswell, Ice Lake, Skylake, Genoa
25
+ *
26
+ * @section usage Usage and Benefits
27
+ *
28
+ *
29
+ *
30
+ * @section references References
31
+ *
32
+ * - x86 intrinsics: https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html
33
+ * - Arm intrinsics: https://developer.arm.com/architectures/instruction-sets/intrinsics/
34
+ *
35
+ */
36
+ #ifndef NK_RANDOM_H
37
+ #define NK_RANDOM_H
38
+
39
+ #include "numkong/types.h"
40
+ #include "numkong/cast.h"
41
+
42
+ #if defined(__cplusplus)
43
+ extern "C" {
44
+ #endif // defined(__cplusplus)
45
+
46
+ #if defined(__cplusplus)
47
+ } // extern "C"
48
+ #endif // defined(__cplusplus)
49
+
50
+ #endif // NK_RANDOM_H