@@ -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 ))
@@ -1300,6 +1307,10 @@ def newman_partition(g, max_div=np.inf):
1300
1307
1301
1308
"""
1302
1309
A = np .asarray (nx .adjacency_matrix (g ))
1310
+ if not A .sum () == A .astype (bool ).sum ():
1311
+ raise ValueError ('Adjacency matrix is weighted, need binary matrix' )
1312
+ ## add line to binarize adj_matrix if not binary
1313
+ ## warning?
1303
1314
k = np .sum (A , axis = 0 )
1304
1315
M = np .sum (A ) # 2x number of edges
1305
1316
B = modularity_matrix (g )
@@ -1312,15 +1323,13 @@ def _divide_partition(p, max_div=np.inf):
1312
1323
----------
1313
1324
p : array of ints
1314
1325
Node labels.
1315
- B : ndarray
1316
- Modularity matrix.
1326
+ max_div : int
1327
+ maximum number of divisions (default np.inf)
1317
1328
1318
1329
Returns
1319
1330
-------
1320
- pp, qq : list of ints
1321
- Partitioning of node labels. If the partition is indivisible, then
1322
- only `pp` is returned.
1323
-
1331
+ out : list of ints
1332
+ Partitioning of node labels.
1324
1333
"""
1325
1334
p = np .asarray (p )
1326
1335
@@ -1329,13 +1338,11 @@ def _divide_partition(p, max_div=np.inf):
1329
1338
1330
1339
# Construct the subgraph modularity matrix
1331
1340
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_)
1341
+ graph_A_ = nx .from_numpy_matrix (A_ , nx .Graph ())
1342
+ # make sure partition has edges
1343
+ if graph_A_ .number_of_edges () <= 1 :
1344
+ return [p ]
1345
+ B_ = modularity_matrix (graph_A_ )
1339
1346
w , v = sl .eigh (B_ , eigvals = (len (B_ ) - 2 , len (B_ ) - 1 ))
1340
1347
1341
1348
# Find the maximum eigenvalue of the modularity matrix
@@ -1349,6 +1356,11 @@ def _divide_partition(p, max_div=np.inf):
1349
1356
# to nodes in the first partition and 1 for nodes in the second
1350
1357
v_max = v [:, n ]
1351
1358
mask = (v_max < 0 )
1359
+ # if the mask is all True or all False, this will not split the partition
1360
+ # and would create an empty partition
1361
+ # catch by checking max vector contains pos and neg values
1362
+ if np .abs (v_max .sum ()) == np .abs (v_max ).sum ():
1363
+ return [p ]
1352
1364
s = np .ones_like (v_max )
1353
1365
s [mask ] = - 1
1354
1366
0 commit comments