@graphty/algorithms 1.8.0 → 2.0.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 (43) hide show
  1. package/README.md +5 -4
  2. package/dist/algorithms.js +518 -525
  3. package/dist/algorithms.js.map +1 -1
  4. package/dist/algorithms.standalone.js +519 -526
  5. package/dist/algorithms.standalone.js.map +1 -1
  6. package/dist/src/algorithms/centrality/eigenvector.d.ts +13 -2
  7. package/dist/src/algorithms/centrality/eigenvector.d.ts.map +1 -1
  8. package/dist/src/algorithms/centrality/eigenvector.js +96 -73
  9. package/dist/src/algorithms/centrality/eigenvector.js.map +1 -1
  10. package/dist/src/algorithms/community/girvan-newman.js +35 -15
  11. package/dist/src/algorithms/community/girvan-newman.js.map +1 -1
  12. package/dist/src/algorithms/community/leiden.d.ts.map +1 -1
  13. package/dist/src/algorithms/community/leiden.js +214 -222
  14. package/dist/src/algorithms/community/leiden.js.map +1 -1
  15. package/dist/src/algorithms/community/louvain-optimized.d.ts +28 -72
  16. package/dist/src/algorithms/community/louvain-optimized.d.ts.map +1 -1
  17. package/dist/src/algorithms/community/louvain-optimized.js +249 -262
  18. package/dist/src/algorithms/community/louvain-optimized.js.map +1 -1
  19. package/dist/src/algorithms/community/modularity-utils.d.ts +15 -7
  20. package/dist/src/algorithms/community/modularity-utils.d.ts.map +1 -1
  21. package/dist/src/algorithms/community/modularity-utils.js +38 -38
  22. package/dist/src/algorithms/community/modularity-utils.js.map +1 -1
  23. package/dist/src/algorithms/shortest-path/bellman-ford.d.ts.map +1 -1
  24. package/dist/src/algorithms/shortest-path/bellman-ford.js +35 -8
  25. package/dist/src/algorithms/shortest-path/bellman-ford.js.map +1 -1
  26. package/dist/src/errors.d.ts +21 -0
  27. package/dist/src/errors.d.ts.map +1 -0
  28. package/dist/src/errors.js +23 -0
  29. package/dist/src/errors.js.map +1 -0
  30. package/dist/src/index.d.ts +1 -0
  31. package/dist/src/index.d.ts.map +1 -1
  32. package/dist/src/index.js +2 -0
  33. package/dist/src/index.js.map +1 -1
  34. package/dist/tsconfig.tsbuildinfo +1 -1
  35. package/package.json +8 -8
  36. package/src/algorithms/centrality/eigenvector.ts +103 -84
  37. package/src/algorithms/community/girvan-newman.ts +38 -17
  38. package/src/algorithms/community/leiden.ts +270 -275
  39. package/src/algorithms/community/louvain-optimized.ts +303 -313
  40. package/src/algorithms/community/modularity-utils.ts +42 -45
  41. package/src/algorithms/shortest-path/bellman-ford.ts +46 -8
  42. package/src/errors.ts +26 -0
  43. package/src/index.ts +3 -0
@@ -8,11 +8,6 @@ export class OptimizedLouvain {
8
8
  */
9
9
  constructor(graph) {
10
10
  this.graph = graph;
11
- this.communities = new Map();
12
- this.communityWeights = new Map();
13
- this.nodeWeights = new Map();
14
- this.nodeDegrees = new Map();
15
- this.totalWeight = 0;
16
11
  this.pruningStats = {
17
12
  leafNodesPruned: 0,
18
13
  lowDegreeNodesPruned: 0,
@@ -22,308 +17,300 @@ export class OptimizedLouvain {
22
17
  /**
23
18
  * Run optimized Louvain algorithm
24
19
  * @param options - Algorithm configuration options
25
- * @returns Community detection result with communities, modularity, and iterations
20
+ * @returns Community detection result with communities, modularity, and iterations (levels)
26
21
  */
27
22
  detectCommunities(options = {}) {
28
- const { resolution = 1.0, maxIterations = 100, tolerance = 1e-6, pruneLeaves = true, importanceOrdering = true, pruningThreshold = 0.01, thresholdCycling = true, } = options;
29
- // Initialize
30
- this.initialize();
31
- let modularity = this.calculateModularity(resolution);
32
- let iteration = 0;
33
- let improved = true;
34
- while (iteration < maxIterations && improved) {
35
- // Get nodes in optimal processing order
36
- const orderedNodes = importanceOrdering
37
- ? this.getNodesInImportanceOrder()
38
- : Array.from(this.graph.nodes()).map((n) => n.id);
39
- // Apply adaptive threshold
40
- const threshold = thresholdCycling ? this.getAdaptiveThreshold(iteration, pruningThreshold) : 0;
41
- // Perform local optimization
42
- improved = this.performLocalMoving(orderedNodes, {
43
- pruneLeaves,
44
- threshold,
45
- resolution,
46
- });
47
- if (improved) {
48
- const newModularity = this.calculateModularity(resolution);
49
- // Check convergence
50
- if (Math.abs(newModularity - modularity) < tolerance) {
51
- break;
52
- }
53
- modularity = newModularity;
54
- iteration++;
55
- }
23
+ const settings = {
24
+ resolution: options.resolution ?? 1.0,
25
+ maxIterations: options.maxIterations ?? 100,
26
+ tolerance: options.tolerance ?? 1e-6,
27
+ pruneLeaves: options.pruneLeaves ?? true,
28
+ importanceOrdering: options.importanceOrdering ?? true,
29
+ pruningThreshold: options.pruningThreshold ?? 0.01,
30
+ thresholdCycling: options.thresholdCycling ?? true,
31
+ };
32
+ const { level: base, ids } = this.buildLevel();
33
+ // membership[i] = the current level's node that original node i has been folded into
34
+ const membership = new Int32Array(base.n);
35
+ for (let i = 0; i < base.n; i++) {
36
+ membership[i] = i;
56
37
  }
57
- // Convert community assignments to result format
58
- const communityGroups = new Map();
59
- for (const [nodeId, community] of this.communities) {
60
- if (!communityGroups.has(community)) {
61
- communityGroups.set(community, []);
38
+ let level = base;
39
+ let iterations = 0;
40
+ while (level.n > 1) {
41
+ const { community, count, moved } = this.localMoving(level, settings);
42
+ if (!moved) {
43
+ break;
62
44
  }
63
- const group = communityGroups.get(community);
64
- if (group) {
65
- group.push(nodeId);
45
+ iterations++;
46
+ for (let i = 0; i < membership.length; i++) {
47
+ membership[i] = community[membership[i]];
66
48
  }
49
+ level = aggregate(level, community, count);
50
+ }
51
+ const groups = Array.from({ length: level.n }, () => []);
52
+ for (let i = 0; i < membership.length; i++) {
53
+ groups[membership[i]].push(ids[i]);
67
54
  }
68
55
  return {
69
- communities: Array.from(communityGroups.values()),
70
- modularity,
71
- iterations: iteration,
56
+ communities: groups.filter((group) => group.length > 0),
57
+ modularity: levelModularity(level, settings.resolution),
58
+ iterations,
72
59
  };
73
60
  }
74
61
  /**
75
- * Initialize data structures
62
+ * Get pruning statistics
63
+ * @returns Statistics about nodes pruned during optimization
76
64
  */
77
- initialize() {
78
- let communityId = 0;
79
- // Initialize each node in its own community
80
- for (const node of this.graph.nodes()) {
81
- this.communities.set(node.id, communityId);
82
- // Calculate node weight and degree
83
- let nodeWeight = 0;
84
- let degree = 0;
85
- for (const neighbor of Array.from(this.graph.neighbors(node.id))) {
86
- const edge = this.graph.getEdge(node.id, neighbor);
87
- const weight = edge?.weight ?? 1;
88
- nodeWeight += weight;
89
- degree++;
90
- }
91
- // For undirected graphs, also check incoming edges
92
- if (!this.graph.isDirected) {
93
- for (const neighbor of Array.from(this.graph.inNeighbors(node.id))) {
94
- if (!this.graph.hasEdge(node.id, neighbor)) {
95
- const edge = this.graph.getEdge(neighbor, node.id);
96
- const weight = edge?.weight ?? 1;
97
- nodeWeight += weight;
98
- degree++;
99
- }
100
- }
101
- }
102
- this.nodeWeights.set(node.id, nodeWeight);
103
- this.nodeDegrees.set(node.id, degree);
104
- this.communityWeights.set(communityId, nodeWeight);
105
- this.totalWeight += nodeWeight;
106
- communityId++;
107
- }
108
- // Total weight is sum of all edge weights
109
- // For undirected graphs, each edge is counted twice from both endpoints
110
- this.totalWeight = this.totalWeight / 2;
65
+ getPruningStats() {
66
+ return { ...this.pruningStats };
111
67
  }
112
68
  /**
113
- * Get nodes ordered by importance (degree * log(weight))
114
- * @returns Array of node IDs sorted by descending importance
69
+ * Index the graph's nodes 0..n-1 and build the level-0 CSR adjacency
70
+ * @returns The level-0 graph and the node id at each index
115
71
  */
116
- getNodesInImportanceOrder() {
117
- const nodeImportance = new Map();
118
- for (const [nodeId, degree] of this.nodeDegrees) {
119
- const weight = this.nodeWeights.get(nodeId) ?? 0;
120
- // Importance score: combination of degree and weight
121
- // High-degree nodes and nodes with heavy edges are processed first
122
- const importance = degree * Math.log(1 + weight);
123
- nodeImportance.set(nodeId, importance);
72
+ buildLevel() {
73
+ const ids = [];
74
+ const index = new Map();
75
+ for (const node of this.graph.nodes()) {
76
+ index.set(node.id, ids.length);
77
+ ids.push(node.id);
78
+ }
79
+ const n = ids.length;
80
+ const edges = [];
81
+ const counts = new Int32Array(n + 1);
82
+ const self = new Float64Array(n);
83
+ const degree = new Float64Array(n);
84
+ for (const edge of this.graph.edges()) {
85
+ const s = index.get(edge.source);
86
+ const t = index.get(edge.target);
87
+ if (s === undefined || t === undefined) {
88
+ continue;
89
+ }
90
+ const w = edge.weight ?? 1;
91
+ degree[s] += w;
92
+ degree[t] += w;
93
+ if (s === t) {
94
+ self[s] += w;
95
+ continue;
96
+ }
97
+ edges.push([s, t, w]);
98
+ counts[s + 1]++;
99
+ counts[t + 1]++;
124
100
  }
125
- // Sort by importance (descending)
126
- return Array.from(nodeImportance.entries())
127
- .sort((a, b) => b[1] - a[1])
128
- .map(([nodeId]) => nodeId);
101
+ return { level: buildCsr(n, counts, edges, self, degree), ids };
129
102
  }
130
103
  /**
131
- * Perform local moving phase with optimizations
132
- * @param nodes - Array of node IDs to process
104
+ * Move each node to the neighbouring community with the best modularity gain, until no move
105
+ * improves modularity
106
+ * @param level - The graph at this level
133
107
  * @param options - Local moving options
134
- * @param options.pruneLeaves - Whether to skip leaf nodes
135
- * @param options.threshold - Minimum gain threshold for moves
136
- * @param options.resolution - Resolution parameter for modularity
137
- * @returns True if any improvement was made, false otherwise
108
+ * @returns Each node's community (numbered 0..count-1), the count, and whether any node moved
138
109
  */
139
- performLocalMoving(nodes, options) {
140
- const { pruneLeaves, threshold, resolution } = options;
141
- let improvement = false;
142
- let hasChanged = true;
143
- while (hasChanged) {
144
- hasChanged = false;
145
- for (const nodeId of nodes) {
146
- // Early pruning: skip leaf nodes
147
- if (pruneLeaves && this.isLeafNode(nodeId)) {
110
+ localMoving(level, options) {
111
+ const { n, offsets, targets, weights, degree } = level;
112
+ const { resolution, maxIterations, tolerance, pruneLeaves } = options;
113
+ const twoM = degree.reduce((sum, d) => sum + d, 0);
114
+ const community = new Int32Array(n);
115
+ const total = new Float64Array(n);
116
+ for (let i = 0; i < n; i++) {
117
+ community[i] = i;
118
+ total[i] = degree[i];
119
+ }
120
+ if (twoM === 0) {
121
+ return { community, count: n, moved: false };
122
+ }
123
+ const order = this.nodeOrder(level, options.importanceOrdering);
124
+ // Scratch: weight from the current node to each community, and the communities touched
125
+ const toCommunity = new Float64Array(n);
126
+ const touched = new Int32Array(n);
127
+ let moved = false;
128
+ let useThreshold = options.thresholdCycling;
129
+ for (let sweep = 0; sweep < maxIterations; sweep++) {
130
+ // The threshold is a fraction of the most node i could gain from any move (all of its
131
+ // weight landing inside the target, k_i), so it scales with the graph
132
+ const threshold = useThreshold ? options.pruningThreshold * Math.pow(0.5, sweep / 10) : 0;
133
+ let sweepMoved = false;
134
+ let sweepGain = 0;
135
+ for (const i of order) {
136
+ const start = offsets[i];
137
+ const end = offsets[i + 1];
138
+ if (pruneLeaves && end - start === 1 && community[targets[start]] === community[i]) {
139
+ // A leaf's only move is to its one neighbour's community, and it is there
148
140
  this.pruningStats.leafNodesPruned++;
149
141
  continue;
150
142
  }
151
- const currentCommunity = this.communities.get(nodeId) ?? 0;
152
- const neighborCommunities = this.getNeighborCommunities(nodeId);
153
- // Skip isolated nodes
154
- if (neighborCommunities.size === 0) {
143
+ if (end === start) {
155
144
  continue;
156
145
  }
157
- // Find best community to move to
158
- let bestCommunity = currentCommunity;
159
- let bestGain = 0;
160
- // Remove node from its current community to calculate gains
161
- this.removeNodeFromCommunity(nodeId, currentCommunity);
162
- for (const community of neighborCommunities) {
163
- const gain = this.calculateModularityGain(nodeId, community, resolution);
164
- // Apply threshold - only move if gain exceeds threshold
165
- if (gain > bestGain + threshold) {
166
- bestGain = gain;
167
- bestCommunity = community;
146
+ const current = community[i];
147
+ let touchedCount = 0;
148
+ for (let e = start; e < end; e++) {
149
+ const c = community[targets[e]];
150
+ if (toCommunity[c] === 0) {
151
+ touched[touchedCount++] = c;
168
152
  }
153
+ toCommunity[c] += weights[e];
169
154
  }
170
- // Try staying in current community
171
- const currentGain = this.calculateModularityGain(nodeId, currentCommunity, resolution);
172
- if (currentGain > bestGain + threshold) {
173
- bestGain = currentGain;
174
- bestCommunity = currentCommunity;
155
+ // Gains are in units of m * dQ: w(i, c) - resolution * tot(c) * k_i / 2m
156
+ const k = degree[i];
157
+ total[current] -= k;
158
+ const stayGain = toCommunity[current] - (resolution * total[current] * k) / twoM;
159
+ let best = current;
160
+ let bestGain = stayGain;
161
+ const minImprovement = threshold * k;
162
+ for (let t = 0; t < touchedCount; t++) {
163
+ const c = touched[t];
164
+ if (c !== current) {
165
+ const gain = toCommunity[c] - (resolution * total[c] * k) / twoM;
166
+ if (gain > bestGain + minImprovement) {
167
+ bestGain = gain;
168
+ best = c;
169
+ }
170
+ }
171
+ toCommunity[c] = 0;
175
172
  }
176
- // Add node to best community
177
- this.addNodeToCommunity(nodeId, bestCommunity);
178
- // Track if node moved
179
- if (bestCommunity !== currentCommunity) {
180
- hasChanged = true;
181
- improvement = true;
173
+ total[best] += k;
174
+ if (best !== current) {
175
+ community[i] = best;
176
+ sweepMoved = true;
177
+ sweepGain += (bestGain - stayGain) / (twoM / 2);
182
178
  }
183
179
  }
184
- }
185
- return improvement;
186
- }
187
- /**
188
- * Check if node is a leaf (degree 1)
189
- * @param nodeId - The node ID to check
190
- * @returns True if the node has degree 1, false otherwise
191
- */
192
- isLeafNode(nodeId) {
193
- const degree = this.nodeDegrees.get(nodeId) ?? 0;
194
- return degree === 1;
195
- }
196
- /**
197
- * Get adaptive threshold that decreases with iterations
198
- * @param iteration - Current iteration number
199
- * @param baseThreshold - Base threshold value to scale
200
- * @returns Adaptive threshold value that decays over iterations
201
- */
202
- getAdaptiveThreshold(iteration, baseThreshold) {
203
- // Exponentially decay threshold with iterations
204
- // This allows coarse movements early and fine-tuning later
205
- return baseThreshold * Math.pow(0.5, iteration / 10);
206
- }
207
- /**
208
- * Calculate modularity gain from moving a node to a community
209
- * @param nodeId - The node ID to move
210
- * @param targetCommunity - The target community ID
211
- * @param resolution - Resolution parameter for modularity calculation
212
- * @returns The modularity gain from moving the node
213
- */
214
- calculateModularityGain(nodeId, targetCommunity, resolution) {
215
- const nodeWeight = this.nodeWeights.get(nodeId) ?? 0;
216
- // Sum of weights from node to target community
217
- let weightToTarget = 0;
218
- for (const neighbor of Array.from(this.graph.neighbors(nodeId))) {
219
- if (this.communities.get(neighbor) === targetCommunity) {
220
- const edge = this.graph.getEdge(nodeId, neighbor);
221
- weightToTarget += edge?.weight ?? 1;
180
+ moved || (moved = sweepMoved);
181
+ if (!sweepMoved || sweepGain < tolerance) {
182
+ // A threshold can stall moves that are still worth making: finish without one
183
+ if (useThreshold) {
184
+ useThreshold = false;
185
+ continue;
186
+ }
187
+ break;
222
188
  }
223
189
  }
224
- // For undirected graphs, also check incoming edges
225
- if (!this.graph.isDirected) {
226
- for (const neighbor of Array.from(this.graph.inNeighbors(nodeId))) {
227
- if (this.communities.get(neighbor) === targetCommunity && !this.graph.hasEdge(nodeId, neighbor)) {
228
- const edge = this.graph.getEdge(neighbor, nodeId);
229
- weightToTarget += edge?.weight ?? 1;
230
- }
190
+ // Renumber the communities 0..count-1
191
+ const renumber = new Int32Array(n).fill(-1);
192
+ let count = 0;
193
+ for (let i = 0; i < n; i++) {
194
+ const c = community[i];
195
+ if (renumber[c] === -1) {
196
+ renumber[c] = count++;
231
197
  }
198
+ community[i] = renumber[c];
232
199
  }
233
- // Weight of target community
234
- const targetWeight = this.communityWeights.get(targetCommunity) ?? 0;
235
- // Modularity gain formula
236
- const gain = (weightToTarget - (resolution * nodeWeight * targetWeight) / (2 * this.totalWeight)) / this.totalWeight;
237
- return gain;
200
+ return { community, count, moved };
238
201
  }
239
202
  /**
240
- * Remove node from community (for gain calculation)
241
- * @param nodeId - The node ID to remove
242
- * @param community - The community ID to remove from
203
+ * Order nodes for local moving, by importance (degree * log(1 + weighted degree)) if asked
204
+ * @param level - The graph at this level
205
+ * @param importanceOrdering - Whether to sort by importance
206
+ * @returns Node indices in processing order
243
207
  */
244
- removeNodeFromCommunity(nodeId, community) {
245
- const nodeWeight = this.nodeWeights.get(nodeId) ?? 0;
246
- this.communityWeights.set(community, (this.communityWeights.get(community) ?? 0) - nodeWeight);
247
- this.communities.delete(nodeId);
248
- }
249
- /**
250
- * Add node to community
251
- * @param nodeId - The node ID to add
252
- * @param community - The community ID to add to
253
- */
254
- addNodeToCommunity(nodeId, community) {
255
- const nodeWeight = this.nodeWeights.get(nodeId) ?? 0;
256
- this.communityWeights.set(community, (this.communityWeights.get(community) ?? 0) + nodeWeight);
257
- this.communities.set(nodeId, community);
258
- }
259
- /**
260
- * Get neighboring communities of a node
261
- * @param nodeId - The node ID to find neighbor communities for
262
- * @returns Set of community IDs that neighbors belong to
263
- */
264
- getNeighborCommunities(nodeId) {
265
- const communities = new Set();
266
- for (const neighbor of Array.from(this.graph.neighbors(nodeId))) {
267
- const community = this.communities.get(neighbor);
268
- if (community !== undefined) {
269
- communities.add(community);
270
- }
208
+ nodeOrder(level, importanceOrdering) {
209
+ const order = new Int32Array(level.n);
210
+ for (let i = 0; i < level.n; i++) {
211
+ order[i] = i;
271
212
  }
272
- // For undirected graphs, also check incoming edges
273
- if (!this.graph.isDirected) {
274
- for (const neighbor of Array.from(this.graph.inNeighbors(nodeId))) {
275
- const community = this.communities.get(neighbor);
276
- if (community !== undefined) {
277
- communities.add(community);
278
- }
279
- }
213
+ if (!importanceOrdering) {
214
+ return order;
280
215
  }
281
- return communities;
282
- }
283
- /**
284
- * Calculate total modularity
285
- * @param resolution - Resolution parameter for modularity calculation
286
- * @returns The modularity score of the current partition
287
- */
288
- calculateModularity(resolution) {
289
- if (this.totalWeight === 0) {
290
- return 0;
216
+ const importance = new Float64Array(level.n);
217
+ for (let i = 0; i < level.n; i++) {
218
+ importance[i] = (level.offsets[i + 1] - level.offsets[i]) * Math.log(1 + level.degree[i]);
291
219
  }
292
- let modularity = 0;
293
- // Sum over all communities
294
- const communityInternalWeights = new Map();
295
- // Calculate internal weights for each community
296
- for (const node of this.graph.nodes()) {
297
- const nodeId = node.id;
298
- const community = this.communities.get(nodeId) ?? 0;
299
- for (const neighbor of Array.from(this.graph.neighbors(nodeId))) {
300
- if (this.communities.get(neighbor) === community) {
301
- const edge = this.graph.getEdge(nodeId, neighbor);
302
- const weight = edge?.weight ?? 1;
303
- communityInternalWeights.set(community, (communityInternalWeights.get(community) ?? 0) + weight);
220
+ return order.sort((a, b) => importance[b] - importance[a]);
221
+ }
222
+ }
223
+ /**
224
+ * Build a CSR level from an undirected edge list (each edge listed once, no self-loops)
225
+ * @param n - Node count
226
+ * @param counts - counts[i + 1] = number of edges incident to node i
227
+ * @param edges - The edges as [source, target, weight]
228
+ * @param self - Self-loop weight of each node
229
+ * @param degree - Weighted degree of each node
230
+ * @returns The level
231
+ */
232
+ function buildCsr(n, counts, edges, self, degree) {
233
+ const offsets = counts;
234
+ for (let i = 0; i < n; i++) {
235
+ offsets[i + 1] += offsets[i];
236
+ }
237
+ const targets = new Int32Array(offsets[n]);
238
+ const weights = new Float64Array(offsets[n]);
239
+ const fill = offsets.slice(0, n);
240
+ for (const [s, t, w] of edges) {
241
+ targets[fill[s]] = t;
242
+ weights[fill[s]++] = w;
243
+ targets[fill[t]] = s;
244
+ weights[fill[t]++] = w;
245
+ }
246
+ return { n, offsets, targets, weights, self, degree };
247
+ }
248
+ /**
249
+ * Fold each community into one node: edges between communities are summed, edges inside a
250
+ * community become its self-loop
251
+ * @param level - The graph at this level
252
+ * @param community - Each node's community, numbered 0..count-1
253
+ * @param count - Number of communities
254
+ * @returns The next level
255
+ */
256
+ function aggregate(level, community, count) {
257
+ const self = new Float64Array(count);
258
+ const degree = new Float64Array(count);
259
+ const members = Array.from({ length: count }, () => []);
260
+ for (let i = 0; i < level.n; i++) {
261
+ const c = community[i];
262
+ members[c].push(i);
263
+ self[c] += level.self[i];
264
+ degree[c] += level.degree[i];
265
+ }
266
+ const edges = [];
267
+ const counts = new Int32Array(count + 1);
268
+ const toCommunity = new Float64Array(count);
269
+ const touched = [];
270
+ for (let c = 0; c < count; c++) {
271
+ for (const i of members[c]) {
272
+ for (let e = level.offsets[i]; e < level.offsets[i + 1]; e++) {
273
+ const d = community[level.targets[e]];
274
+ if (d === c) {
275
+ // Seen once from each endpoint
276
+ self[c] += level.weights[e] / 2;
277
+ }
278
+ else if (d > c) {
279
+ // Keep each inter-community edge once, from its lower-numbered side
280
+ if (toCommunity[d] === 0) {
281
+ touched.push(d);
282
+ }
283
+ toCommunity[d] += level.weights[e];
304
284
  }
305
285
  }
306
286
  }
307
- // Calculate modularity
308
- for (const [community, internalWeight] of communityInternalWeights) {
309
- const communityWeight = this.communityWeights.get(community) ?? 0;
310
- // For undirected graphs, internal weights are counted twice
311
- const aIn = this.graph.isDirected ? internalWeight : internalWeight / 2;
312
- const aTotal = communityWeight;
313
- // Modularity formula: sum of (fraction of edges within community - expected fraction)
314
- const actualFraction = aIn / this.totalWeight;
315
- const expectedFraction = resolution * Math.pow(aTotal / (2 * this.totalWeight), 2);
316
- modularity += actualFraction - expectedFraction;
287
+ for (const d of touched) {
288
+ edges.push([c, d, toCommunity[d]]);
289
+ counts[c + 1]++;
290
+ counts[d + 1]++;
291
+ toCommunity[d] = 0;
317
292
  }
318
- return modularity;
293
+ touched.length = 0;
319
294
  }
320
- /**
321
- * Get pruning statistics
322
- * @returns Statistics about nodes pruned during optimization
323
- */
324
- getPruningStats() {
325
- return { ...this.pruningStats };
295
+ return buildCsr(count, counts, edges, self, degree);
296
+ }
297
+ /**
298
+ * Modularity of the partition that puts each node of `level` in its own community
299
+ * @param level - The graph at this level
300
+ * @param resolution - Resolution parameter
301
+ * @returns Q = sum over nodes c of [ self(c) / m - resolution * (k_c / 2m)^2 ]
302
+ */
303
+ function levelModularity(level, resolution) {
304
+ const twoM = level.degree.reduce((sum, d) => sum + d, 0);
305
+ if (twoM === 0) {
306
+ return 0;
307
+ }
308
+ let modularity = 0;
309
+ for (let c = 0; c < level.n; c++) {
310
+ const share = level.degree[c] / twoM;
311
+ modularity += (2 * level.self[c]) / twoM - resolution * share * share;
326
312
  }
313
+ return modularity;
327
314
  }
328
315
  /**
329
316
  * Optimized Louvain algorithm with automatic optimization selection
@@ -1 +1 @@
1
- {"version":3,"file":"louvain-optimized.js","sourceRoot":"","sources":["../../../../src/algorithms/community/louvain-optimized.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"louvain-optimized.js","sourceRoot":"","sources":["../../../../src/algorithms/community/louvain-optimized.ts"],"names":[],"mappings":"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"}