Intro
I'm referring to the original paper Fast unfolding of communities in large networks by Blondel et al. in this question and adopt their notation. Explanation for the used symbols is on page 4 below equation (2).
I'm wondering why Blondel et al. are dropping the coefficient $\frac{1}{m}$. First, let's simplify their equation (2) to see what I mean:
$$ \Delta Q= \Biggl[ \frac{\Sigma_{in}+2k_{i,in}}{2m} - \Bigl( \frac{\Sigma_{tot}+k_i}{2m} \Bigr)^2 \Biggr] - \Biggl[ \frac{\Sigma_{in}}{2m} - \Bigl( \frac{\Sigma_{tot}}{2m} \Bigr)^2 - \Bigl( \frac{k_i}{2m} \Bigr)^2 \Biggr] $$
$$ \Delta Q = \frac{\Sigma_{in}}{2m} + \frac{2k_{i,in}}{2m} - \Bigl( \frac{\Sigma_{tot}}{2m} + \frac{k_i}{2m}\Bigr)^2 - \frac{\Sigma_{in}}{2m} + \Bigl( \frac{\Sigma_{tot}}{2m} \Bigr)^2 + \Bigl( \frac{k_i}{2m} \Bigr)^2 $$
$$ \Delta Q = \frac{2k_{i,in}}{2m} - \frac{\Sigma_{tot}\cdot 2k_i}{(2m)^2} $$
However, this is not the version they used in their code. On their official code page, they've linked to sourceforge to download the C++ code. In the file Modularity.h
, you'll find the following code:
inline long double
Modularity::gain(int node, int comm, long double dnc, long double degc) {
assert(node>=0 && node<size);
long double totc = tot[comm];
long double m2 = g.total_weight;
return (dnc - totc*degc/m2);
}
dnc
is passed over in line 257 in louvain.cpp
and calculated in the method void Louvain::neigh_comm(int node)
. If you follow the calculations, you will see that this is actually our $k_{i,in}$ in the formula. I'm now wondering where this line in the method Modularity::gain(...)
comes from:
return (dnc - totc*degc/m2);
My guess
Let's further "simplify" our formula to a point where it resembles the code used:
$$\Delta Q = \frac{2k_{i,in}\cdot \frac{1}{2m}}{2m\cdot \frac{1}{2m}} - \frac{\Sigma_{tot}\cdot 2k_i \cdot \frac{1}{2m}}{(2m)^2 \cdot \frac{1}{2m}}$$
$$ \Delta Q = \frac{k_{i,in}}{m} - \frac{\Sigma_{tot}\cdot \frac{k_i}{m}}{2m}$$
Now, let $d$ denote $\frac{k_{i,in}}{m}$ and we get:
$$d=\frac{k_{i,in}}{m} \Rightarrow \Delta Q = d - \frac{\Sigma_{tot}\cdot d}{2m}$$
So, this is pretty much the equation we see in the code. However, Blondel et al. use $k_{i,in}$ and not the scaled version $d$, meaning they are dropping the coefficient $\frac{1}{m}$.
Maybe I'm mistaken and they do actually calculate our variable $d$ in the method void Louvain::neigh_comm(int comm)
. But I just don't find a line where they divide by $m$ in the code. Hope this is not an XY problem I'm asking for here.