phylopomp
Phylodynamics for POMPs
Loading...
Searching...
No Matches
cblv.cc
Go to the documentation of this file.
1#include "genealogy.h"
2#include "generics.h"
3#include "internal.h"
4#include <utility>
5#include <vector>
6
7#include <R.h>
8#include <Rdefines.h>
9#include <Rinternals.h>
10
11static R_INLINE SEXP
13(size_t nrow, size_t ncol, const char **names)
14{
15 SEXP dim, x;
16 SEXP dimnm, nm;
17 int *dimp;
18 size_t k;
19 PROTECT(dim = NEW_INTEGER(2));
20 PROTECT(dimnm = Rf_allocVector(VECSXP,2));
21 PROTECT(nm = NEW_CHARACTER(ncol));
22 for (k = 0; k < ncol; k++)
23 SET_STRING_ELT(nm,k,mkChar(names[k]));
24 dimp = INTEGER(dim);
25 dimp[0] = nrow; dimp[1] = ncol;
26 PROTECT(x = Rf_allocArray(REALSXP,dim));
27 SET_ELEMENT(dimnm,0,R_NilValue);
28 SET_ELEMENT(dimnm,1,nm);
29 SET_DIMNAMES(x,dimnm);
30 UNPROTECT(4);
31 return x;
32}
33
36(const std::unordered_map<name_t, bool>& memo) const
37{
38 const node_t *p = parent();
39 while (!p->is_root() && !memo.at(p->uniq)) p = p->parent();
40 return slate - p->slate;
41}
42
44(
45 std::vector<slate_t>& x,
46 std::vector<slate_t>& y,
47 std::unordered_map<name_t, bool>& memo,
48 const std::unordered_map<name_t, std::vector<node_t*>>& children,
49 slate_t t0
50 ) const
51{
52 assert(!memo[uniq]);
53 const std::vector<node_t*>& ch = children.at(uniq);
54 if (ch.empty()) {
55 // leaf node: push joining branch length to x
56 x.push_back(joining_branch_length(memo));
57 memo[uniq] = true;
58 } else {
59 // first child: recurse
60 ch[0]->cblv(x, y, memo, children, t0);
61 // subsequent children:
62 for (size_t i = 1; i < ch.size(); i++) {
63 // push the height of current node into y
64 y.push_back(slate - t0);
65 memo[uniq] = true;
66 ch[i]->cblv(x, y, memo, children, t0);
67 }
68 }
69}
70
71std::pair<std::vector<slate_t>, std::vector<slate_t>>
73(void) const
74{
75 auto children = children_map();
76 auto roots = ladderize(children);
77 std::vector<slate_t> x, y;
78 x.reserve(nsample());
79 y.reserve(nsample());
80 std::unordered_map<name_t, bool> memo;
81 memo.reserve(size());
82 for (node_t* p : *this) memo[p->uniq] = false;
83 slate_t t0 = timezero();
84 for (node_t* p : roots) {
85 p->cblv(x, y, memo, children, t0);
86 y.push_back(slate_t(0));
87 memo[p->uniq] = true;
88 }
89 return {x, y};
90}
91
94(
95 const double *x,
96 const double *y,
97 int nin,
98 double tin
99 )
100{
101 if (nin <= 0) err("invalid CBLV");
102 size_t n = size_t(nin);
103 slate_t t0 = timezero();
104 slate_t t = slate_t(tin);
105 if (t < t0+slate_t(x[0]))
106 err("invalid CBLV: x[0] = %lg > %lg = time-t0", x[0], t-t0);
107 time() = t;
108 node_t* p = 0;
109 for (size_t k = 0; k < n; k++) {
110 if (p == 0) { // new root node at time t0
111 p = make_node();
112 p->slate = t0;
113 push_back(p);
114 }
115 if (x[k] < 0)
116 err("invalid CBLV: negative tip-edge length in position %zu", k+1);
117 node_t* q = make_node(); // new tip node
118 q->slate = p->slate + slate_t(x[k]);
119 attach(p, q);
120 push_back(q);
121 t = t0 + slate_t(y[k]); // new internal node time
122 if (y[k] < 0)
123 err("invalid CBLV: negative internal branch-time in position %zu", k+1);
124 if (t > t0) {
125 node_t* i = q->parent(); // points to p
126 node_t* j = q;
127 if (j->slate < t) err("invalid CBLV: node %zu cannot attach.", k+1);
128 while (j != i && i->slate > t) {
129 j = i;
130 i = i->parent();
131 }
132 assert(j != i);
133 // Create new internal node at time t
134 node_t* node = make_node();
135 node->slate = t;
136 attach(i, node);
137 move(j->green_ball(), i, node);
138 push_back(node);
139 p = node;
140 } else {
141 p = 0;
142 }
143 }
144 if (p != 0) err("invalid CBLV: last value of y is nonzero.");
145 sort(); cap_tips(); clip_zlb(); weed();
146 return *this;
147}
148
149SEXP
151(genealogy_t& A)
152{
153 const char *colnames[] = {"tip","node"};
154 double *x, *y;
155 size_t i, n;
156 SEXP S;
157 std::pair<std::vector<slate_t>, std::vector<slate_t>> rep;
158 rep = A.prune().obscure().insert_zlb().cblv();
159 n = rep.first.size();
160 PROTECT(S = make_matrix(n,2,colnames));
161 x = REAL(S);
162 y = REAL(S)+n;
163 for (i = 0; i < n; i++) {
164 x[i] = rep.first[i];
165 y[i] = rep.second[i];
166 }
167 UNPROTECT(1);
168 return S;
169}
170
171extern "C" {
172
174 SEXP cblv (SEXP State) {
175 genealogy_t A = State;
176 return cblv(A);
177 }
178
180 SEXP parse_cblv (SEXP XY, SEXP T0, SEXP Time) {
181 int *n = INTEGER(GET_DIM(XY));
182 if (n[1] != 2)
183 err("in 'parse_cblv': 'xy' must be a two-column matrix.");
184 double *xp = REAL(XY);
185 double *yp = xp+n[0];
186 double *t0 = REAL(T0);
187 double *time = REAL(Time);
188 genealogy_t A(*t0);
189 A.parse_cblv(xp,yp,*n,*time);
190 return serial(A);
191 }
192
193}
SEXP parse_cblv(SEXP XY, SEXP T0, SEXP Time)
parse CBLV representation
Definition cblv.cc:180
static R_INLINE SEXP make_matrix(size_t nrow, size_t ncol, const char **names)
Definition cblv.cc:13
SEXP cblv(genealogy_t &A)
Definition cblv.cc:151
Encodes a genealogy.
Definition genealogy.h:20
size_t nsample(void) const
number of samples
Definition genealogy.h:184
genealogy_t & prune(void)
prune the tree (drop all black balls)
Definition genealogy.h:311
genealogy_t(double t0=R_NaReal, size_t ndeme=0)
Definition genealogy.h:103
genealogy_t & parse_cblv(const double *, const double *, int, double)
parse a CBLV representation in the vectors x and y.
Definition cblv.cc:94
void cap_tips(void)
Definition parse.cc:9
void clip_zlb(void)
clip out all zero-length branches
Definition parse.cc:22
slate_t & timezero(void)
view/set zero time.
Definition genealogy.h:154
std::pair< std::vector< slate_t >, std::vector< slate_t > > cblv(void) const
Definition cblv.cc:73
slate_t & time(void)
view/set current time.
Definition genealogy.h:146
node_t * make_node(name_t d=undeme)
Definition genealogy.h:230
friend SEXP cblv(genealogy_t &)
return the CBLV representation as an R matrix
Definition cblv.cc:151
genealogy_t & obscure(void)
erase all deme information
Definition genealogy.h:322
genealogy_t & insert_zlb(void)
insert zero-length branches for samples where needed
Definition genealogy.h:359
Encodes a genealogical node.
Definition node.h:23
node_t * parent(void) const
Definition node.h:117
void cblv(std::vector< slate_t > &, std::vector< slate_t > &, std::unordered_map< name_t, bool > &, const std::unordered_map< name_t, std::vector< node_t * > > &, slate_t) const
Definition cblv.cc:44
slate_t joining_branch_length(const std::unordered_map< name_t, bool > &) const
Definition cblv.cc:36
bool is_root(void) const
Definition node.h:120
node_t(name_t u=0, slate_t t=R_NaReal)
basic constructor for node class
Definition node.h:68
name_t uniq
Definition node.h:34
ball_t * green_ball(void) const
pointer to my green ball
Definition node.h:90
slate_t slate
Definition node.h:35
void weed(void)
drop all dead roots
Definition nodeseq.h:211
std::unordered_map< name_t, std::vector< node_t * > > children_map(void) const
map nodes onto vector of children
Definition nodeseq.h:249
void sort(void)
order nodes in order of increasing time
Definition nodeseq.h:111
void attach(node_t *p, node_t *q)
Definition nodeseq.h:171
std::vector< node_t * > ladderize(std::unordered_map< name_t, std::vector< node_t * > > &children) const
Definition nodeseq.h:283
void move(ball_t *b, node_t *p, node_t *q)
move ball b from p to q
Definition nodeseq.h:156
SEXP time(TYPE &X)
Definition generics.h:27
SEXP serial(const TYPE &X)
binary serialization
Definition generics.h:33
size_t name_t
Definition internal.h:54
#define err(...)
Definition internal.h:18
double slate_t
Definition internal.h:53
#define n
Definition lbdp_pomp.c:9
#define node
Definition lbdp_pomp.c:12
#define S
Definition seirs_pomp.c:38