Newman–Girvan modularity Q = Σ_ij [A_ij − k_i·k_j/2m]·δ(c_i,c_j) / 2m, decomposed as
Q = Σ_c [ in_c/2m − (tot_c/2m)² ] where in_c is the intra-community edge weight (the
adjacency rep counts each undirected edge twice) and tot_c the community's degree sum.
v3.10.0-rc.43 (M7) — FIX: the prior implementation summed the null-model penalty
(k_i·k_j/2m) ONLY over ADJACENT same-community pairs (it lived inside the for (…of neighbors) loop), but the standard formula penalizes ALL same-community pairs incl.
non-adjacent ones (where A_ij=0 but −k_i·k_j/2m still applies). The truncated penalty
inflated Q and could rank a degenerate single-community partition ABOVE the correct
split. Now the penalty is the exact Σ_c tot_c² over per-community degree sums.
Newman–Girvan modularity Q = Σ_ij [A_ij − k_i·k_j/2m]·δ(c_i,c_j) / 2m, decomposed as Q = Σ_c [ in_c/2m − (tot_c/2m)² ] where
in_cis the intra-community edge weight (the adjacency rep counts each undirected edge twice) andtot_cthe community's degree sum.v3.10.0-rc.43 (M7) — FIX: the prior implementation summed the null-model penalty
(k_i·k_j/2m)ONLY over ADJACENT same-community pairs (it lived inside thefor (…of neighbors)loop), but the standard formula penalizes ALL same-community pairs incl. non-adjacent ones (where A_ij=0 but −k_i·k_j/2m still applies). The truncated penalty inflated Q and could rank a degenerate single-community partition ABOVE the correct split. Now the penalty is the exact Σ_c tot_c² over per-community degree sums.