@graphty/algorithms 2.1.1 → 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,175 @@
1
+ import { SeededRandom } from "../utils/math-utilities.js";
2
+ /**
3
+ * Euclidean distance between two rows of a row-major matrix.
4
+ * @param a - First matrix
5
+ * @param i - Row of a
6
+ * @param b - Second matrix
7
+ * @param j - Row of b
8
+ * @param dim - Row length
9
+ * @returns The distance
10
+ */
11
+ function distance(a, i, b, j, dim) {
12
+ let sum = 0;
13
+ for (let k = 0; k < dim; k++) {
14
+ const diff = a[i * dim + k] - b[j * dim + k];
15
+ sum += diff * diff;
16
+ }
17
+ return Math.sqrt(sum);
18
+ }
19
+ /**
20
+ * SynC over a snapshot: node embeddings seeded from degree and a seeded generator, pulled toward
21
+ * their out-neighbours by gradient steps, and clustered by k-means with k-means++ centres. The
22
+ * arithmetic, and the order of every random draw, are the legacy `syncClustering`'s, so for the same
23
+ * seed the labels and embeddings agree with it to rounding; the port draws from its own generator
24
+ * instead of replacing `Math.random` for the duration of the call.
25
+ *
26
+ * Weights are ignored and a parallel arc pulls once per arc. The seeding degree is legacy's: in plus
27
+ * out when directed, the stored arc count when undirected, so an undirected self-loop counts once.
28
+ * @param s - The snapshot
29
+ * @param options - {@link SyncClusteringOptions}
30
+ * @returns Assignments, embeddings and convergence
31
+ */
32
+ export function syncClustering(s, options) {
33
+ const { numClusters, maxIterations = 100, tolerance = 1e-6, seed = 42, learningRate = 0.01, lambda = 0.1, } = options;
34
+ const n = s.nodeCount;
35
+ if (n === 0) {
36
+ return {
37
+ labels: new Uint32Array(0),
38
+ count: numClusters,
39
+ embeddings: new Float64Array(0),
40
+ dimensions: 0,
41
+ loss: 0,
42
+ previousLoss: Infinity,
43
+ iterations: 0,
44
+ converged: true,
45
+ };
46
+ }
47
+ if (!Number.isInteger(numClusters) || numClusters <= 0 || numClusters > n) {
48
+ throw new Error(`Invalid number of clusters: ${String(numClusters)}. Must be between 1 and ${String(n)}`);
49
+ }
50
+ const random = SeededRandom.createGenerator(seed);
51
+ const dim = Math.min(64, n);
52
+ const { rowPtr, colIdx } = s;
53
+ const emb = new Float64Array(n * dim);
54
+ // Legacy's degree: an undirected self-loop counts once (its single stored arc), not twice.
55
+ const degree = s.directed ? s.degree() : s.outDegree();
56
+ for (let u = 0; u < n; u++) {
57
+ const normalized = degree[u] / Math.max(1, n - 1);
58
+ for (let k = 0; k < dim; k++) {
59
+ emb[u * dim + k] = (random() - 0.5) * 0.1 + normalized * 0.1;
60
+ }
61
+ }
62
+ // k-means++: the first centre uniformly, each next one with probability proportional to the
63
+ // squared distance to the nearest centre so far. A draw that rounding carries past the last
64
+ // node adds no centre, as in legacy, so there may be fewer than numClusters.
65
+ const centres = new Float64Array(numClusters * dim);
66
+ const pick = Math.floor(random() * n);
67
+ centres.set(emb.subarray(pick * dim, (pick + 1) * dim), 0);
68
+ let centreCount = 1;
69
+ const weight = new Float64Array(n);
70
+ for (let k = 1; k < numClusters; k++) {
71
+ let total = 0;
72
+ for (let u = 0; u < n; u++) {
73
+ let nearest = Infinity;
74
+ for (let c = 0; c < centreCount; c++) {
75
+ nearest = Math.min(nearest, distance(emb, u, centres, c, dim));
76
+ }
77
+ weight[u] = nearest * nearest;
78
+ total += nearest * nearest;
79
+ }
80
+ let draw = random() * total;
81
+ for (let u = 0; u < n; u++) {
82
+ draw -= weight[u];
83
+ if (draw <= 0) {
84
+ centres.set(emb.subarray(u * dim, (u + 1) * dim), centreCount * dim);
85
+ centreCount++;
86
+ break;
87
+ }
88
+ }
89
+ }
90
+ const labels = new Uint32Array(n);
91
+ const assign = () => {
92
+ for (let u = 0; u < n; u++) {
93
+ let bestCentre = 0;
94
+ let bestDistance = Infinity;
95
+ for (let c = 0; c < centreCount; c++) {
96
+ const d = distance(emb, u, centres, c, dim);
97
+ if (d < bestDistance) {
98
+ bestDistance = d;
99
+ bestCentre = c;
100
+ }
101
+ }
102
+ labels[u] = bestCentre;
103
+ }
104
+ };
105
+ const gradient = new Float64Array(n * dim);
106
+ const sums = new Float64Array(numClusters * dim);
107
+ const sizes = new Uint32Array(numClusters);
108
+ let previousLoss = Infinity;
109
+ let loss = Infinity;
110
+ let iterations = 0;
111
+ let converged = false;
112
+ while (iterations < maxIterations) {
113
+ iterations++;
114
+ assign();
115
+ // Every gradient from the embeddings before this step, then one step for all.
116
+ gradient.fill(0);
117
+ for (let u = 0; u < n; u++) {
118
+ const row = u * dim;
119
+ for (let a = rowPtr[u]; a < rowPtr[u + 1]; a++) {
120
+ const other = colIdx[a] * dim;
121
+ for (let k = 0; k < dim; k++) {
122
+ gradient[row + k] += lambda * (emb[row + k] - emb[other + k]);
123
+ }
124
+ }
125
+ for (let k = 0; k < dim; k++) {
126
+ gradient[row + k] += lambda * emb[row + k];
127
+ }
128
+ }
129
+ for (let i = 0; i < emb.length; i++) {
130
+ emb[i] -= learningRate * gradient[i];
131
+ }
132
+ sums.fill(0);
133
+ sizes.fill(0);
134
+ for (let u = 0; u < n; u++) {
135
+ const c = labels[u];
136
+ for (let k = 0; k < dim; k++) {
137
+ sums[c * dim + k] += emb[u * dim + k];
138
+ }
139
+ sizes[c]++;
140
+ }
141
+ for (let c = 0; c < centreCount; c++) {
142
+ if (sizes[c] > 0) {
143
+ for (let k = 0; k < dim; k++) {
144
+ centres[c * dim + k] = sums[c * dim + k] / sizes[c];
145
+ }
146
+ }
147
+ }
148
+ let clustering = 0;
149
+ let reconstruction = 0;
150
+ let regularization = 0;
151
+ for (let u = 0; u < n; u++) {
152
+ clustering += distance(emb, u, centres, labels[u], dim) ** 2;
153
+ }
154
+ for (let u = 0; u < n; u++) {
155
+ for (let a = rowPtr[u]; a < rowPtr[u + 1]; a++) {
156
+ reconstruction += distance(emb, u, emb, colIdx[a], dim) ** 2;
157
+ }
158
+ }
159
+ for (const value of emb) {
160
+ regularization += value ** 2;
161
+ }
162
+ const current = clustering + lambda * reconstruction + lambda * regularization;
163
+ if (iterations > 1) {
164
+ previousLoss = loss;
165
+ }
166
+ loss = current;
167
+ if (Math.abs(previousLoss - loss) < tolerance) {
168
+ converged = true;
169
+ break;
170
+ }
171
+ }
172
+ assign();
173
+ return { labels, count: numClusters, embeddings: emb, dimensions: dim, loss, previousLoss, iterations, converged };
174
+ }
175
+ //# sourceMappingURL=sync.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sync.js","sourceRoot":"","sources":["../../../src/indexed/sync.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,58 @@
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 TeraHAC, matching the legacy `teraHAC`. @public */
4
+ export interface TeraHacOptions {
5
+ /**
6
+ * How the distance between two clusters is read from their members' pairwise distances: the
7
+ * minimum, the maximum, the mean, or (`"ward"`) the mean of the squares; default `"average"`.
8
+ */
9
+ readonly linkage?: "single" | "complete" | "average" | "ward" | undefined;
10
+ /** Stop merging at this many clusters; a positive integer. Default: merge until one is left. */
11
+ readonly numClusters?: number | undefined;
12
+ /** Stop at the first merge whose linkage distance is above this. Default: no threshold. */
13
+ readonly distanceThreshold?: number | undefined;
14
+ /**
15
+ * Pairwise distance: hop count along out-arcs (true, the default), or 1 for an arc from the
16
+ * lower to the higher node index and 2 for none (false).
17
+ */
18
+ readonly useGraphDistance?: boolean | undefined;
19
+ }
20
+ /**
21
+ * Result of the index-based TeraHAC: the flat clustering plus the dendrogram. Dendrogram node
22
+ * `i < n` is node index i; node `n + k` is the k-th join, with children `left[k]` and `right[k]`.
23
+ * @public
24
+ */
25
+ export interface TeraHacResult extends LabelResult {
26
+ /** Left child of each join (the legacy `ClusterNode.left`). */
27
+ readonly left: U32;
28
+ /** Right child of each join. */
29
+ readonly right: U32;
30
+ /** Linkage distance of each join; Infinity for the joins that tie the remaining clusters under one root. */
31
+ readonly distance: F64;
32
+ /** Node count under each join. */
33
+ readonly size: U32;
34
+ /** Joins made by distance: `distance.subarray(0, merges)` is the legacy `distances` list. */
35
+ readonly merges: number;
36
+ /** The dendrogram root: `2n - 2`, or 0 for a single node. */
37
+ readonly root: number;
38
+ }
39
+ /**
40
+ * TeraHAC over a snapshot: agglomerative clustering that repeatedly merges the closest pair of
41
+ * clusters, with the same distances, merge order and tie-breaks as the legacy `teraHAC` -- but
42
+ * over node indices, so the result no longer depends on what the node ids are.
43
+ *
44
+ * The linkage is kept per ordered cluster pair as an aggregate (minimum, maximum, sum of distances
45
+ * or sum of squared distances) and updated on each merge, instead of rescanning every member pair;
46
+ * the pairwise distances are integers, so the sums, and the means divided out of them, are exact.
47
+ * A pair's distance reads the aggregate in the orientation legacy reads it, which matters on a
48
+ * directed snapshot, and ties go to the pair legacy's stable sort puts first: two original nodes
49
+ * before any pair with a merged cluster, and among those the most recent merge last.
50
+ *
51
+ * Weights are ignored (legacy counts hops). O(n^2) memory and O(n (n + m)) for the distances; the
52
+ * merging keeps each cluster's closest partner and rescans a row only when that partner merges.
53
+ * @param s - The snapshot
54
+ * @param options - {@link TeraHacOptions}
55
+ * @returns The flat clustering and the dendrogram
56
+ */
57
+ export declare function teraHAC(s: GraphSnapshot, options?: TeraHacOptions): TeraHacResult;
58
+ //# sourceMappingURL=terahac.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"terahac.d.ts","sourceRoot":"","sources":["../../../src/indexed/terahac.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,GAAG,EAAE,KAAK,aAAa,EAAqB,KAAK,GAAG,EAAE,MAAM,uBAAuB,CAAC;AAElG,OAAO,EAAE,KAAK,WAAW,EAAc,MAAM,iBAAiB,CAAC;AAE/D,iFAAiF;AACjF,MAAM,WAAW,cAAc;IAC3B;;;OAGG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,QAAQ,GAAG,UAAU,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAAC;IAC1E,gGAAgG;IAChG,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1C,2FAA2F;IAC3F,QAAQ,CAAC,iBAAiB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAChD;;;OAGG;IACH,QAAQ,CAAC,gBAAgB,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;CACnD;AAED;;;;GAIG;AACH,MAAM,WAAW,aAAc,SAAQ,WAAW;IAC9C,+DAA+D;IAC/D,QAAQ,CAAC,IAAI,EAAE,GAAG,CAAC;IACnB,gCAAgC;IAChC,QAAQ,CAAC,KAAK,EAAE,GAAG,CAAC;IACpB,4GAA4G;IAC5G,QAAQ,CAAC,QAAQ,EAAE,GAAG,CAAC;IACvB,kCAAkC;IAClC,QAAQ,CAAC,IAAI,EAAE,GAAG,CAAC;IACnB,6FAA6F;IAC7F,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,6DAA6D;IAC7D,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACzB;AA8CD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,OAAO,CAAC,CAAC,EAAE,aAAa,EAAE,OAAO,GAAE,cAAmB,GAAG,aAAa,CAoJrF"}
@@ -0,0 +1,244 @@
1
+ import { renumberPartition } from "@graphty/graph-format";
2
+ import { withGroups } from "./components.js";
3
+ /** The distance legacy gives an unreachable pair, so that disconnected clusters still merge last. */
4
+ const UNREACHABLE = 100;
5
+ /**
6
+ * All-pairs distances into a row-major n x n matrix: BFS hop counts along out-arcs (Infinity when
7
+ * unreachable) or the 1 / 2 adjacency distance.
8
+ * @param s - The snapshot
9
+ * @param useGraphDistance - Which distance
10
+ * @returns The matrix
11
+ */
12
+ function pairwiseDistances(s, useGraphDistance) {
13
+ const n = s.nodeCount;
14
+ const d = new Float64Array(n * n);
15
+ if (!useGraphDistance) {
16
+ for (let i = 0; i < n; i++) {
17
+ for (let j = i + 1; j < n; j++) {
18
+ d[i * n + j] = d[j * n + i] = s.hasArc(i, j) ? 1 : 2;
19
+ }
20
+ }
21
+ return d;
22
+ }
23
+ d.fill(Infinity);
24
+ const queue = new Uint32Array(n);
25
+ for (let source = 0; source < n; source++) {
26
+ const row = source * n;
27
+ d[row + source] = 0;
28
+ queue[0] = source;
29
+ let head = 0;
30
+ let tail = 1;
31
+ while (head < tail) {
32
+ const u = queue[head++];
33
+ const next = d[row + u] + 1;
34
+ for (let a = s.rowPtr[u]; a < s.rowPtr[u + 1]; a++) {
35
+ const v = s.colIdx[a];
36
+ if (d[row + v] === Infinity) {
37
+ d[row + v] = next;
38
+ queue[tail++] = v;
39
+ }
40
+ }
41
+ }
42
+ }
43
+ return d;
44
+ }
45
+ /**
46
+ * TeraHAC over a snapshot: agglomerative clustering that repeatedly merges the closest pair of
47
+ * clusters, with the same distances, merge order and tie-breaks as the legacy `teraHAC` -- but
48
+ * over node indices, so the result no longer depends on what the node ids are.
49
+ *
50
+ * The linkage is kept per ordered cluster pair as an aggregate (minimum, maximum, sum of distances
51
+ * or sum of squared distances) and updated on each merge, instead of rescanning every member pair;
52
+ * the pairwise distances are integers, so the sums, and the means divided out of them, are exact.
53
+ * A pair's distance reads the aggregate in the orientation legacy reads it, which matters on a
54
+ * directed snapshot, and ties go to the pair legacy's stable sort puts first: two original nodes
55
+ * before any pair with a merged cluster, and among those the most recent merge last.
56
+ *
57
+ * Weights are ignored (legacy counts hops). O(n^2) memory and O(n (n + m)) for the distances; the
58
+ * merging keeps each cluster's closest partner and rescans a row only when that partner merges.
59
+ * @param s - The snapshot
60
+ * @param options - {@link TeraHacOptions}
61
+ * @returns The flat clustering and the dendrogram
62
+ */
63
+ export function teraHAC(s, options = {}) {
64
+ const { linkage = "average", numClusters, distanceThreshold, useGraphDistance = true } = options;
65
+ if (numClusters !== undefined && (numClusters < 1 || !Number.isInteger(numClusters))) {
66
+ throw new Error("numClusters must be a positive integer");
67
+ }
68
+ const n = s.nodeCount;
69
+ if (n === 0) {
70
+ throw new Error("Cannot cluster empty graph");
71
+ }
72
+ // ponytail: dense n x n aggregate matrix, the same memory as legacy's distance matrix; a sparse
73
+ // candidate structure is the upgrade if graphs past ~10k nodes need this.
74
+ const agg = pairwiseDistances(s, useGraphDistance);
75
+ if (linkage === "ward") {
76
+ for (let i = 0; i < agg.length; i++) {
77
+ agg[i] *= agg[i];
78
+ }
79
+ }
80
+ const extremes = { single: Math.min, complete: Math.max, average: null, ward: null };
81
+ const extreme = extremes[linkage];
82
+ const joins = Math.max(0, n - 1);
83
+ const left = new Uint32Array(joins);
84
+ const right = new Uint32Array(joins);
85
+ const distance = new Float64Array(joins);
86
+ const size = new Uint32Array(joins);
87
+ // Slot i holds one active cluster: its dendrogram id, its size, and its closest partner.
88
+ const clusterId = new Uint32Array(n);
89
+ const members = new Uint32Array(n).fill(1);
90
+ const active = new Uint8Array(n).fill(1);
91
+ for (let i = 0; i < n; i++) {
92
+ clusterId[i] = i;
93
+ }
94
+ const orient = (x, y) => {
95
+ // true when x is the pair's first cluster: the lower id of two originals, else the newer one
96
+ const a = clusterId[x];
97
+ const b = clusterId[y];
98
+ return a < n && b < n ? a < b : a > b;
99
+ };
100
+ const pairDistance = (x, y) => {
101
+ const [p, q] = orient(x, y) ? [x, y] : [y, x];
102
+ let value = agg[p * n + q];
103
+ if (clusterId[p] < n && clusterId[q] < n) {
104
+ // Legacy reads two original nodes' distance straight from the matrix, unsquared even for ward.
105
+ value = linkage === "ward" ? Math.sqrt(value) : value;
106
+ }
107
+ else if (!extreme) {
108
+ value /= members[p] * members[q];
109
+ }
110
+ return value === Infinity ? UNREACHABLE : value;
111
+ };
112
+ const pairOrder = (x, y) => {
113
+ const a = clusterId[x];
114
+ const b = clusterId[y];
115
+ const lo = Math.min(a, b);
116
+ const hi = Math.max(a, b);
117
+ return hi < n ? lo * n + hi : n * n + hi * 2 * n + lo;
118
+ };
119
+ const best = new Int32Array(n).fill(-1);
120
+ const bestDistance = new Float64Array(n);
121
+ const bestOrder = new Float64Array(n);
122
+ const offer = (x, y) => {
123
+ const d = pairDistance(x, y);
124
+ const o = pairOrder(x, y);
125
+ if (best[x] === -1 || d < bestDistance[x] || (d === bestDistance[x] && o < bestOrder[x])) {
126
+ best[x] = y;
127
+ bestDistance[x] = d;
128
+ bestOrder[x] = o;
129
+ }
130
+ };
131
+ const rescan = (x) => {
132
+ best[x] = -1;
133
+ for (let y = 0; y < n; y++) {
134
+ if (active[y] && y !== x) {
135
+ offer(x, y);
136
+ }
137
+ }
138
+ };
139
+ for (let x = 0; x < n; x++) {
140
+ rescan(x);
141
+ }
142
+ let remaining = n;
143
+ let merges = 0;
144
+ while (remaining > 1 && (numClusters === undefined || remaining > numClusters)) {
145
+ let x = -1;
146
+ for (let i = 0; i < n; i++) {
147
+ if (active[i] &&
148
+ (x === -1 ||
149
+ bestDistance[i] < bestDistance[x] ||
150
+ (bestDistance[i] === bestDistance[x] && bestOrder[i] < bestOrder[x]))) {
151
+ x = i;
152
+ }
153
+ }
154
+ const d = bestDistance[x];
155
+ if (distanceThreshold !== undefined && d > distanceThreshold) {
156
+ break;
157
+ }
158
+ const [keep, drop] = orient(x, best[x]) ? [x, best[x]] : [best[x], x];
159
+ left[merges] = clusterId[keep];
160
+ right[merges] = clusterId[drop];
161
+ distance[merges] = d;
162
+ size[merges] = members[keep] + members[drop];
163
+ for (let c = 0; c < n; c++) {
164
+ if (active[c] && c !== keep && c !== drop) {
165
+ const kc = keep * n + c;
166
+ const dc = drop * n + c;
167
+ const ck = c * n + keep;
168
+ const cd = c * n + drop;
169
+ agg[kc] = extreme ? extreme(agg[kc], agg[dc]) : agg[kc] + agg[dc];
170
+ agg[ck] = extreme ? extreme(agg[ck], agg[cd]) : agg[ck] + agg[cd];
171
+ }
172
+ }
173
+ clusterId[keep] = n + merges;
174
+ members[keep] = size[merges];
175
+ active[drop] = 0;
176
+ merges++;
177
+ remaining--;
178
+ rescan(keep);
179
+ for (let c = 0; c < n; c++) {
180
+ if (active[c] && c !== keep) {
181
+ if (best[c] === keep || best[c] === drop) {
182
+ rescan(c);
183
+ }
184
+ else {
185
+ offer(c, keep);
186
+ }
187
+ }
188
+ }
189
+ }
190
+ // Tie what is left under one root, in ascending cluster id, as legacy does.
191
+ const rest = Array.from(clusterId.filter((_, i) => active[i] === 1)).sort((a, b) => a - b);
192
+ let root = rest[0];
193
+ const sizeOf = (c) => (c < n ? 1 : size[c - n]);
194
+ for (let k = 1; k < rest.length; k++) {
195
+ const j = merges + k - 1;
196
+ left[j] = root;
197
+ right[j] = rest[k];
198
+ distance[j] = Infinity;
199
+ size[j] = sizeOf(root) + sizeOf(rest[k]);
200
+ root = n + j;
201
+ }
202
+ const cut = cutDendrogram(n, left, right, root, numClusters ?? remaining);
203
+ const { labels, count } = renumberPartition(cut);
204
+ return { ...withGroups(labels, count), left, right, distance, size, merges, root };
205
+ }
206
+ /**
207
+ * Legacy's flat clustering: split dendrogram nodes breadth-first from the root until splitting the
208
+ * next one would exceed `k` clusters, then label every node by the cluster above it.
209
+ * @param n - Node count
210
+ * @param left - Left child of each join
211
+ * @param right - Right child of each join
212
+ * @param root - The root
213
+ * @param k - The cluster count asked for
214
+ * @returns A cluster number per node index
215
+ */
216
+ function cutDendrogram(n, left, right, root, k) {
217
+ const kept = [];
218
+ const queue = [root];
219
+ let head = 0;
220
+ while (head < queue.length && kept.length < k) {
221
+ const c = queue[head++];
222
+ if (c < n || k === 1 || kept.length + (queue.length - head) + 1 >= k) {
223
+ kept.push(c);
224
+ }
225
+ else {
226
+ queue.push(left[c - n], right[c - n]);
227
+ }
228
+ }
229
+ const labels = new Uint32Array(n);
230
+ kept.forEach((top, label) => {
231
+ const stack = [top];
232
+ while (stack.length > 0) {
233
+ const c = stack.pop() ?? 0;
234
+ if (c < n) {
235
+ labels[c] = label;
236
+ }
237
+ else {
238
+ stack.push(left[c - n], right[c - n]);
239
+ }
240
+ }
241
+ });
242
+ return labels;
243
+ }
244
+ //# sourceMappingURL=terahac.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"terahac.js","sourceRoot":"","sources":["../../../src/indexed/terahac.ts"],"names":[],"mappings":"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"}
@@ -5,7 +5,7 @@
5
5
  * `../core/graph.js`.
6
6
  * @module
7
7
  */
8
- import { type GraphSnapshot } from "@graphty/graph-format";
8
+ import { type GraphSnapshot, type U32 } from "@graphty/graph-format";
9
9
  import type { Graph } from "../core/graph.js";
10
10
  /** Options of {@link toSnapshot}. @public */
11
11
  export interface ToSnapshotOptions {
@@ -17,7 +17,8 @@ export interface ToSnapshotOptions {
17
17
  readonly checksum?: boolean | undefined;
18
18
  }
19
19
  /**
20
- * Freeze a legacy `Graph` into a `GraphSnapshot`, memoised on the graph's `mutationCount`.
20
+ * Freeze a legacy `Graph` into a `GraphSnapshot`, memoised on the graph's `mutationCount` and its
21
+ * edge weights (a weight set in place does not move the counter, so a hit re-reads the weights).
21
22
  *
22
23
  * The builder is created with `weightDtype: "f64"` so a legacy graph's double weights survive
23
24
  * exactly: at freeze, graph-format keeps the original values in an f64 edge column with role
@@ -35,4 +36,46 @@ export interface ToSnapshotOptions {
35
36
  * @public
36
37
  */
37
38
  export declare function toSnapshot(graph: Graph, options?: ToSnapshotOptions): GraphSnapshot;
39
+ /**
40
+ * {@link toSnapshot}, or null when an edge weight is NaN: a legacy `Graph` accepts one, a snapshot
41
+ * does not. A facade whose legacy answer depends on how NaN compares keeps its legacy code for such
42
+ * a graph.
43
+ * @param graph - The legacy graph
44
+ * @param options - Conversion options
45
+ * @returns The snapshot, or null
46
+ */
47
+ export declare function toSnapshotOrNull(graph: Graph, options?: ToSnapshotOptions): GraphSnapshot | null;
48
+ /**
49
+ * A snapshot for a port that reads no weights (a traversal, the components, a clustering or link
50
+ * prediction that counts neighbours): {@link toSnapshot}, or,
51
+ * when a NaN weight stops that, the same nodes and edges frozen without weights, so a graph with a
52
+ * NaN weight traverses as it always did.
53
+ * @param graph - The legacy graph
54
+ * @returns The snapshot; its weights are not to be read
55
+ */
56
+ export declare function toTopologySnapshot(graph: Graph): GraphSnapshot;
57
+ /**
58
+ * The order a legacy `Graph` hands out each node's neighbours in, as the `arcOrder` option of the
59
+ * order-sensitive traversals (`depthFirstSearch`, `topologicalSort`, `stronglyConnectedComponents`,
60
+ * `condensation`, `breadthFirstSearch`). A snapshot row is sorted by neighbour index, while the
61
+ * legacy adjacency Map is in insertion order, so a traversal that must visit nodes in the legacy
62
+ * order -- a facade keeping its published result -- passes this.
63
+ * @param graph - The legacy graph
64
+ * @param s - A snapshot with the graph's nodes in the same order and its neighbour pairs, such as
65
+ * `toSnapshot(graph)`; parallel arcs of one pair are kept together in row order
66
+ * @returns For every row, its arcs in legacy neighbour order
67
+ */
68
+ export declare function legacyArcOrder(graph: Graph, s: GraphSnapshot): U32;
69
+ /**
70
+ * Whether a facade must run its legacy code on this graph because a snapshot cannot stand in for it:
71
+ * - an edge weight is NaN, which the graph-format builder rejects, so `toSnapshot` would throw where
72
+ * the legacy code returns a result (the unweighted functions never even read the weight);
73
+ * - two node ids share a spelling (the number 1 and the string "1"), so a result keyed by
74
+ * `String(id)` holds one entry for both, and which value it holds depends on how the legacy code
75
+ * wrote it (betweenness adds the two, others keep the last).
76
+ * Memoised on the graph's `mutationCount`, like {@link toSnapshot}.
77
+ * @param graph - The legacy graph
78
+ * @returns True when the facade must call its legacy implementation
79
+ */
80
+ export declare function needsLegacyCode(graph: Graph): boolean;
38
81
  //# sourceMappingURL=to-snapshot.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"to-snapshot.d.ts","sourceRoot":"","sources":["../../../src/indexed/to-snapshot.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAgB,KAAK,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAEzE,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAE9C,6CAA6C;AAC7C,MAAM,WAAW,iBAAiB;IAC9B;;;;OAIG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;CAC3C;AAeD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,GAAE,iBAAsB,GAAG,aAAa,CAwBvF"}
1
+ {"version":3,"file":"to-snapshot.d.ts","sourceRoot":"","sources":["../../../src/indexed/to-snapshot.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAkC,KAAK,aAAa,EAAE,KAAK,GAAG,EAAE,MAAM,uBAAuB,CAAC;AAErG,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAE9C,6CAA6C;AAC7C,MAAM,WAAW,iBAAiB;IAC9B;;;;OAIG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;CAC3C;AAoCD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,GAAE,iBAAsB,GAAG,aAAa,CAGvF;AAkDD;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,GAAE,iBAAsB,GAAG,aAAa,GAAG,IAAI,CASpG;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,KAAK,GAAG,aAAa,CAE9D;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,KAAK,EAAE,CAAC,EAAE,aAAa,GAAG,GAAG,CAqBlE;AAID;;;;;;;;;;GAUG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,KAAK,GAAG,OAAO,CAqBrD"}