graphwise 1.4.3 → 1.5.1

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 (97) hide show
  1. package/dist/__test__/fixtures/graphs/index.d.ts +1 -0
  2. package/dist/__test__/fixtures/graphs/index.d.ts.map +1 -1
  3. package/dist/__test__/fixtures/graphs/linear-chain.d.ts +18 -0
  4. package/dist/__test__/fixtures/graphs/linear-chain.d.ts.map +1 -0
  5. package/dist/__test__/fixtures/helpers.d.ts +20 -1
  6. package/dist/__test__/fixtures/helpers.d.ts.map +1 -1
  7. package/dist/__test__/fixtures/index.d.ts +1 -0
  8. package/dist/__test__/fixtures/index.d.ts.map +1 -1
  9. package/dist/__test__/fixtures/metrics.d.ts +86 -0
  10. package/dist/__test__/fixtures/metrics.d.ts.map +1 -0
  11. package/dist/__test__/fixtures/metrics.unit.test.d.ts +7 -0
  12. package/dist/__test__/fixtures/metrics.unit.test.d.ts.map +1 -0
  13. package/dist/expansion/dfs-priority.d.ts +23 -0
  14. package/dist/expansion/dfs-priority.d.ts.map +1 -0
  15. package/dist/expansion/dfs-priority.unit.test.d.ts +2 -0
  16. package/dist/expansion/dfs-priority.unit.test.d.ts.map +1 -0
  17. package/dist/expansion/edge.d.ts.map +1 -1
  18. package/dist/expansion/flux.d.ts.map +1 -1
  19. package/dist/expansion/fuse.d.ts.map +1 -1
  20. package/dist/expansion/index.d.ts +3 -0
  21. package/dist/expansion/index.d.ts.map +1 -1
  22. package/dist/expansion/k-hop.d.ts +26 -0
  23. package/dist/expansion/k-hop.d.ts.map +1 -0
  24. package/dist/expansion/k-hop.unit.test.d.ts +2 -0
  25. package/dist/expansion/k-hop.unit.test.d.ts.map +1 -0
  26. package/dist/expansion/lace.d.ts.map +1 -1
  27. package/dist/expansion/maze.d.ts.map +1 -1
  28. package/dist/expansion/priority-helpers.d.ts +43 -0
  29. package/dist/expansion/priority-helpers.d.ts.map +1 -0
  30. package/dist/expansion/random-walk.d.ts +35 -0
  31. package/dist/expansion/random-walk.d.ts.map +1 -0
  32. package/dist/expansion/random-walk.unit.test.d.ts +2 -0
  33. package/dist/expansion/random-walk.unit.test.d.ts.map +1 -0
  34. package/dist/expansion/sage.d.ts.map +1 -1
  35. package/dist/expansion/sift.d.ts.map +1 -1
  36. package/dist/expansion/warp.d.ts.map +1 -1
  37. package/dist/index/index.cjs +887 -297
  38. package/dist/index/index.cjs.map +1 -1
  39. package/dist/index/index.js +878 -299
  40. package/dist/index/index.js.map +1 -1
  41. package/dist/ranking/baselines/betweenness.d.ts.map +1 -1
  42. package/dist/ranking/baselines/communicability.d.ts.map +1 -1
  43. package/dist/ranking/baselines/degree-sum.d.ts.map +1 -1
  44. package/dist/ranking/baselines/hitting-time.d.ts +27 -0
  45. package/dist/ranking/baselines/hitting-time.d.ts.map +1 -0
  46. package/dist/ranking/baselines/hitting-time.unit.test.d.ts +2 -0
  47. package/dist/ranking/baselines/hitting-time.unit.test.d.ts.map +1 -0
  48. package/dist/ranking/baselines/index.d.ts +1 -0
  49. package/dist/ranking/baselines/index.d.ts.map +1 -1
  50. package/dist/ranking/baselines/jaccard-arithmetic.d.ts.map +1 -1
  51. package/dist/ranking/baselines/katz.d.ts.map +1 -1
  52. package/dist/ranking/baselines/pagerank.d.ts.map +1 -1
  53. package/dist/ranking/baselines/random-ranking.d.ts.map +1 -1
  54. package/dist/ranking/baselines/resistance-distance.d.ts.map +1 -1
  55. package/dist/ranking/baselines/shortest.d.ts.map +1 -1
  56. package/dist/ranking/baselines/utils.d.ts +20 -0
  57. package/dist/ranking/baselines/utils.d.ts.map +1 -0
  58. package/dist/ranking/baselines/widest-path.d.ts.map +1 -1
  59. package/dist/ranking/mi/adaptive.d.ts.map +1 -1
  60. package/dist/ranking/mi/cosine.d.ts +13 -0
  61. package/dist/ranking/mi/cosine.d.ts.map +1 -0
  62. package/dist/ranking/mi/cosine.unit.test.d.ts +2 -0
  63. package/dist/ranking/mi/cosine.unit.test.d.ts.map +1 -0
  64. package/dist/ranking/mi/etch.d.ts.map +1 -1
  65. package/dist/ranking/mi/hub-promoted.d.ts +13 -0
  66. package/dist/ranking/mi/hub-promoted.d.ts.map +1 -0
  67. package/dist/ranking/mi/hub-promoted.unit.test.d.ts +2 -0
  68. package/dist/ranking/mi/hub-promoted.unit.test.d.ts.map +1 -0
  69. package/dist/ranking/mi/index.d.ts +5 -0
  70. package/dist/ranking/mi/index.d.ts.map +1 -1
  71. package/dist/ranking/mi/jaccard.d.ts.map +1 -1
  72. package/dist/ranking/mi/notch.d.ts.map +1 -1
  73. package/dist/ranking/mi/overlap-coefficient.d.ts +13 -0
  74. package/dist/ranking/mi/overlap-coefficient.d.ts.map +1 -0
  75. package/dist/ranking/mi/overlap-coefficient.unit.test.d.ts +2 -0
  76. package/dist/ranking/mi/overlap-coefficient.unit.test.d.ts.map +1 -0
  77. package/dist/ranking/mi/resource-allocation.d.ts +13 -0
  78. package/dist/ranking/mi/resource-allocation.d.ts.map +1 -0
  79. package/dist/ranking/mi/resource-allocation.unit.test.d.ts +2 -0
  80. package/dist/ranking/mi/resource-allocation.unit.test.d.ts.map +1 -0
  81. package/dist/ranking/mi/scale.d.ts.map +1 -1
  82. package/dist/ranking/mi/skew.d.ts.map +1 -1
  83. package/dist/ranking/mi/sorensen.d.ts +13 -0
  84. package/dist/ranking/mi/sorensen.d.ts.map +1 -0
  85. package/dist/ranking/mi/sorensen.unit.test.d.ts +2 -0
  86. package/dist/ranking/mi/sorensen.unit.test.d.ts.map +1 -0
  87. package/dist/ranking/mi/span.d.ts.map +1 -1
  88. package/dist/ranking/mi/types.d.ts +1 -1
  89. package/dist/ranking/mi/types.d.ts.map +1 -1
  90. package/dist/schemas/graph.d.ts +1 -1
  91. package/dist/utils/index.cjs +22 -0
  92. package/dist/utils/index.cjs.map +1 -1
  93. package/dist/utils/index.js +22 -1
  94. package/dist/utils/index.js.map +1 -1
  95. package/dist/utils/neighbours.d.ts +23 -0
  96. package/dist/utils/neighbours.d.ts.map +1 -1
  97. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"betweenness.d.ts","sourceRoot":"","sources":["../../../src/ranking/baselines/betweenness.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACrE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAc,MAAM,SAAS,CAAC;AAwG1E;;;;;;;GAOG;AACH,wBAAgB,WAAW,CAAC,CAAC,SAAS,QAAQ,EAAE,CAAC,SAAS,QAAQ,EACjE,KAAK,EAAE,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,EAC1B,KAAK,EAAE,SAAS,aAAa,EAAE,EAC/B,MAAM,CAAC,EAAE,cAAc,GACrB,cAAc,CAgDhB"}
1
+ {"version":3,"file":"betweenness.d.ts","sourceRoot":"","sources":["../../../src/ranking/baselines/betweenness.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACrE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAyG9D;;;;;;;GAOG;AACH,wBAAgB,WAAW,CAAC,CAAC,SAAS,QAAQ,EAAE,CAAC,SAAS,QAAQ,EACjE,KAAK,EAAE,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,EAC1B,KAAK,EAAE,SAAS,aAAa,EAAE,EAC/B,MAAM,CAAC,EAAE,cAAc,GACrB,cAAc,CAuBhB"}
@@ -1 +1 @@
1
- {"version":3,"file":"communicability.d.ts","sourceRoot":"","sources":["../../../src/ranking/baselines/communicability.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACrE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAc,MAAM,SAAS,CAAC;AA2E1E;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAAC,CAAC,SAAS,QAAQ,EAAE,CAAC,SAAS,QAAQ,EACrE,KAAK,EAAE,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,EAC1B,KAAK,EAAE,SAAS,aAAa,EAAE,EAC/B,MAAM,CAAC,EAAE,cAAc,GACrB,cAAc,CAiDhB"}
1
+ {"version":3,"file":"communicability.d.ts","sourceRoot":"","sources":["../../../src/ranking/baselines/communicability.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACrE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AA4E9D;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAAC,CAAC,SAAS,QAAQ,EAAE,CAAC,SAAS,QAAQ,EACrE,KAAK,EAAE,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,EAC1B,KAAK,EAAE,SAAS,aAAa,EAAE,EAC/B,MAAM,CAAC,EAAE,cAAc,GACrB,cAAc,CAwBhB"}
@@ -1 +1 @@
1
- {"version":3,"file":"degree-sum.d.ts","sourceRoot":"","sources":["../../../src/ranking/baselines/degree-sum.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACrE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAc,MAAM,SAAS,CAAC;AAE1E;;;;;;;GAOG;AACH,wBAAgB,SAAS,CAAC,CAAC,SAAS,QAAQ,EAAE,CAAC,SAAS,QAAQ,EAC/D,KAAK,EAAE,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,EAC1B,KAAK,EAAE,SAAS,aAAa,EAAE,EAC/B,MAAM,CAAC,EAAE,cAAc,GACrB,cAAc,CA6ChB"}
1
+ {"version":3,"file":"degree-sum.d.ts","sourceRoot":"","sources":["../../../src/ranking/baselines/degree-sum.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACrE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAG9D;;;;;;;GAOG;AACH,wBAAgB,SAAS,CAAC,CAAC,SAAS,QAAQ,EAAE,CAAC,SAAS,QAAQ,EAC/D,KAAK,EAAE,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,EAC1B,KAAK,EAAE,SAAS,aAAa,EAAE,EAC/B,MAAM,CAAC,EAAE,cAAc,GACrB,cAAc,CAoBhB"}
@@ -0,0 +1,27 @@
1
+ import { NodeData, EdgeData, ReadableGraph } from '../../graph';
2
+ import { ExpansionPath } from '../../expansion/types';
3
+ import { BaselineConfig, BaselineResult } from './types';
4
+ /**
5
+ * Configuration for hitting-time ranking.
6
+ */
7
+ interface HittingTimeConfig extends BaselineConfig {
8
+ /** Computation mode: "exact", "approximate", or "auto" (default: "auto") */
9
+ readonly mode?: "exact" | "approximate" | "auto";
10
+ /** Number of Monte Carlo walks for approximate mode (default: 1000) */
11
+ readonly walks?: number;
12
+ /** Maximum steps per walk (default: 10000) */
13
+ readonly maxSteps?: number;
14
+ /** Random seed for reproducibility (default: 42) */
15
+ readonly seed?: number;
16
+ }
17
+ /**
18
+ * Rank paths by inverse hitting time between endpoints.
19
+ *
20
+ * @param graph - Source graph
21
+ * @param paths - Paths to rank
22
+ * @param config - Configuration options
23
+ * @returns Ranked paths (highest inverse hitting time first)
24
+ */
25
+ export declare function hittingTime<N extends NodeData, E extends EdgeData>(graph: ReadableGraph<N, E>, paths: readonly ExpansionPath[], config?: HittingTimeConfig): BaselineResult;
26
+ export {};
27
+ //# sourceMappingURL=hitting-time.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hitting-time.d.ts","sourceRoot":"","sources":["../../../src/ranking/baselines/hitting-time.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACrE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAG9D;;GAEG;AACH,UAAU,iBAAkB,SAAQ,cAAc;IACjD,4EAA4E;IAC5E,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,GAAG,aAAa,GAAG,MAAM,CAAC;IACjD,uEAAuE;IACvE,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,8CAA8C;IAC9C,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,oDAAoD;IACpD,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;CACvB;AAwVD;;;;;;;GAOG;AACH,wBAAgB,WAAW,CAAC,CAAC,SAAS,QAAQ,EAAE,CAAC,SAAS,QAAQ,EACjE,KAAK,EAAE,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,EAC1B,KAAK,EAAE,SAAS,aAAa,EAAE,EAC/B,MAAM,CAAC,EAAE,iBAAiB,GACxB,cAAc,CA2DhB"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=hitting-time.unit.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hitting-time.unit.test.d.ts","sourceRoot":"","sources":["../../../src/ranking/baselines/hitting-time.unit.test.ts"],"names":[],"mappings":""}
@@ -17,4 +17,5 @@ export * from './katz';
17
17
  export * from './communicability';
18
18
  export * from './resistance-distance';
19
19
  export * from './random-ranking';
20
+ export * from './hitting-time';
20
21
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/ranking/baselines/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,cAAc,SAAS,CAAC;AACxB,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC;AAC7B,cAAc,eAAe,CAAC;AAC9B,cAAc,sBAAsB,CAAC;AACrC,cAAc,YAAY,CAAC;AAC3B,cAAc,eAAe,CAAC;AAC9B,cAAc,QAAQ,CAAC;AACvB,cAAc,mBAAmB,CAAC;AAClC,cAAc,uBAAuB,CAAC;AACtC,cAAc,kBAAkB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/ranking/baselines/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,cAAc,SAAS,CAAC;AACxB,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC;AAC7B,cAAc,eAAe,CAAC;AAC9B,cAAc,sBAAsB,CAAC;AACrC,cAAc,YAAY,CAAC;AAC3B,cAAc,eAAe,CAAC;AAC9B,cAAc,QAAQ,CAAC;AACvB,cAAc,mBAAmB,CAAC;AAClC,cAAc,uBAAuB,CAAC;AACtC,cAAc,kBAAkB,CAAC;AACjC,cAAc,gBAAgB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"jaccard-arithmetic.d.ts","sourceRoot":"","sources":["../../../src/ranking/baselines/jaccard-arithmetic.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACrE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAc,MAAM,SAAS,CAAC;AAG1E;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,CAAC,SAAS,QAAQ,EAAE,CAAC,SAAS,QAAQ,EACvE,KAAK,EAAE,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,EAC1B,KAAK,EAAE,SAAS,aAAa,EAAE,EAC/B,MAAM,CAAC,EAAE,cAAc,GACrB,cAAc,CA6DhB"}
1
+ {"version":3,"file":"jaccard-arithmetic.d.ts","sourceRoot":"","sources":["../../../src/ranking/baselines/jaccard-arithmetic.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACrE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAI9D;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,CAAC,SAAS,QAAQ,EAAE,CAAC,SAAS,QAAQ,EACvE,KAAK,EAAE,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,EAC1B,KAAK,EAAE,SAAS,aAAa,EAAE,EAC/B,MAAM,CAAC,EAAE,cAAc,GACrB,cAAc,CAoChB"}
@@ -1 +1 @@
1
- {"version":3,"file":"katz.d.ts","sourceRoot":"","sources":["../../../src/ranking/baselines/katz.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACrE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAc,MAAM,SAAS,CAAC;AA0E1E;;;;;;;GAOG;AACH,wBAAgB,IAAI,CAAC,CAAC,SAAS,QAAQ,EAAE,CAAC,SAAS,QAAQ,EAC1D,KAAK,EAAE,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,EAC1B,KAAK,EAAE,SAAS,aAAa,EAAE,EAC/B,MAAM,CAAC,EAAE,cAAc,GACrB,cAAc,CAiDhB"}
1
+ {"version":3,"file":"katz.d.ts","sourceRoot":"","sources":["../../../src/ranking/baselines/katz.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACrE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AA2E9D;;;;;;;GAOG;AACH,wBAAgB,IAAI,CAAC,CAAC,SAAS,QAAQ,EAAE,CAAC,SAAS,QAAQ,EAC1D,KAAK,EAAE,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,EAC1B,KAAK,EAAE,SAAS,aAAa,EAAE,EAC/B,MAAM,CAAC,EAAE,cAAc,GACrB,cAAc,CAwBhB"}
@@ -1 +1 @@
1
- {"version":3,"file":"pagerank.d.ts","sourceRoot":"","sources":["../../../src/ranking/baselines/pagerank.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACrE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAc,MAAM,SAAS,CAAC;AA0E1E;;;;;;;GAOG;AACH,wBAAgB,QAAQ,CAAC,CAAC,SAAS,QAAQ,EAAE,CAAC,SAAS,QAAQ,EAC9D,KAAK,EAAE,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,EAC1B,KAAK,EAAE,SAAS,aAAa,EAAE,EAC/B,MAAM,CAAC,EAAE,cAAc,GACrB,cAAc,CAgDhB"}
1
+ {"version":3,"file":"pagerank.d.ts","sourceRoot":"","sources":["../../../src/ranking/baselines/pagerank.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACrE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AA2E9D;;;;;;;GAOG;AACH,wBAAgB,QAAQ,CAAC,CAAC,SAAS,QAAQ,EAAE,CAAC,SAAS,QAAQ,EAC9D,KAAK,EAAE,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,EAC1B,KAAK,EAAE,SAAS,aAAa,EAAE,EAC/B,MAAM,CAAC,EAAE,cAAc,GACrB,cAAc,CAuBhB"}
@@ -1 +1 @@
1
- {"version":3,"file":"random-ranking.d.ts","sourceRoot":"","sources":["../../../src/ranking/baselines/random-ranking.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACrE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAc,MAAM,SAAS,CAAC;AAE1E;;GAEG;AACH,UAAU,mBAAoB,SAAQ,cAAc;IACnD,oDAAoD;IACpD,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;CACvB;AAqBD;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,CAAC,SAAS,QAAQ,EAAE,CAAC,SAAS,QAAQ,EACnE,MAAM,EAAE,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,EAC3B,KAAK,EAAE,SAAS,aAAa,EAAE,EAC/B,MAAM,CAAC,EAAE,mBAAmB,GAC1B,cAAc,CA2ChB"}
1
+ {"version":3,"file":"random-ranking.d.ts","sourceRoot":"","sources":["../../../src/ranking/baselines/random-ranking.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACrE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAG9D;;GAEG;AACH,UAAU,mBAAoB,SAAQ,cAAc;IACnD,oDAAoD;IACpD,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;CACvB;AAqBD;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,CAAC,SAAS,QAAQ,EAAE,CAAC,SAAS,QAAQ,EACnE,MAAM,EAAE,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,EAC3B,KAAK,EAAE,SAAS,aAAa,EAAE,EAC/B,MAAM,CAAC,EAAE,mBAAmB,GAC1B,cAAc,CAkBhB"}
@@ -1 +1 @@
1
- {"version":3,"file":"resistance-distance.d.ts","sourceRoot":"","sources":["../../../src/ranking/baselines/resistance-distance.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACrE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAc,MAAM,SAAS,CAAC;AA0L1E;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,CAAC,SAAS,QAAQ,EAAE,CAAC,SAAS,QAAQ,EACxE,KAAK,EAAE,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,EAC1B,KAAK,EAAE,SAAS,aAAa,EAAE,EAC/B,MAAM,CAAC,EAAE,cAAc,GACrB,cAAc,CA2DhB"}
1
+ {"version":3,"file":"resistance-distance.d.ts","sourceRoot":"","sources":["../../../src/ranking/baselines/resistance-distance.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACrE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AA2L9D;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,CAAC,SAAS,QAAQ,EAAE,CAAC,SAAS,QAAQ,EACxE,KAAK,EAAE,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,EAC1B,KAAK,EAAE,SAAS,aAAa,EAAE,EAC/B,MAAM,CAAC,EAAE,cAAc,GACrB,cAAc,CAkChB"}
@@ -1 +1 @@
1
- {"version":3,"file":"shortest.d.ts","sourceRoot":"","sources":["../../../src/ranking/baselines/shortest.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACrE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAc,MAAM,SAAS,CAAC;AAE1E;;;;;;;;;GASG;AACH,wBAAgB,QAAQ,CAAC,CAAC,SAAS,QAAQ,EAAE,CAAC,SAAS,QAAQ,EAC9D,MAAM,EAAE,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,EAC3B,KAAK,EAAE,SAAS,aAAa,EAAE,EAC/B,MAAM,CAAC,EAAE,cAAc,GACrB,cAAc,CAiChB"}
1
+ {"version":3,"file":"shortest.d.ts","sourceRoot":"","sources":["../../../src/ranking/baselines/shortest.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACrE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAG9D;;;;;;;;;GASG;AACH,wBAAgB,QAAQ,CAAC,CAAC,SAAS,QAAQ,EAAE,CAAC,SAAS,QAAQ,EAC9D,MAAM,EAAE,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,EAC3B,KAAK,EAAE,SAAS,aAAa,EAAE,EAC/B,MAAM,CAAC,EAAE,cAAc,GACrB,cAAc,CAmBhB"}
@@ -0,0 +1,20 @@
1
+ import { ExpansionPath } from '../../expansion/types';
2
+ import { BaselineResult } from './types';
3
+ /**
4
+ * Normalise a set of scored paths and return them sorted highest-first.
5
+ *
6
+ * All scores are normalised relative to the maximum observed score.
7
+ * When `includeScores` is false, raw (un-normalised) scores are preserved.
8
+ * Handles degenerate cases: empty input and all-zero scores.
9
+ *
10
+ * @param paths - Original paths in input order
11
+ * @param scored - Paths paired with their computed scores
12
+ * @param method - Method name to embed in the result
13
+ * @param includeScores - When true, normalise scores to [0, 1]; when false, keep raw scores
14
+ * @returns BaselineResult with ranked paths
15
+ */
16
+ export declare function normaliseAndRank(paths: readonly ExpansionPath[], scored: readonly {
17
+ readonly path: ExpansionPath;
18
+ readonly score: number;
19
+ }[], method: string, includeScores: boolean): BaselineResult;
20
+ //# sourceMappingURL=utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/ranking/baselines/utils.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,KAAK,EAAE,cAAc,EAAc,MAAM,SAAS,CAAC;AAE1D;;;;;;;;;;;;GAYG;AACH,wBAAgB,gBAAgB,CAC/B,KAAK,EAAE,SAAS,aAAa,EAAE,EAC/B,MAAM,EAAE,SAAS;IAAE,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;CAAE,EAAE,EAC3E,MAAM,EAAE,MAAM,EACd,aAAa,EAAE,OAAO,GACpB,cAAc,CAuBhB"}
@@ -1 +1 @@
1
- {"version":3,"file":"widest-path.d.ts","sourceRoot":"","sources":["../../../src/ranking/baselines/widest-path.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACrE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAc,MAAM,SAAS,CAAC;AAG1E;;;;;;;GAOG;AACH,wBAAgB,UAAU,CAAC,CAAC,SAAS,QAAQ,EAAE,CAAC,SAAS,QAAQ,EAChE,KAAK,EAAE,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,EAC1B,KAAK,EAAE,SAAS,aAAa,EAAE,EAC/B,MAAM,CAAC,EAAE,cAAc,GACrB,cAAc,CA2DhB"}
1
+ {"version":3,"file":"widest-path.d.ts","sourceRoot":"","sources":["../../../src/ranking/baselines/widest-path.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACrE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAI9D;;;;;;;GAOG;AACH,wBAAgB,UAAU,CAAC,CAAC,SAAS,QAAQ,EAAE,CAAC,SAAS,QAAQ,EAChE,KAAK,EAAE,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,EAC1B,KAAK,EAAE,SAAS,aAAa,EAAE,EAC/B,MAAM,CAAC,EAAE,cAAc,GACrB,cAAc,CAkChB"}
@@ -1 +1 @@
1
- {"version":3,"file":"adaptive.d.ts","sourceRoot":"","sources":["../../../src/ranking/mi/adaptive.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE7E,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAIhD;;;;;;;;;;;GAWG;AACH,wBAAgB,QAAQ,CAAC,CAAC,SAAS,QAAQ,EAAE,CAAC,SAAS,QAAQ,EAC9D,KAAK,EAAE,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,EAC1B,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,MAAM,CAAC,EAAE,gBAAgB,GACvB,MAAM,CA4CR"}
1
+ {"version":3,"file":"adaptive.d.ts","sourceRoot":"","sources":["../../../src/ranking/mi/adaptive.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE7E,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAGhD;;;;;;;;;;;GAWG;AACH,wBAAgB,QAAQ,CAAC,CAAC,SAAS,QAAQ,EAAE,CAAC,SAAS,QAAQ,EAC9D,KAAK,EAAE,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,EAC1B,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,MAAM,CAAC,EAAE,gBAAgB,GACvB,MAAM,CAoDR"}
@@ -0,0 +1,13 @@
1
+ import { NodeId, NodeData, EdgeData, ReadableGraph } from '../../graph';
2
+ import { MIConfig } from './types';
3
+ /**
4
+ * Compute cosine similarity between neighbourhoods of two nodes.
5
+ *
6
+ * @param graph - Source graph
7
+ * @param source - Source node ID
8
+ * @param target - Target node ID
9
+ * @param config - Optional configuration
10
+ * @returns Cosine similarity in [0, 1]
11
+ */
12
+ export declare function cosine<N extends NodeData, E extends EdgeData>(graph: ReadableGraph<N, E>, source: NodeId, target: NodeId, config?: MIConfig): number;
13
+ //# sourceMappingURL=cosine.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cosine.d.ts","sourceRoot":"","sources":["../../../src/ranking/mi/cosine.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE7E,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAExC;;;;;;;;GAQG;AACH,wBAAgB,MAAM,CAAC,CAAC,SAAS,QAAQ,EAAE,CAAC,SAAS,QAAQ,EAC5D,KAAK,EAAE,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,EAC1B,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,MAAM,CAAC,EAAE,QAAQ,GACf,MAAM,CAuBR"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=cosine.unit.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cosine.unit.test.d.ts","sourceRoot":"","sources":["../../../src/ranking/mi/cosine.unit.test.ts"],"names":[],"mappings":""}
@@ -1 +1 @@
1
- {"version":3,"file":"etch.d.ts","sourceRoot":"","sources":["../../../src/ranking/mi/etch.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE7E,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAExC;;GAEG;AACH,wBAAgB,IAAI,CAAC,CAAC,SAAS,QAAQ,EAAE,CAAC,SAAS,QAAQ,EAC1D,KAAK,EAAE,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,EAC1B,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,MAAM,CAAC,EAAE,QAAQ,GACf,MAAM,CAmCR"}
1
+ {"version":3,"file":"etch.d.ts","sourceRoot":"","sources":["../../../src/ranking/mi/etch.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE7E,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAExC;;GAEG;AACH,wBAAgB,IAAI,CAAC,CAAC,SAAS,QAAQ,EAAE,CAAC,SAAS,QAAQ,EAC1D,KAAK,EAAE,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,EAC1B,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,MAAM,CAAC,EAAE,QAAQ,GACf,MAAM,CA0BR"}
@@ -0,0 +1,13 @@
1
+ import { NodeId, NodeData, EdgeData, ReadableGraph } from '../../graph';
2
+ import { MIConfig } from './types';
3
+ /**
4
+ * Compute Hub Promoted index between neighbourhoods of two nodes.
5
+ *
6
+ * @param graph - Source graph
7
+ * @param source - Source node ID
8
+ * @param target - Target node ID
9
+ * @param config - Optional configuration
10
+ * @returns Hub Promoted index in [0, 1]
11
+ */
12
+ export declare function hubPromoted<N extends NodeData, E extends EdgeData>(graph: ReadableGraph<N, E>, source: NodeId, target: NodeId, config?: MIConfig): number;
13
+ //# sourceMappingURL=hub-promoted.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hub-promoted.d.ts","sourceRoot":"","sources":["../../../src/ranking/mi/hub-promoted.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE7E,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAExC;;;;;;;;GAQG;AACH,wBAAgB,WAAW,CAAC,CAAC,SAAS,QAAQ,EAAE,CAAC,SAAS,QAAQ,EACjE,KAAK,EAAE,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,EAC1B,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,MAAM,CAAC,EAAE,QAAQ,GACf,MAAM,CAwBR"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=hub-promoted.unit.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hub-promoted.unit.test.d.ts","sourceRoot":"","sources":["../../../src/ranking/mi/hub-promoted.unit.test.ts"],"names":[],"mappings":""}
@@ -9,6 +9,11 @@
9
9
  export * from './types';
10
10
  export * from './jaccard';
11
11
  export * from './adamic-adar';
12
+ export * from './cosine';
13
+ export * from './sorensen';
14
+ export * from './resource-allocation';
15
+ export * from './overlap-coefficient';
16
+ export * from './hub-promoted';
12
17
  export * from './scale';
13
18
  export * from './skew';
14
19
  export * from './span';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/ranking/mi/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,cAAc,SAAS,CAAC;AACxB,cAAc,WAAW,CAAC;AAC1B,cAAc,eAAe,CAAC;AAC9B,cAAc,SAAS,CAAC;AACxB,cAAc,QAAQ,CAAC;AACvB,cAAc,QAAQ,CAAC;AACvB,cAAc,QAAQ,CAAC;AACvB,cAAc,SAAS,CAAC;AACxB,cAAc,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/ranking/mi/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,cAAc,SAAS,CAAC;AACxB,cAAc,WAAW,CAAC;AAC1B,cAAc,eAAe,CAAC;AAC9B,cAAc,UAAU,CAAC;AACzB,cAAc,YAAY,CAAC;AAC3B,cAAc,uBAAuB,CAAC;AACtC,cAAc,uBAAuB,CAAC;AACtC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,SAAS,CAAC;AACxB,cAAc,QAAQ,CAAC;AACvB,cAAc,QAAQ,CAAC;AACvB,cAAc,QAAQ,CAAC;AACvB,cAAc,SAAS,CAAC;AACxB,cAAc,YAAY,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"jaccard.d.ts","sourceRoot":"","sources":["../../../src/ranking/mi/jaccard.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE7E,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAExC;;;;;;;;GAQG;AACH,wBAAgB,OAAO,CAAC,CAAC,SAAS,QAAQ,EAAE,CAAC,SAAS,QAAQ,EAC7D,KAAK,EAAE,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,EAC1B,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,MAAM,CAAC,EAAE,QAAQ,GACf,MAAM,CAsBR"}
1
+ {"version":3,"file":"jaccard.d.ts","sourceRoot":"","sources":["../../../src/ranking/mi/jaccard.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE7E,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAExC;;;;;;;;GAQG;AACH,wBAAgB,OAAO,CAAC,CAAC,SAAS,QAAQ,EAAE,CAAC,SAAS,QAAQ,EAC7D,KAAK,EAAE,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,EAC1B,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,MAAM,CAAC,EAAE,QAAQ,GACf,MAAM,CAgBR"}
@@ -1 +1 @@
1
- {"version":3,"file":"notch.d.ts","sourceRoot":"","sources":["../../../src/ranking/mi/notch.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE7E,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAExC;;GAEG;AACH,wBAAgB,KAAK,CAAC,CAAC,SAAS,QAAQ,EAAE,CAAC,SAAS,QAAQ,EAC3D,KAAK,EAAE,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,EAC1B,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,MAAM,CAAC,EAAE,QAAQ,GACf,MAAM,CAuCR"}
1
+ {"version":3,"file":"notch.d.ts","sourceRoot":"","sources":["../../../src/ranking/mi/notch.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE7E,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAExC;;GAEG;AACH,wBAAgB,KAAK,CAAC,CAAC,SAAS,QAAQ,EAAE,CAAC,SAAS,QAAQ,EAC3D,KAAK,EAAE,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,EAC1B,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,MAAM,CAAC,EAAE,QAAQ,GACf,MAAM,CA8BR"}
@@ -0,0 +1,13 @@
1
+ import { NodeId, NodeData, EdgeData, ReadableGraph } from '../../graph';
2
+ import { MIConfig } from './types';
3
+ /**
4
+ * Compute Overlap Coefficient between neighbourhoods of two nodes.
5
+ *
6
+ * @param graph - Source graph
7
+ * @param source - Source node ID
8
+ * @param target - Target node ID
9
+ * @param config - Optional configuration
10
+ * @returns Overlap Coefficient in [0, 1]
11
+ */
12
+ export declare function overlapCoefficient<N extends NodeData, E extends EdgeData>(graph: ReadableGraph<N, E>, source: NodeId, target: NodeId, config?: MIConfig): number;
13
+ //# sourceMappingURL=overlap-coefficient.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"overlap-coefficient.d.ts","sourceRoot":"","sources":["../../../src/ranking/mi/overlap-coefficient.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE7E,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAExC;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAAC,CAAC,SAAS,QAAQ,EAAE,CAAC,SAAS,QAAQ,EACxE,KAAK,EAAE,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,EAC1B,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,MAAM,CAAC,EAAE,QAAQ,GACf,MAAM,CAsBR"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=overlap-coefficient.unit.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"overlap-coefficient.unit.test.d.ts","sourceRoot":"","sources":["../../../src/ranking/mi/overlap-coefficient.unit.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,13 @@
1
+ import { NodeId, NodeData, EdgeData, ReadableGraph } from '../../graph';
2
+ import { MIConfig } from './types';
3
+ /**
4
+ * Compute Resource Allocation index between neighbourhoods of two nodes.
5
+ *
6
+ * @param graph - Source graph
7
+ * @param source - Source node ID
8
+ * @param target - Target node ID
9
+ * @param config - Optional configuration
10
+ * @returns Resource Allocation index (normalised to [0, 1] if configured)
11
+ */
12
+ export declare function resourceAllocation<N extends NodeData, E extends EdgeData>(graph: ReadableGraph<N, E>, source: NodeId, target: NodeId, config?: MIConfig): number;
13
+ //# sourceMappingURL=resource-allocation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resource-allocation.d.ts","sourceRoot":"","sources":["../../../src/ranking/mi/resource-allocation.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE7E,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAExC;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAAC,CAAC,SAAS,QAAQ,EAAE,CAAC,SAAS,QAAQ,EACxE,KAAK,EAAE,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,EAC1B,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,MAAM,CAAC,EAAE,QAAQ,GACf,MAAM,CA+BR"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=resource-allocation.unit.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resource-allocation.unit.test.d.ts","sourceRoot":"","sources":["../../../src/ranking/mi/resource-allocation.unit.test.ts"],"names":[],"mappings":""}
@@ -1 +1 @@
1
- {"version":3,"file":"scale.d.ts","sourceRoot":"","sources":["../../../src/ranking/mi/scale.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE7E,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAExC;;GAEG;AACH,wBAAgB,KAAK,CAAC,CAAC,SAAS,QAAQ,EAAE,CAAC,SAAS,QAAQ,EAC3D,KAAK,EAAE,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,EAC1B,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,MAAM,CAAC,EAAE,QAAQ,GACf,MAAM,CAgCR"}
1
+ {"version":3,"file":"scale.d.ts","sourceRoot":"","sources":["../../../src/ranking/mi/scale.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE7E,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAExC;;GAEG;AACH,wBAAgB,KAAK,CAAC,CAAC,SAAS,QAAQ,EAAE,CAAC,SAAS,QAAQ,EAC3D,KAAK,EAAE,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,EAC1B,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,MAAM,CAAC,EAAE,QAAQ,GACf,MAAM,CAuBR"}
@@ -1 +1 @@
1
- {"version":3,"file":"skew.d.ts","sourceRoot":"","sources":["../../../src/ranking/mi/skew.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE7E,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAExC;;GAEG;AACH,wBAAgB,IAAI,CAAC,CAAC,SAAS,QAAQ,EAAE,CAAC,SAAS,QAAQ,EAC1D,KAAK,EAAE,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,EAC1B,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,MAAM,CAAC,EAAE,QAAQ,GACf,MAAM,CA0BR"}
1
+ {"version":3,"file":"skew.d.ts","sourceRoot":"","sources":["../../../src/ranking/mi/skew.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE7E,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAExC;;GAEG;AACH,wBAAgB,IAAI,CAAC,CAAC,SAAS,QAAQ,EAAE,CAAC,SAAS,QAAQ,EAC1D,KAAK,EAAE,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,EAC1B,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,MAAM,CAAC,EAAE,QAAQ,GACf,MAAM,CAiBR"}
@@ -0,0 +1,13 @@
1
+ import { NodeId, NodeData, EdgeData, ReadableGraph } from '../../graph';
2
+ import { MIConfig } from './types';
3
+ /**
4
+ * Compute Sorensen-Dice similarity between neighbourhoods of two nodes.
5
+ *
6
+ * @param graph - Source graph
7
+ * @param source - Source node ID
8
+ * @param target - Target node ID
9
+ * @param config - Optional configuration
10
+ * @returns Sorensen-Dice coefficient in [0, 1]
11
+ */
12
+ export declare function sorensen<N extends NodeData, E extends EdgeData>(graph: ReadableGraph<N, E>, source: NodeId, target: NodeId, config?: MIConfig): number;
13
+ //# sourceMappingURL=sorensen.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sorensen.d.ts","sourceRoot":"","sources":["../../../src/ranking/mi/sorensen.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE7E,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAExC;;;;;;;;GAQG;AACH,wBAAgB,QAAQ,CAAC,CAAC,SAAS,QAAQ,EAAE,CAAC,SAAS,QAAQ,EAC9D,KAAK,EAAE,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,EAC1B,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,MAAM,CAAC,EAAE,QAAQ,GACf,MAAM,CAsBR"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=sorensen.unit.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sorensen.unit.test.d.ts","sourceRoot":"","sources":["../../../src/ranking/mi/sorensen.unit.test.ts"],"names":[],"mappings":""}
@@ -1 +1 @@
1
- {"version":3,"file":"span.d.ts","sourceRoot":"","sources":["../../../src/ranking/mi/span.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAG7E,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAExC;;GAEG;AACH,wBAAgB,IAAI,CAAC,CAAC,SAAS,QAAQ,EAAE,CAAC,SAAS,QAAQ,EAC1D,KAAK,EAAE,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,EAC1B,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,MAAM,CAAC,EAAE,QAAQ,GACf,MAAM,CAyBR"}
1
+ {"version":3,"file":"span.d.ts","sourceRoot":"","sources":["../../../src/ranking/mi/span.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAG7E,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAExC;;GAEG;AACH,wBAAgB,IAAI,CAAC,CAAC,SAAS,QAAQ,EAAE,CAAC,SAAS,QAAQ,EAC1D,KAAK,EAAE,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,EAC1B,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,MAAM,CAAC,EAAE,QAAQ,GACf,MAAM,CAgBR"}
@@ -11,7 +11,7 @@ export type MIFunction<N extends NodeData = NodeData, E extends EdgeData = EdgeD
11
11
  /**
12
12
  * Names of available MI variants.
13
13
  */
14
- export type MIVariantName = "jaccard" | "adamic-adar" | "scale" | "skew" | "span" | "etch" | "notch" | "adaptive";
14
+ export type MIVariantName = "jaccard" | "adamic-adar" | "cosine" | "sorensen" | "resource-allocation" | "overlap-coefficient" | "hub-promoted" | "scale" | "skew" | "span" | "etch" | "notch" | "adaptive";
15
15
  /**
16
16
  * Configuration for MI computation.
17
17
  */
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/ranking/mi/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE7E;;;;;;;GAOG;AACH,MAAM,MAAM,UAAU,CACrB,CAAC,SAAS,QAAQ,GAAG,QAAQ,EAC7B,CAAC,SAAS,QAAQ,GAAG,QAAQ,IAC1B,CAAC,KAAK,EAAE,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,MAAM,CAAC;AAE3E;;GAEG;AACH,MAAM,MAAM,aAAa,GACtB,SAAS,GACT,aAAa,GACb,OAAO,GACP,MAAM,GACN,MAAM,GACN,MAAM,GACN,OAAO,GACP,UAAU,CAAC;AAEd;;GAEG;AACH,MAAM,WAAW,QAAQ;IACxB,sCAAsC;IACtC,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,4CAA4C;IAC5C,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC;CAC7B;AAED;;GAEG;AACH,MAAM,WAAW,gBAAiB,SAAQ,QAAQ;IACjD,mDAAmD;IACnD,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IACnC,4DAA4D;IAC5D,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAC/B,+CAA+C;IAC/C,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;CAChC"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/ranking/mi/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE7E;;;;;;;GAOG;AACH,MAAM,MAAM,UAAU,CACrB,CAAC,SAAS,QAAQ,GAAG,QAAQ,EAC7B,CAAC,SAAS,QAAQ,GAAG,QAAQ,IAC1B,CAAC,KAAK,EAAE,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,MAAM,CAAC;AAE3E;;GAEG;AACH,MAAM,MAAM,aAAa,GACtB,SAAS,GACT,aAAa,GACb,QAAQ,GACR,UAAU,GACV,qBAAqB,GACrB,qBAAqB,GACrB,cAAc,GACd,OAAO,GACP,MAAM,GACN,MAAM,GACN,MAAM,GACN,OAAO,GACP,UAAU,CAAC;AAEd;;GAEG;AACH,MAAM,WAAW,QAAQ;IACxB,sCAAsC;IACtC,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,4CAA4C;IAC5C,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC;CAC7B;AAED;;GAEG;AACH,MAAM,WAAW,gBAAiB,SAAQ,QAAQ;IACjD,mDAAmD;IACnD,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IACnC,4DAA4D;IAC5D,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAC/B,+CAA+C;IAC/C,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;CAChC"}
@@ -79,7 +79,7 @@ export type Seed = z.infer<typeof Seed>;
79
79
  * Compute backend selection.
80
80
  */
81
81
  export declare const ComputeBackend: z.ZodUnion<readonly [z.ZodLiteral<"cpu">, z.ZodLiteral<"gpu">, z.ZodLiteral<"auto">]> & {
82
- is(value: unknown): value is "cpu" | "gpu" | "auto";
82
+ is(value: unknown): value is "auto" | "cpu" | "gpu";
83
83
  };
84
84
  export type ComputeBackend = z.infer<typeof ComputeBackend>;
85
85
  //# sourceMappingURL=graph.d.ts.map
@@ -162,6 +162,27 @@ function batchClusteringCoefficients(graph, nodeIds) {
162
162
  //#endregion
163
163
  //#region src/utils/neighbours.ts
164
164
  /**
165
+ * Compute Jaccard similarity between the neighbourhoods of two nodes.
166
+ *
167
+ * Each endpoint is excluded from the other's neighbourhood set to avoid
168
+ * the direct edge inflating the overlap score.
169
+ *
170
+ * @param graph - The graph to traverse
171
+ * @param source - Source node ID
172
+ * @param target - Target node ID
173
+ * @returns JaccardResult containing the score and both neighbourhood sets
174
+ */
175
+ function computeJaccard(graph, source, target) {
176
+ const sourceNeighbours = neighbourSet(graph, source, target);
177
+ const targetNeighbours = neighbourSet(graph, target, source);
178
+ const { intersection, union } = neighbourOverlap(sourceNeighbours, targetNeighbours);
179
+ return {
180
+ jaccard: union > 0 ? intersection / union : 0,
181
+ sourceNeighbours,
182
+ targetNeighbours
183
+ };
184
+ }
185
+ /**
165
186
  * Collect neighbours into a Set, optionally excluding a specific node.
166
187
  *
167
188
  * @param graph - The graph to traverse
@@ -240,6 +261,7 @@ function countNodesOfType(graph, type) {
240
261
  exports._computeMean = require_kmeans._computeMean;
241
262
  exports.approximateClusteringCoefficient = approximateClusteringCoefficient;
242
263
  exports.batchClusteringCoefficients = batchClusteringCoefficients;
264
+ exports.computeJaccard = computeJaccard;
243
265
  exports.countEdgesOfType = countEdgesOfType;
244
266
  exports.countNodesOfType = countNodesOfType;
245
267
  exports.entropyFromCounts = entropyFromCounts;
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","names":[],"sources":["../../src/utils/entropy.ts","../../src/utils/clustering-coefficient.ts","../../src/utils/neighbours.ts"],"sourcesContent":["/**\n * Entropy computation utilities for graph analysis.\n *\n * Shannon entropy measures uncertainty or randomness in a distribution.\n * Used in EDGE and HAE algorithms for heterogeneity-aware expansion.\n *\n * @packageDocumentation\n */\n\n/**\n * Compute Shannon entropy of a probability distribution.\n *\n * Shannon entropy is defined as:\n * H(X) = -Σ p(x) × log₂(p(x))\n *\n * A uniform distribution has maximum entropy.\n * A deterministic distribution (all probability on one value) has zero entropy.\n *\n * @param probabilities - Array of probabilities (should sum to 1)\n * @returns Entropy in bits (log base 2), or 0 if probabilities are invalid\n */\nexport function shannonEntropy(probabilities: readonly number[]): number {\n\tif (probabilities.length === 0) {\n\t\treturn 0;\n\t}\n\n\tlet entropy = 0;\n\tfor (const p of probabilities) {\n\t\t// Skip zero probabilities (log(0) is undefined, but 0 * log(0) = 0)\n\t\tif (p > 0) {\n\t\t\tentropy -= p * Math.log2(p);\n\t\t}\n\t}\n\n\treturn entropy;\n}\n\n/**\n * Compute normalised entropy (entropy divided by maximum possible entropy).\n *\n * Normalised entropy is in [0, 1], where:\n * - 0 means the distribution is deterministic (all mass on one value)\n * - 1 means the distribution is uniform (maximum uncertainty)\n *\n * This is useful for comparing entropy across distributions with different\n * numbers of possible values.\n *\n * @param probabilities - Array of probabilities (should sum to 1)\n * @returns Normalised entropy in [0, 1], or 0 if only one category\n */\nexport function normalisedEntropy(probabilities: readonly number[]): number {\n\tif (probabilities.length <= 1) {\n\t\treturn 0;\n\t}\n\n\tconst H = shannonEntropy(probabilities);\n\tconst Hmax = Math.log2(probabilities.length);\n\n\tif (Hmax === 0) {\n\t\treturn 0;\n\t}\n\n\treturn H / Hmax;\n}\n\n/**\n * Compute entropy from a frequency count.\n *\n * Converts counts to probabilities and then computes entropy.\n * This is a convenience function when you have raw counts rather than\n * normalised probabilities.\n *\n * @param counts - Array of frequency counts\n * @returns Entropy in bits\n */\nexport function entropyFromCounts(counts: readonly number[]): number {\n\tif (counts.length === 0) {\n\t\treturn 0;\n\t}\n\n\tconst total = counts.reduce((sum, c) => sum + c, 0);\n\tif (total === 0) {\n\t\treturn 0;\n\t}\n\n\tconst probabilities = counts.map((c) => c / total);\n\treturn shannonEntropy(probabilities);\n}\n\n/**\n * Compute local type entropy for a node's neighbours.\n *\n * This measures the diversity of types among a node's neighbours.\n * High entropy = heterogeneous neighbourhood (diverse types).\n * Low entropy = homogeneous neighbourhood (similar types).\n *\n * @param neighbourTypes - Array of type labels for neighbours\n * @returns Normalised entropy in [0, 1]\n */\nexport function localTypeEntropy(neighbourTypes: readonly string[]): number {\n\tif (neighbourTypes.length <= 1) {\n\t\treturn 0;\n\t}\n\n\t// Count occurrences of each type\n\tconst typeCounts = new Map<string, number>();\n\tfor (const t of neighbourTypes) {\n\t\ttypeCounts.set(t, (typeCounts.get(t) ?? 0) + 1);\n\t}\n\n\t// If all neighbours are the same type, entropy is 0\n\tif (typeCounts.size === 1) {\n\t\treturn 0;\n\t}\n\n\t// Convert to probability array\n\tconst probabilities: number[] = [];\n\tconst total = neighbourTypes.length;\n\tfor (const count of typeCounts.values()) {\n\t\tprobabilities.push(count / total);\n\t}\n\n\treturn normalisedEntropy(probabilities);\n}\n","/**\n * Clustering coefficient computation for graph nodes.\n *\n * The local clustering coefficient measures how close a node's neighbours\n * are to being a complete graph (clique). It is used in SPAN MI variant\n * and GRASP seed selection.\n *\n * @packageDocumentation\n */\n\nimport type { ReadableGraph, NodeId } from \"../graph\";\n\n/**\n * Compute the local clustering coefficient for a single node.\n *\n * The clustering coefficient is defined as:\n * CC(v) = (triangles through v) / (possible triangles)\n * CC(v) = 2 * |{(u,w) : u,w in N(v), (u,w) in E}| / (deg(v) * (deg(v) - 1))\n *\n * For nodes with degree < 2, the clustering coefficient is 0.\n *\n * @param graph - The graph to compute on\n * @param nodeId - The node to compute clustering coefficient for\n * @returns The clustering coefficient in [0, 1], or 0 if undefined\n */\nexport function localClusteringCoefficient(\n\tgraph: ReadableGraph,\n\tnodeId: NodeId,\n): number {\n\tconst neighbours = [...graph.neighbours(nodeId, \"both\")];\n\tconst degree = neighbours.length;\n\n\t// Nodes with degree < 2 have no possible triangles\n\tif (degree < 2) {\n\t\treturn 0;\n\t}\n\n\t// Count actual triangles: pairs of neighbours that are connected\n\tlet triangleCount = 0;\n\n\tfor (let i = 0; i < neighbours.length; i++) {\n\t\tconst u = neighbours[i];\n\t\tif (u === undefined) continue;\n\n\t\tfor (let j = i + 1; j < neighbours.length; j++) {\n\t\t\tconst w = neighbours[j];\n\t\t\tif (w === undefined) continue;\n\n\t\t\t// Check if u and w are connected\n\t\t\tif (\n\t\t\t\tgraph.getEdge(u, w) !== undefined ||\n\t\t\t\tgraph.getEdge(w, u) !== undefined\n\t\t\t) {\n\t\t\t\ttriangleCount++;\n\t\t\t}\n\t\t}\n\t}\n\n\t// Possible triangles: deg * (deg - 1) / 2 pairs\n\t// We multiply by 2 because each triangle is counted once\n\tconst possibleTriangles = (degree * (degree - 1)) / 2;\n\n\treturn triangleCount / possibleTriangles;\n}\n\n/**\n * Compute approximate local clustering coefficient using sampling.\n *\n * For nodes with many neighbours, this samples neighbour pairs rather than\n * checking all pairs. Useful for large graphs where exact computation is expensive.\n *\n * @param graph - The graph to compute on\n * @param nodeId - The node to compute clustering coefficient for\n * @param sampleSize - Maximum number of neighbour pairs to check (default: 100)\n * @returns The approximate clustering coefficient in [0, 1]\n */\nexport function approximateClusteringCoefficient(\n\tgraph: ReadableGraph,\n\tnodeId: NodeId,\n\tsampleSize = 100,\n): number {\n\tconst neighbours = [...graph.neighbours(nodeId, \"both\")];\n\tconst degree = neighbours.length;\n\n\tif (degree < 2) {\n\t\treturn 0;\n\t}\n\n\tconst possibleTriangles = (degree * (degree - 1)) / 2;\n\n\t// If all pairs can be checked within sample limit, use exact computation\n\tif (possibleTriangles <= sampleSize) {\n\t\treturn localClusteringCoefficient(graph, nodeId);\n\t}\n\n\t// Sample pairs uniformly\n\tlet triangleCount = 0;\n\tlet sampled = 0;\n\n\t// Use reservoir sampling style approach for pair selection\n\tfor (let i = 0; i < neighbours.length && sampled < sampleSize; i++) {\n\t\tconst u = neighbours[i];\n\t\tif (u === undefined) continue;\n\n\t\tfor (let j = i + 1; j < neighbours.length && sampled < sampleSize; j++) {\n\t\t\tconst w = neighbours[j];\n\t\t\tif (w === undefined) continue;\n\n\t\t\t// Decide whether to include this pair based on remaining budget\n\t\t\tsampled++;\n\n\t\t\t// Check if u and w are connected\n\t\t\tif (\n\t\t\t\tgraph.getEdge(u, w) !== undefined ||\n\t\t\t\tgraph.getEdge(w, u) !== undefined\n\t\t\t) {\n\t\t\t\ttriangleCount++;\n\t\t\t}\n\t\t}\n\t}\n\n\t// Extrapolate from sample\n\treturn triangleCount / sampled;\n}\n\n/**\n * Compute clustering coefficients for multiple nodes efficiently.\n *\n * Reuses neighbour sets to avoid repeated iteration.\n *\n * @param graph - The graph to compute on\n * @param nodeIds - The nodes to compute clustering coefficients for\n * @returns Map from nodeId to clustering coefficient\n */\nexport function batchClusteringCoefficients(\n\tgraph: ReadableGraph,\n\tnodeIds: readonly NodeId[],\n): Map<NodeId, number> {\n\tconst results = new Map<NodeId, number>();\n\n\tfor (const nodeId of nodeIds) {\n\t\tresults.set(nodeId, localClusteringCoefficient(graph, nodeId));\n\t}\n\n\treturn results;\n}\n","/**\n * Neighbourhood computation utilities.\n *\n * Shared utilities for neighbourhood operations used by MI variants and other graph algorithms.\n * These functions eliminate duplication of neighbourhood set operations across multiple\n * implementations.\n *\n * @packageDocumentation\n */\n\nimport type { NodeId, NodeData, EdgeData, ReadableGraph } from \"../graph\";\n\n/**\n * Collect neighbours into a Set, optionally excluding a specific node.\n *\n * @param graph - The graph to traverse\n * @param nodeId - The source node\n * @param exclude - Optional node ID to exclude from result\n * @returns A ReadonlySet of neighbouring node IDs\n */\nexport function neighbourSet<N extends NodeData, E extends EdgeData>(\n\tgraph: ReadableGraph<N, E>,\n\tnodeId: NodeId,\n\texclude?: NodeId,\n): ReadonlySet<NodeId> {\n\tconst neighbours = new Set(graph.neighbours(nodeId));\n\tif (exclude !== undefined) {\n\t\tneighbours.delete(exclude);\n\t}\n\treturn neighbours;\n}\n\n/**\n * Compute intersection and union sizes of two neighbour sets without allocating the union set.\n *\n * This is more efficient than computing both separately, as it avoids creating a full union Set.\n *\n * @param a - First neighbourhood set\n * @param b - Second neighbourhood set\n * @returns Object with intersection and union sizes\n */\nexport function neighbourOverlap(\n\ta: ReadonlySet<NodeId>,\n\tb: ReadonlySet<NodeId>,\n): { intersection: number; union: number } {\n\tlet intersection = 0;\n\n\t// Count intersection by iterating through the smaller set\n\tconst [smaller, larger] = a.size < b.size ? [a, b] : [b, a];\n\n\tfor (const node of smaller) {\n\t\tif (larger.has(node)) {\n\t\t\tintersection++;\n\t\t}\n\t}\n\n\t// Union size = size(a) + size(b) - intersection\n\tconst union = a.size + b.size - intersection;\n\n\treturn { intersection, union };\n}\n\n/**\n * Return the actual intersection set of two neighbourhood sets.\n *\n * Needed by Adamic-Adar (iterates common neighbours) and ETCH (requires edge types of intersection edges).\n *\n * @param a - First neighbourhood set\n * @param b - Second neighbourhood set\n * @returns A ReadonlySet containing nodes in both a and b\n */\nexport function neighbourIntersection(\n\ta: ReadonlySet<NodeId>,\n\tb: ReadonlySet<NodeId>,\n): ReadonlySet<NodeId> {\n\tconst intersection = new Set<NodeId>();\n\n\t// Iterate through the smaller set for efficiency\n\tconst [smaller, larger] = a.size < b.size ? [a, b] : [b, a];\n\n\tfor (const node of smaller) {\n\t\tif (larger.has(node)) {\n\t\t\tintersection.add(node);\n\t\t}\n\t}\n\n\treturn intersection;\n}\n\n/**\n * Count the number of edges with a specific type in the graph.\n *\n * Used by ETCH MI variant to compute edge rarity weighting.\n *\n * @param graph - The graph to count edges in\n * @param type - The edge type to count\n * @returns The number of edges with the specified type\n */\nexport function countEdgesOfType<N extends NodeData, E extends EdgeData>(\n\tgraph: ReadableGraph<N, E>,\n\ttype: string,\n): number {\n\tlet count = 0;\n\tfor (const edge of graph.edges()) {\n\t\tif (edge.type === type) {\n\t\t\tcount++;\n\t\t}\n\t}\n\treturn count;\n}\n\n/**\n * Count the number of nodes with a specific type in the graph.\n *\n * Used by NOTCH MI variant to compute node rarity weighting.\n *\n * @param graph - The graph to count nodes in\n * @param type - The node type to count\n * @returns The number of nodes with the specified type\n */\nexport function countNodesOfType<N extends NodeData, E extends EdgeData>(\n\tgraph: ReadableGraph<N, E>,\n\ttype: string,\n): number {\n\tlet count = 0;\n\tfor (const nodeId of graph.nodeIds()) {\n\t\tconst node = graph.getNode(nodeId);\n\t\tif (node?.type === type) {\n\t\t\tcount++;\n\t\t}\n\t}\n\treturn count;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AAqBA,SAAgB,eAAe,eAA0C;AACxE,KAAI,cAAc,WAAW,EAC5B,QAAO;CAGR,IAAI,UAAU;AACd,MAAK,MAAM,KAAK,cAEf,KAAI,IAAI,EACP,YAAW,IAAI,KAAK,KAAK,EAAE;AAI7B,QAAO;;;;;;;;;;;;;;;AAgBR,SAAgB,kBAAkB,eAA0C;AAC3E,KAAI,cAAc,UAAU,EAC3B,QAAO;CAGR,MAAM,IAAI,eAAe,cAAc;CACvC,MAAM,OAAO,KAAK,KAAK,cAAc,OAAO;AAE5C,KAAI,SAAS,EACZ,QAAO;AAGR,QAAO,IAAI;;;;;;;;;;;;AAaZ,SAAgB,kBAAkB,QAAmC;AACpE,KAAI,OAAO,WAAW,EACrB,QAAO;CAGR,MAAM,QAAQ,OAAO,QAAQ,KAAK,MAAM,MAAM,GAAG,EAAE;AACnD,KAAI,UAAU,EACb,QAAO;AAIR,QAAO,eADe,OAAO,KAAK,MAAM,IAAI,MAAM,CACd;;;;;;;;;;;;AAarC,SAAgB,iBAAiB,gBAA2C;AAC3E,KAAI,eAAe,UAAU,EAC5B,QAAO;CAIR,MAAM,6BAAa,IAAI,KAAqB;AAC5C,MAAK,MAAM,KAAK,eACf,YAAW,IAAI,IAAI,WAAW,IAAI,EAAE,IAAI,KAAK,EAAE;AAIhD,KAAI,WAAW,SAAS,EACvB,QAAO;CAIR,MAAM,gBAA0B,EAAE;CAClC,MAAM,QAAQ,eAAe;AAC7B,MAAK,MAAM,SAAS,WAAW,QAAQ,CACtC,eAAc,KAAK,QAAQ,MAAM;AAGlC,QAAO,kBAAkB,cAAc;;;;;;;;;;;;;;;;;ACjGxC,SAAgB,2BACf,OACA,QACS;CACT,MAAM,aAAa,CAAC,GAAG,MAAM,WAAW,QAAQ,OAAO,CAAC;CACxD,MAAM,SAAS,WAAW;AAG1B,KAAI,SAAS,EACZ,QAAO;CAIR,IAAI,gBAAgB;AAEpB,MAAK,IAAI,IAAI,GAAG,IAAI,WAAW,QAAQ,KAAK;EAC3C,MAAM,IAAI,WAAW;AACrB,MAAI,MAAM,KAAA,EAAW;AAErB,OAAK,IAAI,IAAI,IAAI,GAAG,IAAI,WAAW,QAAQ,KAAK;GAC/C,MAAM,IAAI,WAAW;AACrB,OAAI,MAAM,KAAA,EAAW;AAGrB,OACC,MAAM,QAAQ,GAAG,EAAE,KAAK,KAAA,KACxB,MAAM,QAAQ,GAAG,EAAE,KAAK,KAAA,EAExB;;;CAOH,MAAM,oBAAqB,UAAU,SAAS,KAAM;AAEpD,QAAO,gBAAgB;;;;;;;;;;;;;AAcxB,SAAgB,iCACf,OACA,QACA,aAAa,KACJ;CACT,MAAM,aAAa,CAAC,GAAG,MAAM,WAAW,QAAQ,OAAO,CAAC;CACxD,MAAM,SAAS,WAAW;AAE1B,KAAI,SAAS,EACZ,QAAO;AAMR,KAH2B,UAAU,SAAS,KAAM,KAG3B,WACxB,QAAO,2BAA2B,OAAO,OAAO;CAIjD,IAAI,gBAAgB;CACpB,IAAI,UAAU;AAGd,MAAK,IAAI,IAAI,GAAG,IAAI,WAAW,UAAU,UAAU,YAAY,KAAK;EACnE,MAAM,IAAI,WAAW;AACrB,MAAI,MAAM,KAAA,EAAW;AAErB,OAAK,IAAI,IAAI,IAAI,GAAG,IAAI,WAAW,UAAU,UAAU,YAAY,KAAK;GACvE,MAAM,IAAI,WAAW;AACrB,OAAI,MAAM,KAAA,EAAW;AAGrB;AAGA,OACC,MAAM,QAAQ,GAAG,EAAE,KAAK,KAAA,KACxB,MAAM,QAAQ,GAAG,EAAE,KAAK,KAAA,EAExB;;;AAMH,QAAO,gBAAgB;;;;;;;;;;;AAYxB,SAAgB,4BACf,OACA,SACsB;CACtB,MAAM,0BAAU,IAAI,KAAqB;AAEzC,MAAK,MAAM,UAAU,QACpB,SAAQ,IAAI,QAAQ,2BAA2B,OAAO,OAAO,CAAC;AAG/D,QAAO;;;;;;;;;;;;AC5HR,SAAgB,aACf,OACA,QACA,SACsB;CACtB,MAAM,aAAa,IAAI,IAAI,MAAM,WAAW,OAAO,CAAC;AACpD,KAAI,YAAY,KAAA,EACf,YAAW,OAAO,QAAQ;AAE3B,QAAO;;;;;;;;;;;AAYR,SAAgB,iBACf,GACA,GAC0C;CAC1C,IAAI,eAAe;CAGnB,MAAM,CAAC,SAAS,UAAU,EAAE,OAAO,EAAE,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,GAAG,EAAE;AAE3D,MAAK,MAAM,QAAQ,QAClB,KAAI,OAAO,IAAI,KAAK,CACnB;CAKF,MAAM,QAAQ,EAAE,OAAO,EAAE,OAAO;AAEhC,QAAO;EAAE;EAAc;EAAO;;;;;;;;;;;AAY/B,SAAgB,sBACf,GACA,GACsB;CACtB,MAAM,+BAAe,IAAI,KAAa;CAGtC,MAAM,CAAC,SAAS,UAAU,EAAE,OAAO,EAAE,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,GAAG,EAAE;AAE3D,MAAK,MAAM,QAAQ,QAClB,KAAI,OAAO,IAAI,KAAK,CACnB,cAAa,IAAI,KAAK;AAIxB,QAAO;;;;;;;;;;;AAYR,SAAgB,iBACf,OACA,MACS;CACT,IAAI,QAAQ;AACZ,MAAK,MAAM,QAAQ,MAAM,OAAO,CAC/B,KAAI,KAAK,SAAS,KACjB;AAGF,QAAO;;;;;;;;;;;AAYR,SAAgB,iBACf,OACA,MACS;CACT,IAAI,QAAQ;AACZ,MAAK,MAAM,UAAU,MAAM,SAAS,CAEnC,KADa,MAAM,QAAQ,OAAO,EACxB,SAAS,KAClB;AAGF,QAAO"}
1
+ {"version":3,"file":"index.cjs","names":[],"sources":["../../src/utils/entropy.ts","../../src/utils/clustering-coefficient.ts","../../src/utils/neighbours.ts"],"sourcesContent":["/**\n * Entropy computation utilities for graph analysis.\n *\n * Shannon entropy measures uncertainty or randomness in a distribution.\n * Used in EDGE and HAE algorithms for heterogeneity-aware expansion.\n *\n * @packageDocumentation\n */\n\n/**\n * Compute Shannon entropy of a probability distribution.\n *\n * Shannon entropy is defined as:\n * H(X) = -Σ p(x) × log₂(p(x))\n *\n * A uniform distribution has maximum entropy.\n * A deterministic distribution (all probability on one value) has zero entropy.\n *\n * @param probabilities - Array of probabilities (should sum to 1)\n * @returns Entropy in bits (log base 2), or 0 if probabilities are invalid\n */\nexport function shannonEntropy(probabilities: readonly number[]): number {\n\tif (probabilities.length === 0) {\n\t\treturn 0;\n\t}\n\n\tlet entropy = 0;\n\tfor (const p of probabilities) {\n\t\t// Skip zero probabilities (log(0) is undefined, but 0 * log(0) = 0)\n\t\tif (p > 0) {\n\t\t\tentropy -= p * Math.log2(p);\n\t\t}\n\t}\n\n\treturn entropy;\n}\n\n/**\n * Compute normalised entropy (entropy divided by maximum possible entropy).\n *\n * Normalised entropy is in [0, 1], where:\n * - 0 means the distribution is deterministic (all mass on one value)\n * - 1 means the distribution is uniform (maximum uncertainty)\n *\n * This is useful for comparing entropy across distributions with different\n * numbers of possible values.\n *\n * @param probabilities - Array of probabilities (should sum to 1)\n * @returns Normalised entropy in [0, 1], or 0 if only one category\n */\nexport function normalisedEntropy(probabilities: readonly number[]): number {\n\tif (probabilities.length <= 1) {\n\t\treturn 0;\n\t}\n\n\tconst H = shannonEntropy(probabilities);\n\tconst Hmax = Math.log2(probabilities.length);\n\n\tif (Hmax === 0) {\n\t\treturn 0;\n\t}\n\n\treturn H / Hmax;\n}\n\n/**\n * Compute entropy from a frequency count.\n *\n * Converts counts to probabilities and then computes entropy.\n * This is a convenience function when you have raw counts rather than\n * normalised probabilities.\n *\n * @param counts - Array of frequency counts\n * @returns Entropy in bits\n */\nexport function entropyFromCounts(counts: readonly number[]): number {\n\tif (counts.length === 0) {\n\t\treturn 0;\n\t}\n\n\tconst total = counts.reduce((sum, c) => sum + c, 0);\n\tif (total === 0) {\n\t\treturn 0;\n\t}\n\n\tconst probabilities = counts.map((c) => c / total);\n\treturn shannonEntropy(probabilities);\n}\n\n/**\n * Compute local type entropy for a node's neighbours.\n *\n * This measures the diversity of types among a node's neighbours.\n * High entropy = heterogeneous neighbourhood (diverse types).\n * Low entropy = homogeneous neighbourhood (similar types).\n *\n * @param neighbourTypes - Array of type labels for neighbours\n * @returns Normalised entropy in [0, 1]\n */\nexport function localTypeEntropy(neighbourTypes: readonly string[]): number {\n\tif (neighbourTypes.length <= 1) {\n\t\treturn 0;\n\t}\n\n\t// Count occurrences of each type\n\tconst typeCounts = new Map<string, number>();\n\tfor (const t of neighbourTypes) {\n\t\ttypeCounts.set(t, (typeCounts.get(t) ?? 0) + 1);\n\t}\n\n\t// If all neighbours are the same type, entropy is 0\n\tif (typeCounts.size === 1) {\n\t\treturn 0;\n\t}\n\n\t// Convert to probability array\n\tconst probabilities: number[] = [];\n\tconst total = neighbourTypes.length;\n\tfor (const count of typeCounts.values()) {\n\t\tprobabilities.push(count / total);\n\t}\n\n\treturn normalisedEntropy(probabilities);\n}\n","/**\n * Clustering coefficient computation for graph nodes.\n *\n * The local clustering coefficient measures how close a node's neighbours\n * are to being a complete graph (clique). It is used in SPAN MI variant\n * and GRASP seed selection.\n *\n * @packageDocumentation\n */\n\nimport type { ReadableGraph, NodeId } from \"../graph\";\n\n/**\n * Compute the local clustering coefficient for a single node.\n *\n * The clustering coefficient is defined as:\n * CC(v) = (triangles through v) / (possible triangles)\n * CC(v) = 2 * |{(u,w) : u,w in N(v), (u,w) in E}| / (deg(v) * (deg(v) - 1))\n *\n * For nodes with degree < 2, the clustering coefficient is 0.\n *\n * @param graph - The graph to compute on\n * @param nodeId - The node to compute clustering coefficient for\n * @returns The clustering coefficient in [0, 1], or 0 if undefined\n */\nexport function localClusteringCoefficient(\n\tgraph: ReadableGraph,\n\tnodeId: NodeId,\n): number {\n\tconst neighbours = [...graph.neighbours(nodeId, \"both\")];\n\tconst degree = neighbours.length;\n\n\t// Nodes with degree < 2 have no possible triangles\n\tif (degree < 2) {\n\t\treturn 0;\n\t}\n\n\t// Count actual triangles: pairs of neighbours that are connected\n\tlet triangleCount = 0;\n\n\tfor (let i = 0; i < neighbours.length; i++) {\n\t\tconst u = neighbours[i];\n\t\tif (u === undefined) continue;\n\n\t\tfor (let j = i + 1; j < neighbours.length; j++) {\n\t\t\tconst w = neighbours[j];\n\t\t\tif (w === undefined) continue;\n\n\t\t\t// Check if u and w are connected\n\t\t\tif (\n\t\t\t\tgraph.getEdge(u, w) !== undefined ||\n\t\t\t\tgraph.getEdge(w, u) !== undefined\n\t\t\t) {\n\t\t\t\ttriangleCount++;\n\t\t\t}\n\t\t}\n\t}\n\n\t// Possible triangles: deg * (deg - 1) / 2 pairs\n\t// We multiply by 2 because each triangle is counted once\n\tconst possibleTriangles = (degree * (degree - 1)) / 2;\n\n\treturn triangleCount / possibleTriangles;\n}\n\n/**\n * Compute approximate local clustering coefficient using sampling.\n *\n * For nodes with many neighbours, this samples neighbour pairs rather than\n * checking all pairs. Useful for large graphs where exact computation is expensive.\n *\n * @param graph - The graph to compute on\n * @param nodeId - The node to compute clustering coefficient for\n * @param sampleSize - Maximum number of neighbour pairs to check (default: 100)\n * @returns The approximate clustering coefficient in [0, 1]\n */\nexport function approximateClusteringCoefficient(\n\tgraph: ReadableGraph,\n\tnodeId: NodeId,\n\tsampleSize = 100,\n): number {\n\tconst neighbours = [...graph.neighbours(nodeId, \"both\")];\n\tconst degree = neighbours.length;\n\n\tif (degree < 2) {\n\t\treturn 0;\n\t}\n\n\tconst possibleTriangles = (degree * (degree - 1)) / 2;\n\n\t// If all pairs can be checked within sample limit, use exact computation\n\tif (possibleTriangles <= sampleSize) {\n\t\treturn localClusteringCoefficient(graph, nodeId);\n\t}\n\n\t// Sample pairs uniformly\n\tlet triangleCount = 0;\n\tlet sampled = 0;\n\n\t// Use reservoir sampling style approach for pair selection\n\tfor (let i = 0; i < neighbours.length && sampled < sampleSize; i++) {\n\t\tconst u = neighbours[i];\n\t\tif (u === undefined) continue;\n\n\t\tfor (let j = i + 1; j < neighbours.length && sampled < sampleSize; j++) {\n\t\t\tconst w = neighbours[j];\n\t\t\tif (w === undefined) continue;\n\n\t\t\t// Decide whether to include this pair based on remaining budget\n\t\t\tsampled++;\n\n\t\t\t// Check if u and w are connected\n\t\t\tif (\n\t\t\t\tgraph.getEdge(u, w) !== undefined ||\n\t\t\t\tgraph.getEdge(w, u) !== undefined\n\t\t\t) {\n\t\t\t\ttriangleCount++;\n\t\t\t}\n\t\t}\n\t}\n\n\t// Extrapolate from sample\n\treturn triangleCount / sampled;\n}\n\n/**\n * Compute clustering coefficients for multiple nodes efficiently.\n *\n * Reuses neighbour sets to avoid repeated iteration.\n *\n * @param graph - The graph to compute on\n * @param nodeIds - The nodes to compute clustering coefficients for\n * @returns Map from nodeId to clustering coefficient\n */\nexport function batchClusteringCoefficients(\n\tgraph: ReadableGraph,\n\tnodeIds: readonly NodeId[],\n): Map<NodeId, number> {\n\tconst results = new Map<NodeId, number>();\n\n\tfor (const nodeId of nodeIds) {\n\t\tresults.set(nodeId, localClusteringCoefficient(graph, nodeId));\n\t}\n\n\treturn results;\n}\n","/**\n * Neighbourhood computation utilities.\n *\n * Shared utilities for neighbourhood operations used by MI variants and other graph algorithms.\n * These functions eliminate duplication of neighbourhood set operations across multiple\n * implementations.\n *\n * @packageDocumentation\n */\n\nimport type { NodeId, NodeData, EdgeData, ReadableGraph } from \"../graph\";\n\n/**\n * Result of a Jaccard computation, including the intermediate neighbourhood sets.\n *\n * Carrying the neighbourhood sets avoids recomputing them in MI variants that need\n * both the Jaccard score and the raw sets (e.g. for overlap coefficient or intersection).\n */\nexport interface JaccardResult {\n\treadonly jaccard: number;\n\treadonly sourceNeighbours: ReadonlySet<NodeId>;\n\treadonly targetNeighbours: ReadonlySet<NodeId>;\n}\n\n/**\n * Compute Jaccard similarity between the neighbourhoods of two nodes.\n *\n * Each endpoint is excluded from the other's neighbourhood set to avoid\n * the direct edge inflating the overlap score.\n *\n * @param graph - The graph to traverse\n * @param source - Source node ID\n * @param target - Target node ID\n * @returns JaccardResult containing the score and both neighbourhood sets\n */\nexport function computeJaccard<N extends NodeData, E extends EdgeData>(\n\tgraph: ReadableGraph<N, E>,\n\tsource: NodeId,\n\ttarget: NodeId,\n): JaccardResult {\n\tconst sourceNeighbours = neighbourSet(graph, source, target);\n\tconst targetNeighbours = neighbourSet(graph, target, source);\n\tconst { intersection, union } = neighbourOverlap(\n\t\tsourceNeighbours,\n\t\ttargetNeighbours,\n\t);\n\treturn {\n\t\tjaccard: union > 0 ? intersection / union : 0,\n\t\tsourceNeighbours,\n\t\ttargetNeighbours,\n\t};\n}\n\n/**\n * Collect neighbours into a Set, optionally excluding a specific node.\n *\n * @param graph - The graph to traverse\n * @param nodeId - The source node\n * @param exclude - Optional node ID to exclude from result\n * @returns A ReadonlySet of neighbouring node IDs\n */\nexport function neighbourSet<N extends NodeData, E extends EdgeData>(\n\tgraph: ReadableGraph<N, E>,\n\tnodeId: NodeId,\n\texclude?: NodeId,\n): ReadonlySet<NodeId> {\n\tconst neighbours = new Set(graph.neighbours(nodeId));\n\tif (exclude !== undefined) {\n\t\tneighbours.delete(exclude);\n\t}\n\treturn neighbours;\n}\n\n/**\n * Compute intersection and union sizes of two neighbour sets without allocating the union set.\n *\n * This is more efficient than computing both separately, as it avoids creating a full union Set.\n *\n * @param a - First neighbourhood set\n * @param b - Second neighbourhood set\n * @returns Object with intersection and union sizes\n */\nexport function neighbourOverlap(\n\ta: ReadonlySet<NodeId>,\n\tb: ReadonlySet<NodeId>,\n): { intersection: number; union: number } {\n\tlet intersection = 0;\n\n\t// Count intersection by iterating through the smaller set\n\tconst [smaller, larger] = a.size < b.size ? [a, b] : [b, a];\n\n\tfor (const node of smaller) {\n\t\tif (larger.has(node)) {\n\t\t\tintersection++;\n\t\t}\n\t}\n\n\t// Union size = size(a) + size(b) - intersection\n\tconst union = a.size + b.size - intersection;\n\n\treturn { intersection, union };\n}\n\n/**\n * Return the actual intersection set of two neighbourhood sets.\n *\n * Needed by Adamic-Adar (iterates common neighbours) and ETCH (requires edge types of intersection edges).\n *\n * @param a - First neighbourhood set\n * @param b - Second neighbourhood set\n * @returns A ReadonlySet containing nodes in both a and b\n */\nexport function neighbourIntersection(\n\ta: ReadonlySet<NodeId>,\n\tb: ReadonlySet<NodeId>,\n): ReadonlySet<NodeId> {\n\tconst intersection = new Set<NodeId>();\n\n\t// Iterate through the smaller set for efficiency\n\tconst [smaller, larger] = a.size < b.size ? [a, b] : [b, a];\n\n\tfor (const node of smaller) {\n\t\tif (larger.has(node)) {\n\t\t\tintersection.add(node);\n\t\t}\n\t}\n\n\treturn intersection;\n}\n\n/**\n * Count the number of edges with a specific type in the graph.\n *\n * Used by ETCH MI variant to compute edge rarity weighting.\n *\n * @param graph - The graph to count edges in\n * @param type - The edge type to count\n * @returns The number of edges with the specified type\n */\nexport function countEdgesOfType<N extends NodeData, E extends EdgeData>(\n\tgraph: ReadableGraph<N, E>,\n\ttype: string,\n): number {\n\tlet count = 0;\n\tfor (const edge of graph.edges()) {\n\t\tif (edge.type === type) {\n\t\t\tcount++;\n\t\t}\n\t}\n\treturn count;\n}\n\n/**\n * Count the number of nodes with a specific type in the graph.\n *\n * Used by NOTCH MI variant to compute node rarity weighting.\n *\n * @param graph - The graph to count nodes in\n * @param type - The node type to count\n * @returns The number of nodes with the specified type\n */\nexport function countNodesOfType<N extends NodeData, E extends EdgeData>(\n\tgraph: ReadableGraph<N, E>,\n\ttype: string,\n): number {\n\tlet count = 0;\n\tfor (const nodeId of graph.nodeIds()) {\n\t\tconst node = graph.getNode(nodeId);\n\t\tif (node?.type === type) {\n\t\t\tcount++;\n\t\t}\n\t}\n\treturn count;\n}\n"],"mappings":"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"}
@@ -161,6 +161,27 @@ function batchClusteringCoefficients(graph, nodeIds) {
161
161
  //#endregion
162
162
  //#region src/utils/neighbours.ts
163
163
  /**
164
+ * Compute Jaccard similarity between the neighbourhoods of two nodes.
165
+ *
166
+ * Each endpoint is excluded from the other's neighbourhood set to avoid
167
+ * the direct edge inflating the overlap score.
168
+ *
169
+ * @param graph - The graph to traverse
170
+ * @param source - Source node ID
171
+ * @param target - Target node ID
172
+ * @returns JaccardResult containing the score and both neighbourhood sets
173
+ */
174
+ function computeJaccard(graph, source, target) {
175
+ const sourceNeighbours = neighbourSet(graph, source, target);
176
+ const targetNeighbours = neighbourSet(graph, target, source);
177
+ const { intersection, union } = neighbourOverlap(sourceNeighbours, targetNeighbours);
178
+ return {
179
+ jaccard: union > 0 ? intersection / union : 0,
180
+ sourceNeighbours,
181
+ targetNeighbours
182
+ };
183
+ }
184
+ /**
164
185
  * Collect neighbours into a Set, optionally excluding a specific node.
165
186
  *
166
187
  * @param graph - The graph to traverse
@@ -236,6 +257,6 @@ function countNodesOfType(graph, type) {
236
257
  return count;
237
258
  }
238
259
  //#endregion
239
- export { _computeMean, approximateClusteringCoefficient, batchClusteringCoefficients, countEdgesOfType, countNodesOfType, entropyFromCounts, localClusteringCoefficient, localTypeEntropy, miniBatchKMeans, neighbourIntersection, neighbourOverlap, neighbourSet, normaliseFeatures, normaliseFeatures as zScoreNormalise, normalisedEntropy, shannonEntropy };
260
+ export { _computeMean, approximateClusteringCoefficient, batchClusteringCoefficients, computeJaccard, countEdgesOfType, countNodesOfType, entropyFromCounts, localClusteringCoefficient, localTypeEntropy, miniBatchKMeans, neighbourIntersection, neighbourOverlap, neighbourSet, normaliseFeatures, normaliseFeatures as zScoreNormalise, normalisedEntropy, shannonEntropy };
240
261
 
241
262
  //# sourceMappingURL=index.js.map