Package trunk :: Package BIP :: Package SDE :: Module gillespie
[hide private]

Source Code for Module trunk.BIP.SDE.gillespie

  1  # -*- coding:utf-8 -*- 
  2  #----------------------------------------------------------------------------- 
  3  # Name:        gillespie.py 
  4  # Project:  Bayesian-Inference 
  5  # Purpose:      
  6  # 
  7  # Author:      Flávio Codeço Coelho<fccoelho@gmail.com> 
  8  # 
  9  # Created:     2008-11-26 
 10  # Copyright:   (c) 2008 by the Author 
 11  # Licence:     GPL 
 12  #----------------------------------------------------------------------------- 
 13  __docformat__ = "restructuredtext en" 
 14  from numpy.random import uniform, multinomial, exponential,random 
 15  from numpy import arange, array, empty,zeros,log, isnan, nanmax, nan_to_num,  ceil 
 16  import time 
 17  import xmlrpclib 
 18  import pdb 
 19  import copy 
 20  from multiprocessing import Pool 
 21  try: 
 22      from liveplots import xmlrpcserver as xmlrpc 
 23      port = xmlrpc.rpc_plot(persist=0) 
 24      server = xmlrpclib.ServerProxy('http://localhost:%s'%port, allow_none=True) 
 25      viz = True 
 26  except: 
 27      print "faio" 
 28      viz = False 
 29  try: 
 30      import psyco 
 31      psyco.full() 
 32  except: 
 33      pass 
34 -def dispatch(model):
35 '''this function is necessary for paralelization''' 36 model.server = server 37 return model.GSSA()
38
39 -class Model:
40 - def __init__(self,vnames,rates,inits, tmat,propensity):
41 ''' 42 Class representing a Stochastic Differential equation. 43 44 :Parameters: 45 - `vnames`: list of strings 46 - `rates`: list of fixed rate parameters 47 - `inits`: list of initial values of variables. Must be integers 48 - `tmat`: Transition matrix; numpy array with shape=(len(inits),len(propensity)) 49 - `propensity`: list of lambda functions of the form: lambda r,ini: some function of rates ans inits. 50 ''' 51 #check types 52 for i in inits: 53 if not isinstance(i, int): 54 i = int(i) 55 for i in tmat.ravel(): 56 assert isinstance(i, int) 57 self.vn = vnames 58 self.rates = tuple(rates) 59 self.inits = tuple(inits) 60 self.tm = tmat 61 self.pv = propensity#[compile(eq,'errmsg','eval') for eq in propensity] 62 self.pvl = len(self.pv) #length of propensity vector 63 self.pv0 = zeros(self.pvl,dtype=float) 64 self.nvars = len(self.inits) #number of variables 65 self.evseries = {} #dictionary with complete time-series for each event type. 66 self.time = None 67 self.tmax = None 68 self.series = None 69 self.steps = 0 70 self.viz = False #if intermediate vizualization should be on
71 72
73 - def getStats(self):
74 return self.time,self.series,self.steps, self.evseries
75
76 - def run(self, method='SSA', tmax=10, reps=1, viz=False, serial=False):
77 ''' 78 Runs the model. 79 80 :Parameters: 81 - `method`: String specifying the solving algorithm. Currently only 'SSA' 82 - `tmax`: duration of the simulation. 83 - `reps`: Number of replicates. 84 - `viz`: Boolean. Whether to show graph of each replicate during simulation 85 - `serial`: Boolean. False to run replicate in parallel when more than one core is a vailable. True to run them serially (easier to debug). 86 87 :Return: 88 a numpy array of shape (reps,tmax,nvars) 89 ''' 90 if viz: #only if Gnuplot.py is installed 91 self.viz = viz 92 self.tmax = tmax 93 #self.res = zeros((tmax,self.nvars,reps),dtype=float) 94 self.res = zeros((tmax,self.nvars),dtype=float) 95 tvec = arange(tmax, dtype=int) 96 97 if method =='SSA': 98 if not serial:# Parallel version 99 pool = Pool() 100 res = pool.map(dispatch,[self]*reps, chunksize=10) 101 self.res = array([i[0] for i in res]) 102 if reps == 0: 103 self.evseries = res[0][1] 104 else: 105 self.evseries = [i[1] for i in res] 106 pool.close() 107 pool.join() 108 else:# Serial 109 res = map(dispatch,[self]*reps) 110 self.res = array([i[0] for i in res]) 111 if reps == 0: 112 self.evseries = res[0][1] 113 else: 114 self.evseries = [i[1] for i in res] 115 116 elif method == 'SSAct': 117 pass 118 119 self.time = tvec 120 self.series = self.res
121 #self.steps=steps 122
123 - def GSSA(self):
124 ''' 125 Gillespie Direct algorithm 126 ''' 127 tmax = self.tmax 128 ini = array(self.inits) 129 #ini = copy.deepcopy(self.inits) 130 r = array(self.rates) 131 for i in r: 132 if i<0: 133 i=0 134 pvi = self.pv #propensity functions 135 tm = self.tm 136 pv = self.pv0 #actual propensity values for each time step 137 tc = 0 #current time 138 last_tim = 0 # first time step of results 139 evts = dict([(i, []) for i in xrange(len(self.pv))]) 140 self.steps = 0 141 self.res[0,:]= ini 142 # for tim in xrange(1,tmax): 143 while tc <= tmax: 144 i=0 145 a0=0.0 146 for p in pvi: 147 pv[i] = p(r,ini) 148 a0+=pv[i] 149 i+=1 150 151 if pv.any():#no change in state is pv is all zeros 152 tau = (-1/a0)*log(random()) 153 tc += tau 154 tim = int(ceil(tc)) 155 156 event = multinomial(1,pv/a0) # event which will happen on this iteration 157 158 e = event.nonzero()[0][0] 159 ini += tm[:,e] 160 if tc <= tmax: 161 evts[e].append(tc) 162 #print tc, ini 163 if tim <= tmax -1: 164 self.steps +=1 165 # if a0 == 0: break 166 if tim - last_tim >1: 167 for j in range(last_tim, tim): 168 self.res[j,:] = self.res[last_tim, :] 169 self.res[tim,:] = ini 170 else: 171 for j in range(last_tim, tmax): 172 self.res[j,:] = self.res[last_tim, :] 173 break 174 last_tim = tim 175 #self.evseries = evts 176 if a0 == 0: break #breaks when no event has prob above 0 177 if self.viz: 178 #self.ser.clearFig() 179 self.server.lines(self.res.T.tolist(),[],self.vn,"Single replica") 180 return self.res, evts
181 182
183 -def p1(r,ini): return r[0]*ini[0]*ini[1]
184 -def p2(r,ini): return r[1]*ini[1]
185
186 -def main():
187 vnames = ['S','I','R'] 188 ini= [500,1,0] 189 rates = [.001,.1] 190 tm = array([[-1,0],[1,-1],[0,1]]) 191 #prop=[lambda r, ini:r[0]*ini[0]*ini[1],lambda r,ini:r[0]*ini[1]] 192 M = Model(vnames = vnames,rates = rates,inits=ini, tmat=tm,propensity=[p1,p2]) 193 t0=time.time() 194 M.run(tmax=80,reps=100,viz=1,serial=1) 195 print 'total time: ',time.time()-t0 196 t,series,steps, evts = M.getStats() 197 ser = series.mean(axis=0) 198 #print evts, len(evts[0]) 199 from pylab import plot , show, legend 200 plot(t,ser,'-.') 201 legend(M.vn,loc=0) 202 show()
203 204 205 if __name__=="__main__": 206 #import cProfile 207 #cProfile.run('main()',sort=1,filename='gillespie.profile') 208 main() 209