graphwise 1.10.0 → 1.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. package/README.md +1 -1
  2. package/dist/gpu/index.cjs +1 -1
  3. package/dist/gpu/index.js +1 -1
  4. package/dist/index/index.cjs +11 -3
  5. package/dist/index/index.js +4 -4
  6. package/dist/{kernel-CigCjrts.js → kernel-BLwhyVSV.js} +1 -1
  7. package/dist/{kernel-CigCjrts.js.map → kernel-BLwhyVSV.js.map} +1 -1
  8. package/dist/{kernel-2oH4Cn32.cjs → kernel-BffKjhZS.cjs} +1 -1
  9. package/dist/{kernel-2oH4Cn32.cjs.map → kernel-BffKjhZS.cjs.map} +1 -1
  10. package/dist/{kernel-CXeGBH3s.cjs → kernel-CbP715Sq.cjs} +1 -1
  11. package/dist/{kernel-CXeGBH3s.cjs.map → kernel-CbP715Sq.cjs.map} +1 -1
  12. package/dist/{kernel-CvnRsF7E.js → kernel-DolEKSSx.js} +1 -1
  13. package/dist/{kernel-CvnRsF7E.js.map → kernel-DolEKSSx.js.map} +1 -1
  14. package/dist/{kernel-DukrXtVb.cjs → kernel-E_h47HjZ.cjs} +1 -1
  15. package/dist/{kernel-DukrXtVb.cjs.map → kernel-E_h47HjZ.cjs.map} +1 -1
  16. package/dist/{kernel-6deK9fh1.js → kernel-lYa4TYth.js} +1 -1
  17. package/dist/{kernel-6deK9fh1.js.map → kernel-lYa4TYth.js.map} +1 -1
  18. package/dist/{operations-D-RB67WP.cjs → operations-CSU0yFPr.cjs} +4 -4
  19. package/dist/{operations-D-RB67WP.cjs.map → operations-CSU0yFPr.cjs.map} +1 -1
  20. package/dist/{operations-D9otVlIH.js → operations-CdrA87Au.js} +4 -4
  21. package/dist/{operations-D9otVlIH.js.map → operations-CdrA87Au.js.map} +1 -1
  22. package/dist/ranking/index.cjs +1 -1
  23. package/dist/ranking/index.js +1 -1
  24. package/dist/{ranking-pe5UaxKg.cjs → ranking-BQqrH26-.cjs} +2 -2
  25. package/dist/{ranking-pe5UaxKg.cjs.map → ranking-BQqrH26-.cjs.map} +1 -1
  26. package/dist/{ranking-DOKDBcIR.js → ranking-B_KdM8Wq.js} +2 -2
  27. package/dist/{ranking-DOKDBcIR.js.map → ranking-B_KdM8Wq.js.map} +1 -1
  28. package/dist/seeds/basil.d.ts +12 -0
  29. package/dist/seeds/basil.d.ts.map +1 -0
  30. package/dist/seeds/brisk.d.ts +18 -0
  31. package/dist/seeds/brisk.d.ts.map +1 -0
  32. package/dist/seeds/crest.d.ts +48 -0
  33. package/dist/seeds/crest.d.ts.map +1 -0
  34. package/dist/seeds/crest.unit.test.d.ts +2 -0
  35. package/dist/seeds/crest.unit.test.d.ts.map +1 -0
  36. package/dist/seeds/crisp.d.ts +57 -0
  37. package/dist/seeds/crisp.d.ts.map +1 -0
  38. package/dist/seeds/crisp.unit.test.d.ts +2 -0
  39. package/dist/seeds/crisp.unit.test.d.ts.map +1 -0
  40. package/dist/seeds/hybrid-core.d.ts +32 -0
  41. package/dist/seeds/hybrid-core.d.ts.map +1 -0
  42. package/dist/seeds/hybrid-ensembles.unit.test.d.ts +2 -0
  43. package/dist/seeds/hybrid-ensembles.unit.test.d.ts.map +1 -0
  44. package/dist/seeds/index.cjs +11 -398
  45. package/dist/seeds/index.d.ts +8 -0
  46. package/dist/seeds/index.d.ts.map +1 -1
  47. package/dist/seeds/index.js +2 -397
  48. package/dist/seeds/omnia.d.ts +12 -0
  49. package/dist/seeds/omnia.d.ts.map +1 -0
  50. package/dist/seeds/prism.d.ts +12 -0
  51. package/dist/seeds/prism.d.ts.map +1 -0
  52. package/dist/seeds/spine.d.ts +50 -0
  53. package/dist/seeds/spine.d.ts.map +1 -0
  54. package/dist/seeds/spine.unit.test.d.ts +2 -0
  55. package/dist/seeds/spine.unit.test.d.ts.map +1 -0
  56. package/dist/seeds/stride.d.ts +55 -0
  57. package/dist/seeds/stride.d.ts.map +1 -0
  58. package/dist/seeds/stride.unit.test.d.ts +2 -0
  59. package/dist/seeds/stride.unit.test.d.ts.map +1 -0
  60. package/dist/seeds--fLhoBaG.cjs +1762 -0
  61. package/dist/seeds--fLhoBaG.cjs.map +1 -0
  62. package/dist/seeds-ihozTw4J.js +1703 -0
  63. package/dist/seeds-ihozTw4J.js.map +1 -0
  64. package/package.json +1 -1
  65. package/dist/seeds/index.cjs.map +0 -1
  66. package/dist/seeds/index.js.map +0 -1
@@ -1,397 +1,2 @@
1
- import { n as miniBatchKMeans, r as normaliseFeatures } from "../kmeans-DLrlrp6i.js";
2
- //#region src/seeds/grasp.ts
3
- /** Default configuration values */
4
- var DEFAULTS$1 = {
5
- nClusters: 100,
6
- pairsPerCluster: 10,
7
- withinClusterRatio: .5,
8
- sampleSize: 2e5,
9
- rngSeed: 42,
10
- pagerankIterations: 10
11
- };
12
- /**
13
- * Simple seeded pseudo-random number generator using mulberry32.
14
- */
15
- function createRNG$1(seed) {
16
- let state = seed >>> 0;
17
- return () => {
18
- state = state + 1831565813 >>> 0;
19
- let t = Math.imul(state ^ state >>> 15, state | 1);
20
- t = (t ^ t >>> 7) * (t | 1640531527);
21
- return ((t ^ t >>> 14) >>> 0) / 4294967296;
22
- };
23
- }
24
- /**
25
- * Reservoir sampling (Vitter's Algorithm R) for streaming node selection.
26
- *
27
- * Maintains a uniform sample of nodes as edges are streamed, without
28
- * requiring the full graph in memory.
29
- */
30
- function reservoirSample(graph, sampleSize, rng) {
31
- const reservoir = [];
32
- const neighbourMap = /* @__PURE__ */ new Map();
33
- const inReservoir = /* @__PURE__ */ new Set();
34
- let nodesSeen = 0;
35
- for (const edge of graph.edges()) {
36
- const source = edge.source;
37
- if (!inReservoir.has(source)) {
38
- nodesSeen++;
39
- if (reservoir.length < sampleSize) {
40
- reservoir.push(source);
41
- inReservoir.add(source);
42
- neighbourMap.set(source, /* @__PURE__ */ new Set());
43
- } else {
44
- const j = Math.floor(rng() * nodesSeen);
45
- if (j < sampleSize) {
46
- const oldNode = reservoir[j];
47
- if (oldNode !== void 0) {
48
- inReservoir.delete(oldNode);
49
- neighbourMap.delete(oldNode);
50
- }
51
- reservoir[j] = source;
52
- inReservoir.add(source);
53
- neighbourMap.set(source, /* @__PURE__ */ new Set());
54
- }
55
- }
56
- }
57
- const target = edge.target;
58
- if (!inReservoir.has(target)) {
59
- nodesSeen++;
60
- if (reservoir.length < sampleSize) {
61
- reservoir.push(target);
62
- inReservoir.add(target);
63
- neighbourMap.set(target, /* @__PURE__ */ new Set());
64
- } else {
65
- const j = Math.floor(rng() * nodesSeen);
66
- if (j < sampleSize) {
67
- const oldNode = reservoir[j];
68
- if (oldNode !== void 0) {
69
- inReservoir.delete(oldNode);
70
- neighbourMap.delete(oldNode);
71
- }
72
- reservoir[j] = target;
73
- inReservoir.add(target);
74
- neighbourMap.set(target, /* @__PURE__ */ new Set());
75
- }
76
- }
77
- }
78
- if (inReservoir.has(source) && inReservoir.has(target)) {
79
- const sourceNeighbours = neighbourMap.get(source);
80
- const targetNeighbours = neighbourMap.get(target);
81
- sourceNeighbours?.add(target);
82
- targetNeighbours?.add(source);
83
- }
84
- }
85
- return {
86
- nodeIds: inReservoir,
87
- neighbourMap
88
- };
89
- }
90
- /**
91
- * Compute approximate PageRank scores using power iteration on the reservoir subgraph.
92
- *
93
- * This is an approximation since it only considers the sampled nodes and their
94
- * connections within the reservoir, not the full graph.
95
- */
96
- function approximatePageRank(nodeIds, neighbourMap, iterations, dampingFactor = .85) {
97
- const n = nodeIds.size;
98
- if (n === 0) return /* @__PURE__ */ new Map();
99
- const nodeIdList = [...nodeIds];
100
- const nodeIndex = new Map(nodeIdList.map((id, i) => [id, i]));
101
- const scores = new Float64Array(n).fill(1 / n);
102
- const newScores = new Float64Array(n);
103
- for (let iter = 0; iter < iterations; iter++) {
104
- newScores.fill((1 - dampingFactor) / n);
105
- for (let i = 0; i < n; i++) {
106
- const nodeId = nodeIdList[i];
107
- if (nodeId === void 0) continue;
108
- const neighbours = neighbourMap.get(nodeId);
109
- if (neighbours === void 0) continue;
110
- const outDegree = neighbours.size;
111
- if (outDegree === 0) continue;
112
- const contribution = dampingFactor * (scores[i] ?? 0) / outDegree;
113
- for (const neighbour of neighbours) {
114
- const neighbourIdx = nodeIndex.get(neighbour);
115
- if (neighbourIdx !== void 0) newScores[neighbourIdx] = (newScores[neighbourIdx] ?? 0) + contribution;
116
- }
117
- }
118
- for (let i = 0; i < n; i++) scores[i] = newScores[i] ?? 0;
119
- }
120
- const result = /* @__PURE__ */ new Map();
121
- for (let i = 0; i < n; i++) {
122
- const nodeId = nodeIdList[i];
123
- const score = scores[i];
124
- if (nodeId !== void 0 && score !== void 0) result.set(nodeId, score);
125
- }
126
- return result;
127
- }
128
- /**
129
- * Compute structural features for sampled nodes.
130
- *
131
- * Features:
132
- * - f1: log(deg(v) + 1) — scale-normalised connectivity
133
- * - f2: clustering_coefficient(v) — local density
134
- * - f3: approx_pagerank(v) — positional importance
135
- */
136
- function computeFeatures(graph, nodeIds, neighbourMap, pagerankScores) {
137
- const features = [];
138
- for (const nodeId of nodeIds) {
139
- const degree = graph.degree(nodeId, "both");
140
- const neighbours = neighbourMap.get(nodeId);
141
- let clusteringCoef = 0;
142
- if (neighbours !== void 0 && neighbours.size >= 2) {
143
- let triangleCount = 0;
144
- const neighbourList = [...neighbours];
145
- for (let i = 0; i < neighbourList.length; i++) for (let j = i + 1; j < neighbourList.length; j++) {
146
- const u = neighbourList[i];
147
- const w = neighbourList[j];
148
- if (u !== void 0 && w !== void 0) {
149
- if (neighbourMap.get(u)?.has(w) === true) triangleCount++;
150
- }
151
- }
152
- const possibleTriangles = degree * (degree - 1) / 2;
153
- clusteringCoef = triangleCount / possibleTriangles;
154
- }
155
- const pagerank = pagerankScores.get(nodeId) ?? 0;
156
- features.push({
157
- nodeId,
158
- f1: Math.log(degree + 1),
159
- f2: clusteringCoef,
160
- f3: pagerank
161
- });
162
- }
163
- return features;
164
- }
165
- /**
166
- * Sample seed pairs from clusters.
167
- *
168
- * For each cluster, samples a mix of within-cluster and cross-cluster pairs.
169
- */
170
- function samplePairs(features, clusterAssignments, nClusters, pairsPerCluster, withinClusterRatio, rng) {
171
- const pairs = [];
172
- const clusterNodes = /* @__PURE__ */ new Map();
173
- for (const feature of features) {
174
- const cluster = clusterAssignments.get(feature.nodeId);
175
- if (cluster === void 0) continue;
176
- let nodes = clusterNodes.get(cluster);
177
- if (nodes === void 0) {
178
- nodes = [];
179
- clusterNodes.set(cluster, nodes);
180
- }
181
- nodes.push(feature);
182
- }
183
- const withinCount = Math.floor(pairsPerCluster * withinClusterRatio);
184
- const crossCount = pairsPerCluster - withinCount;
185
- for (let clusterIdx = 0; clusterIdx < nClusters; clusterIdx++) {
186
- const nodes = clusterNodes.get(clusterIdx);
187
- if (nodes === void 0 || nodes.length < 2) continue;
188
- for (let i = 0; i < withinCount; i++) {
189
- const idx1 = Math.floor(rng() * nodes.length);
190
- let idx2 = Math.floor(rng() * nodes.length);
191
- while (idx1 === idx2) idx2 = Math.floor(rng() * nodes.length);
192
- const source = nodes[idx1];
193
- const target = nodes[idx2];
194
- if (source === void 0 || target === void 0) continue;
195
- const distance = computeFeatureDistance(source, target);
196
- pairs.push({
197
- source: { id: source.nodeId },
198
- target: { id: target.nodeId },
199
- featureDistance: distance,
200
- sameCluster: true,
201
- sourceCluster: clusterIdx,
202
- targetCluster: clusterIdx
203
- });
204
- }
205
- for (let i = 0; i < crossCount; i++) {
206
- const source = nodes[Math.floor(rng() * nodes.length)];
207
- if (source === void 0) continue;
208
- const otherClusterIdx = Math.floor(rng() * nClusters);
209
- if (otherClusterIdx === clusterIdx) continue;
210
- const otherNodes = clusterNodes.get(otherClusterIdx);
211
- if (otherNodes === void 0 || otherNodes.length === 0) continue;
212
- const target = otherNodes[Math.floor(rng() * otherNodes.length)];
213
- if (target === void 0) continue;
214
- const distance = computeFeatureDistance(source, target);
215
- pairs.push({
216
- source: { id: source.nodeId },
217
- target: { id: target.nodeId },
218
- featureDistance: distance,
219
- sameCluster: false,
220
- sourceCluster: clusterIdx,
221
- targetCluster: otherClusterIdx
222
- });
223
- }
224
- }
225
- return pairs;
226
- }
227
- /**
228
- * Compute Euclidean distance between two feature vectors.
229
- */
230
- function computeFeatureDistance(a, b) {
231
- const d1 = a.f1 - b.f1;
232
- const d2 = a.f2 - b.f2;
233
- const d3 = a.f3 - b.f3;
234
- return Math.sqrt(d1 * d1 + d2 * d2 + d3 * d3);
235
- }
236
- /**
237
- * GRASP — Graph-agnostic Representative Seed pAir Sampling.
238
- *
239
- * Selects structurally representative seed pairs without domain knowledge.
240
- * The algorithm streams edges, samples nodes via reservoir sampling, computes
241
- * structural features, clusters nodes, and samples pairs within/across clusters.
242
- *
243
- * @param graph - The graph to sample seeds from
244
- * @param options - Configuration options
245
- * @returns Sampled seed pairs with structural metadata
246
- *
247
- * @example
248
- * ```typescript
249
- * const graph = new AdjacencyMapGraph();
250
- * // ... populate graph ...
251
- *
252
- * const result = grasp(graph, {
253
- * nClusters: 50,
254
- * pairsPerCluster: 20,
255
- * sampleSize: 100000,
256
- * });
257
- *
258
- * console.log(`Sampled ${result.pairs.length} pairs from ${result.sampledNodeCount} nodes`);
259
- * ```
260
- */
261
- function grasp(graph, options = {}) {
262
- const config = {
263
- ...DEFAULTS$1,
264
- ...options
265
- };
266
- const rng = createRNG$1(config.rngSeed);
267
- const { nodeIds, neighbourMap } = reservoirSample(graph, config.sampleSize, rng);
268
- let features = computeFeatures(graph, nodeIds, neighbourMap, approximatePageRank(nodeIds, neighbourMap, config.pagerankIterations));
269
- if (features.length > 0) features = normaliseFeatures(features);
270
- const k = Math.min(config.nClusters, features.length);
271
- const kmeansResult = miniBatchKMeans(features, {
272
- k,
273
- seed: config.rngSeed,
274
- maxIterations: 100
275
- });
276
- return {
277
- pairs: samplePairs(features, kmeansResult.assignments, kmeansResult.k, config.pairsPerCluster, config.withinClusterRatio, rng),
278
- nClusters: kmeansResult.k,
279
- sampledNodeCount: nodeIds.size,
280
- features,
281
- clusterAssignments: kmeansResult.assignments
282
- };
283
- }
284
- //#endregion
285
- //#region src/seeds/stratified.ts
286
- /** Default values */
287
- var DEFAULTS = {
288
- pairsPerStratum: 10,
289
- rngSeed: 42
290
- };
291
- /**
292
- * Simple seeded pseudo-random number generator using mulberry32.
293
- */
294
- function createRNG(seed) {
295
- let state = seed >>> 0;
296
- return () => {
297
- state = state + 1831565813 >>> 0;
298
- let t = Math.imul(state ^ state >>> 15, state | 1);
299
- t = (t ^ t >>> 7) * (t | 1640531527);
300
- return ((t ^ t >>> 14) >>> 0) / 4294967296;
301
- };
302
- }
303
- /**
304
- * Stratified seed selection algorithm.
305
- *
306
- * @param graph - The graph to sample seeds from
307
- * @param options - Configuration options including field classifier
308
- * @returns Stratified selection result
309
- *
310
- * @example
311
- * ```typescript
312
- * const graph = new AdjacencyMapGraph();
313
- * // ... populate graph ...
314
- *
315
- * const result = stratified(graph, {
316
- * fieldClassifier: (node) => node.type === 'paper' ? 'computer-science' : undefined,
317
- * pairsPerStratum: 20,
318
- * });
319
- *
320
- * for (const stratum of result.strata) {
321
- * console.log(`${stratum.name}: ${stratum.pairs.length} pairs`);
322
- * }
323
- * ```
324
- */
325
- function stratified(graph, options) {
326
- const { fieldClassifier, pairsPerStratum = DEFAULTS.pairsPerStratum, rngSeed = DEFAULTS.rngSeed, customStrata } = options;
327
- const rng = createRNG(rngSeed);
328
- const strataDefinitions = customStrata ?? [];
329
- const nodesWithFields = [];
330
- for (const nodeId of graph.nodeIds()) {
331
- const node = graph.getNode(nodeId);
332
- if (node === void 0) continue;
333
- const field = fieldClassifier(node.type !== void 0 ? {
334
- id: nodeId,
335
- type: node.type
336
- } : { id: nodeId });
337
- if (field === void 0) continue;
338
- const nodeWithField = node.type !== void 0 ? {
339
- id: nodeId,
340
- type: node.type,
341
- field
342
- } : {
343
- id: nodeId,
344
- field
345
- };
346
- nodesWithFields.push(nodeWithField);
347
- }
348
- const errors = [];
349
- const strataResults = [];
350
- for (const stratum of strataDefinitions) {
351
- const pairs = [];
352
- const eligiblePairs = [];
353
- for (let i = 0; i < nodesWithFields.length; i++) {
354
- const source = nodesWithFields[i];
355
- if (source === void 0) continue;
356
- for (let j = i + 1; j < nodesWithFields.length; j++) {
357
- if (j === i) continue;
358
- const target = nodesWithFields[j];
359
- if (target === void 0) continue;
360
- if (stratum.predicate(source, target)) eligiblePairs.push({
361
- source,
362
- target
363
- });
364
- }
365
- }
366
- const numToSample = Math.min(pairsPerStratum, eligiblePairs.length);
367
- for (let i = 0; i < numToSample; i++) {
368
- const pair = eligiblePairs[Math.floor(rng() * eligiblePairs.length)];
369
- if (pair === void 0) continue;
370
- const sourceField = fieldClassifier(pair.source);
371
- const targetField = fieldClassifier(pair.target);
372
- pairs.push({
373
- source: { id: pair.source.id },
374
- target: { id: pair.target.id },
375
- stratum: stratum.name,
376
- sameField: sourceField === targetField
377
- });
378
- }
379
- strataResults.push({
380
- name: stratum.name,
381
- pairs
382
- });
383
- }
384
- for (const stratum of strataDefinitions) {
385
- const result = strataResults.find((r) => r.name === stratum.name);
386
- if (result === void 0 || result.pairs.length === 0) errors.push(/* @__PURE__ */ new Error(`No pairs found for stratum: ${stratum.name}`));
387
- }
388
- return {
389
- strata: strataResults,
390
- totalPairs: strataResults.reduce((sum, r) => sum + r.pairs.length, 0),
391
- errors
392
- };
393
- }
394
- //#endregion
395
- export { grasp, stratified };
396
-
397
- //# sourceMappingURL=index.js.map
1
+ import { a as basil, c as grasp, i as brisk, l as crisp, n as prism, o as stride, r as omnia, s as spine, t as stratified, u as crest } from "../seeds-ihozTw4J.js";
2
+ export { basil, brisk, crest, crisp, grasp, omnia, prism, spine, stratified, stride };
@@ -0,0 +1,12 @@
1
+ import { ReadableGraph } from '../graph';
2
+ import { EnsemblePair } from './hybrid-core';
3
+ export interface OmniaOptions {
4
+ readonly nPairs?: number;
5
+ readonly rngSeed?: number;
6
+ readonly blindPriorityBias?: number;
7
+ }
8
+ export interface OmniaResult {
9
+ readonly pairs: readonly EnsemblePair[];
10
+ }
11
+ export declare function omnia(graph: ReadableGraph, options?: OmniaOptions): OmniaResult;
12
+ //# sourceMappingURL=omnia.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"omnia.d.ts","sourceRoot":"","sources":["../../src/seeds/omnia.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAI9C,OAAO,EAMN,KAAK,YAAY,EACjB,MAAM,eAAe,CAAC;AAIvB,MAAM,WAAW,YAAY;IAC5B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,iBAAiB,CAAC,EAAE,MAAM,CAAC;CACpC;AAED,MAAM,WAAW,WAAW;IAC3B,QAAQ,CAAC,KAAK,EAAE,SAAS,YAAY,EAAE,CAAC;CACxC;AAQD,wBAAgB,KAAK,CACpB,KAAK,EAAE,aAAa,EACpB,OAAO,GAAE,YAAiB,GACxB,WAAW,CAqEb"}
@@ -0,0 +1,12 @@
1
+ import { ReadableGraph } from '../graph';
2
+ import { EnsemblePair } from './hybrid-core';
3
+ export interface PrismOptions {
4
+ readonly nPairs?: number;
5
+ readonly rngSeed?: number;
6
+ readonly blindPriorityBias?: number;
7
+ }
8
+ export interface PrismResult {
9
+ readonly pairs: readonly EnsemblePair[];
10
+ }
11
+ export declare function prism(graph: ReadableGraph, options?: PrismOptions): PrismResult;
12
+ //# sourceMappingURL=prism.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prism.d.ts","sourceRoot":"","sources":["../../src/seeds/prism.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAI9C,OAAO,EAKN,KAAK,YAAY,EACjB,MAAM,eAAe,CAAC;AAIvB,MAAM,WAAW,YAAY;IAC5B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,iBAAiB,CAAC,EAAE,MAAM,CAAC;CACpC;AAED,MAAM,WAAW,WAAW;IAC3B,QAAQ,CAAC,KAAK,EAAE,SAAS,YAAY,EAAE,CAAC;CACxC;AAQD,wBAAgB,KAAK,CACpB,KAAK,EAAE,aAAa,EACpB,OAAO,GAAE,YAAiB,GACxB,WAAW,CA+Db"}
@@ -0,0 +1,50 @@
1
+ import { ReadableGraph } from '../graph';
2
+ import { Seed } from '../schemas/index';
3
+ /**
4
+ * Configuration options for SPINE seed selection.
5
+ */
6
+ export interface SpineOptions {
7
+ /** Number of seed pairs to select (default: 100) */
8
+ readonly nPairs?: number;
9
+ /** Random seed for reproducibility (default: 42) */
10
+ readonly rngSeed?: number;
11
+ /** Jaccard diversity threshold for greedy selection (default: 0.5) */
12
+ readonly diversityThreshold?: number;
13
+ }
14
+ /**
15
+ * A seed pair selected by SPINE with skewness metadata.
16
+ */
17
+ export interface SpineSeedPair {
18
+ /** Source seed */
19
+ readonly source: Seed;
20
+ /** Target seed */
21
+ readonly target: Seed;
22
+ /** Skewness of source node's 2-hop degree distribution */
23
+ readonly sourceSkewness: number;
24
+ /** Skewness of target node's 2-hop degree distribution */
25
+ readonly targetSkewness: number;
26
+ }
27
+ /**
28
+ * Result of SPINE seed selection.
29
+ */
30
+ export interface SpineResult {
31
+ /** Selected seed pairs */
32
+ readonly pairs: readonly SpineSeedPair[];
33
+ /** Skewness scores for all nodes */
34
+ readonly skewness: ReadonlyMap<string, number>;
35
+ }
36
+ /**
37
+ * SPINE — Structural Position-Informed Node Extraction.
38
+ *
39
+ * Computes 2-hop degree distribution skewness for each node. Nodes with
40
+ * high positive skewness have structurally diverse neighbours (hub-periphery
41
+ * mix), while nodes with low skewness have uniform neighbours. Pairs
42
+ * connecting high-skewness and low-skewness nodes explore structurally
43
+ * varied terrain.
44
+ *
45
+ * @param graph - The graph to sample seeds from
46
+ * @param options - Configuration options
47
+ * @returns Selected seed pairs with skewness metadata
48
+ */
49
+ export declare function spine(graph: ReadableGraph, options?: SpineOptions): SpineResult;
50
+ //# sourceMappingURL=spine.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spine.d.ts","sourceRoot":"","sources":["../../src/seeds/spine.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAU,MAAM,UAAU,CAAC;AACtD,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAE7C;;GAEG;AACH,MAAM,WAAW,YAAY;IAC5B,oDAAoD;IACpD,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,oDAAoD;IACpD,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,sEAAsE;IACtE,QAAQ,CAAC,kBAAkB,CAAC,EAAE,MAAM,CAAC;CACrC;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC7B,kBAAkB;IAClB,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC;IACtB,kBAAkB;IAClB,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC;IACtB,0DAA0D;IAC1D,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,0DAA0D;IAC1D,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;CAChC;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC3B,0BAA0B;IAC1B,QAAQ,CAAC,KAAK,EAAE,SAAS,aAAa,EAAE,CAAC;IACzC,oCAAoC;IACpC,QAAQ,CAAC,QAAQ,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC/C;AA2DD;;;;;;;;;;;;GAYG;AACH,wBAAgB,KAAK,CACpB,KAAK,EAAE,aAAa,EACpB,OAAO,GAAE,YAAiB,GACxB,WAAW,CAqJb"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=spine.unit.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spine.unit.test.d.ts","sourceRoot":"","sources":["../../src/seeds/spine.unit.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,55 @@
1
+ import { ReadableGraph } from '../graph';
2
+ import { Seed } from '../schemas/index';
3
+ /**
4
+ * Configuration options for STRIDE seed selection.
5
+ */
6
+ export interface StrideOptions {
7
+ /** Number of seed pairs to select (default: 100) */
8
+ readonly nPairs?: number;
9
+ /** Random seed for reproducibility (default: 42) */
10
+ readonly rngSeed?: number;
11
+ /** Jaccard diversity threshold for greedy selection (default: 0.5) */
12
+ readonly diversityThreshold?: number;
13
+ }
14
+ /**
15
+ * A seed pair selected by STRIDE with triad metadata.
16
+ */
17
+ export interface StrideSeedPair {
18
+ /** Source seed */
19
+ readonly source: Seed;
20
+ /** Target seed */
21
+ readonly target: Seed;
22
+ /** Triad count of source node */
23
+ readonly sourceTriads: number;
24
+ /** Triad count of target node */
25
+ readonly targetTriads: number;
26
+ /** Category of source: "core" | "bridge" | "periphery" */
27
+ readonly sourceCategory: string;
28
+ /** Category of target: "core" | "bridge" | "periphery" */
29
+ readonly targetCategory: string;
30
+ }
31
+ /**
32
+ * Result of STRIDE seed selection.
33
+ */
34
+ export interface StrideResult {
35
+ /** Selected seed pairs */
36
+ readonly pairs: readonly StrideSeedPair[];
37
+ /** Triad counts for all nodes */
38
+ readonly triadCounts: ReadonlyMap<string, number>;
39
+ /** Category assignments */
40
+ readonly categories: ReadonlyMap<string, string>;
41
+ }
42
+ /**
43
+ * STRIDE — Shortest-TRIangle Diversity seed selection.
44
+ *
45
+ * Nodes are categorised by local triad count into core, bridge, and
46
+ * periphery. Pairs spanning different categories capture structural
47
+ * diversity: core-periphery pairs traverse community interiors to
48
+ * boundaries, bridge-bridge pairs span community gaps.
49
+ *
50
+ * @param graph - The graph to sample seeds from
51
+ * @param options - Configuration options
52
+ * @returns Selected seed pairs with triad metadata
53
+ */
54
+ export declare function stride(graph: ReadableGraph, options?: StrideOptions): StrideResult;
55
+ //# sourceMappingURL=stride.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stride.d.ts","sourceRoot":"","sources":["../../src/seeds/stride.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAU,MAAM,UAAU,CAAC;AACtD,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAE7C;;GAEG;AACH,MAAM,WAAW,aAAa;IAC7B,oDAAoD;IACpD,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,oDAAoD;IACpD,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,sEAAsE;IACtE,QAAQ,CAAC,kBAAkB,CAAC,EAAE,MAAM,CAAC;CACrC;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC9B,kBAAkB;IAClB,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC;IACtB,kBAAkB;IAClB,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC;IACtB,iCAAiC;IACjC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,iCAAiC;IACjC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,0DAA0D;IAC1D,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,0DAA0D;IAC1D,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;CAChC;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC5B,0BAA0B;IAC1B,QAAQ,CAAC,KAAK,EAAE,SAAS,cAAc,EAAE,CAAC;IAC1C,iCAAiC;IACjC,QAAQ,CAAC,WAAW,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAClD,2BAA2B;IAC3B,QAAQ,CAAC,UAAU,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACjD;AAqED;;;;;;;;;;;GAWG;AACH,wBAAgB,MAAM,CACrB,KAAK,EAAE,aAAa,EACpB,OAAO,GAAE,aAAkB,GACzB,YAAY,CAkJd"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=stride.unit.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stride.unit.test.d.ts","sourceRoot":"","sources":["../../src/seeds/stride.unit.test.ts"],"names":[],"mappings":""}