@graphty/algorithms 2.1.2 → 2.2.0

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 (355) hide show
  1. package/README.md +139 -50
  2. package/dist/algorithms.js +15260 -10390
  3. package/dist/algorithms.js.map +1 -1
  4. package/dist/algorithms.standalone.js +26675 -21542
  5. package/dist/algorithms.standalone.js.map +1 -1
  6. package/dist/src/algorithms/centrality/betweenness.d.ts +18 -0
  7. package/dist/src/algorithms/centrality/betweenness.d.ts.map +1 -1
  8. package/dist/src/algorithms/centrality/betweenness.js +40 -1
  9. package/dist/src/algorithms/centrality/betweenness.js.map +1 -1
  10. package/dist/src/algorithms/centrality/closeness.d.ts +20 -0
  11. package/dist/src/algorithms/centrality/closeness.d.ts.map +1 -1
  12. package/dist/src/algorithms/centrality/closeness.js +93 -8
  13. package/dist/src/algorithms/centrality/closeness.js.map +1 -1
  14. package/dist/src/algorithms/centrality/degree.d.ts +9 -0
  15. package/dist/src/algorithms/centrality/degree.d.ts.map +1 -1
  16. package/dist/src/algorithms/centrality/degree.js +18 -0
  17. package/dist/src/algorithms/centrality/degree.js.map +1 -1
  18. package/dist/src/algorithms/centrality/eigenvector.d.ts +10 -0
  19. package/dist/src/algorithms/centrality/eigenvector.d.ts.map +1 -1
  20. package/dist/src/algorithms/centrality/eigenvector.js +29 -0
  21. package/dist/src/algorithms/centrality/eigenvector.js.map +1 -1
  22. package/dist/src/algorithms/centrality/hits.d.ts +9 -0
  23. package/dist/src/algorithms/centrality/hits.d.ts.map +1 -1
  24. package/dist/src/algorithms/centrality/hits.js +23 -0
  25. package/dist/src/algorithms/centrality/hits.js.map +1 -1
  26. package/dist/src/algorithms/centrality/katz.d.ts +9 -0
  27. package/dist/src/algorithms/centrality/katz.d.ts.map +1 -1
  28. package/dist/src/algorithms/centrality/katz.js +31 -0
  29. package/dist/src/algorithms/centrality/katz.js.map +1 -1
  30. package/dist/src/algorithms/centrality/pagerank.d.ts +13 -13
  31. package/dist/src/algorithms/centrality/pagerank.d.ts.map +1 -1
  32. package/dist/src/algorithms/centrality/pagerank.js +47 -10
  33. package/dist/src/algorithms/centrality/pagerank.js.map +1 -1
  34. package/dist/src/algorithms/community/girvan-newman-legacy.d.ts +27 -0
  35. package/dist/src/algorithms/community/girvan-newman-legacy.d.ts.map +1 -0
  36. package/dist/src/algorithms/community/girvan-newman-legacy.js +335 -0
  37. package/dist/src/algorithms/community/girvan-newman-legacy.js.map +1 -0
  38. package/dist/src/algorithms/community/girvan-newman.d.ts +5 -3
  39. package/dist/src/algorithms/community/girvan-newman.d.ts.map +1 -1
  40. package/dist/src/algorithms/community/girvan-newman.js +34 -308
  41. package/dist/src/algorithms/community/girvan-newman.js.map +1 -1
  42. package/dist/src/algorithms/community/label-propagation.d.ts +9 -6
  43. package/dist/src/algorithms/community/label-propagation.d.ts.map +1 -1
  44. package/dist/src/algorithms/community/label-propagation.js +24 -110
  45. package/dist/src/algorithms/community/label-propagation.js.map +1 -1
  46. package/dist/src/algorithms/components/connected.d.ts.map +1 -1
  47. package/dist/src/algorithms/components/connected.js +28 -77
  48. package/dist/src/algorithms/components/connected.js.map +1 -1
  49. package/dist/src/algorithms/mst/kruskal.d.ts.map +1 -1
  50. package/dist/src/algorithms/mst/kruskal.js +59 -3
  51. package/dist/src/algorithms/mst/kruskal.js.map +1 -1
  52. package/dist/src/algorithms/shortest-path/bellman-ford.d.ts.map +1 -1
  53. package/dist/src/algorithms/shortest-path/bellman-ford.js +46 -0
  54. package/dist/src/algorithms/shortest-path/bellman-ford.js.map +1 -1
  55. package/dist/src/algorithms/shortest-path/dijkstra.d.ts.map +1 -1
  56. package/dist/src/algorithms/shortest-path/dijkstra.js +27 -0
  57. package/dist/src/algorithms/shortest-path/dijkstra.js.map +1 -1
  58. package/dist/src/algorithms/shortest-path/floyd-warshall.d.ts +15 -5
  59. package/dist/src/algorithms/shortest-path/floyd-warshall.d.ts.map +1 -1
  60. package/dist/src/algorithms/shortest-path/floyd-warshall.js +97 -107
  61. package/dist/src/algorithms/shortest-path/floyd-warshall.js.map +1 -1
  62. package/dist/src/algorithms/traversal/bfs-unified.d.ts +2 -12
  63. package/dist/src/algorithms/traversal/bfs-unified.d.ts.map +1 -1
  64. package/dist/src/algorithms/traversal/bfs-unified.js +47 -308
  65. package/dist/src/algorithms/traversal/bfs-unified.js.map +1 -1
  66. package/dist/src/algorithms/traversal/bfs-variants.d.ts.map +1 -1
  67. package/dist/src/algorithms/traversal/bfs-variants.js +5 -25
  68. package/dist/src/algorithms/traversal/bfs-variants.js.map +1 -1
  69. package/dist/src/algorithms/traversal/bfs.d.ts +0 -3
  70. package/dist/src/algorithms/traversal/bfs.d.ts.map +1 -1
  71. package/dist/src/algorithms/traversal/bfs.js +0 -4
  72. package/dist/src/algorithms/traversal/bfs.js.map +1 -1
  73. package/dist/src/algorithms/traversal/dfs.d.ts.map +1 -1
  74. package/dist/src/algorithms/traversal/dfs.js +33 -154
  75. package/dist/src/algorithms/traversal/dfs.js.map +1 -1
  76. package/dist/src/clustering/hierarchical-legacy.d.ts +56 -0
  77. package/dist/src/clustering/hierarchical-legacy.d.ts.map +1 -0
  78. package/dist/src/clustering/hierarchical-legacy.js +441 -0
  79. package/dist/src/clustering/hierarchical-legacy.js.map +1 -0
  80. package/dist/src/clustering/hierarchical.d.ts +7 -39
  81. package/dist/src/clustering/hierarchical.d.ts.map +1 -1
  82. package/dist/src/clustering/hierarchical.js +56 -417
  83. package/dist/src/clustering/hierarchical.js.map +1 -1
  84. package/dist/src/clustering/k-core-legacy.d.ts +30 -0
  85. package/dist/src/clustering/k-core-legacy.d.ts.map +1 -0
  86. package/dist/src/clustering/k-core-legacy.js +191 -0
  87. package/dist/src/clustering/k-core-legacy.js.map +1 -0
  88. package/dist/src/clustering/k-core.d.ts +8 -7
  89. package/dist/src/clustering/k-core.d.ts.map +1 -1
  90. package/dist/src/clustering/k-core.js +33 -174
  91. package/dist/src/clustering/k-core.js.map +1 -1
  92. package/dist/src/clustering/mcl-legacy.d.ts +42 -0
  93. package/dist/src/clustering/mcl-legacy.d.ts.map +1 -0
  94. package/dist/src/clustering/mcl-legacy.js +386 -0
  95. package/dist/src/clustering/mcl-legacy.js.map +1 -0
  96. package/dist/src/clustering/mcl.d.ts +9 -32
  97. package/dist/src/clustering/mcl.d.ts.map +1 -1
  98. package/dist/src/clustering/mcl.js +48 -374
  99. package/dist/src/clustering/mcl.js.map +1 -1
  100. package/dist/src/index.d.ts +29 -3
  101. package/dist/src/index.d.ts.map +1 -1
  102. package/dist/src/index.js +2 -1
  103. package/dist/src/index.js.map +1 -1
  104. package/dist/src/indexed/accelerator.d.ts +141 -11
  105. package/dist/src/indexed/accelerator.d.ts.map +1 -1
  106. package/dist/src/indexed/accelerator.js +319 -5
  107. package/dist/src/indexed/accelerator.js.map +1 -1
  108. package/dist/src/indexed/all-pairs.d.ts +59 -0
  109. package/dist/src/indexed/all-pairs.d.ts.map +1 -0
  110. package/dist/src/indexed/all-pairs.js +274 -0
  111. package/dist/src/indexed/all-pairs.js.map +1 -0
  112. package/dist/src/indexed/bellman-ford.d.ts +25 -0
  113. package/dist/src/indexed/bellman-ford.d.ts.map +1 -0
  114. package/dist/src/indexed/bellman-ford.js +59 -0
  115. package/dist/src/indexed/bellman-ford.js.map +1 -0
  116. package/dist/src/indexed/betweenness.d.ts +85 -0
  117. package/dist/src/indexed/betweenness.d.ts.map +1 -0
  118. package/dist/src/indexed/betweenness.js +188 -0
  119. package/dist/src/indexed/betweenness.js.map +1 -0
  120. package/dist/src/indexed/bfs.d.ts +69 -2
  121. package/dist/src/indexed/bfs.d.ts.map +1 -1
  122. package/dist/src/indexed/bfs.js +148 -1
  123. package/dist/src/indexed/bfs.js.map +1 -1
  124. package/dist/src/indexed/bipartite.d.ts +37 -0
  125. package/dist/src/indexed/bipartite.d.ts.map +1 -0
  126. package/dist/src/indexed/bipartite.js +54 -0
  127. package/dist/src/indexed/bipartite.js.map +1 -0
  128. package/dist/src/indexed/closeness.d.ts +49 -0
  129. package/dist/src/indexed/closeness.d.ts.map +1 -0
  130. package/dist/src/indexed/closeness.js +127 -0
  131. package/dist/src/indexed/closeness.js.map +1 -0
  132. package/dist/src/indexed/common-neighbors.d.ts +14 -1
  133. package/dist/src/indexed/common-neighbors.d.ts.map +1 -1
  134. package/dist/src/indexed/common-neighbors.js +24 -14
  135. package/dist/src/indexed/common-neighbors.js.map +1 -1
  136. package/dist/src/indexed/degree.d.ts +19 -0
  137. package/dist/src/indexed/degree.d.ts.map +1 -0
  138. package/dist/src/indexed/degree.js +45 -0
  139. package/dist/src/indexed/degree.js.map +1 -0
  140. package/dist/src/indexed/delta-pagerank.d.ts +145 -0
  141. package/dist/src/indexed/delta-pagerank.d.ts.map +1 -0
  142. package/dist/src/indexed/delta-pagerank.js +428 -0
  143. package/dist/src/indexed/delta-pagerank.js.map +1 -0
  144. package/dist/src/indexed/dfs.d.ts +55 -0
  145. package/dist/src/indexed/dfs.d.ts.map +1 -0
  146. package/dist/src/indexed/dfs.js +146 -0
  147. package/dist/src/indexed/dfs.js.map +1 -0
  148. package/dist/src/indexed/eigenvector.d.ts +48 -0
  149. package/dist/src/indexed/eigenvector.d.ts.map +1 -0
  150. package/dist/src/indexed/eigenvector.js +162 -0
  151. package/dist/src/indexed/eigenvector.js.map +1 -0
  152. package/dist/src/indexed/facade.d.ts +109 -0
  153. package/dist/src/indexed/facade.d.ts.map +1 -0
  154. package/dist/src/indexed/facade.js +204 -0
  155. package/dist/src/indexed/facade.js.map +1 -0
  156. package/dist/src/indexed/flow.d.ts +120 -0
  157. package/dist/src/indexed/flow.d.ts.map +1 -0
  158. package/dist/src/indexed/flow.js +377 -0
  159. package/dist/src/indexed/flow.js.map +1 -0
  160. package/dist/src/indexed/girvan-newman.d.ts +42 -0
  161. package/dist/src/indexed/girvan-newman.d.ts.map +1 -0
  162. package/dist/src/indexed/girvan-newman.js +90 -0
  163. package/dist/src/indexed/girvan-newman.js.map +1 -0
  164. package/dist/src/indexed/grsbm.d.ts +85 -0
  165. package/dist/src/indexed/grsbm.d.ts.map +1 -0
  166. package/dist/src/indexed/grsbm.js +287 -0
  167. package/dist/src/indexed/grsbm.js.map +1 -0
  168. package/dist/src/indexed/hierarchical.d.ts +69 -0
  169. package/dist/src/indexed/hierarchical.d.ts.map +1 -0
  170. package/dist/src/indexed/hierarchical.js +245 -0
  171. package/dist/src/indexed/hierarchical.js.map +1 -0
  172. package/dist/src/indexed/index.d.ts +29 -3
  173. package/dist/src/indexed/index.d.ts.map +1 -1
  174. package/dist/src/indexed/index.js +29 -3
  175. package/dist/src/indexed/index.js.map +1 -1
  176. package/dist/src/indexed/isomorphism.d.ts +42 -0
  177. package/dist/src/indexed/isomorphism.d.ts.map +1 -0
  178. package/dist/src/indexed/isomorphism.js +269 -0
  179. package/dist/src/indexed/isomorphism.js.map +1 -0
  180. package/dist/src/indexed/label-propagation.d.ts +134 -0
  181. package/dist/src/indexed/label-propagation.d.ts.map +1 -0
  182. package/dist/src/indexed/label-propagation.js +486 -0
  183. package/dist/src/indexed/label-propagation.js.map +1 -0
  184. package/dist/src/indexed/leiden.d.ts +52 -0
  185. package/dist/src/indexed/leiden.d.ts.map +1 -0
  186. package/dist/src/indexed/leiden.js +384 -0
  187. package/dist/src/indexed/leiden.js.map +1 -0
  188. package/dist/src/indexed/link-prediction.d.ts +147 -0
  189. package/dist/src/indexed/link-prediction.d.ts.map +1 -0
  190. package/dist/src/indexed/link-prediction.js +317 -0
  191. package/dist/src/indexed/link-prediction.js.map +1 -0
  192. package/dist/src/indexed/markov.d.ts +54 -0
  193. package/dist/src/indexed/markov.d.ts.map +1 -0
  194. package/dist/src/indexed/markov.js +284 -0
  195. package/dist/src/indexed/markov.js.map +1 -0
  196. package/dist/src/indexed/matching.d.ts +53 -0
  197. package/dist/src/indexed/matching.d.ts.map +1 -0
  198. package/dist/src/indexed/matching.js +139 -0
  199. package/dist/src/indexed/matching.js.map +1 -0
  200. package/dist/src/indexed/min-cut.d.ts +48 -0
  201. package/dist/src/indexed/min-cut.d.ts.map +1 -0
  202. package/dist/src/indexed/min-cut.js +175 -0
  203. package/dist/src/indexed/min-cut.js.map +1 -0
  204. package/dist/src/indexed/modularity.d.ts +34 -0
  205. package/dist/src/indexed/modularity.d.ts.map +1 -0
  206. package/dist/src/indexed/modularity.js +74 -0
  207. package/dist/src/indexed/modularity.js.map +1 -0
  208. package/dist/src/indexed/mst.d.ts +29 -1
  209. package/dist/src/indexed/mst.d.ts.map +1 -1
  210. package/dist/src/indexed/mst.js +62 -0
  211. package/dist/src/indexed/mst.js.map +1 -1
  212. package/dist/src/indexed/pagerank.d.ts +29 -6
  213. package/dist/src/indexed/pagerank.d.ts.map +1 -1
  214. package/dist/src/indexed/pagerank.js +107 -11
  215. package/dist/src/indexed/pagerank.js.map +1 -1
  216. package/dist/src/indexed/point-to-point.d.ts +53 -0
  217. package/dist/src/indexed/point-to-point.d.ts.map +1 -0
  218. package/dist/src/indexed/point-to-point.js +173 -0
  219. package/dist/src/indexed/point-to-point.js.map +1 -0
  220. package/dist/src/indexed/scc.d.ts +53 -0
  221. package/dist/src/indexed/scc.d.ts.map +1 -0
  222. package/dist/src/indexed/scc.js +110 -0
  223. package/dist/src/indexed/scc.js.map +1 -0
  224. package/dist/src/indexed/spectral.d.ts +61 -0
  225. package/dist/src/indexed/spectral.d.ts.map +1 -0
  226. package/dist/src/indexed/spectral.js +476 -0
  227. package/dist/src/indexed/spectral.js.map +1 -0
  228. package/dist/src/indexed/structures/bit-set.d.ts +45 -0
  229. package/dist/src/indexed/structures/bit-set.d.ts.map +1 -0
  230. package/dist/src/indexed/structures/bit-set.js +57 -0
  231. package/dist/src/indexed/structures/bit-set.js.map +1 -0
  232. package/dist/src/indexed/structures/max-heap.d.ts +52 -0
  233. package/dist/src/indexed/structures/max-heap.d.ts.map +1 -0
  234. package/dist/src/indexed/structures/max-heap.js +66 -0
  235. package/dist/src/indexed/structures/max-heap.js.map +1 -0
  236. package/dist/src/indexed/structures/min-heap.d.ts +30 -1
  237. package/dist/src/indexed/structures/min-heap.d.ts.map +1 -1
  238. package/dist/src/indexed/structures/min-heap.js +46 -6
  239. package/dist/src/indexed/structures/min-heap.js.map +1 -1
  240. package/dist/src/indexed/structures/ring-queue.d.ts +41 -0
  241. package/dist/src/indexed/structures/ring-queue.d.ts.map +1 -0
  242. package/dist/src/indexed/structures/ring-queue.js +64 -0
  243. package/dist/src/indexed/structures/ring-queue.js.map +1 -0
  244. package/dist/src/indexed/sync.d.ts +50 -0
  245. package/dist/src/indexed/sync.d.ts.map +1 -0
  246. package/dist/src/indexed/sync.js +175 -0
  247. package/dist/src/indexed/sync.js.map +1 -0
  248. package/dist/src/indexed/terahac.d.ts +58 -0
  249. package/dist/src/indexed/terahac.d.ts.map +1 -0
  250. package/dist/src/indexed/terahac.js +244 -0
  251. package/dist/src/indexed/terahac.js.map +1 -0
  252. package/dist/src/indexed/to-snapshot.d.ts +45 -2
  253. package/dist/src/indexed/to-snapshot.d.ts.map +1 -1
  254. package/dist/src/indexed/to-snapshot.js +140 -6
  255. package/dist/src/indexed/to-snapshot.js.map +1 -1
  256. package/dist/src/link-prediction/common-neighbors-legacy.d.ts +71 -0
  257. package/dist/src/link-prediction/common-neighbors-legacy.d.ts.map +1 -0
  258. package/dist/src/link-prediction/common-neighbors-legacy.js +172 -0
  259. package/dist/src/link-prediction/common-neighbors-legacy.js.map +1 -0
  260. package/dist/src/link-prediction/common-neighbors.d.ts +11 -19
  261. package/dist/src/link-prediction/common-neighbors.d.ts.map +1 -1
  262. package/dist/src/link-prediction/common-neighbors.js +56 -123
  263. package/dist/src/link-prediction/common-neighbors.js.map +1 -1
  264. package/dist/src/optimized/direction-optimized-bfs.d.ts +6 -0
  265. package/dist/src/optimized/direction-optimized-bfs.d.ts.map +1 -1
  266. package/dist/src/optimized/direction-optimized-bfs.js +6 -0
  267. package/dist/src/optimized/direction-optimized-bfs.js.map +1 -1
  268. package/dist/src/research/grsbm-legacy.d.ts +82 -0
  269. package/dist/src/research/grsbm-legacy.d.ts.map +1 -0
  270. package/dist/src/research/grsbm-legacy.js +416 -0
  271. package/dist/src/research/grsbm-legacy.js.map +1 -0
  272. package/dist/src/research/grsbm.d.ts +9 -66
  273. package/dist/src/research/grsbm.d.ts.map +1 -1
  274. package/dist/src/research/grsbm.js +67 -391
  275. package/dist/src/research/grsbm.js.map +1 -1
  276. package/dist/src/research/sync-legacy.d.ts +48 -0
  277. package/dist/src/research/sync-legacy.d.ts.map +1 -0
  278. package/dist/src/research/sync-legacy.js +337 -0
  279. package/dist/src/research/sync-legacy.js.map +1 -0
  280. package/dist/src/research/sync.d.ts +10 -32
  281. package/dist/src/research/sync.d.ts.map +1 -1
  282. package/dist/src/research/sync.js +28 -316
  283. package/dist/src/research/sync.js.map +1 -1
  284. package/package.json +4 -3
  285. package/src/algorithms/centrality/betweenness.ts +51 -1
  286. package/src/algorithms/centrality/closeness.ts +112 -12
  287. package/src/algorithms/centrality/degree.ts +19 -0
  288. package/src/algorithms/centrality/eigenvector.ts +34 -0
  289. package/src/algorithms/centrality/hits.ts +24 -0
  290. package/src/algorithms/centrality/katz.ts +32 -0
  291. package/src/algorithms/centrality/pagerank.ts +53 -13
  292. package/src/algorithms/community/girvan-newman-legacy.ts +414 -0
  293. package/src/algorithms/community/girvan-newman.ts +36 -386
  294. package/src/algorithms/community/label-propagation.ts +24 -133
  295. package/src/algorithms/components/connected.ts +28 -95
  296. package/src/algorithms/mst/kruskal.ts +65 -4
  297. package/src/algorithms/shortest-path/bellman-ford.ts +49 -0
  298. package/src/algorithms/shortest-path/dijkstra.ts +29 -0
  299. package/src/algorithms/shortest-path/floyd-warshall.ts +106 -136
  300. package/src/algorithms/traversal/bfs-unified.ts +52 -366
  301. package/src/algorithms/traversal/bfs-variants.ts +5 -28
  302. package/src/algorithms/traversal/bfs.ts +0 -4
  303. package/src/algorithms/traversal/dfs.ts +39 -182
  304. package/src/clustering/hierarchical-legacy.ts +551 -0
  305. package/src/clustering/hierarchical.ts +64 -520
  306. package/src/clustering/k-core-legacy.ts +229 -0
  307. package/src/clustering/k-core.ts +38 -209
  308. package/src/clustering/mcl-legacy.ts +498 -0
  309. package/src/clustering/mcl.ts +46 -479
  310. package/src/index.ts +90 -3
  311. package/src/indexed/accelerator.ts +502 -16
  312. package/src/indexed/all-pairs.ts +342 -0
  313. package/src/indexed/bellman-ford.ts +72 -0
  314. package/src/indexed/betweenness.ts +258 -0
  315. package/src/indexed/bfs.ts +189 -3
  316. package/src/indexed/bipartite.ts +77 -0
  317. package/src/indexed/closeness.ts +160 -0
  318. package/src/indexed/common-neighbors.ts +31 -14
  319. package/src/indexed/degree.ts +55 -0
  320. package/src/indexed/delta-pagerank.ts +513 -0
  321. package/src/indexed/dfs.ts +189 -0
  322. package/src/indexed/eigenvector.ts +202 -0
  323. package/src/indexed/facade.ts +229 -0
  324. package/src/indexed/flow.ts +500 -0
  325. package/src/indexed/girvan-newman.ts +120 -0
  326. package/src/indexed/grsbm.ts +390 -0
  327. package/src/indexed/hierarchical.ts +295 -0
  328. package/src/indexed/index.ts +94 -3
  329. package/src/indexed/isomorphism.ts +305 -0
  330. package/src/indexed/label-propagation.ts +582 -0
  331. package/src/indexed/leiden.ts +436 -0
  332. package/src/indexed/link-prediction.ts +399 -0
  333. package/src/indexed/markov.ts +324 -0
  334. package/src/indexed/matching.ts +192 -0
  335. package/src/indexed/min-cut.ts +201 -0
  336. package/src/indexed/modularity.ts +81 -0
  337. package/src/indexed/mst.ts +79 -1
  338. package/src/indexed/pagerank.ts +128 -15
  339. package/src/indexed/point-to-point.ts +220 -0
  340. package/src/indexed/scc.ts +132 -0
  341. package/src/indexed/spectral.ts +550 -0
  342. package/src/indexed/structures/bit-set.ts +65 -0
  343. package/src/indexed/structures/max-heap.ts +74 -0
  344. package/src/indexed/structures/min-heap.ts +51 -6
  345. package/src/indexed/structures/ring-queue.ts +70 -0
  346. package/src/indexed/sync.ts +229 -0
  347. package/src/indexed/terahac.ts +290 -0
  348. package/src/indexed/to-snapshot.ts +156 -6
  349. package/src/link-prediction/common-neighbors-legacy.ts +252 -0
  350. package/src/link-prediction/common-neighbors.ts +65 -168
  351. package/src/optimized/direction-optimized-bfs.ts +6 -1
  352. package/src/research/grsbm-legacy.ts +586 -0
  353. package/src/research/grsbm.ts +76 -555
  354. package/src/research/sync-legacy.ts +456 -0
  355. package/src/research/sync.ts +30 -431
@@ -0,0 +1 @@
1
+ {"version":3,"file":"girvan-newman.js","sourceRoot":"","sources":["../../../src/indexed/girvan-newman.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,85 @@
1
+ import { type F64, type GraphSnapshot, type U32 } from "@graphty/graph-format";
2
+ import { type LabelResult } from "./components.js";
3
+ /** Options of the index-based GRSBM, matching the legacy `grsbm`. @public */
4
+ export interface GrsbmOptions {
5
+ /** Clusters at this depth are not split; default 10. */
6
+ readonly maxDepth?: number | undefined;
7
+ /** A cluster is split only when it has at least twice this many members; default 2. */
8
+ readonly minClusterSize?: number | undefined;
9
+ /** Convergence tolerance of the Fiedler-vector iteration; default 1e-6. */
10
+ readonly tolerance?: number | undefined;
11
+ /** Iteration cap of the Fiedler-vector iteration; default 100. */
12
+ readonly maxIterations?: number | undefined;
13
+ /** Seed of the iteration's start vectors; default 42. */
14
+ readonly seed?: number | undefined;
15
+ /**
16
+ * Use arc weights in the Laplacian and the modularity (true, the default), or count arcs
17
+ * (false, which is what the legacy `grsbm` does). A parallel arc counts once per arc.
18
+ */
19
+ readonly weighted?: boolean | undefined;
20
+ }
21
+ /** Why a cluster was split: the legacy `ClusterExplanation`, over node indices. @public */
22
+ export interface GrsbmSplit {
23
+ /** The split's modularity minus the parent's. */
24
+ readonly improvement: number;
25
+ /** Modularity of the chosen split point (the legacy explanation text prints it to 3 places). */
26
+ readonly bisectionModularity: number;
27
+ /** Up to five members with the largest-magnitude Fiedler values, in member order. */
28
+ readonly keyNodes: U32;
29
+ /** The Fiedler vector, one value per member in member order. */
30
+ readonly spectralValues: F64;
31
+ }
32
+ /** One cluster of the hierarchy. @public */
33
+ export interface GrsbmCluster {
34
+ /**
35
+ * 0 for the root, k for the k-th cluster a bisection proposed, counting the proposals that were
36
+ * rejected: the number in the legacy id `cluster_k`.
37
+ */
38
+ readonly serial: number;
39
+ /** Member node indices, in the legacy member order. */
40
+ readonly members: U32;
41
+ /** Depth below the root. */
42
+ readonly depth: number;
43
+ /** Modularity of the split that made this cluster (the root: of the whole graph as one cluster). */
44
+ readonly modularity: number;
45
+ /** Spread of the Fiedler values of the split that made this cluster; 0 for the root. */
46
+ readonly spectralScore: number;
47
+ /** Index in `clusters` of the left child, or `INVALID_INDEX` for a leaf. */
48
+ readonly left: number;
49
+ /** Index in `clusters` of the right child, or `INVALID_INDEX` for a leaf. */
50
+ readonly right: number;
51
+ /** Why this cluster was split; null for a leaf. */
52
+ readonly split: GrsbmSplit | null;
53
+ }
54
+ /**
55
+ * Result of the index-based GRSBM: the leaves as a partition, plus the hierarchy. `clusters[0]` is
56
+ * the root; the others follow in the order they were made, children in pairs.
57
+ * @public
58
+ */
59
+ export interface GrsbmResult extends LabelResult {
60
+ /** Every cluster of the hierarchy. */
61
+ readonly clusters: readonly GrsbmCluster[];
62
+ /** The root's modularity, then each accepted split's, in split order. */
63
+ readonly modularityScores: F64;
64
+ }
65
+ /**
66
+ * GRSBM over a snapshot: recursive spectral bisection. Each cluster's Laplacian (over the arcs
67
+ * between its members, self-loops left out) gives an approximate Fiedler vector; members are sorted
68
+ * by it and cut at the point between 20% and 80% that maximises modularity; the split is kept when
69
+ * modularity drops by no more than 0.01. The arithmetic and the random draws are the legacy
70
+ * `grsbm`'s, so with `weighted: false` the result equals legacy's exactly on a graph without
71
+ * self-loops; the port draws from its own generator instead of replacing `Math.random`.
72
+ *
73
+ * Modularity uses `weightedDegree()` (a self-loop counts twice) against `totalWeight()`, or
74
+ * `degree()` against the edge count when unweighted. Like legacy's, a split's modularity sums only
75
+ * the two halves of the cluster being split. A self-loop follows the standard convention (left out
76
+ * of the Laplacian, twice in the degree), so on a graph with self-loops the result differs from
77
+ * legacy's, which scores the whole graph as one community above 0. On a directed graph the
78
+ * unweighted path keeps legacy's halving of internal arcs; the weighted path does not, so there the
79
+ * whole graph as one community scores 0. Weights must be finite and non-negative (RangeError).
80
+ * @param s - The snapshot
81
+ * @param options - {@link GrsbmOptions}
82
+ * @returns The leaf partition and the hierarchy
83
+ */
84
+ export declare function grsbm(s: GraphSnapshot, options?: GrsbmOptions): GrsbmResult;
85
+ //# sourceMappingURL=grsbm.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"grsbm.d.ts","sourceRoot":"","sources":["../../../src/indexed/grsbm.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,GAAG,EAAE,KAAK,aAAa,EAAoC,KAAK,GAAG,EAAE,MAAM,uBAAuB,CAAC;AAGjH,OAAO,EAAE,KAAK,WAAW,EAAc,MAAM,iBAAiB,CAAC;AAE/D,6EAA6E;AAC7E,MAAM,WAAW,YAAY;IACzB,wDAAwD;IACxD,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACvC,uFAAuF;IACvF,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7C,2EAA2E;IAC3E,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACxC,kEAAkE;IAClE,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5C,yDAAyD;IACzD,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACnC;;;OAGG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;CAC3C;AAED,2FAA2F;AAC3F,MAAM,WAAW,UAAU;IACvB,iDAAiD;IACjD,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,gGAAgG;IAChG,QAAQ,CAAC,mBAAmB,EAAE,MAAM,CAAC;IACrC,qFAAqF;IACrF,QAAQ,CAAC,QAAQ,EAAE,GAAG,CAAC;IACvB,gEAAgE;IAChE,QAAQ,CAAC,cAAc,EAAE,GAAG,CAAC;CAChC;AAED,4CAA4C;AAC5C,MAAM,WAAW,YAAY;IACzB;;;OAGG;IACH,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,uDAAuD;IACvD,QAAQ,CAAC,OAAO,EAAE,GAAG,CAAC;IACtB,4BAA4B;IAC5B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,oGAAoG;IACpG,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,wFAAwF;IACxF,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,4EAA4E;IAC5E,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,6EAA6E;IAC7E,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,mDAAmD;IACnD,QAAQ,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI,CAAC;CACrC;AAED;;;;GAIG;AACH,MAAM,WAAW,WAAY,SAAQ,WAAW;IAC5C,sCAAsC;IACtC,QAAQ,CAAC,QAAQ,EAAE,SAAS,YAAY,EAAE,CAAC;IAC3C,yEAAyE;IACzE,QAAQ,CAAC,gBAAgB,EAAE,GAAG,CAAC;CAClC;AAaD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,KAAK,CAAC,CAAC,EAAE,aAAa,EAAE,OAAO,GAAE,YAAiB,GAAG,WAAW,CAkL/E"}
@@ -0,0 +1,287 @@
1
+ import { INVALID_INDEX, renumberPartition } from "@graphty/graph-format";
2
+ import { SeededRandom } from "../utils/math-utilities.js";
3
+ import { withGroups } from "./components.js";
4
+ /**
5
+ * GRSBM over a snapshot: recursive spectral bisection. Each cluster's Laplacian (over the arcs
6
+ * between its members, self-loops left out) gives an approximate Fiedler vector; members are sorted
7
+ * by it and cut at the point between 20% and 80% that maximises modularity; the split is kept when
8
+ * modularity drops by no more than 0.01. The arithmetic and the random draws are the legacy
9
+ * `grsbm`'s, so with `weighted: false` the result equals legacy's exactly on a graph without
10
+ * self-loops; the port draws from its own generator instead of replacing `Math.random`.
11
+ *
12
+ * Modularity uses `weightedDegree()` (a self-loop counts twice) against `totalWeight()`, or
13
+ * `degree()` against the edge count when unweighted. Like legacy's, a split's modularity sums only
14
+ * the two halves of the cluster being split. A self-loop follows the standard convention (left out
15
+ * of the Laplacian, twice in the degree), so on a graph with self-loops the result differs from
16
+ * legacy's, which scores the whole graph as one community above 0. On a directed graph the
17
+ * unweighted path keeps legacy's halving of internal arcs; the weighted path does not, so there the
18
+ * whole graph as one community scores 0. Weights must be finite and non-negative (RangeError).
19
+ * @param s - The snapshot
20
+ * @param options - {@link GrsbmOptions}
21
+ * @returns The leaf partition and the hierarchy
22
+ */
23
+ export function grsbm(s, options = {}) {
24
+ const { maxDepth = 10, minClusterSize = 2, tolerance = 1e-6, maxIterations = 100, seed = 42, weighted = true, } = options;
25
+ const n = s.nodeCount;
26
+ if (n === 0) {
27
+ throw new Error("Cannot cluster empty graph");
28
+ }
29
+ const random = SeededRandom.createGenerator(seed);
30
+ const arcWeights = weighted ? s.weights : null;
31
+ if (arcWeights !== null) {
32
+ for (let a = 0; a < arcWeights.length; a++) {
33
+ const w = arcWeights[a];
34
+ if (!(w >= 0) || w === Infinity) {
35
+ throw new RangeError(`arc ${String(a)} has weight ${String(w)}; grsbm needs finite, non-negative weights`);
36
+ }
37
+ }
38
+ }
39
+ const degree = weighted ? s.weightedDegree() : s.degree();
40
+ const m = weighted ? s.totalWeight() : s.edgeCount;
41
+ const loopFactor = s.directed ? 1 : 2;
42
+ // An undirected edge is stored as two arcs, so the internal sum counts it twice. A directed arc is
43
+ // stored once; legacy halves it anyway (the whole graph as one community scores -0.5), and the
44
+ // unweighted path keeps that for parity.
45
+ const halveInternal = !s.directed || !weighted;
46
+ const { rowPtr, colIdx } = s;
47
+ // side[u]: the community of u in the split being scored, -1 outside the cluster.
48
+ const side = new Int32Array(n).fill(-1);
49
+ const communityTerm = (group) => {
50
+ let internal = 0;
51
+ let total = 0;
52
+ for (let p = 0; p < group.length; p++) {
53
+ const u = group[p];
54
+ total += degree[u];
55
+ for (let a = rowPtr[u]; a < rowPtr[u + 1]; a++) {
56
+ const v = colIdx[a];
57
+ if (side[v] === side[u]) {
58
+ const w = arcWeights === null ? 1 : arcWeights[a];
59
+ internal += v === u ? loopFactor * w : w;
60
+ }
61
+ }
62
+ }
63
+ if (halveInternal) {
64
+ internal /= 2;
65
+ }
66
+ return (internal - (total * total) / (4 * m)) / m;
67
+ };
68
+ const modularity = (groups) => {
69
+ if (m === 0) {
70
+ return 0;
71
+ }
72
+ let q = 0;
73
+ groups.forEach((group, c) => {
74
+ for (let p = 0; p < group.length; p++) {
75
+ side[group[p]] = c;
76
+ }
77
+ });
78
+ for (const group of groups) {
79
+ if (group.length > 0) {
80
+ q += communityTerm(group);
81
+ }
82
+ }
83
+ for (const group of groups) {
84
+ for (let p = 0; p < group.length; p++) {
85
+ side[group[p]] = -1;
86
+ }
87
+ }
88
+ return q;
89
+ };
90
+ const everyone = new Uint32Array(n);
91
+ for (let i = 0; i < n; i++) {
92
+ everyone[i] = i;
93
+ }
94
+ const initial = modularity([everyone]);
95
+ const clusters = [
96
+ {
97
+ serial: 0,
98
+ members: everyone,
99
+ depth: 0,
100
+ modularity: initial,
101
+ spectralScore: 0,
102
+ left: INVALID_INDEX,
103
+ right: INVALID_INDEX,
104
+ split: null,
105
+ },
106
+ ];
107
+ const scores = [initial];
108
+ const position = new Int32Array(n).fill(-1);
109
+ let nextSerial = 1;
110
+ // The clusters array doubles as the breadth-first work queue: children are appended as made.
111
+ for (let head = 0; head < clusters.length; head++) {
112
+ const cluster = clusters[head];
113
+ const { members } = cluster;
114
+ const size = members.length;
115
+ if (cluster.depth >= maxDepth || size < minClusterSize * 2 || size < 4) {
116
+ continue;
117
+ }
118
+ const fiedler = fiedlerVector(members, position, s, arcWeights, random, tolerance, maxIterations);
119
+ const order = Array.from({ length: size }, (_, p) => p).sort((a, b) => fiedler[a] - fiedler[b]);
120
+ const sorted = Uint32Array.from(order, (p) => members[p]);
121
+ let bestSplit = Math.floor(size / 2);
122
+ let best = -Infinity;
123
+ for (let cut = Math.floor(size * 0.2); cut <= Math.floor(size * 0.8); cut++) {
124
+ const q = modularity([sorted.subarray(0, cut), sorted.subarray(cut)]);
125
+ if (q > best) {
126
+ best = q;
127
+ bestSplit = cut;
128
+ }
129
+ }
130
+ const leftMembers = sorted.slice(0, bestSplit);
131
+ const rightMembers = sorted.slice(bestSplit);
132
+ const byMagnitude = Array.from(fiedler).sort((a, b) => Math.abs(b) - Math.abs(a));
133
+ const threshold = Math.abs(byMagnitude[Math.floor(size * 0.1)]);
134
+ const keyNodes = [];
135
+ for (let p = 0; p < size && keyNodes.length < 5; p++) {
136
+ if (Math.abs(fiedler[p]) >= threshold) {
137
+ keyNodes.push(members[p]);
138
+ }
139
+ }
140
+ const spectralScore = Math.abs(byMagnitude[0] - byMagnitude[size - 1]);
141
+ const leftSerial = nextSerial++;
142
+ const rightSerial = nextSerial++;
143
+ const improvement = best - cluster.modularity;
144
+ if (improvement < -0.01) {
145
+ continue;
146
+ }
147
+ const child = (serial, childMembers) => ({
148
+ serial,
149
+ members: childMembers,
150
+ depth: cluster.depth + 1,
151
+ modularity: best,
152
+ spectralScore,
153
+ left: INVALID_INDEX,
154
+ right: INVALID_INDEX,
155
+ split: null,
156
+ });
157
+ cluster.left = clusters.length;
158
+ cluster.right = clusters.length + 1;
159
+ cluster.split = {
160
+ improvement,
161
+ bisectionModularity: best,
162
+ keyNodes: Uint32Array.from(keyNodes),
163
+ spectralValues: fiedler,
164
+ };
165
+ clusters.push(child(leftSerial, leftMembers), child(rightSerial, rightMembers));
166
+ scores.push(best);
167
+ }
168
+ // One label per leaf, renumbered by each leaf's lowest node index.
169
+ const leafOf = new Uint32Array(n);
170
+ let leaves = 0;
171
+ const stack = [0];
172
+ while (stack.length > 0) {
173
+ const c = clusters[stack.pop() ?? 0];
174
+ if (c.left === INVALID_INDEX) {
175
+ for (const u of c.members) {
176
+ leafOf[u] = leaves;
177
+ }
178
+ leaves++;
179
+ }
180
+ else {
181
+ stack.push(c.right, c.left);
182
+ }
183
+ }
184
+ const { labels, count } = renumberPartition(leafOf);
185
+ return { ...withGroups(labels, count), clusters, modularityScores: Float64Array.from(scores) };
186
+ }
187
+ /**
188
+ * Legacy's approximate Fiedler vector of a cluster's Laplacian: a seeded random start orthogonal to
189
+ * the all-ones vector, then repeated multiplication by -L, re-centred and normalised, until it stops
190
+ * moving. Each row is summed in member order, the order legacy's dense matrix product uses, so the
191
+ * vector matches legacy's to the last bit.
192
+ * @param members - The cluster's node indices
193
+ * @param position - Scratch, -1 everywhere on entry and exit
194
+ * @param s - The snapshot
195
+ * @param arcWeights - Arc weights, or null to count arcs
196
+ * @param random - The generator
197
+ * @param tolerance - Convergence tolerance
198
+ * @param maxIterations - Iteration cap
199
+ * @returns One value per member
200
+ */
201
+ function fiedlerVector(members, position, s, arcWeights, random, tolerance, maxIterations) {
202
+ const size = members.length;
203
+ for (let p = 0; p < size; p++) {
204
+ position[members[p]] = p;
205
+ }
206
+ // The Laplacian as sorted sparse rows: off-diagonal -w per member neighbour, diagonal their sum.
207
+ const rowStart = new Uint32Array(size + 1);
208
+ const cols = [];
209
+ const vals = [];
210
+ const row = new Map();
211
+ for (let p = 0; p < size; p++) {
212
+ const u = members[p];
213
+ row.clear();
214
+ let diagonal = 0;
215
+ for (let a = s.rowPtr[u]; a < s.rowPtr[u + 1]; a++) {
216
+ const q = position[s.colIdx[a]];
217
+ if (q >= 0 && q !== p) {
218
+ const w = arcWeights === null ? 1 : arcWeights[a];
219
+ row.set(q, (row.get(q) ?? 0) - w);
220
+ diagonal += w;
221
+ }
222
+ }
223
+ row.set(p, diagonal);
224
+ for (const q of [...row.keys()].sort((a, b) => a - b)) {
225
+ cols.push(q);
226
+ vals.push(row.get(q) ?? 0);
227
+ }
228
+ rowStart[p + 1] = cols.length;
229
+ }
230
+ for (let p = 0; p < size; p++) {
231
+ position[members[p]] = -1;
232
+ }
233
+ let vector = new Float64Array(size);
234
+ for (let p = 0; p < size; p++) {
235
+ vector[p] = random() - 0.5;
236
+ }
237
+ const recentre = (v) => {
238
+ let sum = 0;
239
+ for (const x of v) {
240
+ sum += x;
241
+ }
242
+ const mean = sum / size;
243
+ for (let p = 0; p < size; p++) {
244
+ v[p] -= mean;
245
+ }
246
+ };
247
+ const norm = (v) => {
248
+ let sum = 0;
249
+ for (const x of v) {
250
+ sum += x * x;
251
+ }
252
+ return Math.sqrt(sum);
253
+ };
254
+ recentre(vector);
255
+ const start = norm(vector);
256
+ if (start > 0) {
257
+ for (let p = 0; p < size; p++) {
258
+ vector[p] /= start;
259
+ }
260
+ }
261
+ for (let iteration = 0; iteration < maxIterations; iteration++) {
262
+ const next = new Float64Array(size);
263
+ for (let p = 0; p < size; p++) {
264
+ let sum = 0;
265
+ for (let k = rowStart[p]; k < rowStart[p + 1]; k++) {
266
+ sum += vals[k] * vector[cols[k]];
267
+ }
268
+ next[p] = -sum;
269
+ }
270
+ recentre(next);
271
+ const length = norm(next);
272
+ if (length < tolerance) {
273
+ break;
274
+ }
275
+ let moved = 0;
276
+ for (let p = 0; p < size; p++) {
277
+ next[p] /= length;
278
+ moved += Math.abs(next[p] - vector[p]);
279
+ }
280
+ vector = next;
281
+ if (moved < tolerance) {
282
+ break;
283
+ }
284
+ }
285
+ return vector;
286
+ }
287
+ //# sourceMappingURL=grsbm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"grsbm.js","sourceRoot":"","sources":["../../../src/indexed/grsbm.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,69 @@
1
+ import { type AdjacencyView } from "@graphty/graph-format";
2
+ /** How the distance between two clusters is taken from their members' hop distances. @public */
3
+ export type Linkage = "single" | "complete" | "average" | "ward";
4
+ /** Options of the index-based hierarchical clustering. @public */
5
+ export interface HierarchicalOptions {
6
+ /** Cluster distance: the minimum, maximum or mean member distance, or Ward's scaled mean; default single. */
7
+ readonly linkage?: Linkage | undefined;
8
+ }
9
+ /**
10
+ * The dendrogram of an agglomerative clustering. Clusters `0 .. nodeCount - 1` are the nodes
11
+ * themselves; merge `k` creates cluster `nodeCount + k` from `left[k]` and `right[k]`.
12
+ * @public
13
+ */
14
+ export interface HierarchicalResult {
15
+ /** The node count the clustering ran over. */
16
+ readonly nodeCount: number;
17
+ /** First cluster of every merge. */
18
+ readonly left: Uint32Array;
19
+ /** Second cluster of every merge. */
20
+ readonly right: Uint32Array;
21
+ /** Linkage distance of every merge. */
22
+ readonly distance: Float64Array;
23
+ /** Height of every cluster: 0 for a node, one more than its taller child for a merge. */
24
+ readonly height: Uint32Array;
25
+ /**
26
+ * The clusters left unmerged, in the order the legacy function lists its forest's trees: one
27
+ * entry (the last merge) when every pair of nodes could be linked, one per disconnected part
28
+ * otherwise, and none for an empty snapshot.
29
+ */
30
+ readonly roots: Uint32Array;
31
+ /**
32
+ * The node indices of a cluster, left subtree first -- the order the legacy function's member
33
+ * Sets iterate in.
34
+ * @param cluster - A cluster index
35
+ */
36
+ members(cluster: number): Uint32Array;
37
+ /**
38
+ * Cut every root at `height`: a cluster no taller than `height` is kept whole, a taller one is
39
+ * replaced by its two children. The clusters come in left-to-right order, root by root.
40
+ * @param height - The cut height
41
+ */
42
+ cut(height: number): Uint32Array[];
43
+ }
44
+ /**
45
+ * Agglomerative hierarchical clustering over hop distances, the index-based port of the legacy
46
+ * `hierarchicalClustering`: every node starts as its own cluster and the closest pair is merged
47
+ * until one cluster remains or no remaining pair is linked by a path.
48
+ *
49
+ * The distance between two nodes is the BFS hop count over out-arcs (weights are ignored, as the
50
+ * legacy function ignores them); an unreachable pair has none and is left out of every linkage.
51
+ * The distance between two clusters over the member pairs that have one is their minimum
52
+ * (`single`), maximum (`complete`), mean (`average`), or mean times `|A| |B| / (|A| + |B|)`
53
+ * (`ward`). A pair with no connected member pair is never merged. On a directed snapshot the
54
+ * distance is taken in one direction, and which one follows the legacy function exactly, as do the
55
+ * tie-breaks: the merges, their order and their distances equal the legacy function's.
56
+ *
57
+ * One difference in what the result offers: `cut` descends into every root of a disconnected
58
+ * snapshot, where the legacy `clusters` map lists all nodes as one cluster at every height (its
59
+ * forest node has no children, so its cut never splits it).
60
+ *
61
+ * O(n^2) memory for the distance aggregates and O(n^3) time for the pair search; the legacy
62
+ * function is the same order with Map and Set per step.
63
+ * @param s - Any snapshot or adjacency view
64
+ * @param options - The linkage
65
+ * @returns The dendrogram
66
+ * @public
67
+ */
68
+ export declare function hierarchicalClustering(s: AdjacencyView, options?: HierarchicalOptions): HierarchicalResult;
69
+ //# sourceMappingURL=hierarchical.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hierarchical.d.ts","sourceRoot":"","sources":["../../../src/indexed/hierarchical.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,aAAa,EAAiB,MAAM,uBAAuB,CAAC;AAE1E,gGAAgG;AAChG,MAAM,MAAM,OAAO,GAAG,QAAQ,GAAG,UAAU,GAAG,SAAS,GAAG,MAAM,CAAC;AAEjE,kEAAkE;AAClE,MAAM,WAAW,mBAAmB;IAChC,6GAA6G;IAC7G,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;CAC1C;AAED;;;;GAIG;AACH,MAAM,WAAW,kBAAkB;IAC/B,8CAA8C;IAC9C,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,oCAAoC;IACpC,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC;IAC3B,qCAAqC;IACrC,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAC;IAC5B,uCAAuC;IACvC,QAAQ,CAAC,QAAQ,EAAE,YAAY,CAAC;IAChC,yFAAyF;IACzF,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;IAC7B;;;;OAIG;IACH,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAC;IAC5B;;;;OAIG;IACH,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,WAAW,CAAC;IACtC;;;;OAIG;IACH,GAAG,CAAC,MAAM,EAAE,MAAM,GAAG,WAAW,EAAE,CAAC;CACtC;AAqDD;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,sBAAsB,CAAC,CAAC,EAAE,aAAa,EAAE,OAAO,GAAE,mBAAwB,GAAG,kBAAkB,CA4K9G"}