phylopomp
Phylodynamics for POMPs
Loading...
Searching...
No Matches
nodeseq.h
Go to the documentation of this file.
1// -*- C++ -*-
2// NODE SEQUENCE CLASS
3
4#ifndef _NODESEQ_H_
5#define _NODESEQ_H_
6
7#include <list>
8#include <unordered_map>
9#include <string>
10#include <cstring>
11#include "node.h"
12#include "internal.h"
13
14typedef typename std::list<node_t*>::const_iterator node_it;
15typedef typename std::list<node_t*>::iterator node_nit;
16typedef typename std::list<node_t*>::const_reverse_iterator node_rev_it;
17
19class nodeseq_t : public std::list<node_t*> {
20
21private:
22
24 void clean (void) {
25 for (node_t *p : *this) delete p;
26 clear();
27 };
28
29public:
30
32 ~nodeseq_t (void) {
33 clean();
34 };
35
36public:
37
38 // SERIALIZATION
40 size_t bytesize (void) const {
41 size_t s = sizeof(size_t);
42 for (node_t *p : *this)
43 s += p->bytesize();
44 return s;
45 };
46
47 friend raw_t* operator>> (const nodeseq_t& G, raw_t* o) {
48 size_t nnode = G.size();
49 memcpy(o,&nnode,sizeof(size_t)); o += sizeof(size_t);
50 for (node_t *p : G) {
51 o = (*p >> o);
52 }
53 return o;
54 };
55
56 friend raw_t* operator>> (raw_t* o, nodeseq_t& G) {
57 G.clean();
58 std::unordered_map<name_t,node_t*> node_names;
59 std::unordered_map<name_t,ball_t*> ball_names;
60 size_t nnode = 0;
61 memcpy(&nnode,o,sizeof(size_t)); o += sizeof(size_t);
62 node_names.reserve(nnode);
63 ball_names.reserve(nnode);
64 for (size_t i = 0; i < nnode; i++) {
65 node_t *p = new node_t();
66 o = (o >> *p);
67 G.push_back(p);
68 node_names.insert({p->uniq,p});
69 }
70 for (node_t *q : G) {
71 q->repair_owners(node_names,&ball_names);
72 }
73 G.repair_owners(ball_names);
75 return o;
76 };
77
78private:
79
82 void repair_owners (std::unordered_map<name_t,ball_t*>& names) {
83 std::unordered_map<name_t,ball_t*>::const_iterator n;
84 for (node_t *p : *this) {
85 n = names.find(p->uniq);
86 assert(n != names.end());
87 ball_t *b = n->second;
88 p->green_ball() = b;
89 }
90 };
91
92private:
93
97 static bool compare (node_t* p, node_t* q) {
98 return (p->slate < q->slate) ||
99 ((p->slate == q->slate) &&
100 ((p==q->green_ball()->holder()) ||
101 ((q!=p->green_ball()->holder()) && (p->uniq < q->uniq))));
102 };
103
104public:
105
108 merge(other,compare);
109 return *this;
110 };
111
113 void sort (void) {
114 std::list<node_t*>::sort(compare);
115 };
116
117private:
118
120 slate_t dawn (void) const {
121 return (empty()) ? R_NaReal : front()->slate;
122 };
123
124 slate_t dusk (void) const {
125 return (empty()) ? R_NaReal : back()->slate;
126 }
127
128public:
129
131 pocket_t* colored (color_t col) const {
132 pocket_t *p = new pocket_t;
133 for (node_t *q : *this) {
134 for (ball_t *b : *q ) {
135 if (b->is(col)) p->insert(b);
136 }
137 }
138 return p;
139 };
140
141 size_t ntime (slate_t t) const {
142 size_t count = 1;
143 for (node_t *p : *this) {
144 if (t < p->slate) {
145 t = p->slate;
146 count++;
147 }
148 }
149 return count;
150 };
151
152 size_t length (void) const {
153 return this->size();
154 };
155
157 int i = 0;
158 node_it k = cbegin();
159 while (i < n && k != cend()) {
160 i++; k++;
161 }
162 assert(k != cend());
163 return *k;
164 };
165
166public:
167
169 void swap (ball_t *a, ball_t *b) {
170 node_t *p = a->holder();
171 node_t *q = b->holder();
172 if (p != q) {
173 p->erase(a); q->insert(a); a->holder() = q;
174 q->erase(b); p->insert(b); b->holder() = p;
175 }
176 };
177
179 void add (node_t *p, ball_t *a) {
180 swap(a,p->green_ball());
181 p->deme() = a->deme();
182 push_back(p);
183 };
184
187 void drop (ball_t *a) {
188 assert(a->is(black));
189 node_t *p = a->holder();
190 if (p->size() > 1) {
191 p->erase(a);
192 delete a;
193 if (p->dead_root()) { // remove isolated root
194 destroy_node(p);
195 }
196 } else {
197 swap(a,p->green_ball());
198 destroy_node(p);
199 drop(a); // recurse
200 }
201 };
202
204 assert(p->dead_root());
205 remove(p);
206 delete p;
207 };
208
210 void comb (void) {
211 for (node_rev_it i = crbegin(); i != crend(); i++) {
212 if ((*i)->size() == 1 && (*i)->holds(green)) {
213 swap((*i)->last_ball(),(*i)->green_ball());
214 }
215 }
216 node_nit j = begin();
217 while (j != end()) {
218 if ((*j)->dead_root()) {
219 destroy_node(*(j++));
220 } else {
221 j++;
222 }
223 }
224 };
225
226private:
227
232 node_t *p = b->holder();
233 while (p->lineage() == null_lineage) {
234 p->lineage() = u;
235 p = p->parent();
236 }
237 };
238
239public:
240
244 void trace_lineages (void) {
245 // we trace each lineage in turn.
246 // because we move from early to late,
247 // the order is guaranteed to be valid.
248 name_t u = 0;
249 for (node_t *p : *this ) {
250 for (ball_t *b : *p) {
251 if (b->color==blue) {
252 trace_lineage(b,u);
253 u++;
254 }
255 }
256 }
257 };
258
259public:
260
262 std::string describe (void) const {
263 std::string o = "";
264 for (node_t *p : *this) {
265 o += p->describe();
266 }
267 return o;
268 };
269
270 virtual std::string yaml (std::string tab = "") const {
271 std::string o = "";
272 std::string t = tab + " ";
273 for (node_t *p : *this) {
274 o += tab + "- " + p->yaml(t);
275 }
276 return o;
277 };
278
279 SEXP structure (void) const {
280 SEXP Nodes;
281 PROTECT(Nodes = NEW_LIST(size()));
282 int k = 0;
283 for (node_t *p : *this) {
284 SET_ELEMENT(Nodes,k++,p->structure());
285 }
286 UNPROTECT(1);
287 return Nodes;
288 };
289
290 std::string newick (slate_t t) const {
291 slate_t te = dawn();
292 std::string o = "";
293 for (node_t *p : *this) {
294 if (p->is_root()) {
295 o += p->newick(t,te) + ";";
296 }
297 }
298 return o;
299 };
300};
301
302#endif
color_t
BALL COLORS.
Definition ball.h:14
@ green
Definition ball.h:14
@ black
Definition ball.h:14
@ blue
Definition ball.h:14
Balls function as pointers.
Definition ball.h:29
name_t deme(void) const
view deme
Definition ball.h:86
node_t * holder(void) const
in whose pocket do I lie?
Definition ball.h:109
bool is(color_t c) const
is a given ball of the given color?
Definition ball.h:117
Encodes a genealogical node.
Definition node.h:23
node_t * parent(void) const
Definition node.h:115
name_t lineage(void) const
view lineage
Definition node.h:104
size_t bytesize(void) const
size of binary serialization
Definition node.h:40
bool dead_root(void) const
Definition node.h:124
bool is_root(void) const
Definition node.h:121
std::string newick(const slate_t &tnow, const slate_t &tpar) const
Newick format.
Definition node.h:214
SEXP structure(void) const
R list description.
Definition node.h:201
std::string describe(void) const
human-readable info
Definition node.h:177
std::string yaml(std::string tab="") const
machine-readable info
Definition node.h:189
name_t deme(void) const
view deme
Definition node.h:96
name_t uniq
Definition node.h:34
ball_t * green_ball(void) const
pointer to my green ball
Definition node.h:88
slate_t slate
Definition node.h:35
A sequence of nodes.
Definition nodeseq.h:19
slate_t dawn(void) const
Earliest time in the sequence.
Definition nodeseq.h:120
std::string describe(void) const
human-readable info
Definition nodeseq.h:262
void clean(void)
clean up: delete all nodes, reset globals
Definition nodeseq.h:24
void trace_lineage(ball_t *b, name_t u)
Definition nodeseq.h:231
virtual std::string yaml(std::string tab="") const
human- & machine-readable info
Definition nodeseq.h:270
size_t ntime(slate_t t) const
Number of distinct timepoints.
Definition nodeseq.h:141
void comb(void)
Definition nodeseq.h:210
void sort(void)
order nodes in order of increasing time
Definition nodeseq.h:113
friend raw_t * operator>>(const nodeseq_t &G, raw_t *o)
binary serialization
Definition nodeseq.h:47
void destroy_node(node_t *p)
remove a dead root node
Definition nodeseq.h:203
nodeseq_t & operator+=(nodeseq_t &other)
merge two node sequences
Definition nodeseq.h:107
SEXP structure(void) const
R list description.
Definition nodeseq.h:279
size_t bytesize(void) const
size of serialized binary form
Definition nodeseq.h:40
void drop(ball_t *a)
Definition nodeseq.h:187
void repair_owners(std::unordered_map< name_t, ball_t * > &names)
Definition nodeseq.h:82
static bool compare(node_t *p, node_t *q)
Definition nodeseq.h:97
void swap(ball_t *a, ball_t *b)
swap balls a and b, wherever they lie
Definition nodeseq.h:169
size_t length(void) const
Number of nodes in the sequence.
Definition nodeseq.h:152
pocket_t * colored(color_t col) const
Get all balls of a color.
Definition nodeseq.h:131
void trace_lineages(void)
Definition nodeseq.h:244
slate_t dusk(void) const
Latest time in the sequence.
Definition nodeseq.h:124
node_t * position(int n)
traverse to nth node, retrieve pointer
Definition nodeseq.h:156
~nodeseq_t(void)
destructor
Definition nodeseq.h:32
std::string newick(slate_t t) const
put genealogy at time t into Newick format.
Definition nodeseq.h:290
void add(node_t *p, ball_t *a)
Definition nodeseq.h:179
A pocket is a set of balls.
Definition pocket.h:32
Rbyte raw_t
Definition internal.h:43
size_t name_t
Definition internal.h:45
double slate_t
Definition internal.h:44
#define n
Definition lbdp_pomp.c:8
static const name_t null_lineage
Definition node.h:13
std::list< node_t * >::const_reverse_iterator node_rev_it
Definition nodeseq.h:16
std::list< node_t * >::const_iterator node_it
Definition nodeseq.h:14
std::list< node_t * >::iterator node_nit
Definition nodeseq.h:15