@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,486 @@
1
+ import { INVALID_INDEX, renumberPartition, } from "@graphty/graph-format";
2
+ import { withGroups } from "./components.js";
3
+ /** Epochs run 0 .. EPOCH_LIMIT - 1 between resets of the Int32 stamp arrays. */
4
+ const EPOCH_LIMIT = 0x7fffffff;
5
+ /**
6
+ * mulberry32: 32-bit state, output in [0, 1). The exact sequence is part of the result contract
7
+ * (design section 2.4): changing it changes every partition.
8
+ * @param seed - Generator seed; only its low 32 bits are used
9
+ * @returns The generator
10
+ */
11
+ export function mulberry32(seed) {
12
+ let a = seed >>> 0;
13
+ return () => {
14
+ a = (a + 0x6d2b79f5) | 0;
15
+ let t = Math.imul(a ^ (a >>> 15), 1 | a);
16
+ t = (t + Math.imul(t ^ (t >>> 7), 61 | t)) ^ t;
17
+ return ((t ^ (t >>> 14)) >>> 0) / 4294967296;
18
+ };
19
+ }
20
+ /**
21
+ * Whether any arc other than a self-loop carries a positive vote under the chosen weighting, which
22
+ * is exactly when the identity labelling is NOT dominant everywhere.
23
+ * @param s - The snapshot
24
+ * @param weights - The arc weights in use, or null when every arc votes 1
25
+ * @returns True when some node has a positive-weight neighbour
26
+ */
27
+ function hasVotingArc(s, weights) {
28
+ for (let u = 0; u < s.nodeCount; u++) {
29
+ const end = s.rowPtr[u + 1];
30
+ for (let a = s.rowPtr[u]; a < end; a++) {
31
+ if (s.colIdx[a] !== u && (weights === null || weights[a] > 0)) {
32
+ return true;
33
+ }
34
+ }
35
+ }
36
+ return false;
37
+ }
38
+ /**
39
+ * Whether every node not held fixed holds a label at the largest vote among its neighbours (or has
40
+ * no neighbour that votes).
41
+ * @param tally - A tally over the voting rows
42
+ * @param label - The label of every node
43
+ * @param fixed - 1 for a node held at its label, or null when none is
44
+ * @returns True when no free node would move
45
+ */
46
+ function allDominant(tally, label, fixed) {
47
+ for (let u = 0; u < label.length; u++) {
48
+ if (fixed !== null && fixed[u] === 1) {
49
+ continue;
50
+ }
51
+ const max = tally.collect(u, label);
52
+ if (max !== 0 && tally.voteOf(label[u]) !== max) {
53
+ return false;
54
+ }
55
+ }
56
+ return true;
57
+ }
58
+ /**
59
+ * The per-arc weights of `view` that the votes use: the snapshot's exact f64 weights when it keeps
60
+ * them (graph-format keeps a role-"weight" f64 edge column whenever some weight is not f32-exact),
61
+ * gathered through arcToEdge; otherwise the view's own f32 arc array. Voting on the f32 values would
62
+ * turn 1 and 1 + 1e-9 into a tie, 1e39 into Infinity and 1e-50 into 0.
63
+ * @param view - The forward snapshot or its reverse view
64
+ * @param exact - The exact per-edge weights, or null when the f32 arc array is exact
65
+ * @returns The arc weights, or null when every arc weighs 1
66
+ */
67
+ export function arcWeightsOf(view, exact) {
68
+ if (exact === null) {
69
+ return view.weights;
70
+ }
71
+ const out = new Float64Array(view.arcCount);
72
+ for (let a = 0; a < out.length; a++) {
73
+ out[a] = exact[view.arcToEdge[a]];
74
+ }
75
+ return out;
76
+ }
77
+ /**
78
+ * The exact per-edge weights of `s`: its role-"weight" f64 edge column when it keeps one, else null
79
+ * (the f32 arc array is then exact).
80
+ * @param s - The snapshot
81
+ * @returns The exact weights per logical edge, or null
82
+ */
83
+ export function exactEdgeWeights(s) {
84
+ const shadow = s.edges.byRole("weight");
85
+ return shadow !== null && shadow.dtype === "f64" ? shadow.data : null;
86
+ }
87
+ /**
88
+ * Gather the voting rows of `s` and reject weights a vote cannot use.
89
+ * @param s - The snapshot
90
+ * @param weighted - Sum arc weights (true) or count each arc as 1 (false)
91
+ * @returns The rows and their weights
92
+ * @throws RangeError when a weight is negative, NaN or infinite
93
+ */
94
+ function votingRows(s, weighted) {
95
+ const weights = weighted ? arcWeightsOf(s, exactEdgeWeights(s)) : null;
96
+ if (weights !== null) {
97
+ for (let a = 0; a < weights.length; a++) {
98
+ const w = weights[a];
99
+ if (!(w >= 0) || w === Infinity) {
100
+ throw new RangeError(`arc ${a} has weight ${w}; label propagation needs finite, non-negative weights`);
101
+ }
102
+ }
103
+ }
104
+ const rev = s.directed ? s.reverse() : null;
105
+ return {
106
+ sides: rev === null ? 1 : 2,
107
+ rowPtrs: [s.rowPtr, rev === null ? s.rowPtr : rev.rowPtr],
108
+ colIdxs: [s.colIdx, rev === null ? s.colIdx : rev.colIdx],
109
+ arcWeights: [weights, weights === null || rev === null ? weights : arcWeightsOf(rev, exactEdgeWeights(s))],
110
+ weights,
111
+ };
112
+ }
113
+ /**
114
+ * Check the options every label propagation shares.
115
+ * @param n - The node count
116
+ * @param maxIterations - The work cap
117
+ * @param randomSeed - The seed, or null when the variant takes none
118
+ * @throws RangeError for a bad option
119
+ */
120
+ function checkOptions(n, maxIterations, randomSeed) {
121
+ if (!Number.isInteger(maxIterations) || maxIterations < 0) {
122
+ throw new RangeError(`maxIterations must be a non-negative integer, got ${maxIterations}`);
123
+ }
124
+ if (randomSeed !== null && !Number.isInteger(randomSeed)) {
125
+ throw new RangeError(`randomSeed must be a finite integer, got ${randomSeed}`);
126
+ }
127
+ if (maxIterations * n > Number.MAX_SAFE_INTEGER) {
128
+ throw new RangeError(`maxIterations * nodeCount (${maxIterations} * ${n}) exceeds Number.MAX_SAFE_INTEGER`);
129
+ }
130
+ }
131
+ /**
132
+ * The per-node vote tally shared by the queue kernel and the synchronous passes: an accumulator
133
+ * per label, stamped by visit so it never needs clearing.
134
+ */
135
+ class Tally {
136
+ constructor(n, rows, weighted) {
137
+ this.rows = rows;
138
+ this.epoch = -1;
139
+ this.count = 0;
140
+ this.acc = new Float64Array(n);
141
+ this.stamp = new Int32Array(n).fill(-1);
142
+ this.touched = new Uint32Array(n);
143
+ this.seen = weighted ? null : new Int32Array(n).fill(-1);
144
+ }
145
+ /**
146
+ * Sum the votes of u's neighbours per label into `acc`, listing the labels met in `touched`.
147
+ * @param u - The node
148
+ * @param label - The label of every node
149
+ * @returns The largest vote, 0 when no neighbour votes
150
+ */
151
+ collect(u, label) {
152
+ if (++this.epoch === EPOCH_LIMIT) {
153
+ // Reset before the epoch leaves the Int32 range: O(n) once per 2^31 - 1 visits.
154
+ this.stamp.fill(-1);
155
+ this.seen?.fill(-1);
156
+ this.epoch = 0;
157
+ }
158
+ const { acc, stamp, touched, seen, rows } = this;
159
+ const visit = this.epoch;
160
+ let count = 0;
161
+ for (let side = 0; side < rows.sides; side++) {
162
+ const rowPtr = rows.rowPtrs[side];
163
+ const colIdx = rows.colIdxs[side];
164
+ const w = rows.arcWeights[side];
165
+ const end = rowPtr[u + 1];
166
+ for (let a = rowPtr[u]; a < end; a++) {
167
+ const v = colIdx[a];
168
+ if (v === u) {
169
+ continue; // a self-loop does not vote
170
+ }
171
+ if (seen !== null) {
172
+ if (seen[v] === visit) {
173
+ continue;
174
+ }
175
+ seen[v] = visit;
176
+ }
177
+ const c = label[v];
178
+ const vote = w === null ? 1 : w[a];
179
+ if (stamp[c] !== visit) {
180
+ stamp[c] = visit;
181
+ acc[c] = vote;
182
+ touched[count++] = c;
183
+ }
184
+ else {
185
+ acc[c] += vote;
186
+ }
187
+ }
188
+ }
189
+ this.count = count;
190
+ let max = 0;
191
+ for (let i = 0; i < count; i++) {
192
+ if (acc[touched[i]] > max) {
193
+ max = acc[touched[i]];
194
+ }
195
+ }
196
+ return max;
197
+ }
198
+ /**
199
+ * The vote label c received in the last `collect`.
200
+ * @param c - A label
201
+ * @returns Its vote, 0 when no neighbour holds it
202
+ */
203
+ voteOf(c) {
204
+ return this.stamp[c] === this.epoch ? this.acc[c] : 0;
205
+ }
206
+ }
207
+ /**
208
+ * The FLPA queue kernel over `label`, updated in place. Nodes marked in `fixed` never enter the
209
+ * queue, so they keep their starting label.
210
+ * @param s - The snapshot
211
+ * @param rows - Its voting rows
212
+ * @param weighted - Whether the rows carry weights
213
+ * @param label - Starting label of every node, each below nodeCount; overwritten with the result
214
+ * @param fixed - 1 for a node whose label never changes, or null
215
+ * @param maxIterations - Work cap in node visits per node
216
+ * @param randomSeed - Seed of the visit order and the tie draws
217
+ * @returns The node visits run and the nodes still queued
218
+ */
219
+ function flpa(s, rows, weighted, label, fixed, maxIterations, randomSeed) {
220
+ const n = s.nodeCount;
221
+ const rand = mulberry32(randomSeed);
222
+ const tally = new Tally(n, rows, weighted);
223
+ // A ring of n + 1 slots: `queued` keeps a node in it at most once.
224
+ const capacity = n + 1;
225
+ const queue = new Uint32Array(capacity);
226
+ const queued = new Uint8Array(n);
227
+ let size = 0;
228
+ for (let i = 0; i < n; i++) {
229
+ if (fixed === null || fixed[i] === 0) {
230
+ queue[size++] = i;
231
+ queued[i] = 1;
232
+ }
233
+ }
234
+ for (let i = size - 1; i >= 1; i--) {
235
+ const j = Math.floor(rand() * (i + 1));
236
+ const t = queue[i];
237
+ queue[i] = queue[j];
238
+ queue[j] = t;
239
+ }
240
+ let head = 0;
241
+ let tail = size;
242
+ const maxVisits = maxIterations * n;
243
+ let visits = 0;
244
+ const { touched, acc } = tally;
245
+ while (size > 0 && visits < maxVisits) {
246
+ const u = queue[head];
247
+ head = head + 1 === capacity ? 0 : head + 1;
248
+ size--;
249
+ queued[u] = 0;
250
+ visits++;
251
+ const max = tally.collect(u, label);
252
+ if (max === 0) {
253
+ continue; // no positive-weight neighbour: keep the label
254
+ }
255
+ // Reservoir draw over the labels at the maximum: the k-th replaces the pick with
256
+ // probability 1/k, so a single dominant label consumes no random number.
257
+ let pick = 0;
258
+ let tied = 0;
259
+ for (let i = 0; i < tally.count; i++) {
260
+ const c = touched[i];
261
+ if (acc[c] === max) {
262
+ tied++;
263
+ if (tied === 1 || rand() * tied < 1) {
264
+ pick = c;
265
+ }
266
+ }
267
+ }
268
+ if (pick === label[u]) {
269
+ continue;
270
+ }
271
+ label[u] = pick;
272
+ // A neighbour already holding the new label can only have been strengthened by the move.
273
+ // Both rows, so on a directed snapshot the nodes that read u are requeued too.
274
+ for (let side = 0; side < rows.sides; side++) {
275
+ const rowPtr = rows.rowPtrs[side];
276
+ const colIdx = rows.colIdxs[side];
277
+ const end = rowPtr[u + 1];
278
+ for (let a = rowPtr[u]; a < end; a++) {
279
+ const v = colIdx[a];
280
+ if (queued[v] === 0 && label[v] !== pick && (fixed === null || fixed[v] === 0)) {
281
+ queued[v] = 1;
282
+ queue[tail] = v;
283
+ tail = tail + 1 === capacity ? 0 : tail + 1;
284
+ size++;
285
+ }
286
+ }
287
+ }
288
+ }
289
+ return { visits, size };
290
+ }
291
+ /**
292
+ * Community detection by fast label propagation (FLPA; Traag and Subelj, Sci. Rep. 13:2701, 2023,
293
+ * Algorithm 3), the queue-driven form of Raghavan, Albert and Kumara's asynchronous label
294
+ * propagation.
295
+ *
296
+ * Every node starts in its own community. Nodes are visited from a queue that starts as a seeded
297
+ * shuffle of all of them; a visited node adopts the label with the largest summed arc weight among
298
+ * its neighbours, drawing uniformly at random among tied labels (its current label included, with
299
+ * no priority). When its label changes, every neighbour holding a different label is queued again.
300
+ * The run ends when the queue empties -- then every node's label is dominant among its neighbours
301
+ * and `converged` is true -- or after `maxIterations * nodeCount` node visits.
302
+ *
303
+ * Conventions: self-loops are skipped; parallel arcs are summed; on a directed snapshot a node's
304
+ * neighbours are its out-arcs AND its in-arcs, so a reciprocal pair counts twice. With
305
+ * `weighted: false` each distinct neighbour votes once. A negative, NaN or infinite weight throws.
306
+ * Votes use the exact f64 weights when the snapshot keeps them (as `toSnapshot` does for a legacy
307
+ * graph whose weights are not all f32-exact), so a weight rounded in the f32 arc array never
308
+ * decides a vote.
309
+ *
310
+ * One `randomSeed` gives one result, bit for bit. The partitions differ from the legacy
311
+ * `labelPropagation` for the same seed: the random stream and the stop rule are different
312
+ * (design `design/algorithms/label-propagation-indexed-port-design.md`, section 3).
313
+ * @param s - Any snapshot
314
+ * @param options - Work cap, seed and weighting
315
+ * @returns The partition, the full-sweep equivalents run, and whether the work queue emptied
316
+ * @public
317
+ */
318
+ export function labelPropagation(s, options = {}) {
319
+ const maxIterations = options.maxIterations ?? 100;
320
+ const randomSeed = options.randomSeed ?? 42;
321
+ const weighted = options.weighted ?? true;
322
+ const n = s.nodeCount;
323
+ checkOptions(n, maxIterations, randomSeed);
324
+ const rows = votingRows(s, weighted);
325
+ const label = new Uint32Array(n);
326
+ for (let i = 0; i < n; i++) {
327
+ label[i] = i;
328
+ }
329
+ if (n === 0 || maxIterations === 0) {
330
+ const { labels, count } = renumberPartition(label);
331
+ return { ...withGroups(labels, count), iterations: 0, converged: !hasVotingArc(s, rows.weights) };
332
+ }
333
+ const { visits, size } = flpa(s, rows, weighted, label, null, maxIterations, randomSeed);
334
+ const { labels, count } = renumberPartition(label);
335
+ return { ...withGroups(labels, count), iterations: Math.ceil(visits / n), converged: size === 0 };
336
+ }
337
+ /**
338
+ * Semi-supervised label propagation: the FLPA kernel of {@link labelPropagation} with some nodes
339
+ * held at a given label (the `initial` / `fixed` inputs of igraph's `community_label_propagation`).
340
+ *
341
+ * A seeded node keeps its label for the whole run and is never visited; every other node starts in
342
+ * its own community and moves as in `labelPropagation`. Seeds that share a label share one community
343
+ * from the start, and seeds with different labels are never merged, so in the result two seeds
344
+ * carry the same label exactly when their seed labels are equal. The result is renumbered to
345
+ * `0..count-1` in first-seen node order like every other partition here, so a seed label's VALUE is
346
+ * not kept: read a seed's community through `labels[seedNode]`. With no seed at all this is
347
+ * `labelPropagation` with the same seed and options, bit for bit.
348
+ *
349
+ * `converged` is true when the work queue emptied, or when `maxIterations` is 0 and the starting
350
+ * labels already are dominant: every unseeded node's label is dominant among its neighbours.
351
+ * Seeded nodes are not held to that.
352
+ * @param s - Any snapshot
353
+ * @param seeds - One entry per node: its fixed label, any value but `INVALID_INDEX`, or
354
+ * `INVALID_INDEX` for a node free to move
355
+ * @param options - Work cap, seed of the visit order and weighting
356
+ * @returns The partition, the full-sweep equivalents run, and whether the work queue emptied
357
+ * @throws RangeError when `seeds` is not one entry per node, or for a bad option or weight
358
+ * @public
359
+ */
360
+ export function labelPropagationSemiSupervised(s, seeds, options = {}) {
361
+ const maxIterations = options.maxIterations ?? 100;
362
+ const randomSeed = options.randomSeed ?? 42;
363
+ const weighted = options.weighted ?? true;
364
+ const n = s.nodeCount;
365
+ if (seeds.length !== n) {
366
+ throw new RangeError(`seeds has ${seeds.length} entries; the snapshot has ${n} nodes`);
367
+ }
368
+ checkOptions(n, maxIterations, randomSeed);
369
+ const rows = votingRows(s, weighted);
370
+ // The kernel's labels are node indices, so a seed label becomes the index of the first node
371
+ // seeded with it: a free node's own index can never collide with it.
372
+ const label = new Uint32Array(n);
373
+ const fixed = new Uint8Array(n);
374
+ const firstWith = new Map();
375
+ for (let u = 0; u < n; u++) {
376
+ const seed = seeds[u];
377
+ if (seed === INVALID_INDEX) {
378
+ label[u] = u;
379
+ continue;
380
+ }
381
+ let first = firstWith.get(seed);
382
+ if (first === undefined) {
383
+ first = u;
384
+ firstWith.set(seed, u);
385
+ }
386
+ label[u] = first;
387
+ fixed[u] = 1;
388
+ }
389
+ const { visits, size } = flpa(s, rows, weighted, label, fixed, maxIterations, randomSeed);
390
+ // At maxIterations 0 nothing was visited, so the queue says nothing: check the labels, as
391
+ // labelPropagation does.
392
+ const converged = size === 0 || (maxIterations === 0 && allDominant(new Tally(n, rows, weighted), label, fixed));
393
+ const { labels, count } = renumberPartition(label);
394
+ return { ...withGroups(labels, count), iterations: n === 0 ? 0 : Math.ceil(visits / n), converged };
395
+ }
396
+ /**
397
+ * Label propagation in synchronous passes: every node reads its neighbours' labels from the
398
+ * previous pass, and all nodes move at once. Deterministic, with no random stream.
399
+ *
400
+ * A node keeps its label when that label is dominant among its neighbours; otherwise it takes the
401
+ * LOWEST label with the largest summed vote. Synchronous updates alone make two neighbours trade
402
+ * labels for ever (on a single edge a-b, a takes b's label while b takes a's), so passes alternate
403
+ * a swap guard: an even pass (the first is pass 0) lets a node move only to a higher label, an odd
404
+ * pass only to a lower one (the up/down rule of cuGraph's Louvain move phase). The run stops after
405
+ * two passes in a row with no move, one up and one down -- then every node's label is dominant and
406
+ * `converged` is true -- or after `maxIterations` passes.
407
+ *
408
+ * The guard stops the single-edge swap but not every cycle: on some weighted graphs a node climbs to
409
+ * a higher label on each up pass and falls back on each down pass. When a pass returns the labels
410
+ * of two passes before, the run can only repeat itself, so it stops there with `converged` false;
411
+ * the result is then the same for any larger `maxIterations`. Longer cycles run to the cap.
412
+ *
413
+ * This is what the legacy `labelPropagationAsync` does, despite its name, with the swap guard it
414
+ * lacks and the tie rule applied to the finished tally rather than to a running one. Conventions
415
+ * match {@link labelPropagation}: self-loops are skipped, parallel arcs summed, a directed snapshot
416
+ * reads out- and in-neighbours, weights are the exact f64 ones when the snapshot keeps them, and a
417
+ * negative, NaN or infinite weight throws.
418
+ * @param s - Any snapshot
419
+ * @param options - Pass cap and weighting
420
+ * @returns The partition, the passes run, and whether every label ended dominant
421
+ * @public
422
+ */
423
+ export function labelPropagationSynchronous(s, options = {}) {
424
+ const maxIterations = options.maxIterations ?? 100;
425
+ const weighted = options.weighted ?? true;
426
+ const n = s.nodeCount;
427
+ checkOptions(n, maxIterations, null);
428
+ const rows = votingRows(s, weighted);
429
+ const tally = new Tally(n, rows, weighted);
430
+ const { touched, acc } = tally;
431
+ let label = new Uint32Array(n);
432
+ let next = new Uint32Array(n);
433
+ // The labels two passes back, to catch a period-2 cycle.
434
+ let before = new Uint32Array(n).fill(INVALID_INDEX);
435
+ for (let i = 0; i < n; i++) {
436
+ label[i] = i;
437
+ }
438
+ let passes = 0;
439
+ let quiet = 0;
440
+ let cycling = false;
441
+ while (quiet < 2 && passes < maxIterations && !cycling) {
442
+ const up = passes % 2 === 0;
443
+ passes++;
444
+ let moved = false;
445
+ for (let u = 0; u < n; u++) {
446
+ const current = label[u];
447
+ next[u] = current;
448
+ const max = tally.collect(u, label);
449
+ if (max === 0 || tally.voteOf(current) === max) {
450
+ continue;
451
+ }
452
+ let best = INVALID_INDEX;
453
+ for (let i = 0; i < tally.count; i++) {
454
+ const c = touched[i];
455
+ if (acc[c] === max && c < best) {
456
+ best = c;
457
+ }
458
+ }
459
+ if (up ? best > current : best < current) {
460
+ next[u] = best;
461
+ moved = true;
462
+ }
463
+ }
464
+ cycling = moved && sameLabels(next, before);
465
+ [before, label, next] = [label, next, before];
466
+ quiet = moved ? 0 : quiet + 1;
467
+ }
468
+ const converged = quiet >= 2 || allDominant(tally, label, null);
469
+ const { labels, count } = renumberPartition(label);
470
+ return { ...withGroups(labels, count), iterations: passes, converged };
471
+ }
472
+ /**
473
+ * Whether two label arrays are equal.
474
+ * @param a - Labels
475
+ * @param b - Labels of the same length
476
+ * @returns True when every entry matches
477
+ */
478
+ function sameLabels(a, b) {
479
+ for (let i = 0; i < a.length; i++) {
480
+ if (a[i] !== b[i]) {
481
+ return false;
482
+ }
483
+ }
484
+ return true;
485
+ }
486
+ //# sourceMappingURL=label-propagation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"label-propagation.js","sourceRoot":"","sources":["../../../src/indexed/label-propagation.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,52 @@
1
+ import { type GraphSnapshot } from "@graphty/graph-format";
2
+ import { type LabelResult } from "./components.js";
3
+ /**
4
+ * Options of the index-based Leiden. The names and defaults are the legacy `leiden`'s, but
5
+ * `maxIterations` counts something else: see below.
6
+ * @public
7
+ */
8
+ export interface LeidenOptions {
9
+ /** Resolution gamma: above 1 favours smaller communities; default 1. */
10
+ readonly resolution?: number | undefined;
11
+ /** Seed of the visit orders; default 42. */
12
+ readonly randomSeed?: number | undefined;
13
+ /**
14
+ * Cap on whole passes over the original graph, each running as many levels as it needs; default
15
+ * 100. The legacy `leiden` caps levels instead, so its `maxIterations: 1` is one level where
16
+ * this is one full pass. The result's `iterations` counts levels.
17
+ */
18
+ readonly maxIterations?: number | undefined;
19
+ /** Stop once a pass improves modularity by no more than this; default 1e-7. */
20
+ readonly threshold?: number | undefined;
21
+ }
22
+ /** Result of the index-based Leiden: a partition plus the modularity it reaches. @public */
23
+ export interface LeidenResult extends LabelResult {
24
+ /** Modularity of the returned partition, at the requested resolution. */
25
+ readonly modularity: number;
26
+ /** Levels processed, summed over every pass. */
27
+ readonly iterations: number;
28
+ }
29
+ /**
30
+ * Leiden community detection (Traag, Waltman and van Eck, Sci. Rep. 9:5233, 2019) over an
31
+ * undirected snapshot: fast local moving, refinement into well-connected sub-communities, and
32
+ * aggregation by `contract()` once per level. Whole passes repeat from the previous answer, keeping
33
+ * a pass only when it raises modularity, until three passes in a row improve it by no more than
34
+ * `threshold` or `maxIterations` passes have run; every pass starts by moving single original
35
+ * nodes, so the answer is also a local optimum of those moves.
36
+ *
37
+ * Modularity follows graph-format's `weightedDegree()` convention (a self-loop counts twice), which
38
+ * on a graph without self-loops equals the legacy `leiden`'s. Weights are the exact f64 ones when
39
+ * the snapshot keeps them. The partition is not the legacy function's move for move: the legacy
40
+ * `leiden` splits disconnected communities rather than refining them, and visits nodes in another
41
+ * order; what this guarantees is connected communities. Both are randomised heuristics, so for one
42
+ * seed either can come out ahead; on the shared fixtures this one's modularity is at least the
43
+ * legacy's at the default seed and on average over seeds.
44
+ * @param s - An undirected snapshot
45
+ * @param options - Resolution, seed, pass cap and stopping threshold
46
+ * @returns The partition, its modularity, and the levels processed
47
+ * @throws Error on a directed snapshot; RangeError for a negative, NaN or infinite weight or a
48
+ * fractional seed
49
+ * @public
50
+ */
51
+ export declare function leiden(s: GraphSnapshot, options?: LeidenOptions): LeidenResult;
52
+ //# sourceMappingURL=leiden.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"leiden.d.ts","sourceRoot":"","sources":["../../../src/indexed/leiden.ts"],"names":[],"mappings":"AAAA,OAAO,EAAY,KAAK,aAAa,EAA+B,MAAM,uBAAuB,CAAC;AAElG,OAAO,EAAE,KAAK,WAAW,EAAc,MAAM,iBAAiB,CAAC;AAI/D;;;;GAIG;AACH,MAAM,WAAW,aAAa;IAC1B,wEAAwE;IACxE,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACzC,4CAA4C;IAC5C,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACzC;;;;OAIG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5C,+EAA+E;IAC/E,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC3C;AAED,4FAA4F;AAC5F,MAAM,WAAW,YAAa,SAAQ,WAAW;IAC7C,yEAAyE;IACzE,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,gDAAgD;IAChD,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC/B;AA0UD;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,MAAM,CAAC,CAAC,EAAE,aAAa,EAAE,OAAO,GAAE,aAAkB,GAAG,YAAY,CAmDlF"}