@@ -160,3 +160,103 @@ def committor(transmat,basins,tol=1e-6,maxstep=20):
160160
161161 return committor
162162
163+ def extend (transmat ,hubstates ):
164+ """
165+ This function returns an extended transition matrix (2N x 2N)
166+ where one set of states (0..N-1) have NOT yet visited hubstates,
167+ and states (N..2N-1) HAVE visited the hubstates.
168+ """
169+ n = transmat .shape [0 ]
170+
171+ # data, rows and cols of the future extended matrix
172+ data = []
173+ rows = []
174+ cols = []
175+
176+ for i in range (len (transmat .data )):
177+ if transmat .row [i ] in hubstates :
178+ # transition TO a hubstate, add to lower left and lower right
179+ # lower left
180+ data .append (transmat .data [i ])
181+ rows .append (transmat .row [i ] + n )
182+ cols .append (transmat .col [i ])
183+ # lower right
184+ data .append (transmat .data [i ])
185+ rows .append (transmat .row [i ] + n )
186+ cols .append (transmat .col [i ] + n )
187+ else :
188+ # transition not to a hubstate, add to upper left and lower right
189+ # upper left
190+ data .append (transmat .data [i ])
191+ rows .append (transmat .row [i ])
192+ cols .append (transmat .col [i ])
193+ # lower right
194+ data .append (transmat .data [i ])
195+ rows .append (transmat .row [i ] + n )
196+ cols .append (transmat .col [i ] + n )
197+
198+ ext_mat = scipy .sparse .coo_matrix ((data , (rows , cols )), shape = (2 * n ,2 * n ))
199+ return ext_mat
200+
201+ def hubscores (transmat ,hubstates ,basins ,tol = 1e-6 ,maxstep = 20 ,wts = None ):
202+ """
203+ This function computes hub scores, which are the probabilities that
204+ transitions between a set of communities will use a given community as
205+ an intermediate. e.g. h_a,b,c is the probability that transitions from
206+ basin a to basin b will use c as an intermediate.
207+
208+ For more information see:
209+ Dickson, A and Brooks III, CL. JCTC, 8, 3044-3052 (2012).
210+
211+ Input:
212+
213+ transmat -- An N x N transition matrix in scipy sparse coo format.
214+ Columns should sum to 1. Indices: [to][from]
215+
216+ hubstates -- A list describing the states in transmat that make up
217+ the hub being measured.
218+
219+ basins -- A list of two lists, describing which two states make up the
220+ basins of attraction.
221+ e.g. [[basin_a_1,basin_a_2,...],[basin_b_1,basin_b_2,...]].
222+
223+ wts -- The equilibrium weights of all states in transmat. If this is not
224+ given then the function will compute them from eig_weights.
225+
226+ Output: [h_a,b,c , h_b,a,c]
227+ """
228+
229+ # make extended sink_matrix
230+ n = transmat .shape [0 ]
231+ ext_transmat = extend (transmat ,hubstates )
232+
233+ flat_sink = [i for b in basins for i in b ]
234+ flat_sink_ext = flat_sink + [i + n for i in flat_sink ]
235+
236+ sink_mat = make_sink (ext_transmat ,flat_sink_ext )
237+
238+ sink_results = trans_mult_iter (sink_mat ,tol ,maxstep )
239+
240+ if wts is None :
241+ wts = eig_weights (transmat )
242+
243+ h = np .zeros ((2 ,2 ),dtype = float )
244+ ring = [getring (transmat ,b ,eig_weights ) for b in basins ]
245+
246+ for source ,sink in [[0 ,1 ],[1 ,0 ]]:
247+ for i ,p in enumerate (ring [source ]):
248+ if p > 0 :
249+ # i is a ring state of source basin, with probability p
250+ if i in hubstates :
251+ testi = i + n
252+ else :
253+ testi = i
254+ c_no = 0
255+ c_yes = 0
256+ for b in basins [sink ]:
257+ c_no += sink_results [b ][testi ]
258+ c_yes += sink_results [b + n ][testi ]
259+ if (c_no + c_yes ) > 0 :
260+ h [source ][sink ] += p * c_yes / (c_no + c_yes )
261+
262+ return [h [0 ,1 ],h [1 ,0 ]]
0 commit comments