@graphty/graph-samples 0.0.1 → 0.1.2

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 (407) hide show
  1. package/LICENSE +21 -0
  2. package/NOTICE +123 -0
  3. package/README.md +190 -1
  4. package/dist/chunks/build-DdCe60t3.js +47 -0
  5. package/dist/chunks/build-DdCe60t3.js.map +1 -0
  6. package/dist/chunks/meta-B6toBzaa.js +19 -0
  7. package/dist/chunks/meta-B6toBzaa.js.map +1 -0
  8. package/dist/chunks/meta-BM_YIhlA.js +28 -0
  9. package/dist/chunks/meta-BM_YIhlA.js.map +1 -0
  10. package/dist/chunks/meta-BMmtUpPx.js +30 -0
  11. package/dist/chunks/meta-BMmtUpPx.js.map +1 -0
  12. package/dist/chunks/meta-BXC7oi86.js +22 -0
  13. package/dist/chunks/meta-BXC7oi86.js.map +1 -0
  14. package/dist/chunks/meta-BaFPvhc1.js +19 -0
  15. package/dist/chunks/meta-BaFPvhc1.js.map +1 -0
  16. package/dist/chunks/meta-C58v1Oy0.js +28 -0
  17. package/dist/chunks/meta-C58v1Oy0.js.map +1 -0
  18. package/dist/chunks/meta-CQRXyexG.js +23 -0
  19. package/dist/chunks/meta-CQRXyexG.js.map +1 -0
  20. package/dist/chunks/meta-DrgM1eS0.js +23 -0
  21. package/dist/chunks/meta-DrgM1eS0.js.map +1 -0
  22. package/dist/chunks/meta-IhoaDXAV.js +19 -0
  23. package/dist/chunks/meta-IhoaDXAV.js.map +1 -0
  24. package/dist/chunks/meta-MQPbBUUB.js +29 -0
  25. package/dist/chunks/meta-MQPbBUUB.js.map +1 -0
  26. package/dist/chunks/meta-Qp4HNYAZ.js +24 -0
  27. package/dist/chunks/meta-Qp4HNYAZ.js.map +1 -0
  28. package/dist/chunks/meta-mns0uFIW.js +19 -0
  29. package/dist/chunks/meta-mns0uFIW.js.map +1 -0
  30. package/dist/datasets/celegans-neural.d.ts +1 -0
  31. package/dist/datasets/celegans-neural.js +7359 -0
  32. package/dist/datasets/celegans-neural.js.map +1 -0
  33. package/dist/datasets/contiguous-usa.d.ts +1 -0
  34. package/dist/datasets/contiguous-usa.js +501 -0
  35. package/dist/datasets/contiguous-usa.js.map +1 -0
  36. package/dist/datasets/davis-southern-women.d.ts +1 -0
  37. package/dist/datasets/davis-southern-women.js +235 -0
  38. package/dist/datasets/davis-southern-women.js.map +1 -0
  39. package/dist/datasets/dolphins.d.ts +1 -0
  40. package/dist/datasets/dolphins.js +406 -0
  41. package/dist/datasets/dolphins.js.map +1 -0
  42. package/dist/datasets/florentine-families.d.ts +1 -0
  43. package/dist/datasets/florentine-families.js +75 -0
  44. package/dist/datasets/florentine-families.js.map +1 -0
  45. package/dist/datasets/football.d.ts +1 -0
  46. package/dist/datasets/football.js +1508 -0
  47. package/dist/datasets/football.js.map +1 -0
  48. package/dist/datasets/karate.d.ts +1 -0
  49. package/dist/datasets/karate.js +295 -0
  50. package/dist/datasets/karate.js.map +1 -0
  51. package/dist/datasets/knuth-miles.d.ts +1 -0
  52. package/dist/datasets/knuth-miles.js +24933 -0
  53. package/dist/datasets/knuth-miles.js.map +1 -0
  54. package/dist/datasets/les-miserables.d.ts +1 -0
  55. package/dist/datasets/les-miserables.js +860 -0
  56. package/dist/datasets/les-miserables.js.map +1 -0
  57. package/dist/datasets/openflights.d.ts +1 -0
  58. package/dist/datasets/openflights.js +130277 -0
  59. package/dist/datasets/openflights.js.map +1 -0
  60. package/dist/datasets/political-blogs.d.ts +1 -0
  61. package/dist/datasets/political-blogs.js +42551 -0
  62. package/dist/datasets/political-blogs.js.map +1 -0
  63. package/dist/datasets/political-books.d.ts +1 -0
  64. package/dist/datasets/political-books.js +1124 -0
  65. package/dist/datasets/political-books.js.map +1 -0
  66. package/dist/generators.d.ts +1 -0
  67. package/dist/generators.js +4496 -0
  68. package/dist/generators.js.map +1 -0
  69. package/dist/graph-samples.d.ts +1 -0
  70. package/dist/graph-samples.js +142 -0
  71. package/dist/graph-samples.js.map +1 -0
  72. package/dist/src/datasets/build.d.ts +89 -0
  73. package/dist/src/datasets/build.d.ts.map +1 -0
  74. package/dist/src/datasets/build.js +53 -0
  75. package/dist/src/datasets/build.js.map +1 -0
  76. package/dist/src/datasets/catalog.d.ts +8 -0
  77. package/dist/src/datasets/catalog.d.ts.map +1 -0
  78. package/dist/src/datasets/catalog.js +34 -0
  79. package/dist/src/datasets/catalog.js.map +1 -0
  80. package/dist/src/datasets/celegans-neural/data.d.ts +3 -0
  81. package/dist/src/datasets/celegans-neural/data.d.ts.map +1 -0
  82. package/dist/src/datasets/celegans-neural/data.js +573 -0
  83. package/dist/src/datasets/celegans-neural/data.js.map +1 -0
  84. package/dist/src/datasets/celegans-neural/index.d.ts +11 -0
  85. package/dist/src/datasets/celegans-neural/index.d.ts.map +1 -0
  86. package/dist/src/datasets/celegans-neural/index.js +14 -0
  87. package/dist/src/datasets/celegans-neural/index.js.map +1 -0
  88. package/dist/src/datasets/celegans-neural/meta.d.ts +4 -0
  89. package/dist/src/datasets/celegans-neural/meta.d.ts.map +1 -0
  90. package/dist/src/datasets/celegans-neural/meta.js +21 -0
  91. package/dist/src/datasets/celegans-neural/meta.js.map +1 -0
  92. package/dist/src/datasets/contiguous-usa/data.d.ts +3 -0
  93. package/dist/src/datasets/contiguous-usa/data.d.ts.map +1 -0
  94. package/dist/src/datasets/contiguous-usa/data.js +162 -0
  95. package/dist/src/datasets/contiguous-usa/data.js.map +1 -0
  96. package/dist/src/datasets/contiguous-usa/index.d.ts +11 -0
  97. package/dist/src/datasets/contiguous-usa/index.d.ts.map +1 -0
  98. package/dist/src/datasets/contiguous-usa/index.js +14 -0
  99. package/dist/src/datasets/contiguous-usa/index.js.map +1 -0
  100. package/dist/src/datasets/contiguous-usa/meta.d.ts +4 -0
  101. package/dist/src/datasets/contiguous-usa/meta.d.ts.map +1 -0
  102. package/dist/src/datasets/contiguous-usa/meta.js +27 -0
  103. package/dist/src/datasets/contiguous-usa/meta.js.map +1 -0
  104. package/dist/src/datasets/davis-southern-women/data.d.ts +3 -0
  105. package/dist/src/datasets/davis-southern-women/data.d.ts.map +1 -0
  106. package/dist/src/datasets/davis-southern-women/data.js +57 -0
  107. package/dist/src/datasets/davis-southern-women/data.js.map +1 -0
  108. package/dist/src/datasets/davis-southern-women/index.d.ts +11 -0
  109. package/dist/src/datasets/davis-southern-women/index.d.ts.map +1 -0
  110. package/dist/src/datasets/davis-southern-women/index.js +14 -0
  111. package/dist/src/datasets/davis-southern-women/index.js.map +1 -0
  112. package/dist/src/datasets/davis-southern-women/meta.d.ts +4 -0
  113. package/dist/src/datasets/davis-southern-women/meta.d.ts.map +1 -0
  114. package/dist/src/datasets/davis-southern-women/meta.js +17 -0
  115. package/dist/src/datasets/davis-southern-women/meta.js.map +1 -0
  116. package/dist/src/datasets/dolphins/data.d.ts +3 -0
  117. package/dist/src/datasets/dolphins/data.d.ts.map +1 -0
  118. package/dist/src/datasets/dolphins/data.js +93 -0
  119. package/dist/src/datasets/dolphins/data.js.map +1 -0
  120. package/dist/src/datasets/dolphins/index.d.ts +11 -0
  121. package/dist/src/datasets/dolphins/index.d.ts.map +1 -0
  122. package/dist/src/datasets/dolphins/index.js +14 -0
  123. package/dist/src/datasets/dolphins/index.js.map +1 -0
  124. package/dist/src/datasets/dolphins/meta.d.ts +4 -0
  125. package/dist/src/datasets/dolphins/meta.d.ts.map +1 -0
  126. package/dist/src/datasets/dolphins/meta.js +17 -0
  127. package/dist/src/datasets/dolphins/meta.js.map +1 -0
  128. package/dist/src/datasets/florentine-families/data.d.ts +3 -0
  129. package/dist/src/datasets/florentine-families/data.d.ts.map +1 -0
  130. package/dist/src/datasets/florentine-families/data.js +31 -0
  131. package/dist/src/datasets/florentine-families/data.js.map +1 -0
  132. package/dist/src/datasets/florentine-families/index.d.ts +11 -0
  133. package/dist/src/datasets/florentine-families/index.d.ts.map +1 -0
  134. package/dist/src/datasets/florentine-families/index.js +14 -0
  135. package/dist/src/datasets/florentine-families/index.js.map +1 -0
  136. package/dist/src/datasets/florentine-families/meta.d.ts +4 -0
  137. package/dist/src/datasets/florentine-families/meta.d.ts.map +1 -0
  138. package/dist/src/datasets/florentine-families/meta.js +17 -0
  139. package/dist/src/datasets/florentine-families/meta.js.map +1 -0
  140. package/dist/src/datasets/football/data.d.ts +3 -0
  141. package/dist/src/datasets/football/data.d.ts.map +1 -0
  142. package/dist/src/datasets/football/data.js +210 -0
  143. package/dist/src/datasets/football/data.js.map +1 -0
  144. package/dist/src/datasets/football/index.d.ts +11 -0
  145. package/dist/src/datasets/football/index.d.ts.map +1 -0
  146. package/dist/src/datasets/football/index.js +14 -0
  147. package/dist/src/datasets/football/index.js.map +1 -0
  148. package/dist/src/datasets/football/meta.d.ts +4 -0
  149. package/dist/src/datasets/football/meta.d.ts.map +1 -0
  150. package/dist/src/datasets/football/meta.js +17 -0
  151. package/dist/src/datasets/football/meta.js.map +1 -0
  152. package/dist/src/datasets/hosted.d.ts +7 -0
  153. package/dist/src/datasets/hosted.d.ts.map +1 -0
  154. package/dist/src/datasets/hosted.js +80 -0
  155. package/dist/src/datasets/hosted.js.map +1 -0
  156. package/dist/src/datasets/karate/data.d.ts +3 -0
  157. package/dist/src/datasets/karate/data.d.ts.map +1 -0
  158. package/dist/src/datasets/karate/data.js +30 -0
  159. package/dist/src/datasets/karate/data.js.map +1 -0
  160. package/dist/src/datasets/karate/index.d.ts +11 -0
  161. package/dist/src/datasets/karate/index.d.ts.map +1 -0
  162. package/dist/src/datasets/karate/index.js +14 -0
  163. package/dist/src/datasets/karate/index.js.map +1 -0
  164. package/dist/src/datasets/karate/meta.d.ts +4 -0
  165. package/dist/src/datasets/karate/meta.d.ts.map +1 -0
  166. package/dist/src/datasets/karate/meta.js +22 -0
  167. package/dist/src/datasets/karate/meta.js.map +1 -0
  168. package/dist/src/datasets/knuth-miles/data.d.ts +3 -0
  169. package/dist/src/datasets/knuth-miles/data.d.ts.map +1 -0
  170. package/dist/src/datasets/knuth-miles/data.js +1203 -0
  171. package/dist/src/datasets/knuth-miles/data.js.map +1 -0
  172. package/dist/src/datasets/knuth-miles/index.d.ts +11 -0
  173. package/dist/src/datasets/knuth-miles/index.d.ts.map +1 -0
  174. package/dist/src/datasets/knuth-miles/index.js +14 -0
  175. package/dist/src/datasets/knuth-miles/index.js.map +1 -0
  176. package/dist/src/datasets/knuth-miles/meta.d.ts +4 -0
  177. package/dist/src/datasets/knuth-miles/meta.d.ts.map +1 -0
  178. package/dist/src/datasets/knuth-miles/meta.js +26 -0
  179. package/dist/src/datasets/knuth-miles/meta.js.map +1 -0
  180. package/dist/src/datasets/les-miserables/data.d.ts +3 -0
  181. package/dist/src/datasets/les-miserables/data.d.ts.map +1 -0
  182. package/dist/src/datasets/les-miserables/data.js +117 -0
  183. package/dist/src/datasets/les-miserables/data.js.map +1 -0
  184. package/dist/src/datasets/les-miserables/index.d.ts +11 -0
  185. package/dist/src/datasets/les-miserables/index.d.ts.map +1 -0
  186. package/dist/src/datasets/les-miserables/index.js +14 -0
  187. package/dist/src/datasets/les-miserables/index.js.map +1 -0
  188. package/dist/src/datasets/les-miserables/meta.d.ts +4 -0
  189. package/dist/src/datasets/les-miserables/meta.d.ts.map +1 -0
  190. package/dist/src/datasets/les-miserables/meta.js +21 -0
  191. package/dist/src/datasets/les-miserables/meta.js.map +1 -0
  192. package/dist/src/datasets/openflights/data.d.ts +3 -0
  193. package/dist/src/datasets/openflights/data.d.ts.map +1 -0
  194. package/dist/src/datasets/openflights/data.js +15457 -0
  195. package/dist/src/datasets/openflights/data.js.map +1 -0
  196. package/dist/src/datasets/openflights/index.d.ts +11 -0
  197. package/dist/src/datasets/openflights/index.d.ts.map +1 -0
  198. package/dist/src/datasets/openflights/index.js +14 -0
  199. package/dist/src/datasets/openflights/index.js.map +1 -0
  200. package/dist/src/datasets/openflights/meta.d.ts +4 -0
  201. package/dist/src/datasets/openflights/meta.d.ts.map +1 -0
  202. package/dist/src/datasets/openflights/meta.js +28 -0
  203. package/dist/src/datasets/openflights/meta.js.map +1 -0
  204. package/dist/src/datasets/political-blogs/data.d.ts +3 -0
  205. package/dist/src/datasets/political-blogs/data.d.ts.map +1 -0
  206. package/dist/src/datasets/political-blogs/data.js +4857 -0
  207. package/dist/src/datasets/political-blogs/data.js.map +1 -0
  208. package/dist/src/datasets/political-blogs/index.d.ts +11 -0
  209. package/dist/src/datasets/political-blogs/index.d.ts.map +1 -0
  210. package/dist/src/datasets/political-blogs/index.js +14 -0
  211. package/dist/src/datasets/political-blogs/index.js.map +1 -0
  212. package/dist/src/datasets/political-blogs/meta.d.ts +4 -0
  213. package/dist/src/datasets/political-blogs/meta.d.ts.map +1 -0
  214. package/dist/src/datasets/political-blogs/meta.js +26 -0
  215. package/dist/src/datasets/political-blogs/meta.js.map +1 -0
  216. package/dist/src/datasets/political-books/data.d.ts +3 -0
  217. package/dist/src/datasets/political-books/data.d.ts.map +1 -0
  218. package/dist/src/datasets/political-books/data.js +165 -0
  219. package/dist/src/datasets/political-books/data.js.map +1 -0
  220. package/dist/src/datasets/political-books/index.d.ts +11 -0
  221. package/dist/src/datasets/political-books/index.d.ts.map +1 -0
  222. package/dist/src/datasets/political-books/index.js +14 -0
  223. package/dist/src/datasets/political-books/index.js.map +1 -0
  224. package/dist/src/datasets/political-books/meta.d.ts +4 -0
  225. package/dist/src/datasets/political-books/meta.d.ts.map +1 -0
  226. package/dist/src/datasets/political-books/meta.js +20 -0
  227. package/dist/src/datasets/political-books/meta.js.map +1 -0
  228. package/dist/src/datasets/remote.d.ts +27 -0
  229. package/dist/src/datasets/remote.d.ts.map +1 -0
  230. package/dist/src/datasets/remote.js +30 -0
  231. package/dist/src/datasets/remote.js.map +1 -0
  232. package/dist/src/element.d.ts +20 -0
  233. package/dist/src/element.d.ts.map +1 -0
  234. package/dist/src/element.js +27 -0
  235. package/dist/src/element.js.map +1 -0
  236. package/dist/src/generators/bipartite.d.ts +51 -0
  237. package/dist/src/generators/bipartite.d.ts.map +1 -0
  238. package/dist/src/generators/bipartite.js +99 -0
  239. package/dist/src/generators/bipartite.js.map +1 -0
  240. package/dist/src/generators/block-model.d.ts +75 -0
  241. package/dist/src/generators/block-model.d.ts.map +1 -0
  242. package/dist/src/generators/block-model.js +116 -0
  243. package/dist/src/generators/block-model.js.map +1 -0
  244. package/dist/src/generators/classic.d.ts +208 -0
  245. package/dist/src/generators/classic.d.ts.map +1 -0
  246. package/dist/src/generators/classic.js +437 -0
  247. package/dist/src/generators/classic.js.map +1 -0
  248. package/dist/src/generators/degree-sequence.d.ts +273 -0
  249. package/dist/src/generators/degree-sequence.d.ts.map +1 -0
  250. package/dist/src/generators/degree-sequence.js +646 -0
  251. package/dist/src/generators/degree-sequence.js.map +1 -0
  252. package/dist/src/generators/directed.d.ts +141 -0
  253. package/dist/src/generators/directed.d.ts.map +1 -0
  254. package/dist/src/generators/directed.js +329 -0
  255. package/dist/src/generators/directed.js.map +1 -0
  256. package/dist/src/generators/erdos-renyi.d.ts +58 -0
  257. package/dist/src/generators/erdos-renyi.d.ts.map +1 -0
  258. package/dist/src/generators/erdos-renyi.js +154 -0
  259. package/dist/src/generators/erdos-renyi.js.map +1 -0
  260. package/dist/src/generators/flow.d.ts +153 -0
  261. package/dist/src/generators/flow.d.ts.map +1 -0
  262. package/dist/src/generators/flow.js +346 -0
  263. package/dist/src/generators/flow.js.map +1 -0
  264. package/dist/src/generators/geometric.d.ts +133 -0
  265. package/dist/src/generators/geometric.d.ts.map +1 -0
  266. package/dist/src/generators/geometric.js +495 -0
  267. package/dist/src/generators/geometric.js.map +1 -0
  268. package/dist/src/generators/growth.d.ts +187 -0
  269. package/dist/src/generators/growth.d.ts.map +1 -0
  270. package/dist/src/generators/growth.js +445 -0
  271. package/dist/src/generators/growth.js.map +1 -0
  272. package/dist/src/generators/hyperbolic.d.ts +84 -0
  273. package/dist/src/generators/hyperbolic.d.ts.map +1 -0
  274. package/dist/src/generators/hyperbolic.js +153 -0
  275. package/dist/src/generators/hyperbolic.js.map +1 -0
  276. package/dist/src/generators/index.d.ts +25 -0
  277. package/dist/src/generators/index.d.ts.map +1 -0
  278. package/dist/src/generators/index.js +24 -0
  279. package/dist/src/generators/index.js.map +1 -0
  280. package/dist/src/generators/lattices.d.ts +87 -0
  281. package/dist/src/generators/lattices.d.ts.map +1 -0
  282. package/dist/src/generators/lattices.js +237 -0
  283. package/dist/src/generators/lattices.js.map +1 -0
  284. package/dist/src/generators/lfr.d.ts +55 -0
  285. package/dist/src/generators/lfr.d.ts.map +1 -0
  286. package/dist/src/generators/lfr.js +178 -0
  287. package/dist/src/generators/lfr.js.map +1 -0
  288. package/dist/src/generators/named.d.ts +23 -0
  289. package/dist/src/generators/named.d.ts.map +1 -0
  290. package/dist/src/generators/named.js +191 -0
  291. package/dist/src/generators/named.js.map +1 -0
  292. package/dist/src/generators/preferential-attachment.d.ts +66 -0
  293. package/dist/src/generators/preferential-attachment.d.ts.map +1 -0
  294. package/dist/src/generators/preferential-attachment.js +157 -0
  295. package/dist/src/generators/preferential-attachment.js.map +1 -0
  296. package/dist/src/generators/trees-and-dags.d.ts +53 -0
  297. package/dist/src/generators/trees-and-dags.d.ts.map +1 -0
  298. package/dist/src/generators/trees-and-dags.js +108 -0
  299. package/dist/src/generators/trees-and-dags.js.map +1 -0
  300. package/dist/src/generators/util.d.ts +84 -0
  301. package/dist/src/generators/util.d.ts.map +1 -0
  302. package/dist/src/generators/util.js +138 -0
  303. package/dist/src/generators/util.js.map +1 -0
  304. package/dist/src/generators/variants.d.ts +85 -0
  305. package/dist/src/generators/variants.d.ts.map +1 -0
  306. package/dist/src/generators/variants.js +215 -0
  307. package/dist/src/generators/variants.js.map +1 -0
  308. package/dist/src/generators/weights.d.ts +65 -0
  309. package/dist/src/generators/weights.d.ts.map +1 -0
  310. package/dist/src/generators/weights.js +135 -0
  311. package/dist/src/generators/weights.js.map +1 -0
  312. package/dist/src/index.d.ts +12 -0
  313. package/dist/src/index.d.ts.map +1 -0
  314. package/dist/src/index.js +10 -0
  315. package/dist/src/index.js.map +1 -0
  316. package/dist/src/random/exp.d.ts +23 -0
  317. package/dist/src/random/exp.d.ts.map +1 -0
  318. package/dist/src/random/exp.js +101 -0
  319. package/dist/src/random/exp.js.map +1 -0
  320. package/dist/src/random/log.d.ts +19 -0
  321. package/dist/src/random/log.d.ts.map +1 -0
  322. package/dist/src/random/log.js +83 -0
  323. package/dist/src/random/log.js.map +1 -0
  324. package/dist/src/random/stream.d.ts +93 -0
  325. package/dist/src/random/stream.d.ts.map +1 -0
  326. package/dist/src/random/stream.js +154 -0
  327. package/dist/src/random/stream.js.map +1 -0
  328. package/dist/src/random/threefry.d.ts +19 -0
  329. package/dist/src/random/threefry.d.ts.map +1 -0
  330. package/dist/src/random/threefry.js +43 -0
  331. package/dist/src/random/threefry.js.map +1 -0
  332. package/dist/src/random/trig.d.ts +16 -0
  333. package/dist/src/random/trig.d.ts.map +1 -0
  334. package/dist/src/random/trig.js +78 -0
  335. package/dist/src/random/trig.js.map +1 -0
  336. package/dist/src/types.d.ts +28 -0
  337. package/dist/src/types.d.ts.map +1 -0
  338. package/dist/src/types.js +2 -0
  339. package/dist/src/types.js.map +1 -0
  340. package/package.json +102 -5
  341. package/src/datasets/build.ts +140 -0
  342. package/src/datasets/catalog.ts +35 -0
  343. package/src/datasets/celegans-neural/data.ts +575 -0
  344. package/src/datasets/celegans-neural/index.ts +17 -0
  345. package/src/datasets/celegans-neural/meta.ts +25 -0
  346. package/src/datasets/contiguous-usa/data.ts +164 -0
  347. package/src/datasets/contiguous-usa/index.ts +17 -0
  348. package/src/datasets/contiguous-usa/meta.ts +31 -0
  349. package/src/datasets/davis-southern-women/data.ts +59 -0
  350. package/src/datasets/davis-southern-women/index.ts +17 -0
  351. package/src/datasets/davis-southern-women/meta.ts +20 -0
  352. package/src/datasets/dolphins/data.ts +95 -0
  353. package/src/datasets/dolphins/index.ts +17 -0
  354. package/src/datasets/dolphins/meta.ts +21 -0
  355. package/src/datasets/florentine-families/data.ts +33 -0
  356. package/src/datasets/florentine-families/index.ts +17 -0
  357. package/src/datasets/florentine-families/meta.ts +20 -0
  358. package/src/datasets/football/data.ts +212 -0
  359. package/src/datasets/football/index.ts +17 -0
  360. package/src/datasets/football/meta.ts +20 -0
  361. package/src/datasets/hosted.ts +90 -0
  362. package/src/datasets/karate/data.ts +32 -0
  363. package/src/datasets/karate/index.ts +17 -0
  364. package/src/datasets/karate/meta.ts +25 -0
  365. package/src/datasets/knuth-miles/data.ts +1205 -0
  366. package/src/datasets/knuth-miles/index.ts +17 -0
  367. package/src/datasets/knuth-miles/meta.ts +29 -0
  368. package/src/datasets/les-miserables/data.ts +119 -0
  369. package/src/datasets/les-miserables/index.ts +17 -0
  370. package/src/datasets/les-miserables/meta.ts +24 -0
  371. package/src/datasets/openflights/data.ts +15459 -0
  372. package/src/datasets/openflights/index.ts +17 -0
  373. package/src/datasets/openflights/meta.ts +31 -0
  374. package/src/datasets/political-blogs/data.ts +4859 -0
  375. package/src/datasets/political-blogs/index.ts +17 -0
  376. package/src/datasets/political-blogs/meta.ts +30 -0
  377. package/src/datasets/political-books/data.ts +167 -0
  378. package/src/datasets/political-books/index.ts +17 -0
  379. package/src/datasets/political-books/meta.ts +23 -0
  380. package/src/datasets/remote.ts +42 -0
  381. package/src/element.ts +41 -0
  382. package/src/generators/bipartite.ts +127 -0
  383. package/src/generators/block-model.ts +160 -0
  384. package/src/generators/classic.ts +461 -0
  385. package/src/generators/degree-sequence.ts +807 -0
  386. package/src/generators/directed.ts +418 -0
  387. package/src/generators/erdos-renyi.ts +188 -0
  388. package/src/generators/flow.ts +443 -0
  389. package/src/generators/geometric.ts +591 -0
  390. package/src/generators/growth.ts +532 -0
  391. package/src/generators/hyperbolic.ts +193 -0
  392. package/src/generators/index.ts +133 -0
  393. package/src/generators/lattices.ts +290 -0
  394. package/src/generators/lfr.ts +227 -0
  395. package/src/generators/named.ts +198 -0
  396. package/src/generators/preferential-attachment.ts +188 -0
  397. package/src/generators/trees-and-dags.ts +139 -0
  398. package/src/generators/util.ts +167 -0
  399. package/src/generators/variants.ts +253 -0
  400. package/src/generators/weights.ts +177 -0
  401. package/src/index.ts +12 -0
  402. package/src/random/exp.ts +104 -0
  403. package/src/random/log.ts +86 -0
  404. package/src/random/stream.ts +169 -0
  405. package/src/random/threefry.ts +45 -0
  406. package/src/random/trig.ts +83 -0
  407. package/src/types.ts +28 -0
@@ -0,0 +1,646 @@
1
+ /**
2
+ * Degree-sequence models: power-law degree sequences, the configuration model (undirected,
3
+ * directed and bipartite), Chung-Lu expected-degree graphs, the degree-corrected stochastic block
4
+ * model and random regular graphs.
5
+ */
6
+ import { MAX_COUNT } from "@graphty/graph-format";
7
+ import { detPow } from "../random/exp.js";
8
+ import { detLog } from "../random/log.js";
9
+ import { RandomStream, resolveSeed } from "../random/stream.js";
10
+ import { checkEdgeCount, checkInt, checkProbability, EdgeBuffer, toGraph } from "./util.js";
11
+ import { applyWeights } from "./weights.js";
12
+ /** The largest power-law support (maxDegree - minDegree + 1): the size of the cumulative table. */
13
+ const MAX_POWER_LAW_SUPPORT = 2 ** 24;
14
+ /**
15
+ * Throw unless `exponent` is a finite number >= 0.
16
+ * @param name - the option name
17
+ * @param exponent - the value
18
+ */
19
+ function checkExponent(name, exponent) {
20
+ if (!(Number.isFinite(exponent) && exponent >= 0)) {
21
+ throw new RangeError(`${name} must be a finite number >= 0, got ${String(exponent)}`);
22
+ }
23
+ }
24
+ /**
25
+ * A sampler of the discrete power law P(d) ~ d^-exponent on [min, max]: a cumulative table of
26
+ * detPow(d, -exponent), and per draw one nextFloat u and a binary search for the first entry
27
+ * above u times the total. Checks its arguments.
28
+ * @param names - the option names of [exponent, min, max], for the messages
29
+ * @param exponent - the exponent, >= 0
30
+ * @param min - the smallest value, >= 1
31
+ * @param max - the largest value, >= min
32
+ * @returns the sampler
33
+ */
34
+ export function powerLawSampler(names, exponent, min, max) {
35
+ checkExponent(names[0], exponent);
36
+ checkInt(names[1], min, 1);
37
+ checkInt(names[2], max, min, Math.min(MAX_COUNT, min + MAX_POWER_LAW_SUPPORT - 1));
38
+ const count = max - min + 1;
39
+ const cdf = new Float64Array(count);
40
+ let total = 0;
41
+ for (let k = 0; k < count; k++) {
42
+ total += detPow(min + k, -exponent);
43
+ cdf[k] = total;
44
+ }
45
+ return (stream) => {
46
+ const u = stream.nextFloat() * total;
47
+ let lo = 0;
48
+ let hi = count - 1;
49
+ while (lo < hi) {
50
+ const mid = (lo + hi) >>> 1;
51
+ if (cdf[mid] > u) {
52
+ hi = mid;
53
+ }
54
+ else {
55
+ lo = mid + 1;
56
+ }
57
+ }
58
+ return min + lo;
59
+ };
60
+ }
61
+ /**
62
+ * Make the sum of `seq` even by changing its LAST entry: +1 when it is below `max`, else -1 when
63
+ * it is above `min`; a RangeError when neither is possible.
64
+ * @param seq - the sequence, changed in place
65
+ * @param min - the smallest allowed value
66
+ * @param max - the largest allowed value
67
+ */
68
+ export function makeSumEven(seq, min, max) {
69
+ let total = 0;
70
+ for (const d of seq) {
71
+ total += d;
72
+ }
73
+ if (total % 2 === 0) {
74
+ return;
75
+ }
76
+ const last = seq.length - 1;
77
+ if (seq[last] < max) {
78
+ seq[last]++;
79
+ }
80
+ else if (seq[last] > min) {
81
+ seq[last]--;
82
+ }
83
+ else {
84
+ throw new RangeError(`cannot make the degree sum even: every degree is ${min} and n is odd`);
85
+ }
86
+ }
87
+ /**
88
+ * A sequence of n integers drawn independently from the discrete power law
89
+ * P(d) ~ d^-exponent on [minDegree, maxDegree], by inversion of a cumulative table built with
90
+ * detPow: entry i is one nextFloat of stream (seed, "power-law", 0), in index order. With
91
+ * `evenSum` (the default) an odd sum is fixed by changing the last entry: +1 when it is below
92
+ * maxDegree, else -1. O(n log(maxDegree - minDegree) + maxDegree - minDegree).
93
+ * @param options - n, exponent, minDegree, maxDegree, evenSum and seed
94
+ * @returns the sequence
95
+ */
96
+ export function powerLawDegreeSequence(options) {
97
+ const { n, exponent, minDegree, maxDegree } = options;
98
+ const seed = resolveSeed(options.seed);
99
+ checkInt("n", n, 0);
100
+ const sample = powerLawSampler(["exponent", "minDegree", "maxDegree"], exponent, minDegree, maxDegree);
101
+ const stream = new RandomStream(seed, "power-law", 0);
102
+ const seq = new Uint32Array(n);
103
+ for (let i = 0; i < n; i++) {
104
+ seq[i] = sample(stream);
105
+ }
106
+ if ((options.evenSum ?? true) && n > 0) {
107
+ makeSumEven(seq, minDegree, maxDegree);
108
+ }
109
+ return seq;
110
+ }
111
+ /**
112
+ * Check a degree sequence and return its sum.
113
+ * @param name - the option name
114
+ * @param degrees - the degrees
115
+ * @returns the sum
116
+ */
117
+ function degreeSum(name, degrees) {
118
+ checkInt(`${name}.length`, degrees.length, 0);
119
+ let total = 0;
120
+ for (let i = 0; i < degrees.length; i++) {
121
+ const d = degrees[i];
122
+ if (!(Number.isInteger(d) && d >= 0 && d <= MAX_COUNT)) {
123
+ checkInt(`${name}[${i}]`, d, 0);
124
+ }
125
+ total += d;
126
+ }
127
+ checkEdgeCount(total / 2);
128
+ return total;
129
+ }
130
+ /**
131
+ * The option value of a keep / erase policy, checked.
132
+ * @param name - the option name
133
+ * @param value - the value (default "erase")
134
+ * @returns true for keep
135
+ */
136
+ function keeps(name, value) {
137
+ if (value !== undefined && value !== "keep" && value !== "erase") {
138
+ throw new RangeError(`${name} must be "keep" or "erase", got ${String(value)}`);
139
+ }
140
+ return value === "keep";
141
+ }
142
+ /**
143
+ * The stub list: node i + offset repeated degrees[i] times, ascending.
144
+ * @param degrees - the degrees
145
+ * @param total - their sum
146
+ * @param offset - added to every node index
147
+ * @returns the stubs
148
+ */
149
+ export function stubList(degrees, total, offset = 0) {
150
+ const stubs = new Uint32Array(total);
151
+ let k = 0;
152
+ for (let i = 0; i < degrees.length; i++) {
153
+ stubs.fill(i + offset, k, k + degrees[i]);
154
+ k += degrees[i];
155
+ }
156
+ return stubs;
157
+ }
158
+ /**
159
+ * Fisher-Yates shuffle in place: for i = length - 1 down to 1, swap entries i and nextBelow(i + 1).
160
+ * @param a - the array
161
+ * @param stream - the stream
162
+ */
163
+ export function shuffle(a, stream) {
164
+ for (let i = a.length - 1; i > 0; i--) {
165
+ const j = stream.nextBelow(i + 1);
166
+ const t = a[i];
167
+ a[i] = a[j];
168
+ a[j] = t;
169
+ }
170
+ }
171
+ /**
172
+ * Filter an edge list, keeping edge order: drop self-loops unless `keepLoops`, drop edges whose
173
+ * endpoints share a `group` value when `group` is given, and drop every repeat of a pair (ordered
174
+ * when directed, unordered otherwise) after its first kept occurrence unless `keepMulti`. O(n + m)
175
+ * by a counting sort on the smaller endpoint and a last-seen mark per node, no hashing.
176
+ * @param n - the node count
177
+ * @param src - the sources
178
+ * @param dst - the targets
179
+ * @param directed - whether pairs are ordered
180
+ * @param keepLoops - keep self-loops
181
+ * @param keepMulti - keep repeated pairs
182
+ * @param out - receives the kept edges
183
+ * @param group - a node column; edges inside one group are dropped
184
+ */
185
+ function eraseEdges(n, src, dst, directed, keepLoops, keepMulti, out, group) {
186
+ const m = src.length;
187
+ const keep = new Uint8Array(m).fill(1);
188
+ for (let e = 0; e < m; e++) {
189
+ const u = src[e];
190
+ const v = dst[e];
191
+ if ((!keepLoops && u === v) || (group !== undefined && group[u] === group[v])) {
192
+ keep[e] = 0;
193
+ }
194
+ }
195
+ if (!keepMulti) {
196
+ const lo = (e) => (directed ? src[e] : Math.min(src[e], dst[e]));
197
+ const start = new Uint32Array(n + 1);
198
+ for (let e = 0; e < m; e++) {
199
+ start[lo(e) + 1]++;
200
+ }
201
+ for (let i = 0; i < n; i++) {
202
+ start[i + 1] += start[i];
203
+ }
204
+ const fill = start.slice(0, n);
205
+ const order = new Uint32Array(m);
206
+ for (let e = 0; e < m; e++) {
207
+ order[fill[lo(e)]++] = e;
208
+ }
209
+ // mark[v] = u + 1 when the pair (u, v) has been seen in u's bucket
210
+ const mark = new Uint32Array(n);
211
+ for (let k = 0; k < m; k++) {
212
+ const e = order[k];
213
+ if (keep[e] === 0) {
214
+ continue;
215
+ }
216
+ const u = lo(e);
217
+ const v = directed ? dst[e] : Math.max(src[e], dst[e]);
218
+ if (mark[v] === u + 1) {
219
+ keep[e] = 0;
220
+ }
221
+ else {
222
+ mark[v] = u + 1;
223
+ }
224
+ }
225
+ }
226
+ for (let e = 0; e < m; e++) {
227
+ if (keep[e] === 1) {
228
+ out.push(src[e], dst[e]);
229
+ }
230
+ }
231
+ }
232
+ /**
233
+ * Pair consecutive stubs of a shuffled undirected stub list into edges (stubs[2k], stubs[2k + 1])
234
+ * and erase as asked.
235
+ * @param n - the node count
236
+ * @param stubs - the shuffled stubs (even length)
237
+ * @param keepLoops - keep self-loops
238
+ * @param keepMulti - keep repeated pairs
239
+ * @param out - receives the edges
240
+ * @param group - a node column; edges inside one group are dropped
241
+ */
242
+ export function pairStubs(n, stubs, keepLoops, keepMulti, out, group) {
243
+ const m = stubs.length / 2;
244
+ const src = new Uint32Array(m);
245
+ const dst = new Uint32Array(m);
246
+ for (let k = 0; k < m; k++) {
247
+ src[k] = stubs[2 * k];
248
+ dst[k] = stubs[2 * k + 1];
249
+ }
250
+ eraseEdges(n, src, dst, false, keepLoops, keepMulti, out, group);
251
+ }
252
+ /**
253
+ * The configuration model (E. A. Bender and E. R. Canfield, "The asymptotic number of labeled
254
+ * graphs with given degree sequences", J. Combin. Theory A 24, 296-307, 1978,
255
+ * doi:10.1016/0097-3165(78)90059-6; M. Molloy and B. Reed, "A critical point for random graphs with
256
+ * a given degree sequence", Random Struct. Algorithms 6, 161-179, 1995, doi:10.1002/rsa.3240060204;
257
+ * M. E. J. Newman, S. H. Strogatz and D. J. Watts, "Random graphs with arbitrary degree
258
+ * distributions and their applications", Phys. Rev. E 64, 026118, 2001,
259
+ * doi:10.1103/PhysRevE.64.026118). The stub list (node i repeated degrees[i] times, ascending) is
260
+ * Fisher-Yates shuffled with stream (seed, "configuration", 0) and consecutive stubs are paired:
261
+ * edge k is (stubs[2k], stubs[2k + 1]), in that order. With keep / keep the degrees are exact (a
262
+ * multigraph); erasing drops self-loops and every repeat of a pair after its first occurrence, so
263
+ * degrees can only go down. An odd degree sum is a RangeError. O(n + m).
264
+ * @param options - degrees, selfLoops, multiEdges and seed
265
+ * @returns the undirected graph
266
+ */
267
+ export function configurationModelGraph(options) {
268
+ const { degrees } = options;
269
+ const seed = resolveSeed(options.seed);
270
+ const keepLoops = keeps("selfLoops", options.selfLoops);
271
+ const keepMulti = keeps("multiEdges", options.multiEdges);
272
+ const total = degreeSum("degrees", degrees);
273
+ if (total % 2 !== 0) {
274
+ throw new RangeError(`the degree sum must be even, got ${total}`);
275
+ }
276
+ const n = degrees.length;
277
+ const stubs = stubList(degrees, total);
278
+ shuffle(stubs, new RandomStream(seed, "configuration", 0));
279
+ const out = new EdgeBuffer(total / 2);
280
+ pairStubs(n, stubs, keepLoops, keepMulti, out);
281
+ return applyWeights(toGraph(n, out, false), options);
282
+ }
283
+ /**
284
+ * The directed configuration model (Newman, Strogatz and Watts 2001, section on directed graphs):
285
+ * the in-stub list (node i repeated inDegrees[i] times, ascending) is Fisher-Yates shuffled with
286
+ * stream (seed, "configuration-directed", 0) and paired in order with the ascending out-stub list,
287
+ * so edge k runs from the k-th out-stub to the k-th shuffled in-stub (edges come grouped by
288
+ * source, ascending). Erasing works as in {@link configurationModelGraph} on ordered pairs.
289
+ * O(n + m).
290
+ * @param options - outDegrees, inDegrees, selfLoops, multiEdges and seed
291
+ * @returns the directed graph
292
+ */
293
+ export function directedConfigurationModelGraph(options) {
294
+ const { outDegrees, inDegrees } = options;
295
+ const seed = resolveSeed(options.seed);
296
+ const keepLoops = keeps("selfLoops", options.selfLoops);
297
+ const keepMulti = keeps("multiEdges", options.multiEdges);
298
+ const outTotal = degreeSum("outDegrees", outDegrees);
299
+ const inTotal = degreeSum("inDegrees", inDegrees);
300
+ if (outDegrees.length !== inDegrees.length) {
301
+ throw new RangeError(`outDegrees and inDegrees must have the same length`);
302
+ }
303
+ if (outTotal !== inTotal) {
304
+ throw new RangeError(`the out-degree sum (${outTotal}) must equal the in-degree sum (${inTotal})`);
305
+ }
306
+ const n = outDegrees.length;
307
+ const dst = stubList(inDegrees, inTotal);
308
+ shuffle(dst, new RandomStream(seed, "configuration-directed", 0));
309
+ const out = new EdgeBuffer(outTotal);
310
+ eraseEdges(n, stubList(outDegrees, outTotal), dst, true, keepLoops, keepMulti, out);
311
+ return applyWeights(toGraph(n, out, true), options);
312
+ }
313
+ /**
314
+ * The bipartite configuration model (Newman, Strogatz and Watts 2001, section on bipartite
315
+ * graphs): left nodes are 0 .. L - 1, right nodes L .. L + R - 1. The right stub list (ascending)
316
+ * is Fisher-Yates shuffled with stream (seed, "bipartite-configuration", 0) and paired in order with
317
+ * the ascending left stub list; edge k is (k-th left stub, k-th shuffled right stub). Node column
318
+ * `side` (u8): 0 left, 1 right. O(n + m).
319
+ * @param options - leftDegrees, rightDegrees, multiEdges and seed
320
+ * @returns the undirected bipartite graph
321
+ */
322
+ export function bipartiteConfigurationModelGraph(options) {
323
+ const { leftDegrees, rightDegrees } = options;
324
+ const seed = resolveSeed(options.seed);
325
+ const keepMulti = keeps("multiEdges", options.multiEdges);
326
+ const leftTotal = degreeSum("leftDegrees", leftDegrees);
327
+ const rightTotal = degreeSum("rightDegrees", rightDegrees);
328
+ if (leftTotal !== rightTotal) {
329
+ throw new RangeError(`the left degree sum (${leftTotal}) must equal the right degree sum (${rightTotal})`);
330
+ }
331
+ const left = leftDegrees.length;
332
+ const n = left + rightDegrees.length;
333
+ checkInt("the node count", n, 0);
334
+ const dst = stubList(rightDegrees, rightTotal, left);
335
+ shuffle(dst, new RandomStream(seed, "bipartite-configuration", 0));
336
+ const out = new EdgeBuffer(leftTotal);
337
+ eraseEdges(n, stubList(leftDegrees, leftTotal), dst, false, true, keepMulti, out);
338
+ const side = new Uint8Array(n).fill(1, left);
339
+ return applyWeights(toGraph(n, out, false, { side }), options);
340
+ }
341
+ /**
342
+ * Check weights (finite, >= 0) and return their sum.
343
+ * @param weights - the weights
344
+ * @returns the sum
345
+ */
346
+ function weightSum(weights) {
347
+ checkInt("expectedDegrees.length", weights.length, 0);
348
+ let total = 0;
349
+ for (let i = 0; i < weights.length; i++) {
350
+ if (!(Number.isFinite(weights[i]) && weights[i] >= 0)) {
351
+ throw new RangeError(`expectedDegrees[${i}] must be a finite number >= 0, got ${String(weights[i])}`);
352
+ }
353
+ total += weights[i];
354
+ }
355
+ return total;
356
+ }
357
+ /**
358
+ * Build the rows of an expected-degree model: nodes of each block (consecutive index ranges) sorted
359
+ * by weight descending, ties by index ascending.
360
+ * @param weights - the node weights
361
+ * @param nodeStarts - block boundaries in node indices
362
+ * @param factor - the block-pair factors
363
+ * @param seed - the seed
364
+ * @param domain - the stream domain
365
+ * @param total - the weight sum
366
+ * @returns the plan
367
+ */
368
+ function planRows(weights, nodeStarts, factor, seed, domain, total) {
369
+ const n = weights.length;
370
+ const order = new Uint32Array(n);
371
+ const rowBlock = new Uint32Array(n);
372
+ for (let i = 0; i < n; i++) {
373
+ order[i] = i;
374
+ }
375
+ for (let b = 0; b + 1 < nodeStarts.length; b++) {
376
+ order.subarray(nodeStarts[b], nodeStarts[b + 1]).sort((x, y) => weights[y] - weights[x] || x - y);
377
+ rowBlock.fill(b, nodeStarts[b], nodeStarts[b + 1]);
378
+ }
379
+ const weight = Float64Array.from(order, (i) => weights[i]);
380
+ return { n, seed, domain, order, weight, rowBlock, starts: nodeStarts, factor, total };
381
+ }
382
+ /**
383
+ * Check Chung-Lu options and build the plan: one block, factor 1 / S.
384
+ * @param options - the options
385
+ * @returns the plan
386
+ */
387
+ export function planChungLu(options) {
388
+ const seed = resolveSeed(options.seed);
389
+ const total = weightSum(options.expectedDegrees);
390
+ const n = options.expectedDegrees.length;
391
+ return planRows(options.expectedDegrees, [0, n], [[total > 0 ? 1 / total : 0]], seed, "chung-lu", total);
392
+ }
393
+ /**
394
+ * Rows [start, end) of an expected-degree model (Chung-Lu, or the DC-SBM with its own plan and
395
+ * domain) by the skipping of Miller and Hagberg: row `row` (in block r) draws from stream
396
+ * (seed, domain, row) and walks blocks s = r .. B - 1 in order; inside block s it visits the later
397
+ * rows v (all rows of s when s > r) in row order, whose weights never increase, skipping with the
398
+ * previous probability p (nextSkip(detLog(1 - p)) unless p = 1) and accepting the landing v with
399
+ * probability q / p (one nextFloat), q = min(1, factor[r][s] w_row w_v). Edges are
400
+ * (order[row], order[v]) in original node indices. Concatenating consecutive row ranges gives
401
+ * the whole graph.
402
+ * @param plan - the checked options
403
+ * @param start - the first row
404
+ * @param end - one past the last row
405
+ * @param out - receives the edges
406
+ */
407
+ export function chungLuRows(plan, start, end, out) {
408
+ const { order, weight, rowBlock, starts, factor } = plan;
409
+ const stream = new RandomStream(plan.seed, plan.domain, 0);
410
+ const count = starts.length - 1;
411
+ for (let row = start; row < end; row++) {
412
+ stream.reset(row);
413
+ const r = rowBlock[row];
414
+ // ponytail: O(B) per row like the block model; iterate non-zero blocks if B grows large
415
+ for (let s = r; s < count; s++) {
416
+ const cu = factor[r][s] * weight[row];
417
+ let v = s === r ? row + 1 : starts[s];
418
+ const hi = starts[s + 1];
419
+ if (cu === 0 || v >= hi) {
420
+ continue;
421
+ }
422
+ let p = Math.min(1, cu * weight[v]);
423
+ while (v < hi && p > 0) {
424
+ if (p !== 1) {
425
+ const logQ = detLog(1 - p);
426
+ // p below 2^-53 rounds 1 - p to 1: no further edge in this segment
427
+ if (logQ === 0) {
428
+ break;
429
+ }
430
+ v += stream.nextSkip(logQ);
431
+ if (v >= hi) {
432
+ break;
433
+ }
434
+ }
435
+ const q = Math.min(1, cu * weight[v]);
436
+ if (stream.nextFloat() < q / p) {
437
+ out.push(order[row], order[v]);
438
+ }
439
+ p = q;
440
+ v++;
441
+ }
442
+ }
443
+ }
444
+ }
445
+ /**
446
+ * Run a plan over all its rows.
447
+ * @param plan - the plan
448
+ * @param nodeColumns - ground-truth columns
449
+ * @param options - for the weights option
450
+ * @returns the graph
451
+ */
452
+ function runPlan(plan, nodeColumns, options) {
453
+ const mean = plan.total / 2;
454
+ checkEdgeCount(mean);
455
+ const out = new EdgeBuffer(Math.ceil(mean + 6 * Math.sqrt(mean) + 16));
456
+ chungLuRows(plan, 0, plan.n, out);
457
+ return applyWeights(toGraph(plan.n, out, false, nodeColumns), options);
458
+ }
459
+ /**
460
+ * The Chung-Lu expected-degree graph (F. Chung and L. Lu, "The average distances in random graphs
461
+ * with given expected degrees", PNAS 99, 15879-15882, 2002, doi:10.1073/pnas.252631999): every
462
+ * pair u != v is joined independently with probability min(1, w_u w_v / S), S the weight sum, so
463
+ * node u's expected degree is about w_u when every w_u w_v is below S. Linear time by the skipping
464
+ * of J. C. Miller and A. Hagberg, "Efficient generation of networks with given expected degrees",
465
+ * WAW 2011, LNCS 6732, 115-126, doi:10.1007/978-3-642-21286-4_10. Rows are the nodes sorted by
466
+ * weight descending (ties by index ascending); row i draws from stream (seed, "chung-lu", i) (see
467
+ * {@link chungLuRows}). Edges are listed by row, each (row node, later node) in original indices.
468
+ * Simple, undirected. O(n log n + m).
469
+ * @param options - expectedDegrees and seed
470
+ * @returns the undirected graph
471
+ */
472
+ export function chungLuGraph(options) {
473
+ return runPlan(planChungLu(options), undefined, options);
474
+ }
475
+ /**
476
+ * Check DC-SBM options and build the plan.
477
+ * @param options - the options
478
+ * @returns the plan
479
+ */
480
+ export function planDegreeCorrectedSbm(options) {
481
+ const { sizes, expectedDegrees, mixing } = options;
482
+ const seed = resolveSeed(options.seed);
483
+ checkInt("sizes.length", sizes.length, 1);
484
+ checkProbability("mixing", mixing);
485
+ const total = weightSum(expectedDegrees);
486
+ const starts = [0];
487
+ for (let b = 0; b < sizes.length; b++) {
488
+ checkInt(`sizes[${b}]`, sizes[b], 0);
489
+ starts.push(starts[b] + sizes[b]);
490
+ }
491
+ if (starts[sizes.length] !== expectedDegrees.length) {
492
+ throw new RangeError(`the sizes sum to ${starts[sizes.length]}, but expectedDegrees has ${expectedDegrees.length} entries`);
493
+ }
494
+ const kappa = sizes.map((_, b) => {
495
+ let k = 0;
496
+ for (let i = starts[b]; i < starts[b + 1]; i++) {
497
+ k += expectedDegrees[i];
498
+ }
499
+ return k;
500
+ });
501
+ const between = total > 0 ? mixing / total : 0;
502
+ const inside = kappa.map((kr) => (kr > 0 ? (1 - mixing) / kr : 0));
503
+ const factor = kappa.map((_, r) => kappa.map((_2, s) => (r === s ? inside[r] : between)));
504
+ return planRows(expectedDegrees, starts, factor, seed, "dcsbm", total);
505
+ }
506
+ /**
507
+ * The degree-corrected stochastic block model (B. Karrer and M. E. J. Newman, "Stochastic
508
+ * blockmodels and community structure in networks", Phys. Rev. E 83, 016107, 2011,
509
+ * doi:10.1103/PhysRevE.83.016107), sampled as a simple graph with Bernoulli edges:
510
+ * P(uv) = min(1, theta_u theta_v omega_rs) with theta_u = d_u / kappa_r (kappa_r the degree total of
511
+ * u's block r, K the grand total), omega_rr = (1 - mu) kappa_r and omega_rs = mu kappa_r kappa_s / K
512
+ * for r != s. So node u's expected degree is about d_u (1 - mu kappa_r / K): the inside share is
513
+ * 1 - mu, but the outside share misses the mu kappa_r / K that would land in u's own block.
514
+ * Rows: block by block, inside a block the nodes sorted by d descending (ties by index); row i
515
+ * draws from stream (seed, "dcsbm", i) and walks its own block's later rows, then every later
516
+ * block (see {@link chungLuRows}). Edges are listed by row in original node indices. Node column
517
+ * `community` (u32). With one block and mu = 0 it is Chung-Lu. O(n log n + n B + m).
518
+ * @param options - sizes, expectedDegrees, mixing and seed
519
+ * @returns the undirected graph
520
+ */
521
+ export function degreeCorrectedSbmGraph(options) {
522
+ const plan = planDegreeCorrectedSbm(options);
523
+ const community = new Uint32Array(plan.n);
524
+ for (let b = 0; b + 1 < plan.starts.length; b++) {
525
+ community.fill(b, plan.starts[b], plan.starts[b + 1]);
526
+ }
527
+ return runPlan(plan, { community }, options);
528
+ }
529
+ /** Attempts before randomRegularGraph gives up. */
530
+ const REGULAR_ATTEMPTS = 100;
531
+ /** Re-pairing rounds inside one attempt before it counts as failed. */
532
+ const REGULAR_ROUNDS = 1000;
533
+ /**
534
+ * One attempt of the Steger-Wormald pairing; fills `adj` (d slots per node) and `deg`.
535
+ * @param n - the node count
536
+ * @param d - the degree
537
+ * @param stream - the attempt's stream
538
+ * @param adj - the adjacency slots
539
+ * @param deg - the filled slot count per node
540
+ * @returns true on success
541
+ */
542
+ function regularAttempt(n, d, stream, adj, deg) {
543
+ deg.fill(0);
544
+ const has = (u, v) => {
545
+ const base = u * d;
546
+ for (let k = base; k < base + deg[u]; k++) {
547
+ if (adj[k] === v) {
548
+ return true;
549
+ }
550
+ }
551
+ return false;
552
+ };
553
+ const potential = new Uint32Array(n);
554
+ let stubs = stubList(new Uint32Array(n).fill(d), n * d);
555
+ for (let round = 0; round < REGULAR_ROUNDS && stubs.length > 0; round++) {
556
+ shuffle(stubs, stream);
557
+ const touched = [];
558
+ for (let k = 0; k < stubs.length; k += 2) {
559
+ const u = Math.min(stubs[k], stubs[k + 1]);
560
+ const v = Math.max(stubs[k], stubs[k + 1]);
561
+ if (u !== v && !has(u, v)) {
562
+ adj[u * d + deg[u]++] = v;
563
+ adj[v * d + deg[v]++] = u;
564
+ }
565
+ else {
566
+ for (const x of [u, v]) {
567
+ if (potential[x]++ === 0) {
568
+ touched.push(x);
569
+ }
570
+ }
571
+ }
572
+ }
573
+ touched.sort((a, b) => a - b);
574
+ // suitable: some pair of distinct leftover nodes is not yet an edge
575
+ let suitable = touched.length === 0;
576
+ for (let i = 0; i < touched.length && !suitable; i++) {
577
+ for (let j = i + 1; j < touched.length && !suitable; j++) {
578
+ suitable = !has(touched[i], touched[j]);
579
+ }
580
+ }
581
+ if (!suitable) {
582
+ return false;
583
+ }
584
+ let total = 0;
585
+ for (const x of touched) {
586
+ total += potential[x];
587
+ }
588
+ const next = new Uint32Array(total);
589
+ let k = 0;
590
+ for (const x of touched) {
591
+ next.fill(x, k, k + potential[x]);
592
+ k += potential[x];
593
+ potential[x] = 0;
594
+ }
595
+ stubs = next;
596
+ }
597
+ return stubs.length === 0;
598
+ }
599
+ /**
600
+ * A uniformly-ish random d-regular simple graph by the pairing algorithm of A. Steger and
601
+ * N. C. Wormald, "Generating random regular graphs quickly", Combin. Probab. Comput. 8, 377-396,
602
+ * 1999, doi:10.1017/S0963548399003867, structured like networkx's `random_regular_graph`: attempt
603
+ * a (a = 0, 1, ...) draws from stream (seed, "random-regular", a); it Fisher-Yates shuffles the
604
+ * stub list (node i repeated d times, ascending), keeps each consecutive pair that is not a loop
605
+ * and not yet an edge, and re-pairs the leftover stubs (ascending node order) while some leftover
606
+ * pair could still be joined; otherwise it restarts. At most 100 attempts of at most 1000 rounds,
607
+ * then a RangeError. Edges (u, v), u < v, in lexicographic order. Expected O(n d^2) for small d.
608
+ * @param options - n, d and seed
609
+ * @returns the undirected graph
610
+ */
611
+ export function randomRegularGraph(options) {
612
+ const { n, d } = options;
613
+ const seed = resolveSeed(options.seed);
614
+ checkInt("n", n, 0);
615
+ checkInt("d", d, 0, Math.max(0, n - 1));
616
+ if ((n * d) % 2 !== 0) {
617
+ throw new RangeError(`n * d must be even, got ${n} * ${d}`);
618
+ }
619
+ checkEdgeCount((n * d) / 2);
620
+ const out = new EdgeBuffer((n * d) / 2);
621
+ if (d > 0) {
622
+ const adj = new Uint32Array(n * d);
623
+ const deg = new Uint32Array(n);
624
+ const stream = new RandomStream(seed, "random-regular", 0);
625
+ let attempt = 0;
626
+ for (; attempt < REGULAR_ATTEMPTS; attempt++) {
627
+ stream.reset(attempt);
628
+ if (regularAttempt(n, d, stream, adj, deg)) {
629
+ break;
630
+ }
631
+ }
632
+ if (attempt === REGULAR_ATTEMPTS) {
633
+ throw new RangeError(`randomRegularGraph found no ${d}-regular graph on ${n} nodes in ${REGULAR_ATTEMPTS} attempts`);
634
+ }
635
+ for (let u = 0; u < n; u++) {
636
+ const row = adj.subarray(u * d, u * d + d).sort();
637
+ for (const v of row) {
638
+ if (v > u) {
639
+ out.push(u, v);
640
+ }
641
+ }
642
+ }
643
+ }
644
+ return applyWeights(toGraph(n, out, false), options);
645
+ }
646
+ //# sourceMappingURL=degree-sequence.js.map