@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,17 @@
1
+ /**
2
+ * `@graphty/graph-samples/datasets/political-blogs`: US political blogs, 2004.
3
+ */
4
+
5
+ import { type SampleGraph } from "../../types.js";
6
+ import { buildDataset } from "../build.js";
7
+ import { DATA } from "./data.js";
8
+
9
+ export { politicalBlogsMeta } from "./meta.js";
10
+
11
+ /**
12
+ * US political blogs, 2004: 1,490 blogs, 19,022 directed links, and each blog's political lean (`lean`).
13
+ * @returns a fresh copy of the graph as typed arrays
14
+ */
15
+ export function politicalBlogs(): SampleGraph {
16
+ return buildDataset(DATA);
17
+ }
@@ -0,0 +1,30 @@
1
+ import { type DatasetMeta } from "../build.js";
2
+
3
+ /** What the politicalBlogs dataset is, where it came from and under which terms. */
4
+ export const politicalBlogsMeta: DatasetMeta = {
5
+ name: "political-blogs",
6
+ title: "US political blogs, 2004",
7
+ description:
8
+ "Hyperlinks between US political weblogs, crawled from their front pages in February 2005, with each blog labelled liberal or conservative from blog directories and by hand. Directed; 266 blogs have no links. The crawl recorded 65 links twice and 3 blogs linking to themselves: each link is kept once and the self-links are dropped.",
9
+ citation:
10
+ "L. A. Adamic and N. Glance, The political blogosphere and the 2004 U.S. election: divided they blog, Proceedings of the 3rd International Workshop on Link Discovery (LinkKDD 2005), 36-43. doi:10.1145/1134271.1134277",
11
+ source: "https://web.archive.org/web/20240730122800id_/https://public.websites.umich.edu/~mejn/netdata/polblogs.zip",
12
+ license:
13
+ 'unclear: posted on Mark Newman\'s data page with the authors\' permission, "free for scientific use"; the SuiteSparse Matrix Collection republishes the graph under CC BY 4.0.',
14
+ nodes: 1490,
15
+ edges: 19022,
16
+ directed: true,
17
+ weighted: false,
18
+ attributes: {
19
+ label: "string: the blog's address",
20
+ lean: "dict: liberal or conservative (ground truth)",
21
+ directory: "string: the blog directories the label came from",
22
+ },
23
+ groundTruth: "lean",
24
+ showcases: [
25
+ "two-way community detection against the political lean",
26
+ "PageRank and HITS on a directed graph",
27
+ "degree-corrected block models",
28
+ "force-directed layouts coloured by lean",
29
+ ],
30
+ };
@@ -0,0 +1,167 @@
1
+ // THIS FILE IS AUTO GENERATED: DO NOT EDIT THIS FILE. INSTEAD EDIT graph-samples/scripts/convert-datasets.mjs
2
+ // Source: https://web.archive.org/web/20240730210010id_/https://public.websites.umich.edu/~mejn/netdata/polbooks.zip
3
+ // sha256: b8e37351ae9ae8ee39f8b75ed52170d2435f290855605680c9b4f4c8b46b3c37
4
+
5
+ import { type DatasetData } from "../build.js";
6
+
7
+ export const DATA: DatasetData = {
8
+ directed: false,
9
+ nodeCount: 105,
10
+ ids: null,
11
+ edges: [
12
+ 1, 0, 2, 0, 3, 0, 3, 1, 4, 0, 4, 2, 5, 0, 5, 1, 5, 2, 5, 3, 5, 4, 6, 0, 6, 1, 6, 4, 6, 5, 7, 2, 7, 5, 7, 6, 8,
13
+ 3, 9, 3, 9, 8, 10, 3, 10, 6, 10, 8, 11, 3, 11, 8, 11, 9, 11, 10, 12, 3, 12, 6, 12, 8, 12, 9, 12, 10, 12, 11, 13,
14
+ 3, 13, 8, 13, 11, 13, 12, 14, 3, 14, 8, 14, 9, 14, 11, 14, 12, 14, 7, 15, 3, 15, 10, 15, 12, 16, 3, 16, 10, 16,
15
+ 15, 17, 3, 17, 11, 17, 12, 17, 13, 18, 3, 18, 6, 18, 12, 19, 3, 19, 10, 20, 3, 20, 8, 20, 9, 20, 11, 21, 3, 21,
16
+ 8, 21, 10, 21, 11, 22, 3, 22, 6, 22, 8, 22, 11, 23, 3, 23, 8, 23, 12, 23, 21, 24, 3, 24, 8, 24, 9, 24, 12, 24,
17
+ 20, 25, 3, 25, 6, 25, 14, 25, 22, 26, 3, 26, 8, 26, 11, 26, 14, 26, 24, 27, 3, 27, 8, 27, 9, 27, 11, 27, 23, 28,
18
+ 4, 29, 4, 29, 6, 29, 11, 29, 13, 30, 4, 30, 7, 31, 4, 31, 30, 32, 8, 32, 12, 32, 13, 32, 23, 33, 32, 33, 8, 33,
19
+ 10, 33, 12, 33, 23, 35, 34, 35, 8, 35, 10, 36, 34, 36, 35, 36, 12, 37, 34, 37, 8, 37, 10, 37, 35, 37, 33, 38,
20
+ 34, 38, 10, 38, 35, 38, 12, 38, 37, 38, 33, 39, 34, 39, 10, 39, 35, 39, 12, 39, 38, 39, 33, 40, 8, 40, 35, 40,
21
+ 12, 40, 13, 40, 20, 40, 22, 40, 39, 40, 24, 40, 25, 40, 26, 40, 27, 41, 8, 41, 9, 41, 40, 41, 12, 41, 36, 41,
22
+ 27, 42, 8, 42, 40, 42, 13, 42, 39, 43, 8, 43, 35, 43, 13, 43, 42, 44, 8, 44, 40, 44, 35, 44, 12, 44, 13, 45, 8,
23
+ 45, 9, 45, 40, 45, 11, 45, 26, 46, 8, 46, 12, 47, 9, 47, 40, 47, 41, 47, 11, 47, 12, 47, 13, 47, 42, 47, 36, 47,
24
+ 37, 47, 17, 47, 33, 47, 45, 47, 46, 47, 23, 47, 24, 47, 26, 47, 27, 48, 9, 48, 20, 49, 9, 49, 20, 49, 31, 49,
25
+ 48, 50, 9, 50, 11, 51, 9, 52, 9, 52, 22, 52, 51, 53, 40, 53, 20, 53, 24, 53, 26, 54, 40, 54, 41, 54, 12, 54, 47,
26
+ 54, 23, 54, 27, 55, 10, 55, 12, 55, 15, 55, 19, 56, 11, 56, 19, 56, 43, 57, 13, 57, 56, 57, 20, 57, 48, 57, 49,
27
+ 58, 14, 58, 7, 58, 30, 58, 49, 58, 50, 58, 51, 58, 52, 60, 59, 61, 59, 62, 59, 62, 60, 63, 59, 63, 60, 63, 62,
28
+ 64, 58, 64, 51, 64, 52, 65, 64, 65, 58, 65, 51, 66, 64, 66, 28, 66, 30, 67, 64, 67, 65, 67, 66, 67, 30, 68, 64,
29
+ 68, 58, 68, 65, 69, 64, 69, 58, 69, 65, 69, 51, 70, 64, 70, 66, 70, 30, 71, 7, 71, 68, 71, 70, 72, 71, 72, 28,
30
+ 72, 66, 72, 49, 72, 70, 73, 71, 73, 72, 73, 66, 73, 30, 73, 31, 74, 71, 74, 72, 74, 73, 74, 66, 74, 30, 74, 31,
31
+ 75, 71, 75, 72, 75, 73, 75, 74, 75, 30, 75, 31, 75, 70, 76, 71, 76, 72, 76, 75, 76, 66, 76, 30, 76, 31, 76, 49,
32
+ 76, 53, 77, 71, 77, 75, 77, 58, 77, 30, 77, 19, 77, 31, 77, 76, 78, 71, 78, 72, 78, 74, 78, 75, 78, 31, 79, 71,
33
+ 79, 72, 79, 74, 79, 75, 79, 30, 80, 71, 80, 72, 80, 66, 80, 30, 81, 71, 82, 71, 82, 72, 82, 73, 82, 74, 82, 75,
34
+ 82, 30, 82, 31, 82, 76, 83, 71, 83, 73, 83, 75, 83, 30, 83, 76, 84, 72, 84, 74, 84, 75, 84, 66, 84, 73, 84, 60,
35
+ 84, 30, 84, 62, 84, 76, 84, 79, 84, 81, 84, 82, 84, 83, 85, 72, 85, 7, 85, 58, 85, 65, 85, 66, 86, 72, 86, 73,
36
+ 86, 66, 86, 84, 86, 60, 86, 30, 86, 61, 86, 76, 86, 81, 87, 72, 87, 74, 87, 84, 87, 83, 88, 72, 88, 74, 88, 66,
37
+ 88, 84, 89, 72, 89, 73, 89, 66, 89, 84, 89, 86, 89, 88, 90, 72, 90, 66, 90, 70, 91, 72, 91, 74, 91, 75, 91, 31,
38
+ 91, 90, 91, 79, 92, 72, 92, 73, 92, 75, 93, 73, 93, 66, 93, 86, 93, 30, 94, 73, 94, 84, 94, 93, 95, 73, 95, 94,
39
+ 95, 61, 96, 73, 96, 66, 96, 84, 96, 94, 97, 73, 97, 66, 97, 84, 97, 86, 97, 96, 97, 81, 98, 73, 98, 74, 98, 87,
40
+ 98, 91, 99, 73, 99, 74, 99, 66, 99, 84, 99, 93, 99, 60, 99, 59, 99, 30, 99, 62, 99, 63, 99, 90, 100, 73, 100,
41
+ 66, 100, 84, 100, 86, 100, 96, 100, 98, 100, 99, 100, 62, 100, 79, 100, 91, 100, 83, 101, 84, 101, 86, 101, 94,
42
+ 101, 100, 101, 61, 102, 93, 102, 94, 102, 95, 102, 46, 103, 67, 104, 67, 104, 69, 104, 103,
43
+ ],
44
+ weights: null,
45
+ columns: {
46
+ label: {
47
+ dtype: "string",
48
+ role: "label",
49
+ values: [
50
+ "1000 Years for Revenge",
51
+ "Bush vs. the Beltway",
52
+ "Charlie Wilson's War",
53
+ "Losing Bin Laden",
54
+ "Sleeping With the Devil",
55
+ "The Man Who Warned America",
56
+ "Why America Slept",
57
+ "Ghost Wars",
58
+ "A National Party No More",
59
+ "Bush Country",
60
+ "Dereliction of Duty",
61
+ "Legacy",
62
+ "Off with Their Heads",
63
+ "Persecution",
64
+ "Rumsfeld's War",
65
+ "Breakdown",
66
+ "Betrayal",
67
+ "Shut Up and Sing",
68
+ "Meant To Be",
69
+ "The Right Man",
70
+ "Ten Minutes from Normal",
71
+ "Hillary's Scheme",
72
+ "The French Betrayal of America",
73
+ "Tales from the Left Coast",
74
+ "Hating America",
75
+ "The Third Terrorist",
76
+ "Endgame",
77
+ "Spin Sisters",
78
+ "All the Shah's Men",
79
+ "Dangerous Dimplomacy",
80
+ "The Price of Loyalty",
81
+ "House of Bush, House of Saud",
82
+ "The Death of Right and Wrong",
83
+ "Useful Idiots",
84
+ "The O'Reilly Factor",
85
+ "Let Freedom Ring",
86
+ "Those Who Trespass",
87
+ "Bias",
88
+ "Slander",
89
+ "The Savage Nation",
90
+ "Deliver Us from Evil",
91
+ "Give Me a Break",
92
+ "The Enemy Within",
93
+ "The Real America",
94
+ "Who's Looking Out for You?",
95
+ "The Official Handbook Vast Right Wing Conspiracy",
96
+ "Power Plays",
97
+ "Arrogance",
98
+ "The Perfect Wife",
99
+ "The Bushes",
100
+ "Things Worth Fighting For",
101
+ "Surprise, Security, the American Experience",
102
+ "Allies",
103
+ "Why Courage Matters",
104
+ "Hollywood Interrupted",
105
+ "Fighting Back",
106
+ "We Will Prevail",
107
+ "The Faith of George W Bush",
108
+ "Rise of the Vulcans",
109
+ "Downsize This!",
110
+ "Stupid White Men",
111
+ "Rush Limbaugh Is a Big Fat Idiot",
112
+ "The Best Democracy Money Can Buy",
113
+ "The Culture of Fear",
114
+ "America Unbound",
115
+ "The Choice",
116
+ "The Great Unraveling",
117
+ "Rogue Nation",
118
+ "Soft Power",
119
+ "Colossus",
120
+ "The Sorrows of Empire",
121
+ "Against All Enemies",
122
+ "American Dynasty",
123
+ "Big Lies",
124
+ "The Lies of George W. Bush",
125
+ "Worse Than Watergate",
126
+ "Plan of Attack",
127
+ "Bush at War",
128
+ "The New Pearl Harbor",
129
+ "Bushwomen",
130
+ "The Bubble of American Supremacy",
131
+ "Living History",
132
+ "The Politics of Truth",
133
+ "Fanatics and Fools",
134
+ "Bushwhacked",
135
+ "Disarming Iraq",
136
+ "Lies and the Lying Liars Who Tell Them",
137
+ "MoveOn's 50 Ways to Love Your Country",
138
+ "The Buying of the President 2004",
139
+ "Perfectly Legal",
140
+ "Hegemony or Survival",
141
+ "The Exception to the Rulers",
142
+ "Freethinkers",
143
+ "Had Enough?",
144
+ "It's Still the Economy, Stupid!",
145
+ "We're Right They're Wrong",
146
+ "What Liberal Media?",
147
+ "The Clinton Wars",
148
+ "Weapons of Mass Deception",
149
+ "Dude, Where's My Country?",
150
+ "Thieves in High Places",
151
+ "Shrub",
152
+ "Buck Up Suck Up",
153
+ "The Future of Freedom",
154
+ "Empire",
155
+ ],
156
+ },
157
+ lean: {
158
+ dtype: "dict",
159
+ categories: ["liberal", "conservative", "neutral"],
160
+ codes: [
161
+ 2, 1, 1, 1, 2, 1, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 0, 0, 1, 1, 1,
162
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 2, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2,
163
+ 0, 0, 0, 0, 0, 0, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2,
164
+ ],
165
+ },
166
+ },
167
+ };
@@ -0,0 +1,17 @@
1
+ /**
2
+ * `@graphty/graph-samples/datasets/political-books`: Books about US politics.
3
+ */
4
+
5
+ import { type SampleGraph } from "../../types.js";
6
+ import { buildDataset } from "../build.js";
7
+ import { DATA } from "./data.js";
8
+
9
+ export { politicalBooksMeta } from "./meta.js";
10
+
11
+ /**
12
+ * The political books co-purchase network: 105 books, 441 co-purchases, each book's `label` and political `lean`.
13
+ * @returns a fresh copy of the graph as typed arrays
14
+ */
15
+ export function politicalBooks(): SampleGraph {
16
+ return buildDataset(DATA);
17
+ }
@@ -0,0 +1,23 @@
1
+ import { type DatasetMeta } from "../build.js";
2
+
3
+ /** What the politicalBooks dataset is, where it came from and under which terms. */
4
+ export const politicalBooksMeta: DatasetMeta = {
5
+ name: "political-books",
6
+ title: "Books about US politics",
7
+ description:
8
+ "Books about US politics sold by Amazon.com around the 2004 election, joined when the same buyers frequently bought both. Mark Newman labelled each book liberal, neutral or conservative from its descriptions and reviews.",
9
+ citation: "V. Krebs, unpublished (compiled 2004), http://www.orgnet.com/; labels by M. E. J. Newman.",
10
+ source: "https://web.archive.org/web/20240730210010id_/https://public.websites.umich.edu/~mejn/netdata/polbooks.zip",
11
+ license:
12
+ 'unclear: Mark Newman\'s data page says only "free for scientific use to the best of my knowledge"; the SuiteSparse Matrix Collection republishes the graph under CC BY 4.0.',
13
+ nodes: 105,
14
+ edges: 441,
15
+ directed: false,
16
+ weighted: false,
17
+ attributes: { label: "string: the book title", lean: "dict: liberal, conservative or neutral (ground truth)" },
18
+ groundTruth: "lean",
19
+ showcases: [
20
+ "two- and three-way community detection against the political lean",
21
+ "force-directed layouts coloured by lean",
22
+ ],
23
+ };
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Datasets too large to bundle (over about 5,000 nodes) are hosted on graphty.app as
3
+ * graph-format wire bytes and fetched at runtime.
4
+ */
5
+
6
+ import { fromBytes, type GraphSnapshot } from "@graphty/graph-format";
7
+
8
+ /**
9
+ * Where hosted datasets live: `<base><name>.gsnp.gz`, a gzipped graph-format wire container.
10
+ * The `v1` segment is the hosting layout's version, independent of the package version.
11
+ */
12
+ export const DEFAULT_DATASET_BASE_URL = "https://graphty.app/data/graph-samples/v1/";
13
+
14
+ /** Options of {@link fetchDataset}. */
15
+ export interface FetchDatasetOptions {
16
+ /** Serve the files from elsewhere (self-hosting, a mirror, a test server). */
17
+ baseUrl?: string | undefined;
18
+ /** The fetch implementation; the global `fetch` by default. */
19
+ fetch?: typeof fetch | undefined;
20
+ /** Cancels the download. */
21
+ signal?: AbortSignal | undefined;
22
+ }
23
+
24
+ /**
25
+ * Download a hosted dataset and decode it.
26
+ * @param name - the dataset name: lowercase letters, digits and dashes
27
+ * @param options - the base URL, fetch implementation and abort signal
28
+ * @returns the graph as a frozen graph-format snapshot
29
+ */
30
+ export async function fetchDataset(name: string, options: FetchDatasetOptions = {}): Promise<GraphSnapshot> {
31
+ if (!/^[a-z0-9][a-z0-9-]*$/.test(name)) {
32
+ throw new RangeError(`not a dataset name: ${JSON.stringify(name)}`);
33
+ }
34
+ const base = options.baseUrl ?? DEFAULT_DATASET_BASE_URL;
35
+ const url = new URL(`${name}.gsnp.gz`, base.endsWith("/") ? base : `${base}/`);
36
+ const response = await (options.fetch ?? fetch)(url, { signal: options.signal ?? null });
37
+ if (!response.ok || response.body === null) {
38
+ throw new Error(`fetching ${url.href} failed: HTTP ${response.status}`);
39
+ }
40
+ const unzipped = response.body.pipeThrough(new DecompressionStream("gzip"));
41
+ return fromBytes(new Uint8Array(await new Response(unzipped).arrayBuffer()));
42
+ }
package/src/element.ts ADDED
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Records for graphty-element's `nodeData` / `edgeData` properties.
3
+ */
4
+
5
+ import { type SampleGraph } from "./types.js";
6
+
7
+ /** The node and edge records graphty-element loads. */
8
+ export interface ElementData {
9
+ /** One record per node: `id` plus one field per node column. */
10
+ readonly nodes: Record<string, unknown>[];
11
+ /** One record per edge: `source`, `target` and, when weighted, `weight`. */
12
+ readonly edges: Record<string, unknown>[];
13
+ }
14
+
15
+ /**
16
+ * Turn a graph into the plain records `<graphty-element>` takes as `nodeData` and `edgeData`.
17
+ * A node's id is its external id when the graph has them, else its index. Builds one object per
18
+ * node and edge, so it is meant for graphs a browser draws, not for millions of edges.
19
+ * @param graph - a generator's or dataset's graph
20
+ * @returns the node and edge records
21
+ */
22
+ export function toElementData(graph: SampleGraph): ElementData {
23
+ const { ids, src, dst, weights } = graph;
24
+ const columns = Object.entries(graph.nodeColumns ?? {}).map(
25
+ ([name, column]) => [name, ArrayBuffer.isView(column) ? column : column.data] as const,
26
+ );
27
+ const idOf = (i: number): string | number => (ids === undefined ? i : ids[i]);
28
+ const nodes = Array.from({ length: graph.nodeCount }, (_, i) => {
29
+ const record: Record<string, unknown> = { id: idOf(i) };
30
+ for (const [name, data] of columns) {
31
+ record[name] = data[i];
32
+ }
33
+ return record;
34
+ });
35
+ const edges = Array.from(src, (u, e) =>
36
+ weights === undefined
37
+ ? { source: idOf(u), target: idOf(dst[e]) }
38
+ : { source: idOf(u), target: idOf(dst[e]), weight: weights[e] },
39
+ );
40
+ return { nodes, edges };
41
+ }
@@ -0,0 +1,127 @@
1
+ /**
2
+ * The random bipartite graph G(n1, n2, p), optionally with a planted perfect matching.
3
+ */
4
+
5
+ import { type U32 } from "@graphty/graph-format";
6
+
7
+ import { detLog } from "../random/log.js";
8
+ import { RandomStream, resolveSeed } from "../random/stream.js";
9
+ import { type SampleGraph } from "../types.js";
10
+ import { binomialBuffer, checkInt, checkProbability, type EdgeBuffer, toGraph } from "./util.js";
11
+ import { applyWeights, type WeightOptions } from "./weights.js";
12
+
13
+ /** Options of {@link randomBipartiteGraph}. */
14
+ export interface RandomBipartiteOptions extends WeightOptions {
15
+ /** The left side's size, >= 0. */
16
+ n1: number;
17
+ /** The right side's size, >= 0. */
18
+ n2: number;
19
+ /** The probability of each left-right pair, in [0, 1]. */
20
+ p: number;
21
+ /**
22
+ * Plant a perfect matching: left node i is always joined to right node `matching[i]` of a
23
+ * uniformly random permutation, so a perfect matching is guaranteed. Needs n1 === n2.
24
+ */
25
+ perfectMatching?: boolean | undefined;
26
+ /** The seed, an integer in [0, 2^53); default 0. */
27
+ seed?: number | undefined;
28
+ }
29
+
30
+ /**
31
+ * The planted matching: a Fisher-Yates shuffle of 0 .. n - 1 from stream (seed,
32
+ * "bipartite-matching", 0), drawing nextBelow(i + 1) for i = n - 1 down to 1.
33
+ * @param n - the side size
34
+ * @param seed - the seed
35
+ * @returns match[i] = the right-side offset joined to left node i
36
+ */
37
+ export function plantedMatching(n: number, seed: number): U32 {
38
+ const stream = new RandomStream(seed, "bipartite-matching", 0);
39
+ const match = new Uint32Array(n);
40
+ for (let i = 0; i < n; i++) {
41
+ match[i] = i;
42
+ }
43
+ for (let i = n - 1; i > 0; i--) {
44
+ const j = stream.nextBelow(i + 1);
45
+ const t = match[i];
46
+ match[i] = match[j];
47
+ match[j] = t;
48
+ }
49
+ return match;
50
+ }
51
+
52
+ /**
53
+ * Rows [start, end) of the bipartite graph: left node u draws from stream (seed, "bipartite", u)
54
+ * and holds (u, n1 + j) for the chosen right offsets j in ascending order, with the planted match
55
+ * merged in at its place (never twice).
56
+ * @param options - the checked options
57
+ * @param match - the planted matching, or null
58
+ * @param start - the first row
59
+ * @param end - one past the last row
60
+ * @param out - receives the edges
61
+ */
62
+ export function bipartiteRows(
63
+ options: RandomBipartiteOptions,
64
+ match: U32 | null,
65
+ start: number,
66
+ end: number,
67
+ out: EdgeBuffer,
68
+ ): void {
69
+ const { n1, n2, p } = options;
70
+ const seed = resolveSeed(options.seed);
71
+ const logQ = detLog(1 - p);
72
+ const stream = new RandomStream(seed, "bipartite", 0);
73
+ for (let u = start; u < end; u++) {
74
+ stream.reset(u);
75
+ let pending = match === null ? -1 : match[u];
76
+ const emit = (j: number): void => {
77
+ if (pending >= 0 && pending < j) {
78
+ out.push(u, n1 + pending);
79
+ }
80
+ if (pending >= 0 && pending <= j) {
81
+ pending = -1;
82
+ }
83
+ out.push(u, n1 + j);
84
+ };
85
+ if (p === 1) {
86
+ for (let j = 0; j < n2; j++) {
87
+ emit(j);
88
+ }
89
+ } else if (p > 0) {
90
+ let j = stream.nextSkip(logQ);
91
+ while (j < n2) {
92
+ emit(j);
93
+ j += 1 + stream.nextSkip(logQ);
94
+ }
95
+ }
96
+ if (pending >= 0) {
97
+ out.push(u, n1 + pending);
98
+ }
99
+ }
100
+ }
101
+
102
+ /**
103
+ * The random bipartite graph G(n1, n2, p) in O(n + m): left nodes 0 .. n1 - 1, right nodes
104
+ * n1 .. n1 + n2 - 1, each left-right pair independently with probability p; edges row by row from
105
+ * the left side, right ends ascending. Node column `side` (u8): 0 left, 1 right.
106
+ * @param options - n1, n2, p, perfectMatching and seed
107
+ * @returns the undirected graph
108
+ */
109
+ export function randomBipartiteGraph(options: RandomBipartiteOptions): SampleGraph {
110
+ const { n1, n2, p } = options;
111
+ checkInt("n1", n1, 0);
112
+ checkInt("n2", n2, 0);
113
+ checkInt("n1 + n2", n1 + n2, 0);
114
+ checkProbability("p", p);
115
+ const seed = resolveSeed(options.seed);
116
+ let match: U32 | null = null;
117
+ if (options.perfectMatching === true) {
118
+ if (n1 !== n2) {
119
+ throw new RangeError(`perfectMatching needs n1 === n2, got ${n1} and ${n2}`);
120
+ }
121
+ match = plantedMatching(n1, seed);
122
+ }
123
+ const out = binomialBuffer(n1 * n2, p);
124
+ bipartiteRows(options, match, 0, n1, out);
125
+ const side = new Uint8Array(n1 + n2).fill(1, n1);
126
+ return applyWeights(toGraph(n1 + n2, out, false, { side }), options);
127
+ }
@@ -0,0 +1,160 @@
1
+ /**
2
+ * Stochastic block models (P. W. Holland, K. B. Laskey and S. Leinhardt, "Stochastic blockmodels:
3
+ * first steps", Social Networks 5, 109-137, 1983) and the planted partition model (A. Condon and
4
+ * R. M. Karp, Random Structures and Algorithms 18, 116-140, 2001), with the planted blocks emitted
5
+ * as ground truth.
6
+ */
7
+
8
+ import { type U32 } from "@graphty/graph-format";
9
+
10
+ import { detLog } from "../random/log.js";
11
+ import { RandomStream, resolveSeed } from "../random/stream.js";
12
+ import { type SampleGraph } from "../types.js";
13
+ import { bernoulliSegment, binomialBuffer, checkInt, checkProbability, type EdgeBuffer, toGraph } from "./util.js";
14
+ import { applyWeights, type WeightOptions } from "./weights.js";
15
+
16
+ /** Options of {@link stochasticBlockModelGraph}. */
17
+ export interface StochasticBlockModelOptions extends WeightOptions {
18
+ /** The size of every block; block b holds the next `sizes[b]` node indices. */
19
+ sizes: readonly number[];
20
+ /** The symmetric B x B matrix of edge probabilities between blocks. */
21
+ probabilities: readonly (readonly number[])[];
22
+ /** The seed, an integer in [0, 2^53); default 0. */
23
+ seed?: number | undefined;
24
+ }
25
+
26
+ /** The checked and precomputed form of the options. */
27
+ interface BlockPlan {
28
+ readonly n: number;
29
+ readonly seed: number;
30
+ /** starts[b] = first node of block b; starts[B] = n. */
31
+ readonly starts: readonly number[];
32
+ readonly block: U32;
33
+ readonly p: readonly (readonly number[])[];
34
+ readonly logQ: readonly (readonly number[])[];
35
+ }
36
+
37
+ /**
38
+ * Check the options and precompute block boundaries and detLog(1 - p).
39
+ * @param options - the options
40
+ * @returns the plan
41
+ */
42
+ export function planBlocks(options: StochasticBlockModelOptions): BlockPlan {
43
+ const { sizes, probabilities } = options;
44
+ const seed = resolveSeed(options.seed);
45
+ const count = sizes.length;
46
+ checkInt("sizes.length", count, 1);
47
+ if (probabilities.length !== count) {
48
+ throw new RangeError(`probabilities must be ${count} x ${count}`);
49
+ }
50
+ const starts = [0];
51
+ for (let b = 0; b < count; b++) {
52
+ checkInt(`sizes[${b}]`, sizes[b], 0);
53
+ starts.push(starts[b] + sizes[b]);
54
+ if (probabilities[b].length !== count) {
55
+ throw new RangeError(`probabilities must be ${count} x ${count}`);
56
+ }
57
+ for (let c = 0; c < count; c++) {
58
+ checkProbability(`probabilities[${b}][${c}]`, probabilities[b][c]);
59
+ if (probabilities[b][c] !== probabilities[c][b]) {
60
+ throw new RangeError(`probabilities must be symmetric: [${b}][${c}] differs from [${c}][${b}]`);
61
+ }
62
+ }
63
+ }
64
+ const n = starts[count];
65
+ checkInt("the total size", n, 0);
66
+ const block = new Uint32Array(n);
67
+ for (let b = 0; b < count; b++) {
68
+ block.fill(b, starts[b], starts[b + 1]);
69
+ }
70
+ return {
71
+ n,
72
+ seed,
73
+ starts,
74
+ block,
75
+ p: probabilities,
76
+ logQ: probabilities.map((row) => row.map((p) => detLog(1 - p))),
77
+ };
78
+ }
79
+
80
+ /**
81
+ * Rows [start, end) of the block model: row u (in block b) draws from stream (seed, "sbm", u) and
82
+ * walks blocks c = b .. B - 1 in order, holding the pairs (u, v) for v > u in block c with
83
+ * probability p[b][c], ascending v. Concatenating consecutive row ranges gives the whole graph.
84
+ * @param plan - the checked options
85
+ * @param start - the first row
86
+ * @param end - one past the last row
87
+ * @param out - receives the edges
88
+ */
89
+ export function blockModelRows(plan: BlockPlan, start: number, end: number, out: EdgeBuffer): void {
90
+ const { starts, block, p, logQ } = plan;
91
+ const stream = new RandomStream(plan.seed, "sbm", 0);
92
+ const count = starts.length - 1;
93
+ for (let u = start; u < end; u++) {
94
+ stream.reset(u);
95
+ const b = block[u];
96
+ // ponytail: O(B) per row, fine to n * B ~ 1e8; iterate only non-zero blocks if B grows large
97
+ for (let c = b; c < count; c++) {
98
+ bernoulliSegment(stream, p[b][c], logQ[b][c], u, c === b ? u + 1 : starts[c], starts[c + 1], out);
99
+ }
100
+ }
101
+ }
102
+
103
+ /**
104
+ * The stochastic block model in O(n B + m): node pairs are joined independently with the
105
+ * probability of their blocks, by geometric skipping inside each row's block segments. Edges are
106
+ * the pairs (u, v), u < v, row-major. Node column `community` (u32): the block.
107
+ * @param options - sizes, probabilities and seed
108
+ * @returns the undirected graph
109
+ */
110
+ export function stochasticBlockModelGraph(options: StochasticBlockModelOptions): SampleGraph {
111
+ const plan = planBlocks(options);
112
+ let expected = 0;
113
+ let pairs = 0;
114
+ for (let b = 0; b < plan.starts.length - 1; b++) {
115
+ for (let c = b; c < plan.starts.length - 1; c++) {
116
+ const sb = plan.starts[b + 1] - plan.starts[b];
117
+ const sc = plan.starts[c + 1] - plan.starts[c];
118
+ const blockPairs = b === c ? (sb * (sb - 1)) / 2 : sb * sc;
119
+ expected += blockPairs * plan.p[b][c];
120
+ pairs += blockPairs;
121
+ }
122
+ }
123
+ const out = binomialBuffer(pairs, pairs === 0 ? 0 : expected / pairs);
124
+ blockModelRows(plan, 0, plan.n, out);
125
+ return applyWeights(toGraph(plan.n, out, false, { community: plan.block }), options);
126
+ }
127
+
128
+ /** Options of {@link plantedPartitionGraph}. */
129
+ export interface PlantedPartitionOptions extends WeightOptions {
130
+ /** The number of groups, >= 1. */
131
+ groups: number;
132
+ /** The size of every group, >= 1. */
133
+ groupSize: number;
134
+ /** The edge probability inside a group. */
135
+ pIn: number;
136
+ /** The edge probability between groups. */
137
+ pOut: number;
138
+ /** The seed, an integer in [0, 2^53); default 0. */
139
+ seed?: number | undefined;
140
+ }
141
+
142
+ /**
143
+ * The planted partition model: `groups` equal blocks, `pIn` inside, `pOut` between. Exactly the
144
+ * stochastic block model with that matrix (same seed, same graph). Node column `community` (u32).
145
+ * @param options - groups, groupSize, pIn, pOut and seed
146
+ * @returns the undirected graph
147
+ */
148
+ export function plantedPartitionGraph(options: PlantedPartitionOptions): SampleGraph {
149
+ const { groups, groupSize, pIn, pOut, seed } = options;
150
+ checkInt("groups", groups, 1);
151
+ checkInt("groupSize", groupSize, 1);
152
+ return stochasticBlockModelGraph({
153
+ sizes: new Array<number>(groups).fill(groupSize),
154
+ probabilities: Array.from({ length: groups }, (_, b) =>
155
+ Array.from({ length: groups }, (_2, c) => (b === c ? pIn : pOut)),
156
+ ),
157
+ seed,
158
+ weights: options.weights,
159
+ });
160
+ }