phylopomp
Phylodynamics for POMPs
Loading...
Searching...
No Matches
genealogy.h
Go to the documentation of this file.
1// -*- C++ -*-
2// GENEALOGY class
3
4#ifndef _GENEALOGY_H_
5#define _GENEALOGY_H_
6
7#include <string>
8#include <cstring>
9#include <utility>
10#include <stdexcept>
11
12#include "nodeseq.h"
13#include "inventory.h"
14#include "internal.h"
15
16static const size_t MEMORY_MAX = (1<<28); // 256MB
17
19
22class genealogy_t : public nodeseq_t {
23
24private:
25
26 // GENEALOGY member data:
27 // - a counter of serial numbers
28 // - an initial time
29 // - the current time
30 // - a sequence of nodes
31
39 size_t _ndeme;
40
41 const static name_t magic = 1123581321;
42
43private:
44
46 name_t unique (void) {
47 name_t u = _unique;
48 _unique++;
49 return u;
50 };
51
53 void clean (void) {
54 _unique = 0;
55 _t0 = _time = R_NaReal;
56 };
57
58public:
59
61 size_t ndeme (void) const {
62 return _ndeme;
63 };
64
65 size_t& ndeme (void) {
66 return _ndeme;
67 };
68
69public:
70
71 // SERIALIZATION
73 size_t bytesize (void) const {
74 return 3*sizeof(name_t) +
75 2*sizeof(slate_t) + nodeseq_t::bytesize();
76 };
77
78 friend raw_t* operator>> (const genealogy_t& G, raw_t* o) {
79 name_t A[3]; A[0] = magic; A[1] = G._unique; A[2] = name_t(G._ndeme);
80 slate_t B[2]; B[0] = G.timezero(); B[1] = G.time();
81 memcpy(o,A,sizeof(A)); o += sizeof(A);
82 memcpy(o,B,sizeof(B)); o += sizeof(B);
83 return reinterpret_cast<const nodeseq_t&>(G) >> o;
84 };
85
87 G.clean();
88 name_t A[3];
89 slate_t B[2];
90 memcpy(A,o,sizeof(A)); o += sizeof(A);
91 memcpy(B,o,sizeof(B)); o += sizeof(B);
92 if (A[0] != magic)
93 err("in %s (%s line %d) corrupted genealogy serialization.",
94 __func__,__FILE__,__LINE__);
95 G._unique = A[1]; G._ndeme = size_t(A[2]);
96 G.timezero() = B[0]; G.time() = B[1];
97 return o >> reinterpret_cast<nodeseq_t&>(G);
98 };
99
100
101public:
102 // CONSTRUCTORS
105 genealogy_t (double t0 = 0, name_t u = 0, size_t nd = 1) {
106 clean();
107 _ndeme = nd;
108 _unique = u;
109 _time = _t0 = slate_t(t0);
110 };
111
113 o >> *this;
114 };
115
116 genealogy_t (SEXP o) {
117 if (LENGTH(o)==0)
118 err("in %s (%s line %d): cannot deserialize a NULL.",
119 __func__,__FILE__,__LINE__);
120 PROTECT(o = AS_RAW(o));
121 RAW(o) >> *this;
122 UNPROTECT(1);
123 };
124
126 raw_t *o = new raw_t[G.bytesize()];
127 G >> o;
128 o >> *this;
129 delete[] o;
130 };
131
133 clean();
134 raw_t *o = new raw_t[G.bytesize()];
135 G >> o;
136 o >> *this;
137 delete[] o;
138 return *this;
139 };
140
146 clean();
147 };
148
150 slate_t& time (void) {
151 return _time;
152 };
153
154 slate_t time (void) const {
155 return _time;
156 };
157
159 return _t0;
160 };
161
162 slate_t timezero (void) const {
163 return _t0;
164 };
165
166public:
167
175 void lineage_count (double *tout, int *deme,
176 int *ell, int *sat, int *etype) const {
177 slate_t tcur = timezero();
178 for (size_t j = 0; j < _ndeme; j++) {
179 tout[j] = tcur;
180 deme[j] = j+1;
181 sat[j] = ell[j] = 0;
182 etype[j] = 0;
183 }
184 for (const node_t *p : *this) {
185 if (tcur < p->slate) {
186 tout += _ndeme; ell += _ndeme; sat += _ndeme;
187 deme += _ndeme; etype += _ndeme;
188 tcur = p->slate;
189 for (size_t j = 0; j < _ndeme; j++) {
190 tout[j] = tcur;
191 deme[j] = j+1;
192 ell[j] = (ell-_ndeme)[j];
193 sat[j] = 0;
194 etype[j] = 0;
195 }
196 }
197 p->lineage_incr(ell,sat,etype);
198 }
199 tout += _ndeme; ell += _ndeme; sat += _ndeme;
200 deme += _ndeme; etype += _ndeme;
201 tcur = time();
202 for (size_t j = 0; j < _ndeme; j++) {
203 tout[j] = tcur;
204 sat[j] = ell[j] = 0;
205 deme[j] = j+1;
206 etype[j] = 3;
207 }
208 };
209
210 SEXP lineage_count (void) const {
211 SEXP tout, deme, ell, sat, etype, out, outn;
212 int nt = ntime(timezero())+1;
213 int nl = _ndeme*nt;
214 PROTECT(tout = NEW_NUMERIC(nl));
215 PROTECT(deme = NEW_INTEGER(nl));
216 PROTECT(ell = NEW_INTEGER(nl));
217 PROTECT(sat = NEW_INTEGER(nl));
218 PROTECT(etype = NEW_INTEGER(nl));
219 PROTECT(out = NEW_LIST(5));
220 PROTECT(outn = NEW_CHARACTER(5));
221 set_list_elem(out,outn,tout,"time",0);
222 set_list_elem(out,outn,deme,"deme",1);
223 set_list_elem(out,outn,ell,"lineages",2);
224 set_list_elem(out,outn,sat,"saturation",3);
225 set_list_elem(out,outn,etype,"event_type",4);
226 SET_NAMES(out,outn);
227 lineage_count(REAL(tout),INTEGER(deme),INTEGER(ell),
228 INTEGER(sat),INTEGER(etype));
229 UNPROTECT(7);
230 return out;
231 };
232
233 void gendat (double *tout, int *anc, int *lin,
234 int *sat, int *type, int *deme,
235 int *index, int *child) const {
236 int m, n, k;
237 node_it i, j;
238 for (k = 0, n = 0, i = begin(); i != end(); i++, n++) {
239 node_t *p = *i;
240 assert(!p->holds(black)); // tree should be pruned first
241 tout[n] = p->slate;
242 deme[n] = p->deme();
243 if (p->is_root()) {
244 type[n] = 0; // root node
245 } else if (p->holds(blue)) {
246 type[n] = 1; // sample node
247 deme[n] = p->ball(blue)->deme();
248 } else {
249 type[n] = 2; // internal node
250 }
251 lin[n] = p->lineage(); // 0-based indexing
252 sat[n] = p->nchildren();
253 index[n] = k;
254 k += sat[n];
255 child[n] = NA_INTEGER;
256 if (p->is_root()) {
257 anc[n] = n; // 0-based indexing
258 } else {
259 for (m = 0, j = begin(); j != i; j++, m++) {
260 node_t *q = *j;
261 if (p->parent()->uniq == q->uniq) {
262 anc[n] = m;
263 break;
264 }
265 }
266 }
267 }
268 tout[n] = time();
269 for (k = 0, n = 0, i = begin(); i != end(); i++, n++) {
270 node_t *p = *i;
271 j = i; j++;
272 for (m = n+1; j != end(); m++, j++) {
273 node_t *q = *j;
274 if (p->uniq == q->parent()->uniq) {
275 child[k++] = m;
276 }
277 }
278 }
279 };
280
281 SEXP gendat (void) const {
282 SEXP tout, anc, lin, sat, type, deme, index, child, ns, nn;
283 SEXP out, outn;
284 size_t n = length();
285 PROTECT(tout = NEW_NUMERIC(n+1));
286 PROTECT(type = NEW_INTEGER(n));
287 PROTECT(deme = NEW_INTEGER(n));
288 PROTECT(lin = NEW_INTEGER(n));
289 PROTECT(sat = NEW_INTEGER(n));
290 PROTECT(index = NEW_INTEGER(n));
291 PROTECT(child = NEW_INTEGER(n));
292 PROTECT(anc = NEW_INTEGER(n));
293 PROTECT(ns = NEW_INTEGER(1));
294 PROTECT(nn = NEW_INTEGER(1));
295 PROTECT(out = NEW_LIST(10));
296 PROTECT(outn = NEW_CHARACTER(10));
297 set_list_elem(out,outn,tout,"nodetime",0);
298 set_list_elem(out,outn,type,"nodetype",1);
299 set_list_elem(out,outn,deme,"deme",2);
300 set_list_elem(out,outn,lin,"lineage",3);
301 set_list_elem(out,outn,sat,"saturation",4);
302 set_list_elem(out,outn,index,"index",5);
303 set_list_elem(out,outn,child,"child",6);
304 set_list_elem(out,outn,anc,"ancestor",7);
305 set_list_elem(out,outn,ns,"nsample",8);
306 set_list_elem(out,outn,nn,"nnode",9);
307 SET_NAMES(out,outn);
308 gendat(REAL(tout),INTEGER(anc),INTEGER(lin),INTEGER(sat),
309 INTEGER(type),INTEGER(deme),INTEGER(index),INTEGER(child));
310 *INTEGER(ns) = nsample(); // number of samples
311 *INTEGER(nn) = length(); // number of nodes
312 UNPROTECT(12);
313 return out;
314 };
315
317 size_t nsample (void) const {
318 size_t n = 0;
319 for (const node_t *p : *this) {
320 if (p->holds(blue)) n++;
321 }
322 return n;
323 };
324
325public:
326
328 SEXP structure (void) const {
329 SEXP O, On, T0, Time, Nodes;
330 PROTECT(O = NEW_LIST(3));
331 PROTECT(On = NEW_CHARACTER(3));
332 PROTECT(Time = NEW_NUMERIC(1));
333 *REAL(Time) = double(time());
334 PROTECT(T0 = NEW_NUMERIC(1));
335 *REAL(T0) = double(timezero());
336 PROTECT(Nodes = nodeseq_t::structure());
337 set_list_elem(O,On,Time,"time",0);
338 set_list_elem(O,On,T0,"t0",1);
339 set_list_elem(O,On,Nodes,"nodes",2);
340 SET_NAMES(O,On);
341 UNPROTECT(5);
342 return O;
343 };
344
345public:
346
348 std::string describe (void) const {
349 std::string o = "t0 = " + std::to_string(double(timezero()))
350 + "\ntime = " + std::to_string(double(time())) + "\n"
352 return o;
353 };
354
355public:
356
358 virtual std::string yaml (std::string tab = "") const {
359 std::string o;
360 std::string t = tab + " ";
361 o = tab + "t0: " + std::to_string(timezero()) + "\n"
362 + tab + "time: " + std::to_string(time()) + "\n"
363 + tab + "nodes:\n" + nodeseq_t::yaml(tab);
364 return o;
365 };
366
367public:
368
370 std::string newick (void) const {
371 return nodeseq_t::newick(time());
372 };
373
374public:
375
377 void valid (void) const {};
379 bool check_genealogy_size (size_t grace = 0) const {
380 static size_t maxq = MEMORY_MAX/(sizeof(node_t)+2*sizeof(ball_t));
381 bool ok = true;
382 if (size() > maxq+grace) {
383 err("maximum genealogy size exceeded!"); // #nocov
384 } else if (size() > maxq) {
385 ok = false; // #nocov
386 }
387 return ok;
388 };
389
390public:
391
396 name_t u = unique();
397 node_t *p = new node_t(u,_time);
398 ball_t *g = new ball_t(p,u,green,d);
399 p->green_ball() = g;
400 p->insert(g);
401 return p;
402 };
403
404public:
405
408 time() = t;
409 node_t *p = make_node(a->deme());
410 ball_t *b = new ball_t (p,p->uniq,black,d);
411 p->insert(b);
412 p->slate = time();
413 add(p,a);
414 return b;
415 };
416
418 ball_t *b = new ball_t(p,unique(),black,d);
419 p->insert(b);
420 return b;
421 };
422
423 void death (ball_t *a, slate_t t) {
424 time() = t;
425 drop(a);
426 };
427
429 time() = t;
430 node_t *p = make_node(d);
431 ball_t *b = new ball_t (p,p->uniq,black,d);
432 p->insert(b);
433 p->slate = timezero();
434 push_front(p);
435 return b;
436 };
437
438 void sample (ball_t* a, slate_t t) {
439 time() = t;
440 node_t *p = make_node(a->deme());
441 ball_t *b = new ball_t (p,p->uniq,blue,a->deme());
442 p->insert(b);
443 p->slate = time();
444 add(p,a);
445 };
446
448 time() = t;
449 node_t *p = make_node(a->deme());
450 ball_t *b = new ball_t (p,p->uniq,blue,a->deme());
451 p->insert(b);
452 p->slate = time();
453 add(p,a);
454 drop(a);
455 };
456
457 void migrate (ball_t* a, slate_t t, name_t d = 0) {
458 time() = t;
459 node_t *p = make_node(a->deme());
460 p->slate = time();
461 add(p,a);
462 a->deme() = d;
463 };
464
465 void sample_migrate (ball_t* a, slate_t t, name_t d = 0) {
466 time() = t;
467 node_t *p = make_node(a->deme());
468 ball_t *b = new ball_t (p,p->uniq,blue,a->deme());
469 p->insert(b);
470 p->slate = time();
471 add(p,a);
472 a->deme() = d;
473 };
474
476 std::pair<node_it, node_it> extant (void) const {
477 return std::pair<node_it,node_it>(cbegin(),cend());
478 };
479
481 pocket_t *blacks = colored(black);
482 while (!blacks->empty()) {
483 ball_t *b = *(blacks->begin());
484 blacks->erase(b);
485 drop(b);
486 }
487 delete blacks;
488 return *this;
489 };
490
492 // erase deme information from black balls.
493 pocket_t *blacks = colored(black);
494 while (!blacks->empty()) {
495 ball_t *a = *(blacks->begin());
496 a->deme() = 0;
497 blacks->erase(a);
498 }
499 delete blacks;
500 // erase deme information from nodes.
501 for (node_t *p : *this) {
502 p->deme() = 0;
503 }
504 // drop superfluous nodes (holding just one ball).
505 comb();
506 _ndeme = 1;
507 return *this;
508 };
509
511 void curtail (slate_t tnew, slate_t troot) {
512 if (tnew < troot) troot = tnew;
513 if (!empty() && tnew < time()) {
514 node_t *p = back();
515 while (!empty() && p->slate > tnew) {
516 ball_t *b;
517 while (p->size() > 1) {
518 b = p->last_ball();
519 switch (b->color) {
520 case black:
521 p->erase(b); delete b;
522 break;
523 case green: case blue: // #nocov
524 assert(0); // #nocov
525 break; // #nocov
526 }
527 }
528 b = p->last_ball();
529 switch (b->color) {
530 case blue:
531 b->color = black;
532 case black:
533 b->deme() = p->deme();
534 swap(b,p->green_ball());
535 case green:
536 destroy_node(p);
537 break;
538 }
539 if (!empty()) p = back();
540 }
541 }
542 time() = tnew;
543 if (!empty() && troot > timezero()) {
544 node_t *p = front();
545 node_t *q;
546 while (!empty() && p->slate < troot) {
547 ball_t *b;
548 assert(p->holds_own());
549 while (p->size() > 1) {
550 b = p->last_ball();
551 switch (b->color) {
552 case blue:
553 p->erase(b); delete b;
554 break;
555 case black:
556 q = make_node(b->deme());
557 q->slate = troot;
558 q->insert(b); p->erase(b);
559 b->holder() = q;
560 push_back(q);
561 break;
562 case green:
563 q = b->child();
564 if (q == p) {
565 b = p->first_ball();
566 q = b->child();
567 }
568 if (q->slate < troot) {
569 q->insert(b); p->erase(b);
570 b->holder() = q;
571 } else {
572 node_t *pp = make_node(b->deme());
573 pp->slate = troot;
574 pp->insert(b); p->erase(b);
575 b->holder() = pp;
576 push_back(pp);
577 }
578 break;
579 }
580 }
581 destroy_node(p);
582 if (!empty()) p = front();
583 }
584 sort();
585 }
586 if (troot > timezero()) timezero() = troot;
587 };
588
594 reinterpret_cast<nodeseq_t&>(*this) += reinterpret_cast<nodeseq_t&>(G);
595 _t0 = (_t0 > G._t0) ? G._t0 : _t0;
596 _time = (_time < G._time) ? G._time : _time;
597 _unique = (_unique < G._unique) ? G._unique : _unique;
598 _ndeme = (_ndeme < G.ndeme()) ? G.ndeme() : _ndeme;
599 return *this;
600 };
601
602private:
603
604 size_t scan_color (const std::string& s, color_t* col) const {
605 return 1;
606 };
607
609 size_t scan_label (const std::string& s, color_t* col,
610 name_t *deme, slate_t *time) const {
611 size_t n = s.size();
612 if (n < 1)
613 err("in '%s' (%s line %d): invalid Newick format: empty label.",__func__,__FILE__,__LINE__);
614 size_t sz, i = 1;
615 switch (s[0]) {
616 case 'o':
617 *col = black;
618 break;
619 case 'b':
620 *col = blue;
621 break;
622 case 'g': case 'm':
623 *col = green;
624 break;
625 default:
626 err("in '%s' (%s line %d): invalid Newick label: expected one of 'b','g','m', or 'o', got '%c'.",
627 __func__,__FILE__,__LINE__,s[0]);
628 break;
629 }
630 while (i < n && s[i] == '_') i++;
631 if (i == n)
632 err("in '%s': invalid Newick format: premature termination.",__func__);
633 if (s[i] == '(' || s[i] == ')' || s[i] == ',' || s[i] == ';')
634 err("in '%s' (%s line %d): invalid Newick format.",__func__,__FILE__,__LINE__);
635 if (s[i] == ':') {
636 *deme = 0;
637 } else {
638 try {
639 *deme = name_t(stoi(s.substr(i),&sz));
640 i += sz;
641 }
642 catch (const std::invalid_argument& e) {
643 err("in '%s' (%s line %d): invalid Newick format: deme should be indicated with an integer.",
644 __func__,__FILE__,__LINE__);
645 }
646 catch (const std::out_of_range& e) {
647 err("in '%s': invalid Newick format: deme out of range.",__func__);
648 }
649 catch (const std::exception& e) {
650 err("in '%s': parsing deme label: %s.",__func__,e.what());
651 }
652 catch (...) {
653 err("in '%s': other deme-parsing error.",__func__);
654 }
655 }
656 // skip to branch length
657 while (i < n && s[i] != ':' &&
658 s[i] != '(' && s[i] != ')' && s[i] != ',' && s[i] != ';') i++;
659 if (i == n || s[i] != ':')
660 err("in '%s': invalid Newick format: missing or invalid branch length.",__func__);
661 i++;
662 try {
663 *time = slate_t(stod(s.substr(i),&sz));
664 }
665 catch (const std::invalid_argument& e) {
666 err("in '%s': invalid Newick format: branch length should be a non-negative decimal number.",__func__);
667 }
668 catch (const std::out_of_range& e) {
669 err("in '%s': invalid Newick format: branch length out of range.",__func__);
670 }
671 catch (const std::exception& e) {
672 err("in '%s': parsing branch-length: %s.",__func__,e.what());
673 }
674 catch (...) {
675 err("in '%s': other branch-length parsing error.",__func__);
676 }
677 if (*time < 0.0) err("in '%s': negative branch length detected.",__func__);
678 i += sz;
679 return i;
680 };
681
683 size_t scan_ball (const std::string& s, const slate_t t0, node_t *p) {
684 color_t col;
685 name_t deme;
686 slate_t t;
687 ball_t *b;
688 size_t i = scan_label(s,&col,&deme,&t);
689 t += t0;
690 _time = (_time < t) ? t : _time;
691 _ndeme = (_ndeme <= deme) ? deme+1 : _ndeme;
692 if (col != black) err("in '%s': bad Newick string (1)",__func__);
693 if (p == 0) err("in '%s': bad Newick string (2)",__func__);
694 b = new ball_t(p,unique(),col,deme);
695 p->insert(b);
696 return i;
697 };
698
699 size_t scan_node (const std::string& s, const slate_t t0, node_t **q) {
700 size_t i;
701 color_t col;
702 name_t deme;
703 slate_t t;
704 name_t u = unique();
705 i = scan_label(s,&col,&deme,&t);
706 t += t0;
707 _ndeme = (_ndeme <= deme) ? deme+1 : _ndeme;
708 _time = (_time < t) ? t : _time;
709 node_t *p = new node_t(u,t);
710 ball_t *g = new ball_t(p,u,green,deme);
711 p->green_ball() = g;
712 p->insert(g);
713 if (col==blue) {
714 ball_t *b = new ball_t(p,p->uniq,blue,deme);
715 p->insert(b);
716 }
717 push_back(p);
718 *q = p;
719 return i;
720 };
721
723 size_t scan_tree (const std::string& s,
724 const slate_t t0, node_t **root) {
725 size_t n = s.size();
726 size_t i = 1, j = 1, k;
727 size_t stack = 1;
728 while (j < n && stack > 0) {
729 switch (s[j]) {
730 case '(':
731 stack++;
732 break;
733 case ')':
734 stack--;
735 break;
736 default:
737 break;
738 }
739 j++;
740 }
741 if (stack > 0)
742 err("in '%s': premature end of Newick string.",__func__);
743 node_t *p = 0;
744 k = j;
745 k += scan_node(s.substr(j),t0,&p);
746 parse(s.substr(i,j-i-1),p->slate,p);
747 *root = p;
748 return k;
749 };
750
751public:
752
754 genealogy_t& parse (const std::string& s, slate_t t0, node_t *p = 0) {
755 size_t i = 0;
756 size_t n = s.size();
757 while (i < n) {
758 switch (s[i]) {
759 case '(':
760 {
761 genealogy_t G(t0,unique());
762 node_t *q = 0;
763 i += G.scan_tree(s.substr(i),t0,&q);
764 *this += G;
765 if (p != 0) {
766 ball_t *g = q->green_ball();
767 q->erase(g); p->insert(g); g->holder() = p;
768 }
769 }
770 break;
771 case 'b':
772 {
773 node_t *q = 0;
774 i += scan_node(s.substr(i),t0,&q);
775 if (p != 0) {
776 ball_t *g = q->green_ball();
777 q->erase(g); p->insert(g); g->holder() = p;
778 }
779 }
780 break;
781 case 'o':
782 i += scan_ball(s.substr(i),t0,p);
783 break;
784 case ',': case ';': case ' ': case '\n': case '\t':
785 i++;
786 break;
787 case ')':
788 err("in '%s': invalid Newick string: unbalanced parentheses.",__func__);
789 break;
790 default:
791 err("in '%s': invalid Newick string.",__func__);
792 break;
793 }
794 }
795 sort();
796 return *this;
797 };
798};
799
800#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
color_t color
Definition ball.h:38
node_t * child(void) const
a child is the owner of a green ball
Definition ball.h:104
size_t & ndeme(void)
number of demes
Definition genealogy.h:65
slate_t time(void) const
view current time.
Definition genealogy.h:154
size_t nsample(void) const
number of samples
Definition genealogy.h:317
~genealogy_t(void)
destructor
Definition genealogy.h:145
SEXP structure(void) const
R list description.
Definition genealogy.h:328
void clean(void)
clean up
Definition genealogy.h:53
std::string newick(void) const
put genealogy at current time into Newick format.
Definition genealogy.h:370
virtual std::string yaml(std::string tab="") const
machine-readable info
Definition genealogy.h:358
genealogy_t(double t0=0, name_t u=0, size_t nd=1)
Definition genealogy.h:105
void valid(void) const
check the validity of the genealogy.
Definition genealogy.h:377
genealogy_t(SEXP o)
constructor from RAW SEXP (containing binary serialization)
Definition genealogy.h:116
genealogy_t & operator=(const genealogy_t &G)
copy assignment operator
Definition genealogy.h:132
void death(ball_t *a, slate_t t)
death
Definition genealogy.h:423
size_t scan_ball(const std::string &s, const slate_t t0, node_t *p)
Definition genealogy.h:683
SEXP lineage_count(void) const
lineage count and saturation
Definition genealogy.h:210
genealogy_t & prune(void)
prune the tree (drop all black balls)
Definition genealogy.h:480
size_t bytesize(void) const
size of serialized binary form
Definition genealogy.h:73
std::string describe(void) const
human-readable info
Definition genealogy.h:348
size_t ndeme(void) const
number of demes
Definition genealogy.h:61
genealogy_t(const genealogy_t &G)
copy constructor
Definition genealogy.h:125
bool check_genealogy_size(size_t grace=0) const
check the size of the genealogy (to prevent memory exhaustion).
Definition genealogy.h:379
node_t * make_node(name_t d)
Definition genealogy.h:394
size_t scan_label(const std::string &s, color_t *col, name_t *deme, slate_t *time) const
Definition genealogy.h:609
slate_t timezero(void) const
get zero time.
Definition genealogy.h:162
ball_t * graft(slate_t t, name_t d)
graft a new lineage into deme d
Definition genealogy.h:428
genealogy_t & operator+=(genealogy_t &G)
Definition genealogy.h:593
void migrate(ball_t *a, slate_t t, name_t d=0)
movement into deme d
Definition genealogy.h:457
slate_t _time
The current time.
Definition genealogy.h:37
size_t scan_node(const std::string &s, const slate_t t0, node_t **q)
Scan the Newick string and create the indicated node.
Definition genealogy.h:699
SEXP gendat(void) const
genealogy information in list format
Definition genealogy.h:281
ball_t * birth(node_t *p, name_t d)
birth of second or subsequent sibling into deme d
Definition genealogy.h:417
size_t _ndeme
The number of demes.
Definition genealogy.h:39
void gendat(double *tout, int *anc, int *lin, int *sat, int *type, int *deme, int *index, int *child) const
genealogy information in list format
Definition genealogy.h:233
slate_t & timezero(void)
view/set zero time.
Definition genealogy.h:158
void sample_death(ball_t *a, slate_t t)
insert a sample node and simultaneously terminate the lineage
Definition genealogy.h:447
genealogy_t(raw_t *o)
constructor from serialized binary form
Definition genealogy.h:112
slate_t & time(void)
view/set current time.
Definition genealogy.h:150
std::pair< node_it, node_it > extant(void) const
Definition genealogy.h:476
void curtail(slate_t tnew, slate_t troot)
Definition genealogy.h:511
friend raw_t * operator>>(const genealogy_t &G, raw_t *o)
binary serialization
Definition genealogy.h:78
size_t scan_tree(const std::string &s, const slate_t t0, node_t **root)
Definition genealogy.h:723
void sample_migrate(ball_t *a, slate_t t, name_t d=0)
insert a sample node and simultaneously migrate the lineage
Definition genealogy.h:465
static const name_t magic
Definition genealogy.h:41
name_t unique(void)
get the next unique name
Definition genealogy.h:46
size_t scan_color(const std::string &s, color_t *col) const
Definition genealogy.h:604
void sample(ball_t *a, slate_t t)
insert a sample node
Definition genealogy.h:438
void lineage_count(double *tout, int *deme, int *ell, int *sat, int *etype) const
Definition genealogy.h:175
slate_t _t0
The initial time.
Definition genealogy.h:35
genealogy_t & parse(const std::string &s, slate_t t0, node_t *p=0)
Parse a Newick string and create the indicated genealogy.
Definition genealogy.h:754
name_t _unique
The next unique name.
Definition genealogy.h:33
genealogy_t(genealogy_t &&)=default
move constructor
ball_t * birth(ball_t *a, slate_t t, name_t d)
birth into deme d
Definition genealogy.h:407
genealogy_t & obscure(void)
erase all deme information
Definition genealogy.h:491
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
bool is_root(void) const
Definition node.h:121
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
void lineage_incr(int *incr, int *sat, int *etype) const
Definition node.h:151
bool holds_own(void) const
Definition node.h:118
int nchildren(void) const
number of descendants
Definition node.h:131
A sequence of nodes.
Definition nodeseq.h:19
std::string describe(void) const
human-readable info
Definition nodeseq.h:262
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
void destroy_node(node_t *p)
remove a dead root node
Definition nodeseq.h:203
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 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
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
ball_t * ball(const color_t c) const
retrieve the first ball of the specified color.
Definition pocket.h:132
ball_t * last_ball(void) const
retrieve the last ball
Definition pocket.h:128
ball_t * first_ball(void) const
retrieve the first ball
Definition pocket.h:124
bool holds(ball_t *b) const
does this node hold the given ball?
Definition pocket.h:111
static const size_t MEMORY_MAX
Definition genealogy.h:16
Rbyte raw_t
Definition internal.h:43
static int set_list_elem(SEXP list, SEXP names, SEXP element, const char *name, int pos)
Definition internal.h:67
size_t name_t
Definition internal.h:45
#define err(...)
Definition internal.h:18
double slate_t
Definition internal.h:44
static const int deme
Definition lbdp.cc:7
#define ell
Definition lbdp_pomp.c:10
#define n
Definition lbdp_pomp.c:8
std::list< node_t * >::const_iterator node_it
Definition nodeseq.h:14