phylopomp
Phylodynamics for POMPs
Loading...
Searching...
No Matches
bdss_pomp.c File Reference
#include "pomplink.h"
#include "internal.h"
Include dependency graph for bdss_pomp.c:

Go to the source code of this file.

Macros

#define Normal   1
 
#define Superspreader   2
 
#define lambda_nn   (__p[__parindex[0]])
 
#define lambda_ns   (__p[__parindex[1]])
 
#define lambda_sn   (__p[__parindex[2]])
 
#define lambda_ss   (__p[__parindex[3]])
 
#define mu   (__p[__parindex[4]])
 
#define chi   (__p[__parindex[5]])
 
#define POP   (__p[__parindex[6]])
 
#define N0   (__p[__parindex[7]])
 
#define S0   (__p[__parindex[8]])
 
#define N   (__x[__stateindex[0]])
 
#define S   (__x[__stateindex[1]])
 
#define ll   (__x[__stateindex[2]])
 
#define node   (__x[__stateindex[3]])
 
#define ell1   (__x[__stateindex[4]])
 
#define ell2   (__x[__stateindex[5]])
 
#define COLOR   (__x[__stateindex[6]])
 
#define EVENT_RATES
 
#define lik   (__lik[0])
 

Functions

static int random_choice (double n)
 
static void change_color (double *color, int nsample, int n, int from, int to)
 
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 *logpi, double *penalty)
 
void bdss_rinit (double *__x, const double *__p, double t0, const int *__stateindex, const int *__parindex, const int *__covindex, const double *__covars)
 
void bdss_gill (double *__x, const double *__p, const int *__stateindex, const int *__parindex, const int *__covindex, const double *__covars, double t, double dt)
 
void bdss_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).
 

Variables

static const int nrate = 8
 

Macro Definition Documentation

◆ chi

#define chi   (__p[__parindex[5]])

Definition at line 31 of file bdss_pomp.c.

◆ COLOR

#define COLOR   (__x[__stateindex[6]])

Definition at line 41 of file bdss_pomp.c.

◆ ell1

#define ell1   (__x[__stateindex[4]])

Definition at line 39 of file bdss_pomp.c.

◆ ell2

#define ell2   (__x[__stateindex[5]])

Definition at line 40 of file bdss_pomp.c.

◆ EVENT_RATES

#define EVENT_RATES
Value:
event_rates(__x,__p,t, \
__stateindex,__parindex,__covindex, \
__covars,rate,logpi,&penalty) \
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 *logpi, double *penalty)
Definition bdei_pomp.c:47

Definition at line 43 of file bdss_pomp.c.

43#define EVENT_RATES \
44 event_rates(__x,__p,t, \
45 __stateindex,__parindex,__covindex, \
46 __covars,rate,logpi,&penalty) \
47

◆ lambda_nn

#define lambda_nn   (__p[__parindex[0]])

Definition at line 26 of file bdss_pomp.c.

◆ lambda_ns

#define lambda_ns   (__p[__parindex[1]])

Definition at line 27 of file bdss_pomp.c.

◆ lambda_sn

#define lambda_sn   (__p[__parindex[2]])

Definition at line 28 of file bdss_pomp.c.

◆ lambda_ss

#define lambda_ss   (__p[__parindex[3]])

Definition at line 29 of file bdss_pomp.c.

◆ lik

#define lik   (__lik[0])

Definition at line 389 of file bdss_pomp.c.

◆ ll

#define ll   (__x[__stateindex[2]])

Definition at line 37 of file bdss_pomp.c.

◆ mu

#define mu   (__p[__parindex[4]])

Definition at line 30 of file bdss_pomp.c.

◆ N

#define N   (__x[__stateindex[0]])

Definition at line 35 of file bdss_pomp.c.

◆ N0

#define N0   (__p[__parindex[7]])

Definition at line 33 of file bdss_pomp.c.

◆ node

#define node   (__x[__stateindex[3]])

Definition at line 38 of file bdss_pomp.c.

◆ Normal

#define Normal   1

Definition at line 4 of file bdss_pomp.c.

◆ POP

#define POP   (__p[__parindex[6]])

Definition at line 32 of file bdss_pomp.c.

◆ S

#define S   (__x[__stateindex[1]])

Definition at line 36 of file bdss_pomp.c.

◆ S0

#define S0   (__p[__parindex[8]])

Definition at line 34 of file bdss_pomp.c.

◆ Superspreader

#define Superspreader   2

Definition at line 5 of file bdss_pomp.c.

Function Documentation

◆ bdss_dmeas()

void bdss_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).

Definition at line 392 of file bdss_pomp.c.

405 {
406 assert(!ISNAN(ll));
407 lik = (give_log) ? ll : exp(ll);
408}
#define lik
Definition bdei_pomp.c:317
#define ll
Definition bdei_pomp.c:35

◆ bdss_gill()

void bdss_gill ( double * __x,
const double * __p,
const int * __stateindex,
const int * __parindex,
const int * __covindex,
const double * __covars,
double t,
double dt )

Simulator for the latent-state process (rprocess).

This is the Gillespie algorithm applied to the solution of the filter equation for the BDSS process.

Definition at line 162 of file bdss_pomp.c.

172 {
173 double tstep = 0.0, tmax = t + dt;
174 double *color = &COLOR;
175 const int nsample = *get_userdata_int("nsample");
176 const int *nodetype = get_userdata_int("nodetype");
177 const int *lineage = get_userdata_int("lineage");
178 const int *sat = get_userdata_int("saturation");
179 const int *index = get_userdata_int("index");
180 const int *child = get_userdata_int("child");
181
182 int parent = (int) nearbyint(node);
183
184#ifndef NDEBUG
185 int nnode = *get_userdata_int("nnode");
186 assert(parent>=0);
187 assert(parent<=nnode);
188#endif
189
190 int parlin = lineage[parent];
191 int parcol = color[parlin];
192 assert(parlin >= 0 && parlin < nsample);
193
194 ll = 0;
195
196 // singular portion of filter equation
197 switch (nodetype[parent]) {
198 default:
199 break;
200 case 0: // root
201 assert(sat[parent]==1);
202 {
203 int c = child[index[parent]];
204 assert(lineage[parent]==lineage[c]);
205 if (N-ell1 + S-ell2 > 0) {
206 double x = (N-ell1)/(N-ell1 + S-ell2);
207 if (unif_rand() < x) {
208 color[lineage[c]] = Normal;
209 ell1 += 1;
210 ll -= log(x);
211 } else {
212 color[lineage[c]] = Superspreader;
213 ell2 += 1;
214 ll -= log(1-x);
215 }
216 } else {
217 ll += R_NegInf;
218 if (unif_rand() < 0.5) {
219 color[lineage[c]] = Normal;
220 ell1 += 1; N += 1;
221 } else {
222 color[lineage[c]] = Superspreader;
223 ell2 += 1; S += 1;
224 }
225 }
226 }
227 break;
228 case 1: // sample (destructive only)
229 if (sat[parent] == 0) {
230 if (parcol == Normal) {
231 ell1 -= 1;
232 ll += (N > 0) ? log(chi*N) : R_NegInf;
233 N -= 1;
234 } else if (parcol == Superspreader) {
235 ell2 -= 1;
236 ll += (S > 0) ? log(chi*S) : R_NegInf;
237 S -= 1;
238 } else {
239 ll += R_NegInf;
240 }
241 } else {
242 assert(0); // #nocov
243 ll += R_NegInf; // #nocov
244 }
245 color[parlin] = R_NaReal;
246 break;
247 case 2: // branch point
248 assert(sat[parent]==2);
249 {
250 int c1 = child[index[parent]];
251 int c2 = child[index[parent]+1];
252 assert(c1 != c2);
253 assert(lineage[c1] != lineage[c2]);
254 assert(lineage[c1] != parlin || lineage[c2] != parlin);
255 assert(lineage[c1] == parlin || lineage[c2] == parlin);
256
257 if (parcol == Normal) {
258 double lam = lambda_nn + lambda_ns;
259 if (lam <= 0) { ll += R_NegInf; break; }
260 double p_nn = lambda_nn/lam;
261 if (unif_rand() < p_nn) {
262 // N->N birth: both children Normal
263 N += 1; ell1 += 1;
264 ll += log(2*lam/N);
265 if (N*(N-1) <= 0) ll += R_NegInf;
266 color[lineage[c1]] = Normal;
267 color[lineage[c2]] = Normal;
268 } else {
269 // N->S birth: one N, one S
270 S += 1; ell2 += 1;
271 ll += log(lam/S);
272 if (N*S <= 0) ll += R_NegInf;
273 if (unif_rand() < 0.5) {
274 color[lineage[c1]] = Normal;
275 color[lineage[c2]] = Superspreader;
276 } else {
277 color[lineage[c1]] = Superspreader;
278 color[lineage[c2]] = Normal;
279 }
280 ll -= log(0.5);
281 }
282 } else if (parcol == Superspreader) {
283 double lam = lambda_sn + lambda_ss;
284 if (lam <= 0) { ll += R_NegInf; break; }
285 double p_ss = lambda_ss/lam;
286 if (unif_rand() < p_ss) {
287 // S->S birth: both children Superspreader
288 S += 1; ell2 += 1;
289 ll += log(2*lam/S);
290 if (S*(S-1) <= 0) ll += R_NegInf;
291 color[lineage[c1]] = Superspreader;
292 color[lineage[c2]] = Superspreader;
293 } else {
294 // S->N birth: one S, one N
295 N += 1; ell1 += 1;
296 ll += log(lam/N);
297 if (N*S <= 0) ll += R_NegInf;
298 if (unif_rand() < 0.5) {
299 color[lineage[c1]] = Normal;
300 color[lineage[c2]] = Superspreader;
301 } else {
302 color[lineage[c1]] = Superspreader;
303 color[lineage[c2]] = Normal;
304 }
305 ll -= log(0.5);
306 }
307 } else {
308 ll += R_NegInf;
309 }
310 }
311 break;
312 }
313
314 // regular portion of filter equation
315 if (tmax > t && R_FINITE(ll)) {
316
317 double rate[nrate], logpi[nrate];
318 int event;
319 double event_rate = 0;
320 double penalty = 0;
321
322 event_rate = EVENT_RATES;
323 tstep = exp_rand()/event_rate;
324
325 while (t + tstep < tmax) {
326 event = rcateg(event_rate,rate,nrate);
327 assert(event>=0 && event<nrate);
328 ll -= penalty*tstep + logpi[event];
329 switch (event) {
330 case 0: // N->N birth
331 N += 1;
332 assert(!ISNAN(ll));
333 break;
334 case 1: // N->S birth, s=(0,0) or s=(0,1)
335 S += 1;
336 ll += log(1-ell2/S);
337 assert(!ISNAN(ll));
338 break;
339 case 2: // N->S birth, s=(1,0)
341 ell1 -= 1; ell2 += 1;
342 S += 1;
343 ll += log(1-ell1/N)-log(S);
344 assert(!ISNAN(ll));
345 break;
346 case 3: // S->S birth
347 S += 1;
348 assert(!ISNAN(ll));
349 break;
350 case 4: // S->N birth, s=(0,0) or s=(1,0)
351 N += 1;
352 ll += log(1-ell1/N);
353 assert(!ISNAN(ll));
354 break;
355 case 5: // S->N birth, s=(0,1)
357 ell2 -= 1; ell1 += 1;
358 N += 1;
359 ll += log(1-ell2/S)-log(N);
360 assert(!ISNAN(ll));
361 break;
362 case 6: // death N
363 assert(N>=1);
364 N -= 1;
365 break;
366 case 7: // death S
367 assert(S>=1);
368 S -= 1;
369 break;
370 default: // #nocov
371 assert(0); // #nocov
372 break; // #nocov
373 }
374
375 ell1 = nearbyint(ell1);
376 ell2 = nearbyint(ell2);
377
378 t += tstep;
379 event_rate = EVENT_RATES;
380 tstep = exp_rand()/event_rate;
381
382 }
383 tstep = tmax - t;
384 ll -= penalty*tstep;
385 }
386 node += 1;
387}
#define COLOR
Definition bdei_pomp.c:39
#define chi
Definition bdei_pomp.c:29
static const int nrate
Definition bdei_pomp.c:7
#define EVENT_RATES
Definition bdei_pomp.c:41
#define node
Definition bdei_pomp.c:36
#define N
Definition bdss_pomp.c:35
#define ell1
Definition bdss_pomp.c:39
static void change_color(double *color, int nsample, int n, int from, int to)
Definition bdss_pomp.c:13
#define lambda_ns
Definition bdss_pomp.c:27
static int random_choice(double n)
Definition bdss_pomp.c:9
#define Normal
Definition bdss_pomp.c:4
#define lambda_nn
Definition bdss_pomp.c:26
#define Superspreader
Definition bdss_pomp.c:5
#define lambda_sn
Definition bdss_pomp.c:28
#define ell2
Definition bdss_pomp.c:40
#define S
Definition bdss_pomp.c:36
#define lambda_ss
Definition bdss_pomp.c:29
SEXP nsample(TYPE &X)
Definition generics.h:12
get_userdata_int_t * get_userdata_int
Definition init.c:7
static int rcateg(double erate, double *rate, int nrate)
Definition internal.h:85
Here is the call graph for this function:

◆ bdss_rinit()

void bdss_rinit ( double * __x,
const double * __p,
double t0,
const int * __stateindex,
const int * __parindex,
const int * __covindex,
const double * __covars )

Latent-state initializer (rinit component).

The state variables include N, S plus 'ell1' and 'ell2' (numbers of N- and S-deme lineages), the accumulated weight ('ll'), the current node number ('node'), and the coloring of each lineage ('COLOR').

Definition at line 128 of file bdss_pomp.c.

137 {
138 if (!R_FINITE(lambda_nn) || lambda_nn < 0 ||
139 !R_FINITE(lambda_ns) || lambda_ns < 0 ||
140 !R_FINITE(lambda_sn) || lambda_sn < 0 ||
141 !R_FINITE(lambda_ss) || lambda_ss < 0 ||
142 !R_FINITE(mu) || mu < 0 || !R_FINITE(chi) || chi < 0)
143 err("BDSS rates must be finite and nonnegative.");
144 if (!R_FINITE(POP) || POP < 0 ||
145 !R_FINITE(N0) || N0 < 0 || !R_FINITE(S0) || S0 < 0 ||
146 !R_FINITE(N0+S0) || N0+S0 <= 0)
147 err("BDSS initial values must be finite and nonnegative, with N0+S0 > 0.");
148 double adj = POP/(N0+S0);
149 if (!R_FINITE(adj)) err("BDSS: pop/(N0+S0) must be finite.");
150 N = nearbyint(N0*adj);
151 S = nearbyint(S0*adj);
152 ell1 = 0;
153 ell2 = 0;
154 ll = 0;
155 node = 0;
156}
#define POP
Definition bdei_pomp.c:30
#define mu
Definition bdei_pomp.c:28
#define N0
Definition bdss_pomp.c:33
#define S0
Definition bdss_pomp.c:34
#define err(...)
Definition internal.h:18

◆ change_color()

static void change_color ( double * color,
int nsample,
int n,
int from,
int to )
static

Definition at line 13 of file bdss_pomp.c.

14 {
15 int i = -1;
16 while (n >= 0 && i < nsample) {
17 i++;
18 if (!ISNA(color[i]) && nearbyint(color[i]) == from) n--;
19 }
20 assert(i < nsample);
21 assert(n == -1);
22 assert(nearbyint(color[i]) == from);
23 color[i] = to;
24}
#define n
Definition lbdp_pomp.c:9
Here is the call graph for this function:
Here is the caller graph for this function:

◆ event_rates()

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 * logpi,
double * penalty )
static

Definition at line 48 of file bdss_pomp.c.

60 {
61 double event_rate = 0;
62 double alpha, pi, disc;
63 *penalty = 0;
64 assert(N >= ell1 && ell1 >= 0);
65 assert(S >= ell2 && ell2 >= 0);
66 // 0: N->N birth, s=(0,0) or s=(1,0)
67 alpha = lambda_nn*N;
68 disc = (N > 0) ? ell1*(ell1-1)/N/(N+1) : 1;
69 *penalty += alpha*disc;
70 event_rate += (*rate = alpha*(1-disc)); rate++;
71 *logpi = 0; logpi++;
72 // 1: N->S birth, s=(0,0) or s=(0,1)
73 alpha = lambda_ns*N;
74 pi = 1/(ell1+1);
75 event_rate += (*rate = alpha*pi); rate++;
76 *logpi = log(pi); logpi++;
77 // 2: N->S birth, s=(1,0)
78 pi = ell1/(ell1+1);
79 event_rate += (*rate = alpha*pi); rate++;
80 *logpi = (ell1 > 0) ? -log(ell1+1) : 0; logpi++;
81 // 3: S->S birth, s=(0,0) or s=(0,1)
82 alpha = lambda_ss*S;
83 disc = (S > 0) ? ell2*(ell2-1)/S/(S+1) : 1;
84 *penalty += alpha*disc;
85 event_rate += (*rate = alpha*(1-disc)); rate++;
86 *logpi = 0; logpi++;
87 // 4: S->N birth, s=(0,0) or s=(1,0)
88 alpha = lambda_sn*S;
89 pi = 1/(ell2+1);
90 event_rate += (*rate = alpha*pi); rate++;
91 *logpi = log(pi); logpi++;
92 // 5: S->N birth, s=(0,1)
93 pi = ell2/(ell2+1);
94 event_rate += (*rate = alpha*pi); rate++;
95 *logpi = (ell2 > 0) ? -log(ell2+1) : 0; logpi++;
96 // 6: death N
97 alpha = mu*N;
98 if (N > ell1) {
99 event_rate += (*rate = alpha); rate++;
100 *logpi = 0; logpi++;
101 } else {
102 *rate = 0; rate++;
103 *logpi = 0; logpi++;
104 *penalty += alpha;
105 }
106 // 7: death S
107 alpha = mu*S;
108 if (S > ell2) {
109 event_rate += (*rate = alpha); rate++;
110 *logpi = 0; logpi++;
111 } else {
112 *rate = 0; rate++;
113 *logpi = 0; logpi++;
114 *penalty += alpha;
115 }
116 // sampling (Q = 0): destructive only
117 *penalty += chi*(N+S);
118 assert(R_FINITE(event_rate));
119 return event_rate;
120}

◆ random_choice()

static int random_choice ( double n)
inlinestatic

Definition at line 9 of file bdss_pomp.c.

9 {
10 return floor(R_unif_index(n));
11}
Here is the caller graph for this function:

Variable Documentation

◆ nrate

const int nrate = 8
static

Definition at line 7 of file bdss_pomp.c.