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 <vector>
10#include <algorithm>
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[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 (const std::unordered_map<name_t,ball_t*>& names) {
83 for (node_t *p : *this) {
84 p->green_ball() = names.at(p->uniq);
85 }
86 };
87
89 std::unordered_map<name_t, node_t*>
90 node_map (void) const {
91 std::unordered_map<name_t, node_t*> m;
92 m.reserve(size());
93 for (node_t* p : *this)
94 m[p->uniq] = p;
95 return m;
96 };
97
98public:
99
103 static bool compare (node_t* p, node_t* q) {
104 return (p->slate < q->slate) ||
105 ((p->slate == q->slate) &&
106 ((p == q->parent()) ||
107 ((q != p->parent()) && (p->uniq < q->uniq))));
108 };
109
111 void sort (void) {
112 std::list<node_t*>::sort(compare);
113 };
114
115public:
116
118 pocket_t* colored (color_t col) const {
119 pocket_t *p = new pocket_t;
120 for (node_t *q : *this) {
121 for (ball_t *b : *q ) {
122 if (b->is(col)) p->insert(b);
123 }
124 }
125 return p;
126 };
127
128 size_t ntime (slate_t t) const {
129 size_t count = 1;
130 for (node_t *p : *this) {
131 if (t < p->slate) {
132 t = p->slate;
133 count++;
134 }
135 }
136 return count;
137 };
138
139 size_t length (void) const {
140 return this->size();
141 };
142
144 int i = 0;
145 node_it k = cbegin();
146 while (i < n && k != cend()) {
147 i++; k++;
148 }
149 assert(k != cend());
150 return *k;
151 };
152
153public:
154
156 void move (ball_t *b, node_t *p, node_t *q) {
157 assert(b->holder() == p);
158 p->erase(b); q->insert(b);
159 };
160
161 void swap (ball_t *a, ball_t *b) {
162 node_t *p = a->holder();
163 node_t *q = b->holder();
164 if (p != q) {
165 p->erase(a); q->insert(a);
166 q->erase(b); p->insert(b);
167 }
168 };
169
171 void attach (node_t *p, node_t *q) {
172 move(q->green_ball(),q,p);
173 };
174
176 void detach (node_t *p) {
177 move(p->green_ball(),p->parent(),p);
178 };
179
181 void add (node_t *p, ball_t *a) {
182 swap(a,p->green_ball());
183 p->deme() = a->deme();
184 push_back(p);
185 };
186
189 void drop (ball_t *a) {
190 assert(a->is(black));
191 node_t *p = a->holder();
192 if (p->size() > 1) {
193 p->erase(a);
194 delete a;
195 if (p->dead_root()) { // remove isolated root
196 destroy_node(p);
197 }
198 } else {
199 swap(a,p->green_ball());
200 destroy_node(p);
201 drop(a); // recurse
202 }
203 };
204
206 assert(p->dead_root());
207 remove(p);
208 delete p;
209 };
210
211 void weed (void) {
212 node_nit j = begin();
213 while (j != end()) {
214 if ((*j)->dead_root()) {
215 destroy_node(*(j++));
216 } else {
217 j++;
218 }
219 }
220 };
221
223 void comb (void) {
224 for (node_t *p : *this) {
225 if (p->size() == 1 && p->holds(green)) {
226 swap(p->last_ball(),p->green_ball());
227 }
228 }
229 weed();
230 };
231
232private:
233
238 node_t *p = b->holder();
239 while (p->lineage() == null_lineage) {
240 p->lineage() = u;
241 p = p->parent();
242 }
243 };
244
245public:
246
248 std::unordered_map<name_t, std::vector<node_t*>>
249 children_map (void) const {
250 std::unordered_map<name_t, std::vector<node_t*>> children;
251 children.reserve(size());
252 // initialise every node with an empty vector
253 for (node_t* p : *this)
254 children[p->uniq];
255 for (node_t* p : *this) {
256 if (!p->is_root())
257 children[p->parent()->uniq].push_back(p);
258 }
259 return children;
260 };
261
263 std::vector<node_t*>
265 (
266 const std::unordered_map<name_t, slate_t>& height
267 ) const {
268 std::vector<node_t*> roots;
269 for (node_t* p : *this)
270 if (p->is_root()) roots.push_back(p);
271 std::sort(roots.begin(), roots.end(),
272 [&height](node_t* a, node_t* b) {
273 return height.at(a->uniq) > height.at(b->uniq);
274 });
275 return roots;
276 };
277
281 std::vector<node_t*>
283 (
284 std::unordered_map<name_t,std::vector<node_t*>>& children
285 ) const {
286 std::unordered_map<name_t, slate_t> height;
287 height.reserve(size());
288 for (auto it = rbegin(); it != rend(); ++it) {
289 node_t* p = *it;
290 auto& ch = children.at(p->uniq);
291 if (ch.empty()) {
292 height[p->uniq] = p->slate;
293 } else {
294 std::sort(ch.begin(), ch.end(),
295 [&height](node_t* a, node_t* b) {
296 return height.at(a->uniq) > height.at(b->uniq);
297 });
298 height[p->uniq] = height.at(ch[0]->uniq);
299 }
300 }
301 return sorted_roots(height);
302 };
303
304public:
305
309 void trace_lineages (void) {
310 // we trace each lineage in turn.
311 // because we move from early to late,
312 // the order is guaranteed to be valid.
313 name_t u = 0;
314 for (node_t *p : *this ) {
315 for (ball_t *b : *p) {
316 if (b->color==blue) {
317 trace_lineage(b,u);
318 u++;
319 }
320 }
321 }
322 };
323
324public:
325
327 string_t yaml (string_t tab = "") const;
329 SEXP structure (void) const;
331 string_t newick (slate_t t, slate_t te, bool showdeme, bool extended) const;
332
333};
334
335#endif
color_t
BALL COLORS.
Definition ball.h:12
@ green
Definition ball.h:12
@ black
Definition ball.h:12
@ blue
Definition ball.h:12
Balls function as pointers.
Definition ball.h:27
name_t deme(void) const
view deme
Definition ball.h:84
node_t * holder(void) const
in whose pocket do I lie?
Definition ball.h:107
bool is(color_t c) const
is a given ball of the given color?
Definition ball.h:115
Encodes a genealogical node.
Definition node.h:23
node_t * parent(void) const
Definition node.h:117
name_t lineage(void) const
view lineage
Definition node.h:106
size_t bytesize(void) const
size of binary serialization
Definition node.h:40
bool dead_root(void) const
Definition node.h:123
bool is_root(void) const
Definition node.h:120
name_t deme(void) const
view deme
Definition node.h:98
name_t uniq
Definition node.h:34
ball_t * green_ball(void) const
pointer to my green ball
Definition node.h:90
void insert(ball_t *a)
insert a ball into the pocket of a node
Definition node.h:167
slate_t slate
Definition node.h:35
A sequence of nodes.
Definition nodeseq.h:19
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 detach(node_t *p)
Definition nodeseq.h:176
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:237
string_t newick(slate_t t, slate_t te, bool showdeme, bool extended) const
put genealogy at time t into Newick format.
Definition newick.cc:93
std::unordered_map< name_t, node_t * > node_map(void) const
map node names onto pointers
Definition nodeseq.h:90
size_t ntime(slate_t t) const
Number of distinct timepoints.
Definition nodeseq.h:128
void comb(void)
Definition nodeseq.h:223
void sort(void)
order nodes in order of increasing time
Definition nodeseq.h:111
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:205
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
SEXP structure(void) const
R list description.
Definition structure.cc:71
size_t bytesize(void) const
size of serialized binary form
Definition nodeseq.h:40
void drop(ball_t *a)
Definition nodeseq.h:189
string_t yaml(string_t tab="") const
human/machine-readable info
Definition yaml.cc:52
static bool compare(node_t *p, node_t *q)
Definition nodeseq.h:103
void swap(ball_t *a, ball_t *b)
swap balls a and b, wherever they lie
Definition nodeseq.h:161
size_t length(void) const
Number of nodes in the sequence.
Definition nodeseq.h:139
void move(ball_t *b, node_t *p, node_t *q)
move ball b from p to q
Definition nodeseq.h:156
pocket_t * colored(color_t col) const
Get all balls of a color.
Definition nodeseq.h:118
void trace_lineages(void)
Definition nodeseq.h:309
std::vector< node_t * > sorted_roots(const std::unordered_map< name_t, slate_t > &height) const
collect root nodes and sort them in order of decreasing subtree height
Definition nodeseq.h:265
node_t * position(int n)
traverse to nth node, retrieve pointer
Definition nodeseq.h:143
void repair_owners(const std::unordered_map< name_t, ball_t * > &names)
Definition nodeseq.h:82
~nodeseq_t(void)
destructor
Definition nodeseq.h:32
void add(node_t *p, ball_t *a)
Definition nodeseq.h:181
A pocket is a set of balls.
Definition pocket.h:30
ball_t * last_ball(void) const
retrieve the last ball
Definition pocket.h:118
bool holds(ball_t *b) const
does this node hold the given ball?
Definition pocket.h:101
Rbyte raw_t
Definition internal.h:52
size_t name_t
Definition internal.h:54
double slate_t
Definition internal.h:53
#define n
Definition lbdp_pomp.c:9
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