phylopomp
Phylodynamics for POMPs
Loading...
Searching...
No Matches
strains_pomp.c
Go to the documentation of this file.
1#include "pomplink.h"
2#include "internal.h"
3
4static const int nrate = 6;
5
6#define STRAIN1 0
7#define STRAIN2 1
8#define STRAIN3 2
9
10#define Beta1 (__p[__parindex[0]])
11#define Beta2 (__p[__parindex[1]])
12#define Beta3 (__p[__parindex[2]])
13#define gamma (__p[__parindex[3]])
14#define psi1 (__p[__parindex[4]])
15#define psi2 (__p[__parindex[5]])
16#define psi3 (__p[__parindex[6]])
17#define S_0 (__p[__parindex[7]])
18#define I1_0 (__p[__parindex[8]])
19#define I2_0 (__p[__parindex[9]])
20#define I3_0 (__p[__parindex[10]])
21#define R_0 (__p[__parindex[11]])
22#define N (__p[__parindex[12]])
23#define S (__x[__stateindex[0]])
24#define I1 (__x[__stateindex[1]])
25#define I2 (__x[__stateindex[2]])
26#define I3 (__x[__stateindex[3]])
27#define R (__x[__stateindex[4]])
28#define ll (__x[__stateindex[5]])
29#define ellI1 (__x[__stateindex[6]])
30#define ellI2 (__x[__stateindex[7]])
31#define ellI3 (__x[__stateindex[8]])
32#define node (__x[__stateindex[9]])
33
34#define EVENT_RATES \
35 event_rates(__x,__p,t, \
36 __stateindex,__parindex,__covindex, \
37 __covars,rate,&penalty) \
38
39static double event_rates
40(
41 double *__x,
42 const double *__p,
43 double t,
44 const int *__stateindex,
45 const int *__parindex,
46 const int *__covindex,
47 const double *__covars,
48 double *rate,
49 double *penalty
50 ) {
51 double event_rate = 0;
52 double alpha, disc;
53 *penalty = 0;
54 assert(S >= 0);
55 assert(I1 >= ellI1);
56 assert(I2 >= ellI2);
57 assert(I3 >= ellI3);
58 assert(ellI1 >= 0);
59 assert(ellI2 >= 0);
60 assert(ellI3 >= 0);
61 // 0: strain-1 transmission with saturation 0 or 1
62 alpha = Beta1*S*I1/N;
63 disc = (I1 > 0) ? ellI1*(ellI1-1)/I1/(I1+1) : 1;
64 event_rate += (*rate = alpha*(1-disc)); rate++;
65 *penalty += alpha*disc;
66 // 1: strain 1 recovery
67 alpha = gamma*I1;
68 if (I1 > ellI1) {
69 event_rate += (*rate = alpha); rate++;
70 } else {
71 *rate = 0; rate++;
72 *penalty += alpha;
73 }
74 // strain 1 sampling
75 alpha = psi1*I1;
76 *penalty += alpha;
77 // 2: strain-2 transmission with saturation 0 or 1
78 alpha = Beta2*S*I2/N;
79 disc = (I2 > 0) ? ellI2*(ellI2-1)/I2/(I2+1) : 1;
80 event_rate += (*rate = alpha*(1-disc)); rate++;
81 *penalty += alpha*disc;
82 // 3: strain 2 recovery
83 alpha = gamma*I2;
84 if (I2 > ellI2) {
85 event_rate += (*rate = alpha); rate++;
86 } else {
87 *rate = 0; rate++;
88 *penalty += alpha;
89 }
90 // strain 2 sampling
91 alpha = psi2*I2;
92 *penalty += alpha;
93 // 4: strain-3 transmission with saturation 0 or 1
94 alpha = Beta3*S*I3/N;
95 disc = (I3 > 0) ? ellI3*(ellI3-1)/I3/(I3+1) : 1;
96 event_rate += (*rate = alpha*(1-disc)); rate++;
97 *penalty += alpha*disc;
98 // 5: strain 3 recovery
99 alpha = gamma*I3;
100 if (I3 > ellI3) {
101 event_rate += (*rate = alpha); rate++;
102 } else {
103 *rate = 0; rate++;
104 *penalty += alpha;
105 }
106 // strain 3 sampling
107 alpha = psi3*I3;
108 *penalty += alpha;
109 assert(R_FINITE(event_rate));
110 return event_rate;
111}
112
115(
116 double *__x,
117 const double *__p,
118 double t,
119 const int *__stateindex,
120 const int *__parindex,
121 const int *__covindex,
122 const double *__covars
123 ){
124 double m = N/(S_0+I1_0+I2_0+I3_0+R_0);
125 S = nearbyint(S_0*m);
126 I1 = nearbyint(I1_0*m);
127 I2 = nearbyint(I2_0*m);
128 I3 = nearbyint(I3_0*m);
129 R = nearbyint(R_0*m);
130 ll = 0;
131 ellI1 = 0;
132 ellI2 = 0;
133 ellI3 = 0;
134 node = 0;
135}
136
141(
142 double *__x,
143 const double *__p,
144 const int *__stateindex,
145 const int *__parindex,
146 const int *__covindex,
147 const double *__covars,
148 double t,
149 double dt
150 ){
151 double tstep = 0.0, tmax = t + dt;
152 const int *nodetype = get_userdata_int("nodetype");
153 const int *sat = get_userdata_int("saturation");
154 const int *deme = get_userdata_int("deme");
155
156 int parent = (int) nearbyint(node);
157
158#ifndef NDEBUG
159 int nnode = *get_userdata_int("nnode");
160 assert(parent>=0);
161 assert(parent<=nnode);
162#endif
163
164 ll = 0;
165
166 // singular portion of filter equation
167 switch (nodetype[parent]) {
168 default: // non-genealogical event
169 break;
170 case 0: // root
171 switch (deme[parent]) {
172 case STRAIN1:
173 ellI1 += 1; break;
174 case STRAIN2:
175 ellI2 += 1; break;
176 case STRAIN3:
177 ellI3 += 1; break;
178 default:
179 assert(0); break;
180 }
181 break;
182 case 1: // sample
183 assert(sat[parent]==0);
184 switch (deme[parent]) {
185 case STRAIN1:
186 assert(I1 >= ellI1);
187 assert(ellI1 >= 0);
188 ellI1 -= 1; I1 -= 1;
189 ll += log(psi1);
190 break;
191 case STRAIN2:
192 assert(I2 >= ellI2);
193 assert(ellI2 >= 0);
194 ellI2 -= 1; I2 -= 1;
195 ll += log(psi2);
196 break;
197 case STRAIN3:
198 assert(I3 >= ellI3);
199 assert(ellI3 >= 0);
200 ellI3 -= 1; I3 -= 1;
201 ll += log(psi3);
202 break;
203 default:
204 assert(0); break;
205 }
206 break;
207 case 2: // branch point s=(1,1)
208 assert(S >= 0);
209 if (sat[parent]!=2) break;
210 switch (deme[parent]) {
211 case STRAIN1:
212 assert(I1 >= 0);
213 assert(ellI1 > 0);
214 ll += (I1 > 0 && I1 >= ellI1) ? log(Beta1*S*I1/N) : R_NegInf;
215 S -= 1; I1 += 1; ellI1 += 1;
216 ll -= log(I1*(I1-1)/2);
217 break;
218 case STRAIN2:
219 assert(I2 >= 0);
220 assert(ellI2 > 0);
221 ll += (I2 > 0 && I2 >= ellI2) ? log(Beta2*S*I2/N) : R_NegInf;
222 S -= 1; I2 += 1; ellI2 += 1;
223 ll -= log(I2*(I2-1)/2);
224 break;
225 case STRAIN3:
226 assert(I3 >= 0);
227 assert(ellI3 > 0);
228 ll += (I3 > 0 && I3 >= ellI3) ? log(Beta3*S*I3/N) : R_NegInf;
229 S -= 1; I3 += 1; ellI3 += 1;
230 ll -= log(I3*(I3-1)/2);
231 break;
232 default:
233 assert(0);
234 break;
235 }
236 S = (S > 0) ? S : 0;
237 break;
238 }
239
240 if (tmax > t) {
241
242 // take Gillespie steps to the end of the interval:
243 int event;
244 double penalty = 0;
245 double rate[nrate];
246
247 double event_rate = EVENT_RATES;
248 tstep = exp_rand()/event_rate;
249
250 while (t + tstep < tmax) {
251 event = rcateg(event_rate,rate,nrate);
252 assert(event>=0 && event<nrate);
253 ll -= penalty*tstep;
254 switch (event) {
255 case 0: // strain-1 transmission
256 S -= 1; I1 += 1;
257 break;
258 case 1: // strain-1 recovery
259 I1 -= 1; R += 1;
260 break;
261 case 2: // strain-2 transmission
262 S -= 1; I2 += 1;
263 break;
264 case 3: // strain-2 recovery
265 I2 -= 1; R += 1;
266 break;
267 case 4: // strain-3 transmission
268 S -= 1; I3 += 1;
269 break;
270 case 5: // strain-3 recovery
271 I3 -= 1; R += 1;
272 break;
273 default: // #nocov
274 assert(0); // #nocov
275 break; // #nocov
276 }
277 t += tstep;
278 event_rate = EVENT_RATES;
279 tstep = exp_rand()/event_rate;
280 }
281 tstep = tmax - t;
282 ll -= penalty*tstep;
283 }
284 node += 1;
285}
286
287# define lik (__lik[0])
288
291(
292 double *__lik,
293 const double *__y,
294 const double *__x,
295 const double *__p,
296 int give_log,
297 const int *__obsindex,
298 const int *__stateindex,
299 const int *__parindex,
300 const int *__covindex,
301 const double *__covars,
302 double t
303 ){
304 assert(!ISNAN(ll));
305 lik = (give_log) ? ll : exp(ll);
306}
get_userdata_int_t * get_userdata_int
Definition init.c:7
static int rcateg(double erate, double *rate, int nrate)
Definition internal.h:76
static const int deme
Definition lbdp.cc:7
#define lik
Definition lbdp_pomp.c:160
#define ll
Definition lbdp_pomp.c:9
#define EVENT_RATES
Definition lbdp_pomp.c:13
#define node
Definition lbdp_pomp.c:11
#define N
Definition seirs_pomp.c:32
#define gamma
Definition seirs_pomp.c:25
#define R
Definition seirs_pomp.c:36
static const int nrate
Definition seirs_pomp.c:4
#define S
Definition seirs_pomp.c:33
static double event_rates(double *__x, const double *__p, double t, const int *__stateindex, const int *__parindex, const int *__covindex, const double *__covars, double *rate, double *penalty)
#define I2_0
#define psi1
#define Beta3
#define psi3
void strains_gill(double *__x, const double *__p, const int *__stateindex, const int *__parindex, const int *__covindex, const double *__covars, double t, double dt)
#define STRAIN3
Definition strains_pomp.c:8
#define S_0
void strains_dmeas(double *__lik, const double *__y, const double *__x, const double *__p, int give_log, const int *__obsindex, const int *__stateindex, const int *__parindex, const int *__covindex, const double *__covars, double t)
Measurement model likelihood (dmeasure).
#define ellI1
#define ellI2
#define ellI3
#define I3_0
#define STRAIN1
Definition strains_pomp.c:6
#define STRAIN2
Definition strains_pomp.c:7
#define I2
#define Beta2
#define Beta1
#define I1_0
#define psi2
void strains_rinit(double *__x, const double *__p, double t, const int *__stateindex, const int *__parindex, const int *__covindex, const double *__covars)
Latent-state initializer (rinit).
#define I3
#define I1
#define R_0