1
2
3
4
5
6
7
8
9
10
11
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
38
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
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
62 self.pvl = len(self.pv)
63 self.pv0 = zeros(self.pvl,dtype=float)
64 self.nvars = len(self.inits)
65 self.evseries = {}
66 self.time = None
67 self.tmax = None
68 self.series = None
69 self.steps = 0
70 self.viz = False
71
72
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:
91 self.viz = viz
92 self.tmax = tmax
93
94 self.res = zeros((tmax,self.nvars),dtype=float)
95 tvec = arange(tmax, dtype=int)
96
97 if method =='SSA':
98 if not serial:
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:
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
122
124 '''
125 Gillespie Direct algorithm
126 '''
127 tmax = self.tmax
128 ini = array(self.inits)
129
130 r = array(self.rates)
131 for i in r:
132 if i<0:
133 i=0
134 pvi = self.pv
135 tm = self.tm
136 pv = self.pv0
137 tc = 0
138 last_tim = 0
139 evts = dict([(i, []) for i in xrange(len(self.pv))])
140 self.steps = 0
141 self.res[0,:]= ini
142
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():
152 tau = (-1/a0)*log(random())
153 tc += tau
154 tim = int(ceil(tc))
155
156 event = multinomial(1,pv/a0)
157
158 e = event.nonzero()[0][0]
159 ini += tm[:,e]
160 if tc <= tmax:
161 evts[e].append(tc)
162
163 if tim <= tmax -1:
164 self.steps +=1
165
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
176 if a0 == 0: break
177 if self.viz:
178
179 self.server.lines(self.res.T.tolist(),[],self.vn,"Single replica")
180 return self.res, evts
181
182
184 -def p2(r,ini): return r[1]*ini[1]
185
187 vnames = ['S','I','R']
188 ini= [500,1,0]
189 rates = [.001,.1]
190 tm = array([[-1,0],[1,-1],[0,1]])
191
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
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
207
208 main()
209