Skip to content

Commit a020c2d

Browse files
author
cindeem
committed
Merge pull request #6 from kbegany/edits
Added check_integrity method to GraphPartition to check for empty or nan partitions
2 parents dbb0add + ed4513d commit a020c2d

File tree

1 file changed

+17
-71
lines changed

1 file changed

+17
-71
lines changed

brainx/modularity.py

Lines changed: 17 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,7 @@ def _edge_info(self, mod_e=None, mod_a=None, index=None):
156156
mod_e[m] = perc_within #all of the E's
157157
mod_a[m] = perc_btwn+perc_within #all of the A's
158158
if np.isnan(mod_e[m]) or np.isnan(mod_a[m]):
159-
raise ArithmaticError('NAN found: mod_e=%s, mod_a=%s'%(mod_e[m], mod_a[m]))
159+
raise ArithmeticError('NAN found: mod_e=%s, mod_a=%s'%(mod_e[m], mod_a[m]))
160160

161161
return mod_e, mod_a
162162

@@ -172,7 +172,7 @@ def modularity_newman(self):
172172
mod = modularity
173173
"""
174174
if np.isnan((np.array(self.mod_e) - (np.array(self.mod_a)**2)).sum()):
175-
1/0
175+
raise ArithmeticError('NAN found: mod_e=%s, mod_a=%s'%(mod_e[m], mod_a[m]))
176176
return (np.array(self.mod_e) - (np.array(self.mod_a)**2)).sum()
177177

178178
##TODO can we remove this?? CM
@@ -516,7 +516,6 @@ def random_mod(self):
516516

517517
if coin_flip > 0.5:
518518
#merge
519-
#return self.module_merge(m1,m2)
520519
return self.compute_module_merge(m1,m2)
521520
else:
522521
#split
@@ -537,7 +536,7 @@ def random_mod(self):
537536
return self.compute_module_split(m1,n1,n2)
538537

539538
def determine_node_split(self,m1):
540-
""" Determine hwo to split notes within a module
539+
""" Determine how to split nodes within a module
541540
"""
542541

543542
# list of nodes within that module
@@ -553,68 +552,6 @@ def determine_node_split(self,m1):
553552

554553
return n1,n2
555554

556-
557-
def random_mod_old(self):
558-
"""Makes a choice whether to merge or split modules in a partition
559-
560-
Returns:
561-
-------
562-
if splitting: m1, n1, n2
563-
m1: the module to split
564-
n1: the set of nodes to put in the first output module
565-
n2: the set of nodes to put in the second output module
566-
567-
if merging: m1, m2
568-
m1: module 1 to merge
569-
m2: module 2 to merge
570-
"""
571-
572-
# number of modules in the partition
573-
num_mods=len(self)
574-
575-
576-
# Make a random choice bounded between 0 and 1, less than 0.5 means we will split the modules
577-
# greater than 0.5 means we will merge the modules.
578-
579-
if num_mods >= self.num_nodes-1:
580-
coin_flip = 1 #always merge if each node is in a separate module
581-
elif num_mods <= 2:
582-
coin_flip = 0 #always split if there's only one module
583-
else:
584-
coin_flip = random.random()
585-
586-
#randomly select two modules to operate on
587-
rand_mods = np.random.permutation(range(num_mods))
588-
m1 = rand_mods[0]
589-
m2 = rand_mods[1]
590-
591-
if coin_flip > 0.5:
592-
#merge
593-
#return self.module_merge(m1,m2)
594-
return self.module_merge(m1,m2)
595-
else:
596-
#split
597-
# cannot have a module with less than 1 node
598-
while len(self.index[m1]) <= 1:
599-
600-
#reselect the first module
601-
rand_mods = np.random.permutation(range(num_mods))
602-
m1 = rand_mods[0]
603-
#m1 = random.randint(0,num_mods)
604-
605-
# list of nodes within that module
606-
list_nods = list(self.index[m1])
607-
608-
# randomly partition the list of nodes into 2
609-
nod_split_ind = random.randint(1,len(list_nods)) #can't pick the first node as the division
610-
n1 = set(list_nods[:nod_split_ind])
611-
n2 = set(list_nods[nod_split_ind:])
612-
613-
#We may want to return output of merging/splitting directly, but
614-
#for now we're returning inputs for those modules.
615-
616-
return self.module_split(m1,n1,n2)
617-
618555
def random_node(self):
619556
""" Randomly reassign one node from one module to another
620557
@@ -662,7 +599,16 @@ def store_best(self):
662599
#Store references to the original graph and label dict
663600
self.bestindex = copy.deepcopy(self.index)
664601

602+
def check_integrity(self, partition):
603+
""" Raises error if partition structure contains
604+
empty partitions or Nan values"""
665605

606+
for tmpset in partition.values():
607+
if tmpset == set([]):
608+
raise ValueError("Partition has empty key : %s"%partition)
609+
if any([np.isnan(x) for x in tmpset]):
610+
raise ValueError("Partition contains NaN value(s)")
611+
666612

667613
#-----------------------------------------------------------------------------
668614
# Functions
@@ -1276,13 +1222,12 @@ def simulated_annealing(g, p0=None, temperature = 50, temp_scaling = 0.995, tmin
12761222
npt.assert_almost_equal(debug_partition.modularity(),
12771223
graph_part_final.modularity(), 11)
12781224

1279-
for mod in graph_part_final.index:
1280-
if len(graph_part_final.index[mod]) < 1:
1281-
empty_module('LAST CHECK: Empty module after module %s,SA' % (movetype))
1225+
debug_partition.check_integrity(graph_part_final.index)
12821226

12831227
if extra_info:
12841228
extra_dict = dict(energy = energy_array, temp = temp_array)
1285-
#return graph_partition, extra_dict
1229+
graph_part_final.check_integrity(graph_part_final.index)
1230+
#return graph_partition, extra_dict
12861231
return graph_part_final, extra_dict
12871232
else:
12881233
#return graph_partition
@@ -1298,8 +1243,9 @@ def simulated_annealing(g, p0=None, temperature = 50, temp_scaling = 0.995, tmin
12981243

12991244
if np.abs(finalmodval - (-energy_best)) > 0.000001: #to account for float error
13001245
raise ValueError('mismatch in energy and modularity')
1246+
13011247

1302-
return graph_part_final,graph_part_final.modularity()
1248+
return graph_part_final, graph_part_final.modularity()
13031249

13041250

13051251
def modularity_matrix(g):

0 commit comments

Comments
 (0)