@@ -1270,13 +1270,20 @@ def simulated_annealing(g, p0=None, temperature = 50, temp_scaling = 0.995, tmin
1270
1270
1271
1271
def modularity_matrix (g ):
1272
1272
"""Modularity matrix of the graph.
1273
+
1274
+ Parameters
1275
+ ----------
1276
+ g : NetworkX graph
1277
+ input graph
1273
1278
1274
- The eigenvector corresponding to the largest eigenvalue of the modularity
1275
- matrix is analyzed to assign clusters.
1276
-
1279
+ Returns
1280
+ -------
1281
+ B : numpy array
1282
+ modularity matrix (graph laplacian)
1283
+
1277
1284
"""
1278
1285
A = np .asarray (nx .adjacency_matrix (g ))
1279
- k = np .sum (A , axis = 0 )
1286
+ k = np .sum (A , axis = 0 ) #vertex degree
1280
1287
M = np .sum (k ) # 2x number of edges
1281
1288
1282
1289
return A - ((k * k [:, None ]) / float (M ))
@@ -1312,15 +1319,13 @@ def _divide_partition(p, max_div=np.inf):
1312
1319
----------
1313
1320
p : array of ints
1314
1321
Node labels.
1315
- B : ndarray
1316
- Modularity matrix.
1322
+ max_div : int
1323
+ maximum number of divisions (default np.inf)
1317
1324
1318
1325
Returns
1319
1326
-------
1320
- pp, qq : list of ints
1321
- Partitioning of node labels. If the partition is indivisible, then
1322
- only `pp` is returned.
1323
-
1327
+ out : list of ints
1328
+ Partitioning of node labels.
1324
1329
"""
1325
1330
p = np .asarray (p )
1326
1331
@@ -1329,13 +1334,8 @@ def _divide_partition(p, max_div=np.inf):
1329
1334
1330
1335
# Construct the subgraph modularity matrix
1331
1336
A_ = A [p , p [:, None ]]
1332
- k_ = np .sum (A_ , axis = 0 )
1333
- M_ = np .sum (k_ )
1334
-
1335
- B_ = B [p , p [:, None ]]
1336
- B_ = B_ - np .diag (k_ - k [p ] * M_ / float (M ))
1337
-
1338
- # w, v = nl.eigh(B_)
1337
+ graph_A_ = nx .from_numpy_matrix (A_ , nx .Graph ())
1338
+ B_ = modularity_matrix (graph_A_ )
1339
1339
w , v = sl .eigh (B_ , eigvals = (len (B_ ) - 2 , len (B_ ) - 1 ))
1340
1340
1341
1341
# Find the maximum eigenvalue of the modularity matrix
@@ -1349,6 +1349,9 @@ def _divide_partition(p, max_div=np.inf):
1349
1349
# to nodes in the first partition and 1 for nodes in the second
1350
1350
v_max = v [:, n ]
1351
1351
mask = (v_max < 0 )
1352
+ # if the mask is all true or all false, this will not split the partition
1353
+ if not np .any (mask ) or not np .any (~ mask ):
1354
+ return [p ]
1352
1355
s = np .ones_like (v_max )
1353
1356
s [mask ] = - 1
1354
1357
0 commit comments