34 grid->delete_top_level_A =
false;
37 grid->agglomerate_regardless =
false;
40 double modularity = 0;
41 int *ia =
A->ia, *ja =
A->ja;
43 double *deg, *a =
A->a;
49 double *indeg =
gv_calloc(n,
sizeof(
double));
50 for (i = 0; i < n; i++){
53 for (j = ia[i]; j < ia[i+1]; j++){
55 if (ja[j] == i) indeg[i] = a[j];
59 deg_total = fmax(deg_total, 1);
60 for (i = 0; i < n; i++){
61 modularity += (indeg[i] - deg[i]*deg[i]/deg_total)/deg_total;
63 grid->deg_total = deg_total;
65 grid->modularity = modularity;
76 if (
grid->level == 0) {
93 int n =
grid->
n, level =
grid->level, nc = 0;
94 double modularity = 0;
95 int *ia =
A->ia, *ja =
A->ja;
96 double *deg =
grid->deg;
97 int i, j, jj, jc, jmax;
98 double inv_deg_total = 1./
grid->deg_total;
101 double total_gain = 0;
102 modularity =
grid->modularity;
104 double *deg_new =
gv_calloc(n,
sizeof(
double));
105 double *deg_inter =
gv_calloc(n,
sizeof(
double));
107 for (i = 0; i < n; i++) mask[i] = -1;
110 for (i = 0; i < n; i++) matching[i] =
UNMATCHED;
116 for (i = 0; i < n; i++){
119 for (j = ia[i]; j < ia[i+1]; j++){
121 if (jj == i)
continue;
125 deg_inter[jc] = a[j];
127 deg_inter[jc] += a[j];
134 for (j = ia[i]; j < ia[i+1]; j++){
136 if (jj == i)
continue;
139 gain = (2*a[j] - 2*deg[i]*deg[jj]*inv_deg_total)*inv_deg_total;
141 if (deg_inter[jc] > 0){
143 gain = (2*deg_inter[jc] - 2*deg[i]*deg_new[jc]*inv_deg_total)*inv_deg_total;
150 if (jmax < 0 || gain > maxgain){
158 if (maxgain > 0 ||
grid->agglomerate_regardless){
159 total_gain += maxgain;
163 matching[i] = matching[jmax] = nc;
164 deg_new[nc] = deg[i] + deg[jmax];
168 deg_new[jc] += deg[i];
172 assert(maxgain <= 0);
174 deg_new[nc] = deg[i];
180 if (
Verbose) fprintf(stderr,
"modularity = %f new modularity = %f level = %d, n = %d, nc = %d, gain = %g\n", modularity, modularity + total_gain,
181 level, n, nc, total_gain);
183 if (ncluster_target > 0){
184 if (nc <= ncluster_target && n >= ncluster_target){
185 if (n - ncluster_target > ncluster_target - nc){
187 }
else if (n - ncluster_target <= ncluster_target - nc){
188 fprintf(stderr,
"ncluster_target = %d, close to n=%d\n", ncluster_target, n);
189 for (i = 0; i < n; i++) matching[i] = i;
193 }
else if (n < ncluster_target){
194 fprintf(stderr,
"n < target\n");
195 for (i = 0; i < n; i++) matching[i] = i;
201 if (nc >= 1 && (total_gain > 0 || nc < n)){
208 for (i = 0; i < n; i++){
230 cgrid->
deg = deg_new;
238 if (ncluster_target > 0 && nc > ncluster_target && !(
grid->agglomerate_regardless)){
246 for (i = 0; i < n; i++) matching[i] = i;
275 if (
A != A0)
grid->delete_top_level_A =
true;
281 int *nclusters,
int **assignment,
double *modularity){
300 assert(
A->m ==
A->n);
313 double *u =
gv_calloc(cgrid->
n,
sizeof(
double));
314 for (i = 0; i < cgrid->
n; i++) u[i] = (
double) (cgrid->
matching)[i];
315 *nclusters = cgrid->
n;
328 matching = *assignment;
331 *assignment = matching;
333 for (i = 0; i <
grid->n; i++) (matching)[i] = (int) u[i];
342 int *nclusters,
int **assignment,
double *modularity){
358 assert(
A->m ==
A->n);
362 if (!inplace &&
B ==
A) {
SparseMatrix SparseMatrix_from_coordinate_format(SparseMatrix A)
SparseMatrix SparseMatrix_transpose(SparseMatrix A)
SparseMatrix SparseMatrix_symmetrize(SparseMatrix A, bool pattern_symmetric_only)
SparseMatrix SparseMatrix_coordinate_form_add_entry(SparseMatrix A, int irn, int jcn, const void *val)
bool SparseMatrix_is_symmetric(SparseMatrix A, bool test_pattern_symmetry_only)
void SparseMatrix_multiply_vector(SparseMatrix A, double *v, double **res)
SparseMatrix SparseMatrix_multiply(SparseMatrix A, SparseMatrix B)
void SparseMatrix_delete(SparseMatrix A)
SparseMatrix SparseMatrix_copy(SparseMatrix A)
SparseMatrix SparseMatrix_set_entries_to_real_one(SparseMatrix A)
SparseMatrix SparseMatrix_get_real_adjacency_matrix_symmetrized(SparseMatrix A)
SparseMatrix SparseMatrix_remove_diagonal(SparseMatrix A)
SparseMatrix SparseMatrix_new(int m, int n, int nz, int type, int format)
Memory allocation wrappers that exit on failure.
static void * gv_calloc(size_t nmemb, size_t size)
static void * gv_alloc(size_t size)
static Multilevel_Modularity_Clustering Multilevel_Modularity_Clustering_establish(Multilevel_Modularity_Clustering grid, int ncluster_target)
void modularity_clustering(SparseMatrix A, bool inplace, int ncluster_target, int *nclusters, int **assignment, double *modularity)
static Multilevel_Modularity_Clustering Multilevel_Modularity_Clustering_new(SparseMatrix A0, int ncluster_target)
static Multilevel_Modularity_Clustering Multilevel_Modularity_Clustering_init(SparseMatrix A, int level)
static void hierachical_modularity_clustering(SparseMatrix A, int ncluster_target, int *nclusters, int **assignment, double *modularity)
static void Multilevel_Modularity_Clustering_delete(Multilevel_Modularity_Clustering grid)
Multilevel_Modularity_Clustering prev
bool agglomerate_regardless
Multilevel_Modularity_Clustering next