@@ -71,9 +71,17 @@ def __init__(self, graph, index):
71
71
objects.
72
72
"""
73
73
# Store references to the original graph and label dict
74
+ if not type (index ) == type ({}):
75
+ raise TypeError ('index should be of type dict(), not %s' % type (index ))
76
+
74
77
self .index = copy .deepcopy (index )
75
- #self.graph = graph
76
78
79
+ ## add quick check to make sure the passed index is
80
+ ## a dict of sets
81
+ self ._check_index_contains_sets ()
82
+ ## raise useful error if index is missing nodes in graph
83
+ self ._check_allnodes_in_index (graph )
84
+
77
85
# We'll need the graph's adjacency matrix often, so store it once
78
86
self .graph_adj_matrix = nx .adj_matrix (graph )
79
87
@@ -102,6 +110,25 @@ def copy(self):
102
110
def __len__ (self ):
103
111
return len (self .index )
104
112
113
+
114
+ def _check_index_contains_sets (self ):
115
+ """ the index in a GraphPartition is a dict of node sets
116
+ validate that the values of this dict are all of type(set)"""
117
+ index_types = [ type (x ) for x in self .index .values () ]
118
+ if not all ([ x == type (set ()) for x in index_types ]):
119
+ raise TypeError ('index values should be of type set():: %s' % (index_types ))
120
+
121
+ def _check_allnodes_in_index (self , graph ):
122
+ """Check that index contains all nodes in graph"""
123
+ sets = self .index .values ()
124
+ all = []
125
+ for item in sets :
126
+ all += list (item )
127
+ if not sorted (all ) == sorted (graph .nodes ()):
128
+ missing = [x for x in all if not x in graph .nodes ()]
129
+ raise ValueError ('index does not contain all nodes: missing %s' % missing )
130
+
131
+
105
132
def _edge_info (self , mod_e = None , mod_a = None , index = None ):
106
133
"""Create the vectors of edge information.
107
134
@@ -116,26 +143,20 @@ def _edge_info(self, mod_e=None, mod_a=None, index=None):
116
143
if mod_a is None : mod_a = [0 ] * num_mod
117
144
if index is None : index = self .index
118
145
119
- norm_factor = 1.0 / (2.0 * self .num_edges )
146
+ norm_factor = 1.0 / (2.0 * self .num_edges )
120
147
mat = self .graph_adj_matrix
121
- set_nodes = self ._node_set
122
- for m ,modnodes in index .iteritems ():
123
- #set_modnodes=set(modnodes)
124
- #btwnnodes = list(set_nodes - modnodes)
125
- btwnnodes = list (set_nodes - set (index [m ]))
148
+ node_set = self ._node_set
149
+ for m , modnodes in index .iteritems ():
150
+ btwnnodes = list (node_set - modnodes )
126
151
modnodes = list (modnodes )
127
- #why isnt' self.index a set already? graph_partition.index[m]
128
- #looks like a set when we read it in ipython
129
152
mat_within = mat [modnodes ,:][:,modnodes ]
130
153
mat_between = mat [modnodes ,:][:,btwnnodes ]
131
154
perc_within = mat_within .sum () * norm_factor
132
155
perc_btwn = mat_between .sum () * norm_factor
133
156
mod_e [m ] = perc_within #all of the E's
134
157
mod_a [m ] = perc_btwn + perc_within #all of the A's
135
- #mod_e.append(perc_within)
136
- #mod_a.append(perc_btwn+perc_within)
137
158
if np .isnan (mod_e [m ]) or np .isnan (mod_a [m ]):
138
- 1 / 0
159
+ raise ArithmaticError ( 'NAN found: mod_e=%s, mod_a=%s' % ( mod_e [ m ], mod_a [ m ]))
139
160
140
161
return mod_e , mod_a
141
162
@@ -154,42 +175,9 @@ def modularity_newman(self):
154
175
1 / 0
155
176
return (np .array (self .mod_e ) - (np .array (self .mod_a )** 2 )).sum ()
156
177
178
+ ##TODO can we remove this?? CM
157
179
modularity = modularity_newman
158
180
159
- #modularity = modularity_guimera
160
-
161
-
162
- ## def modularity_guimera(self, g, part):
163
- ## """This function takes in a graph and a partition and returns Newman's
164
- ## modularity for that graph"""
165
-
166
- ## """ Parameters
167
- ## # g = graph part = partition; a dictionary that contains a list of
168
- ## # nodes that make up that module"""
169
-
170
- ## #graph values
171
- ## num_mod = len(part)
172
- ## L = nx.number_of_edges(g)
173
- ## # construct an adjacency matrix from the input graph (g)
174
- ## mat = nx.adj_matrix(g)
175
-
176
- ## M = 0
177
- ## # loop over the modules in the graph, create an adjacency matrix
178
- ## for m, val in part.iteritems():
179
- ## #create a 'sub mat'
180
- ## submat = mat[val,:][:,val]
181
-
182
- ## #make a graph
183
- ## subg = nx.from_numpy_matrix(submat)
184
-
185
- ## #calculate module-specific metrics
186
- ## link_s = float(subg.number_of_edges())
187
- ## deg_s = np.sum(nx.degree(g,val), dtype=float)
188
-
189
- ## #compute modularity!
190
- ## M += ((link_s/L) - (deg_s/(2*L))**2)
191
-
192
- ## return M
193
181
194
182
def compute_module_merge (self , m1 , m2 ):
195
183
"""Merges two modules in a given partition.
0 commit comments