@graphty/algorithms 2.0.6 → 2.1.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 (75) hide show
  1. package/README.md +9 -11
  2. package/dist/algorithms.js +499 -30
  3. package/dist/algorithms.js.map +1 -1
  4. package/dist/algorithms.standalone.js +500 -31
  5. package/dist/algorithms.standalone.js.map +1 -1
  6. package/dist/src/algorithms/centrality/betweenness.js +2 -2
  7. package/dist/src/algorithms/centrality/betweenness.js.map +1 -1
  8. package/dist/src/algorithms/community/girvan-newman.js +1 -1
  9. package/dist/src/algorithms/community/girvan-newman.js.map +1 -1
  10. package/dist/src/algorithms/matching/isomorphism.js +3 -3
  11. package/dist/src/algorithms/matching/isomorphism.js.map +1 -1
  12. package/dist/src/algorithms/mst/prim.js +1 -1
  13. package/dist/src/algorithms/mst/prim.js.map +1 -1
  14. package/dist/src/algorithms/shortest-path/bellman-ford.js +1 -1
  15. package/dist/src/algorithms/shortest-path/bellman-ford.js.map +1 -1
  16. package/dist/src/algorithms/shortest-path/bidirectional-dijkstra.js +1 -1
  17. package/dist/src/algorithms/shortest-path/bidirectional-dijkstra.js.map +1 -1
  18. package/dist/src/algorithms/shortest-path/dijkstra.js +1 -1
  19. package/dist/src/algorithms/shortest-path/dijkstra.js.map +1 -1
  20. package/dist/src/algorithms/traversal/bfs-unified.js +2 -2
  21. package/dist/src/algorithms/traversal/bfs-unified.js.map +1 -1
  22. package/dist/src/algorithms/traversal/dfs.js +2 -2
  23. package/dist/src/algorithms/traversal/dfs.js.map +1 -1
  24. package/dist/src/clustering/spectral.js +2 -2
  25. package/dist/src/clustering/spectral.js.map +1 -1
  26. package/dist/src/index.d.ts +4 -0
  27. package/dist/src/index.d.ts.map +1 -1
  28. package/dist/src/index.js.map +1 -1
  29. package/dist/src/indexed/accelerator.d.ts +14 -2
  30. package/dist/src/indexed/accelerator.d.ts.map +1 -1
  31. package/dist/src/indexed/accelerator.js +8 -0
  32. package/dist/src/indexed/accelerator.js.map +1 -1
  33. package/dist/src/indexed/components.d.ts +8 -0
  34. package/dist/src/indexed/components.d.ts.map +1 -1
  35. package/dist/src/indexed/components.js +8 -1
  36. package/dist/src/indexed/components.js.map +1 -1
  37. package/dist/src/indexed/hits.d.ts +39 -0
  38. package/dist/src/indexed/hits.d.ts.map +1 -0
  39. package/dist/src/indexed/hits.js +95 -0
  40. package/dist/src/indexed/hits.js.map +1 -0
  41. package/dist/src/indexed/index.d.ts +5 -1
  42. package/dist/src/indexed/index.d.ts.map +1 -1
  43. package/dist/src/indexed/index.js +5 -1
  44. package/dist/src/indexed/index.js.map +1 -1
  45. package/dist/src/indexed/k-core.d.ts +32 -0
  46. package/dist/src/indexed/k-core.d.ts.map +1 -0
  47. package/dist/src/indexed/k-core.js +118 -0
  48. package/dist/src/indexed/k-core.js.map +1 -0
  49. package/dist/src/indexed/katz.d.ts +38 -0
  50. package/dist/src/indexed/katz.d.ts.map +1 -0
  51. package/dist/src/indexed/katz.js +61 -0
  52. package/dist/src/indexed/katz.js.map +1 -0
  53. package/dist/src/indexed/louvain.d.ts +33 -0
  54. package/dist/src/indexed/louvain.d.ts.map +1 -0
  55. package/dist/src/indexed/louvain.js +301 -0
  56. package/dist/src/indexed/louvain.js.map +1 -0
  57. package/package.json +6 -6
  58. package/src/algorithms/centrality/betweenness.ts +2 -2
  59. package/src/algorithms/community/girvan-newman.ts +1 -1
  60. package/src/algorithms/matching/isomorphism.ts +3 -3
  61. package/src/algorithms/mst/prim.ts +1 -1
  62. package/src/algorithms/shortest-path/bellman-ford.ts +3 -3
  63. package/src/algorithms/shortest-path/bidirectional-dijkstra.ts +1 -1
  64. package/src/algorithms/shortest-path/dijkstra.ts +1 -1
  65. package/src/algorithms/traversal/bfs-unified.ts +2 -2
  66. package/src/algorithms/traversal/dfs.ts +2 -2
  67. package/src/clustering/spectral.ts +2 -2
  68. package/src/index.ts +10 -0
  69. package/src/indexed/accelerator.ts +26 -2
  70. package/src/indexed/components.ts +8 -1
  71. package/src/indexed/hits.ts +126 -0
  72. package/src/indexed/index.ts +5 -7
  73. package/src/indexed/k-core.ts +138 -0
  74. package/src/indexed/katz.ts +88 -0
  75. package/src/indexed/louvain.ts +345 -0
@@ -3281,7 +3281,7 @@ function breadthFirstSearchStandard(graph, startNode, options = {}) {
3281
3281
  if (options.visitCallback) {
3282
3282
  options.visitCallback(current.node, current.level);
3283
3283
  }
3284
- if (options.targetNode && current.node === options.targetNode) {
3284
+ if (options.targetNode !== void 0 && current.node === options.targetNode) {
3285
3285
  break;
3286
3286
  }
3287
3287
  for (const neighbor of graph.neighbors(current.node)) {
@@ -3471,7 +3471,7 @@ function isBipartite(graph) {
3471
3471
  visited.add(node.id);
3472
3472
  while (queue.length > 0) {
3473
3473
  const current = queue.shift();
3474
- if (!current) {
3474
+ if (current === void 0) {
3475
3475
  break;
3476
3476
  }
3477
3477
  const currentColor = color.get(current);
@@ -3525,7 +3525,7 @@ function dfsIterative(graph, startNode, visited, order, tree, options) {
3525
3525
  if (options.visitCallback) {
3526
3526
  options.visitCallback(current.node, current.depth);
3527
3527
  }
3528
- if (options.targetNode && current.node === options.targetNode) {
3528
+ if (options.targetNode !== void 0 && current.node === options.targetNode) {
3529
3529
  break;
3530
3530
  }
3531
3531
  const neighbors = Array.from(graph.neighbors(current.node));
@@ -3546,7 +3546,7 @@ function dfsRecursive(graph, node, visited, order, tree, options, depth, parent
3546
3546
  if (options.visitCallback) {
3547
3547
  options.visitCallback(node, depth);
3548
3548
  }
3549
- if (options.targetNode && node === options.targetNode) {
3549
+ if (options.targetNode !== void 0 && node === options.targetNode) {
3550
3550
  return;
3551
3551
  }
3552
3552
  }
@@ -3722,7 +3722,7 @@ function bellmanFord(graph, source, options = {}) {
3722
3722
  distances.set(v, newDistance);
3723
3723
  predecessors.set(v, u);
3724
3724
  updated = true;
3725
- if (options.target && v === options.target) {
3725
+ if (options.target !== void 0 && v === options.target) {
3726
3726
  break;
3727
3727
  }
3728
3728
  }
@@ -4076,7 +4076,7 @@ class BidirectionalDijkstra {
4076
4076
  return minDist;
4077
4077
  }
4078
4078
  reconstructPath() {
4079
- if (!this.meetingNode) {
4079
+ if (this.meetingNode === null) {
4080
4080
  return [];
4081
4081
  }
4082
4082
  const path = [];
@@ -4137,7 +4137,7 @@ function dijkstra$1(graph, source, options = {}) {
4137
4137
  continue;
4138
4138
  }
4139
4139
  visited.add(currentNode);
4140
- if (options.target && currentNode === options.target) {
4140
+ if (options.target !== void 0 && currentNode === options.target) {
4141
4141
  break;
4142
4142
  }
4143
4143
  if (currentDistance === Infinity) {
@@ -4712,7 +4712,7 @@ function accumulateBetweenness(result, source, centrality, options) {
4712
4712
  }
4713
4713
  for (let i = stack.length - 1; i >= 0; i--) {
4714
4714
  const w = stack[i];
4715
- if (!w) {
4715
+ if (w === void 0) {
4716
4716
  continue;
4717
4717
  }
4718
4718
  const wPreds = predecessors.get(w) ?? [];
@@ -4746,7 +4746,7 @@ function accumulateEdgeBetweenness(result, source, edgeCentrality, options) {
4746
4746
  }
4747
4747
  for (let i = stack.length - 1; i >= 0; i--) {
4748
4748
  const w = stack[i];
4749
- if (!w) {
4749
+ if (w === void 0) {
4750
4750
  continue;
4751
4751
  }
4752
4752
  const wPreds = predecessors.get(w) ?? [];
@@ -5380,7 +5380,7 @@ function nodeEigenvectorCentrality(graph, nodeId, options = {}) {
5380
5380
  const centrality = eigenvectorCentrality(graph, options);
5381
5381
  return centrality[nodeId.toString()] ?? 0;
5382
5382
  }
5383
- function hits(graph, options = {}) {
5383
+ function hits$1(graph, options = {}) {
5384
5384
  const { maxIterations = 100, tolerance = 1e-6, normalized = true } = options;
5385
5385
  const hubs = {};
5386
5386
  const authorities = {};
@@ -5497,14 +5497,14 @@ function nodeHITS(graph, nodeId, options = {}) {
5497
5497
  if (!graph.hasNode(nodeId)) {
5498
5498
  throw new Error(`Node ${String(nodeId)} not found in graph`);
5499
5499
  }
5500
- const result = hits(graph, options);
5500
+ const result = hits$1(graph, options);
5501
5501
  const key = nodeId.toString();
5502
5502
  return {
5503
5503
  hub: result.hubs[key] ?? 0,
5504
5504
  authority: result.authorities[key] ?? 0
5505
5505
  };
5506
5506
  }
5507
- function katzCentrality(graph, options = {}) {
5507
+ function katzCentrality$1(graph, options = {}) {
5508
5508
  const { alpha = 0.1, beta = 1, maxIterations = 100, tolerance = 1e-6, normalized = true } = options;
5509
5509
  const centrality = {};
5510
5510
  const nodes = Array.from(graph.nodes());
@@ -5565,7 +5565,7 @@ function nodeKatzCentrality(graph, nodeId, options = {}) {
5565
5565
  if (!graph.hasNode(nodeId)) {
5566
5566
  throw new Error(`Node ${String(nodeId)} not found in graph`);
5567
5567
  }
5568
- const centrality = katzCentrality(graph, options);
5568
+ const centrality = katzCentrality$1(graph, options);
5569
5569
  return centrality[nodeId.toString()] ?? 0;
5570
5570
  }
5571
5571
  class SimpleDeltaPageRank {
@@ -6410,7 +6410,7 @@ function primMST(graph, startNode) {
6410
6410
  };
6411
6411
  }
6412
6412
  const start = startNode ?? nodes[0]?.id;
6413
- if (!start) {
6413
+ if (start === void 0) {
6414
6414
  return {
6415
6415
  edges: [],
6416
6416
  totalWeight: 0
@@ -6578,7 +6578,7 @@ function findAllShortestPaths(graph, source) {
6578
6578
  let queueIndex = 0;
6579
6579
  while (queueIndex < queue.length) {
6580
6580
  const current = queue[queueIndex++];
6581
- if (!current) {
6581
+ if (current === void 0) {
6582
6582
  continue;
6583
6583
  }
6584
6584
  if (visited.has(current)) {
@@ -7360,7 +7360,7 @@ class OptimizedLouvain {
7360
7360
  for (let i = 0; i < membership.length; i++) {
7361
7361
  membership[i] = community[membership[i]];
7362
7362
  }
7363
- level = aggregate(level, community, count);
7363
+ level = aggregate$1(level, community, count);
7364
7364
  }
7365
7365
  const groups = Array.from({ length: level.n }, () => []);
7366
7366
  for (let i = 0; i < membership.length; i++) {
@@ -7543,7 +7543,7 @@ function buildCsr(n, counts, edges, self, degree) {
7543
7543
  }
7544
7544
  return { n, offsets, targets, weights, self, degree };
7545
7545
  }
7546
- function aggregate(level, community, count) {
7546
+ function aggregate$1(level, community, count) {
7547
7547
  const self = new Float64Array(count);
7548
7548
  const degree = new Float64Array(count);
7549
7549
  const members = Array.from({ length: count }, () => []);
@@ -7651,7 +7651,7 @@ function calculateModularity$1(graph, communities, resolution = 1) {
7651
7651
  }
7652
7652
  return modularity;
7653
7653
  }
7654
- function louvain(graph, options = {}) {
7654
+ function louvain$1(graph, options = {}) {
7655
7655
  const resolution = options.resolution ?? 1;
7656
7656
  const maxIterations = options.maxIterations ?? 100;
7657
7657
  const tolerance = options.tolerance ?? 1e-6;
@@ -9017,7 +9017,7 @@ function kCoreDecompositionImpl(graph) {
9017
9017
  return { cores, coreness, maxCore };
9018
9018
  }
9019
9019
  function getKCore(graph, k) {
9020
- const { coreness } = kCoreDecomposition(graph);
9020
+ const { coreness } = kCoreDecomposition$1(graph);
9021
9021
  const kCore = /* @__PURE__ */ new Set();
9022
9022
  for (const [node, core] of coreness) {
9023
9023
  if (core >= k) {
@@ -9026,7 +9026,7 @@ function getKCore(graph, k) {
9026
9026
  }
9027
9027
  return kCore;
9028
9028
  }
9029
- function kCoreDecomposition(graph) {
9029
+ function kCoreDecomposition$1(graph) {
9030
9030
  const adjacencySet = graphToAdjacencySet(graph);
9031
9031
  return kCoreDecompositionImpl(adjacencySet);
9032
9032
  }
@@ -9382,7 +9382,7 @@ function spectralClustering(graph, options) {
9382
9382
  for (let i = 0; i < nodeIds.length; i++) {
9383
9383
  const clusterId = kmeans.assignments[i] ?? 0;
9384
9384
  const nodeId = nodeIds[i];
9385
- if (!nodeId) {
9385
+ if (nodeId === void 0) {
9386
9386
  continue;
9387
9387
  }
9388
9388
  if (clusterId >= 0 && clusterId < k) {
@@ -9414,7 +9414,7 @@ function buildAdjacencyMatrix(graph, nodeIds) {
9414
9414
  nodeIds.forEach((id, index2) => nodeToIndex.set(id, index2));
9415
9415
  for (let i = 0; i < n; i++) {
9416
9416
  const nodeId = nodeIds[i];
9417
- if (!nodeId) {
9417
+ if (nodeId === void 0) {
9418
9418
  continue;
9419
9419
  }
9420
9420
  const neighbors = graph.neighbors(nodeId);
@@ -9954,7 +9954,7 @@ function getCandidatePairs(g1, g2, state, nodes1, nodes2) {
9954
9954
  break;
9955
9955
  }
9956
9956
  }
9957
- if (!node1) {
9957
+ if (node1 === null) {
9958
9958
  for (const [n] of state.in1) {
9959
9959
  if (!state.core1.has(n)) {
9960
9960
  node1 = n;
@@ -9962,7 +9962,7 @@ function getCandidatePairs(g1, g2, state, nodes1, nodes2) {
9962
9962
  }
9963
9963
  }
9964
9964
  }
9965
- if (!node1) {
9965
+ if (node1 === null) {
9966
9966
  for (const n of nodes1) {
9967
9967
  if (!state.core1.has(n)) {
9968
9968
  node1 = n;
@@ -9970,7 +9970,7 @@ function getCandidatePairs(g1, g2, state, nodes1, nodes2) {
9970
9970
  }
9971
9971
  }
9972
9972
  }
9973
- if (!node1) {
9973
+ if (node1 === null) {
9974
9974
  return pairs;
9975
9975
  }
9976
9976
  for (const node2 of nodes2) {
@@ -18476,7 +18476,7 @@ function checkUniqueColumn(table, column) {
18476
18476
  throw err;
18477
18477
  }
18478
18478
  }
18479
- const WIRE_PRODUCER = `@graphty/graph-format@${"5290d3c12aaf"}`;
18479
+ const WIRE_PRODUCER = `@graphty/graph-format@${"b109fac22143"}`;
18480
18480
  const SCALAR_VIEWS = /* @__PURE__ */ new Set(["totalWeight", "symmetric"]);
18481
18481
  const encoder = new TextEncoder();
18482
18482
  function assertLittleEndianHost(littleEndian = IS_LITTLE_ENDIAN) {
@@ -24316,6 +24316,467 @@ function dijkstra(g, source, options = {}) {
24316
24316
  pathEdges: (target) => walkPredEdges(g, predArc, source, target)
24317
24317
  };
24318
24318
  }
24319
+ function l2Normalize(v) {
24320
+ let sum = 0;
24321
+ for (let i = 0; i < v.length; i++) {
24322
+ sum += v[i] * v[i];
24323
+ }
24324
+ const norm = Math.sqrt(sum);
24325
+ if (norm > 0) {
24326
+ for (let i = 0; i < v.length; i++) {
24327
+ v[i] /= norm;
24328
+ }
24329
+ }
24330
+ }
24331
+ function maxNormalize(v) {
24332
+ let max = 0;
24333
+ for (let i = 0; i < v.length; i++) {
24334
+ if (v[i] > max) {
24335
+ max = v[i];
24336
+ }
24337
+ }
24338
+ if (max > 0) {
24339
+ for (let i = 0; i < v.length; i++) {
24340
+ v[i] /= max;
24341
+ }
24342
+ }
24343
+ }
24344
+ function hits(s, o = {}) {
24345
+ const n = s.nodeCount;
24346
+ const maxIter = o.maxIterations ?? 100;
24347
+ const tol = o.tolerance ?? 1e-6;
24348
+ const rev = s.reverse();
24349
+ const fwdW = o.weighted === true ? s.weights : null;
24350
+ const revW = o.weighted === true ? rev.weights : null;
24351
+ let hubs = new Float64Array(n).fill(n === 0 ? 0 : 1 / Math.sqrt(n));
24352
+ let authorities = new Float64Array(n).fill(n === 0 ? 0 : 1 / Math.sqrt(n));
24353
+ let nextHubs = new Float64Array(n);
24354
+ let nextAuthorities = new Float64Array(n);
24355
+ let it = 0;
24356
+ let converged = false;
24357
+ for (; it < maxIter && !converged; it++) {
24358
+ for (let v = 0; v < n; v++) {
24359
+ let auth = 0;
24360
+ const inEnd = rev.rowPtr[v + 1];
24361
+ for (let a = rev.rowPtr[v]; a < inEnd; a++) {
24362
+ auth += hubs[rev.colIdx[a]] * (revW === null ? 1 : revW[a]);
24363
+ }
24364
+ nextAuthorities[v] = auth;
24365
+ let hub = 0;
24366
+ const outEnd = s.rowPtr[v + 1];
24367
+ for (let a = s.rowPtr[v]; a < outEnd; a++) {
24368
+ hub += authorities[s.colIdx[a]] * (fwdW === null ? 1 : fwdW[a]);
24369
+ }
24370
+ nextHubs[v] = hub;
24371
+ }
24372
+ l2Normalize(nextAuthorities);
24373
+ l2Normalize(nextHubs);
24374
+ let maxDiff = 0;
24375
+ for (let v = 0; v < n; v++) {
24376
+ const dh = Math.abs(nextHubs[v] - hubs[v]);
24377
+ if (dh > maxDiff) {
24378
+ maxDiff = dh;
24379
+ }
24380
+ const da = Math.abs(nextAuthorities[v] - authorities[v]);
24381
+ if (da > maxDiff) {
24382
+ maxDiff = da;
24383
+ }
24384
+ }
24385
+ [hubs, nextHubs] = [nextHubs, hubs];
24386
+ [authorities, nextAuthorities] = [nextAuthorities, authorities];
24387
+ converged = maxDiff < tol;
24388
+ }
24389
+ if (o.normalized === false) {
24390
+ maxNormalize(hubs);
24391
+ maxNormalize(authorities);
24392
+ }
24393
+ return { hubs, authorities, iterations: it, converged };
24394
+ }
24395
+ function kCoreDecomposition(s) {
24396
+ if (s.directed) {
24397
+ throw new Error("k-core requires an undirected graph. Pass s.toUndirected().snapshot.");
24398
+ }
24399
+ const n = s.nodeCount;
24400
+ const { rowPtr, colIdx } = s;
24401
+ const degree = new Uint32Array(n);
24402
+ let maxDegree = 0;
24403
+ for (let u = 0; u < n; u++) {
24404
+ let d = 0;
24405
+ let last = -1;
24406
+ const end = rowPtr[u + 1];
24407
+ for (let a = rowPtr[u]; a < end; a++) {
24408
+ const v = colIdx[a];
24409
+ if (v !== u && v !== last) {
24410
+ d++;
24411
+ }
24412
+ last = v;
24413
+ }
24414
+ degree[u] = d;
24415
+ if (d > maxDegree) {
24416
+ maxDegree = d;
24417
+ }
24418
+ }
24419
+ const bin = new Uint32Array(maxDegree + 1);
24420
+ for (let u = 0; u < n; u++) {
24421
+ bin[degree[u]]++;
24422
+ }
24423
+ let start = 0;
24424
+ for (let d = 0; d <= maxDegree; d++) {
24425
+ const count = bin[d];
24426
+ bin[d] = start;
24427
+ start += count;
24428
+ }
24429
+ const vert = new Uint32Array(n);
24430
+ const pos = new Uint32Array(n);
24431
+ for (let u = 0; u < n; u++) {
24432
+ pos[u] = bin[degree[u]];
24433
+ vert[pos[u]] = u;
24434
+ bin[degree[u]]++;
24435
+ }
24436
+ for (let d = maxDegree; d > 0; d--) {
24437
+ bin[d] = bin[d - 1];
24438
+ }
24439
+ bin[0] = 0;
24440
+ let maxCore = 0;
24441
+ for (let i = 0; i < n; i++) {
24442
+ const v = vert[i];
24443
+ const dv = degree[v];
24444
+ if (dv > maxCore) {
24445
+ maxCore = dv;
24446
+ }
24447
+ const end = rowPtr[v + 1];
24448
+ let last = -1;
24449
+ for (let a = rowPtr[v]; a < end; a++) {
24450
+ const u = colIdx[a];
24451
+ const skip = u === v || u === last;
24452
+ last = u;
24453
+ if (skip) {
24454
+ continue;
24455
+ }
24456
+ const du = degree[u];
24457
+ if (du > dv) {
24458
+ const pu = pos[u];
24459
+ const pw = bin[du];
24460
+ const w = vert[pw];
24461
+ if (u !== w) {
24462
+ vert[pu] = w;
24463
+ vert[pw] = u;
24464
+ pos[u] = pw;
24465
+ pos[w] = pu;
24466
+ }
24467
+ bin[du]++;
24468
+ degree[u] = du - 1;
24469
+ }
24470
+ }
24471
+ }
24472
+ let cached = null;
24473
+ return {
24474
+ coreness: degree,
24475
+ maxCore,
24476
+ cores() {
24477
+ if (cached === null) {
24478
+ const sizes = new Uint32Array(maxCore + 1);
24479
+ for (let u = 0; u < n; u++) {
24480
+ sizes[degree[u]]++;
24481
+ }
24482
+ const out = [];
24483
+ for (let k = 0; k <= maxCore; k++) {
24484
+ out.push(new Uint32Array(sizes[k]));
24485
+ }
24486
+ const fill = new Uint32Array(maxCore + 1);
24487
+ for (let u = 0; u < n; u++) {
24488
+ const k = degree[u];
24489
+ out[k][fill[k]++] = u;
24490
+ }
24491
+ cached = out;
24492
+ }
24493
+ return cached;
24494
+ }
24495
+ };
24496
+ }
24497
+ function katzCentrality(s, o = {}) {
24498
+ const n = s.nodeCount;
24499
+ const alpha = o.alpha ?? 0.1;
24500
+ const beta = o.beta ?? 1;
24501
+ const maxIter = o.maxIterations ?? 100;
24502
+ const tol = o.tolerance ?? 1e-6;
24503
+ const rev = s.reverse();
24504
+ const weights = o.weighted === true ? rev.weights : null;
24505
+ let cur = new Float64Array(n).fill(beta);
24506
+ let next = new Float64Array(n);
24507
+ let it = 0;
24508
+ let converged = false;
24509
+ for (; it < maxIter && !converged; it++) {
24510
+ let maxDiff = 0;
24511
+ for (let v = 0; v < n; v++) {
24512
+ let sum = 0;
24513
+ const end = rev.rowPtr[v + 1];
24514
+ for (let a = rev.rowPtr[v]; a < end; a++) {
24515
+ sum += cur[rev.colIdx[a]] * (weights === null ? 1 : weights[a]);
24516
+ }
24517
+ next[v] = alpha * sum + beta;
24518
+ const diff = Math.abs(next[v] - cur[v]);
24519
+ if (diff > maxDiff) {
24520
+ maxDiff = diff;
24521
+ }
24522
+ }
24523
+ [cur, next] = [next, cur];
24524
+ converged = maxDiff < tol;
24525
+ }
24526
+ if (o.normalized !== false) {
24527
+ let min = Infinity;
24528
+ let max = -Infinity;
24529
+ for (let v = 0; v < n; v++) {
24530
+ if (cur[v] < min) {
24531
+ min = cur[v];
24532
+ }
24533
+ if (cur[v] > max) {
24534
+ max = cur[v];
24535
+ }
24536
+ }
24537
+ const range = max - min;
24538
+ if (range > 0) {
24539
+ for (let v = 0; v < n; v++) {
24540
+ cur[v] = (cur[v] - min) / range;
24541
+ }
24542
+ }
24543
+ }
24544
+ return { scores: cur, iterations: it, converged };
24545
+ }
24546
+ function buildLevel0(s) {
24547
+ const n = s.nodeCount;
24548
+ const rowPtr = new Uint32Array(n + 1);
24549
+ for (let u = 0; u < n; u++) {
24550
+ let kept = 0;
24551
+ const end = s.rowPtr[u + 1];
24552
+ for (let a = s.rowPtr[u]; a < end; a++) {
24553
+ if (s.colIdx[a] !== u) {
24554
+ kept++;
24555
+ }
24556
+ }
24557
+ rowPtr[u + 1] = rowPtr[u] + kept;
24558
+ }
24559
+ const arcs = rowPtr[n];
24560
+ const colIdx = new Uint32Array(arcs);
24561
+ const w = new Float64Array(arcs);
24562
+ const loop = new Float64Array(n);
24563
+ const deg = new Float64Array(n);
24564
+ let k = 0;
24565
+ for (let u = 0; u < n; u++) {
24566
+ let rowWeight = 0;
24567
+ const end = s.rowPtr[u + 1];
24568
+ for (let a = s.rowPtr[u]; a < end; a++) {
24569
+ const v = s.colIdx[a];
24570
+ const weight = s.weights === null ? 1 : s.weights[a];
24571
+ if (v === u) {
24572
+ loop[u] += weight;
24573
+ } else {
24574
+ colIdx[k] = v;
24575
+ w[k] = weight;
24576
+ k++;
24577
+ rowWeight += weight;
24578
+ }
24579
+ }
24580
+ deg[u] = rowWeight + 2 * loop[u];
24581
+ }
24582
+ return { n, rowPtr, colIdx, w, loop, deg };
24583
+ }
24584
+ function modularityOf(level, comm, count, resolution, m2) {
24585
+ const inside = new Float64Array(count);
24586
+ const tot = new Float64Array(count);
24587
+ for (let u = 0; u < level.n; u++) {
24588
+ const c = comm[u];
24589
+ tot[c] += level.deg[u];
24590
+ inside[c] += 2 * level.loop[u];
24591
+ const end = level.rowPtr[u + 1];
24592
+ for (let a = level.rowPtr[u]; a < end; a++) {
24593
+ if (comm[level.colIdx[a]] === c) {
24594
+ inside[c] += level.w[a];
24595
+ }
24596
+ }
24597
+ }
24598
+ let q = 0;
24599
+ for (let c = 0; c < count; c++) {
24600
+ const share = tot[c] / m2;
24601
+ q += inside[c] / m2 - resolution * share * share;
24602
+ }
24603
+ return q;
24604
+ }
24605
+ function localMove(level, comm, resolution, m2, maxVisitsPerNode) {
24606
+ const { n } = level;
24607
+ const tot = new Float64Array(n);
24608
+ for (let u = 0; u < n; u++) {
24609
+ comm[u] = u;
24610
+ tot[u] = level.deg[u];
24611
+ }
24612
+ const acc = new Float64Array(n);
24613
+ const stamp = new Int32Array(n).fill(-1);
24614
+ const touched = new Uint32Array(n);
24615
+ const capacity = n + 1;
24616
+ const queue = new Uint32Array(capacity);
24617
+ const queued = new Uint8Array(n);
24618
+ let head = 0;
24619
+ let tail = n;
24620
+ for (let u = 0; u < n; u++) {
24621
+ queue[u] = u;
24622
+ queued[u] = 1;
24623
+ }
24624
+ let mark = 0;
24625
+ let visits = 0;
24626
+ const maxVisits = maxVisitsPerNode * n;
24627
+ let movedAny = false;
24628
+ while (head !== tail && visits < maxVisits) {
24629
+ const u = queue[head];
24630
+ head = head + 1 === capacity ? 0 : head + 1;
24631
+ queued[u] = 0;
24632
+ visits++;
24633
+ const cu = comm[u];
24634
+ const ku = level.deg[u];
24635
+ tot[cu] -= ku;
24636
+ mark++;
24637
+ let cnt = 0;
24638
+ const end = level.rowPtr[u + 1];
24639
+ for (let a = level.rowPtr[u]; a < end; a++) {
24640
+ const c = comm[level.colIdx[a]];
24641
+ if (stamp[c] !== mark) {
24642
+ stamp[c] = mark;
24643
+ acc[c] = 0;
24644
+ touched[cnt++] = c;
24645
+ }
24646
+ acc[c] += level.w[a];
24647
+ }
24648
+ let best = cu;
24649
+ let bestGain = (stamp[cu] === mark ? acc[cu] : 0) - resolution * ku * tot[cu] / m2;
24650
+ for (let i = 0; i < cnt; i++) {
24651
+ const c = touched[i];
24652
+ if (c === cu) {
24653
+ continue;
24654
+ }
24655
+ const gain = acc[c] - resolution * ku * tot[c] / m2;
24656
+ if (gain > bestGain) {
24657
+ bestGain = gain;
24658
+ best = c;
24659
+ }
24660
+ }
24661
+ tot[best] += ku;
24662
+ if (best !== cu) {
24663
+ comm[u] = best;
24664
+ movedAny = true;
24665
+ for (let a = level.rowPtr[u]; a < end; a++) {
24666
+ const v = level.colIdx[a];
24667
+ if (queued[v] === 0 && comm[v] !== best) {
24668
+ queued[v] = 1;
24669
+ queue[tail] = v;
24670
+ tail = tail + 1 === capacity ? 0 : tail + 1;
24671
+ }
24672
+ }
24673
+ }
24674
+ }
24675
+ return movedAny;
24676
+ }
24677
+ function aggregate(level, comm, count) {
24678
+ const start = new Uint32Array(count + 1);
24679
+ for (let u = 0; u < level.n; u++) {
24680
+ start[comm[u] + 1]++;
24681
+ }
24682
+ for (let c = 0; c < count; c++) {
24683
+ start[c + 1] += start[c];
24684
+ }
24685
+ const members = new Uint32Array(level.n);
24686
+ const fill = start.slice(0, count);
24687
+ for (let u = 0; u < level.n; u++) {
24688
+ members[fill[comm[u]]++] = u;
24689
+ }
24690
+ const rowPtr = new Uint32Array(count + 1);
24691
+ const colIdx = new Uint32Array(level.colIdx.length);
24692
+ const w = new Float64Array(level.colIdx.length);
24693
+ const loop = new Float64Array(count);
24694
+ const deg = new Float64Array(count);
24695
+ const acc = new Float64Array(count);
24696
+ const stamp = new Int32Array(count).fill(-1);
24697
+ const touched = new Uint32Array(count);
24698
+ let k = 0;
24699
+ for (let c = 0; c < count; c++) {
24700
+ rowPtr[c] = k;
24701
+ let internalArcs = 0;
24702
+ let cnt = 0;
24703
+ for (let i = start[c]; i < start[c + 1]; i++) {
24704
+ const u = members[i];
24705
+ loop[c] += level.loop[u];
24706
+ const end = level.rowPtr[u + 1];
24707
+ for (let a = level.rowPtr[u]; a < end; a++) {
24708
+ const other = comm[level.colIdx[a]];
24709
+ if (other === c) {
24710
+ internalArcs += level.w[a];
24711
+ continue;
24712
+ }
24713
+ if (stamp[other] !== c) {
24714
+ stamp[other] = c;
24715
+ acc[other] = 0;
24716
+ touched[cnt++] = other;
24717
+ }
24718
+ acc[other] += level.w[a];
24719
+ }
24720
+ }
24721
+ loop[c] += internalArcs / 2;
24722
+ let rowWeight = 0;
24723
+ for (let i = 0; i < cnt; i++) {
24724
+ const other = touched[i];
24725
+ colIdx[k] = other;
24726
+ w[k] = acc[other];
24727
+ rowWeight += acc[other];
24728
+ k++;
24729
+ }
24730
+ deg[c] = rowWeight + 2 * loop[c];
24731
+ }
24732
+ rowPtr[count] = k;
24733
+ return { n: count, rowPtr, colIdx: colIdx.subarray(0, k), w: w.subarray(0, k), loop, deg };
24734
+ }
24735
+ function louvain(s, o = {}) {
24736
+ if (s.directed) {
24737
+ throw new Error("Louvain requires an undirected graph. Pass s.toUndirected().snapshot.");
24738
+ }
24739
+ const resolution = o.resolution ?? 1;
24740
+ const maxIterations = o.maxIterations ?? 100;
24741
+ const tolerance = o.tolerance ?? 1e-6;
24742
+ const n0 = s.nodeCount;
24743
+ const labels = new Uint32Array(n0);
24744
+ for (let u = 0; u < n0; u++) {
24745
+ labels[u] = u;
24746
+ }
24747
+ let level = buildLevel0(s);
24748
+ let m2 = 0;
24749
+ for (let u = 0; u < n0; u++) {
24750
+ m2 += level.deg[u];
24751
+ }
24752
+ if (m2 === 0) {
24753
+ return { ...withGroups(labels, n0), modularity: 0, iterations: 0 };
24754
+ }
24755
+ let q = modularityOf(level, labels, n0, resolution, m2);
24756
+ let iterations = 0;
24757
+ for (let iteration = 0; iteration < maxIterations; iteration++) {
24758
+ const comm = new Uint32Array(level.n);
24759
+ if (!localMove(level, comm, resolution, m2, maxIterations)) {
24760
+ break;
24761
+ }
24762
+ const dense = renumberPartition(comm);
24763
+ const { count } = dense;
24764
+ const packed = dense.labels;
24765
+ const newQ = modularityOf(level, packed, count, resolution, m2);
24766
+ for (let u = 0; u < n0; u++) {
24767
+ labels[u] = packed[labels[u]];
24768
+ }
24769
+ iterations = iteration + 1;
24770
+ const gain = newQ - q;
24771
+ q = newQ;
24772
+ if (gain < tolerance || count === level.n) {
24773
+ break;
24774
+ }
24775
+ level = aggregate(level, packed, count);
24776
+ }
24777
+ const final = renumberPartition(labels);
24778
+ return { ...withGroups(final.labels, final.count), modularity: q, iterations };
24779
+ }
24319
24780
  function kruskalMST(s, o = {}) {
24320
24781
  const el = s.edgeList();
24321
24782
  const m = s.edgeCount;
@@ -24399,7 +24860,11 @@ const index = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.definePropert
24399
24860
  commonNeighborsScore,
24400
24861
  connectedComponents,
24401
24862
  dijkstra,
24863
+ hits,
24864
+ kCoreDecomposition,
24865
+ katzCentrality,
24402
24866
  kruskalMST,
24867
+ louvain,
24403
24868
  pageRank,
24404
24869
  walkPredArcs,
24405
24870
  walkPredEdges,
@@ -24445,7 +24910,11 @@ function accelerated(acc) {
24445
24910
  breadthFirstSearch: (s, source, options) => acc?.breadthFirstSearch !== void 0 ? acc.breadthFirstSearch(s, source, options) : Promise.resolve(breadthFirstSearch(s, source, options)),
24446
24911
  connectedComponents: (s) => acc?.connectedComponents !== void 0 ? acc.connectedComponents(s) : Promise.resolve(connectedComponents(s)),
24447
24912
  weaklyConnectedComponents: (s) => acc?.weaklyConnectedComponents !== void 0 ? acc.weaklyConnectedComponents(s) : Promise.resolve(weaklyConnectedComponents(s)),
24448
- minimumSpanningTree: (s, options) => acc?.minimumSpanningTree !== void 0 ? acc.minimumSpanningTree(s, options) : Promise.resolve(kruskalMST(s, options))
24913
+ minimumSpanningTree: (s, options) => acc?.minimumSpanningTree !== void 0 ? acc.minimumSpanningTree(s, options) : Promise.resolve(kruskalMST(s, options)),
24914
+ kCoreDecomposition: (s) => acc?.kCoreDecomposition !== void 0 ? acc.kCoreDecomposition(s) : Promise.resolve(kCoreDecomposition(s)),
24915
+ katzCentrality: (s, options) => acc?.katzCentrality !== void 0 ? acc.katzCentrality(s, options) : Promise.resolve(katzCentrality(s, options)),
24916
+ hits: (s, options) => acc?.hits !== void 0 ? acc.hits(s, options) : Promise.resolve(hits(s, options)),
24917
+ louvain: (s, options) => acc?.louvain !== void 0 ? acc.louvain(s, options) : Promise.resolve(louvain(s, options))
24449
24918
  };
24450
24919
  }
24451
24920
  export {
@@ -24511,7 +24980,7 @@ export {
24511
24980
  hasNegativeCycle,
24512
24981
  heuristics,
24513
24982
  hierarchicalClustering,
24514
- hits,
24983
+ hits$1 as hits,
24515
24984
  index as indexed,
24516
24985
  isBipartite,
24517
24986
  isCSRGraph,
@@ -24519,16 +24988,16 @@ export {
24519
24988
  isGraphIsomorphic,
24520
24989
  isStronglyConnected,
24521
24990
  isWeaklyConnected,
24522
- kCoreDecomposition,
24991
+ kCoreDecomposition$1 as kCoreDecomposition,
24523
24992
  kargerMinCut,
24524
- katzCentrality,
24993
+ katzCentrality$1 as katzCentrality,
24525
24994
  kruskalMST$1 as kruskalMST,
24526
24995
  labelPropagation,
24527
24996
  labelPropagationAsync,
24528
24997
  labelPropagationSemiSupervised,
24529
24998
  largestConnectedComponent,
24530
24999
  leiden,
24531
- louvain,
25000
+ louvain$1 as louvain,
24532
25001
  markovClustering,
24533
25002
  maximumBipartiteMatching,
24534
25003
  minSTCut,