bpp-phyl3 3.0.0
BipartitionList.cpp
Go to the documentation of this file.
1// SPDX-FileCopyrightText: The Bio++ Development Group
2//
3// SPDX-License-Identifier: CECILL-2.1
4
5#include <Bpp/Exceptions.h>
6#include <Bpp/Io/FileTools.h>
9
10#include "BipartitionList.h"
11#include "BipartitionTools.h"
12#include "TreeTemplate.h"
13
14// From SeqLib:
17
18
19using namespace bpp;
20
21// From the STL:
22#include <iostream>
23#include <climits> // defines CHAR_BIT
24
25using namespace std;
26
27/****************************************************************/
28/* utilitary classes required for sorting elements/bipartitions */
29/****************************************************************/
30
32{
33public:
34 int ind;
35 string str;
36
37public:
39 str() {}
40};
41
43{
44 if (sai1.str < sai2.str)
45 return true;
46 return false;
47}
48
49/******************************************************************************/
50
52{
53public:
54 size_t ind;
55 int val;
56};
57
59{
60 if (iai1.val < iai2.val)
61 return true;
62 return false;
63}
64
65
66/******************************************************************************/
67
68BipartitionList::BipartitionList(const Tree& tr, bool sorted, std::vector<int>* index) :
69 bitBipartitionList_(),
70 elements_(),
71 sorted_(sorted)
72{
73 size_t nbbip;
74
76
77 if (tr.isRooted())
78 nbbip = tr.getNumberOfNodes() - 2;
79 else
80 nbbip = tr.getNumberOfNodes() - 1;
81
82 if (sorted)
83 std::sort(elements_.begin(), elements_.end());
84
85 size_t lword = static_cast<size_t>(BipartitionTools::LWORD);
86 size_t nbword = (elements_.size() + lword - 1) / lword;
87 size_t nbint = nbword * lword / (CHAR_BIT * sizeof(int));
88
89 for (size_t i = 0; i < nbbip; i++)
90 {
91 bitBipartitionList_.push_back(new int[nbint]);
92 for (size_t j = 0; j < nbint; j++)
93 {
94 bitBipartitionList_[i][j] = 0;
95 }
96 }
97
98 size_t cpt = 0;
99 vector<string> underlyingNames;
100 const Tree* tree = &tr;
101 const TreeTemplate<Node>* ttree = dynamic_cast<const TreeTemplate<Node>*>(tree);
102 if (ttree)
103 {
104 // Gain some time...
106 }
107 else
108 {
109 TreeTemplate<Node> tmp(tr);
111 }
112}
113
114/******************************************************************************/
115
117 const std::vector<std::string>& elements,
118 const std::vector<int*>& bitBipL) :
119 bitBipartitionList_(),
120 elements_(elements),
121 sorted_()
122{
123 size_t lword = static_cast<size_t>(BipartitionTools::LWORD);
124 size_t nbword = (elements.size() + lword - 1) / lword;
125 size_t nbint = nbword * lword / (CHAR_BIT * sizeof(int));
126
127 for (size_t i = 0; i < bitBipL.size(); i++)
128 {
129 bitBipartitionList_.push_back(new int[nbint]);
130 for (size_t j = 0; j < nbint; j++)
131 {
132 bitBipartitionList_[i][j] = bitBipL[i][j];
133 }
134 }
135
136 vector<string> cpelements_ = elements;
137 std::sort(cpelements_.begin(), cpelements_.end());
138 if (cpelements_ == elements)
139 sorted_ = true;
140 else
141 sorted_ = false;
142}
143
144/******************************************************************************/
145
147 bitBipartitionList_(),
148 elements_(bipL.elements_),
149 sorted_(bipL.sorted_)
150{
151 size_t lword = static_cast<size_t>(BipartitionTools::LWORD);
152 size_t nbword = (bipL.getNumberOfElements() + lword - 1) / lword;
153 size_t nbint = nbword * lword / (CHAR_BIT * sizeof(int));
154
156 vector<int*> bitBipL = bipL.getBitBipartitionList();
157 for (size_t i = 0; i < bipL.getNumberOfBipartitions(); i++)
158 {
159 bitBipartitionList_[i] = new int[nbint];
160 for (size_t j = 0; j < nbint; j++)
161 {
162 bitBipartitionList_[i][j] = bitBipL[i][j];
163 }
164 }
165}
166
167/******************************************************************************/
168
170{
171 size_t lword = static_cast<size_t>(BipartitionTools::LWORD);
172 size_t nbword = (bipL.getNumberOfElements() + lword - 1) / lword;
173 size_t nbint = nbword * lword / (CHAR_BIT * sizeof(int));
174
175 for (size_t i = 0; i < bitBipartitionList_.size(); i++)
176 {
177 delete[] bitBipartitionList_[i];
178 }
180 vector<int*> bitBipL = bipL.getBitBipartitionList();
181 for (size_t i = 0; i < bipL.getNumberOfBipartitions(); i++)
182 {
183 bitBipartitionList_[i] = new int[nbint];
184 for (size_t j = 0; j < nbint; j++)
185 {
186 bitBipartitionList_[i][j] = bitBipL[i][j];
187 }
188 }
189
190 elements_ = bipL.elements_;
191 sorted_ = bipL.sorted_;
192 return *this;
193}
194
195/******************************************************************************/
196
198{
199 for (size_t i = 0; i < bitBipartitionList_.size(); i++)
200 {
201 delete[] bitBipartitionList_[i];
202 }
203}
204
205/******************************************************************************/
206
207map<string, bool> BipartitionList::getBipartition(size_t i) const
208{
209 map<string, bool> bip;
210
211 if (i >= bitBipartitionList_.size())
212 throw Exception("Bipartition index exceeds BipartitionList size");
213
214 for (size_t j = 0; j < elements_.size(); j++)
215 {
216 if (BipartitionTools::testBit(bitBipartitionList_[i], static_cast<int>(j)))
217 bip[elements_[j]] = true;
218 else
219 bip[elements_[j]] = false;
220 }
221 return bip;
222}
223
224/******************************************************************************/
225
227{
228 if (i >= bitBipartitionList_.size())
229 throw Exception("Bipartition index exceeds BipartitionList size");
230
231 return bitBipartitionList_[i];
232}
233
234/******************************************************************************/
235
236bool BipartitionList::haveSameElementsThan(map<string, bool>& bipart) const
237{
238 vector<string> elements = elements_;
239 vector<string> keys;
240
241 map<string, bool>::iterator it;
242
243 for (it = bipart.begin(); it != bipart.end(); it++)
244 {
245 keys.push_back(it->first);
246 }
247
248 std::sort(elements.begin(), elements.end());
249 std::sort(keys.begin(), keys.end());
250
251 if (elements == keys)
252 return true;
253 return false;
254}
255
256/******************************************************************************/
257
258void BipartitionList::addBipartition(map<string, bool>& bipart, bool checkElements)
259{
260 if (checkElements && !BipartitionList::haveSameElementsThan(bipart))
261 throw Exception("Distinct bipartition element sets");
262
263 size_t lword = static_cast<size_t>(BipartitionTools::LWORD);
264 size_t nbword = (elements_.size() + lword - 1) / lword;
265 size_t nbint = nbword * lword / (CHAR_BIT * sizeof(int));
266 bitBipartitionList_.push_back(new int[nbint]);
267 size_t ind = bitBipartitionList_.size() - 1;
268 for (size_t j = 0; j < nbint; j++)
269 {
270 bitBipartitionList_[ind][j] = 0;
271 }
272
273 for (size_t i = 0; i < elements_.size(); i++)
274 {
275 if (bipart[elements_[i]] == true)
276 BipartitionTools::bit1(bitBipartitionList_[ind], static_cast<int>(i));
277 else
278 BipartitionTools::bit0(bitBipartitionList_[ind], static_cast<int>(i));
279 }
280}
281
282/******************************************************************************/
283
285{
286 if (i >= bitBipartitionList_.size())
287 throw Exception("Bipartition index exceeds BipartitionList size");
288
289 delete[] bitBipartitionList_[i];
290 bitBipartitionList_.erase(bitBipartitionList_.begin() + static_cast<ptrdiff_t>(i));
291}
292
293/******************************************************************************/
294
295bool BipartitionList::containsBipartition(map<string, bool>& bipart, bool checkElements) const
296{
297 size_t i, j;
298 bool dac, padac;
299
300 if (checkElements && !BipartitionList::haveSameElementsThan(bipart))
301 throw Exception("Distinct bipartition element sets");
302
303 for (i = 0; i < bitBipartitionList_.size(); i++)
304 {
305 dac = padac = false;
306 for (j = 0; j < elements_.size(); j++)
307 {
308 if (BipartitionTools::testBit(bitBipartitionList_[i], static_cast<int>(j)))
309 {
310 if (bipart[elements_[j]])
311 dac = true;
312 else
313 padac = true;
314 }
315 else
316 {
317 if (bipart[elements_[j]])
318 padac = true;
319 else
320 dac = true;
321 }
322 if (dac && padac)
323 break;
324 }
325 if (j == elements_.size())
326 return true;
327 }
328 return false;
329}
330
331/******************************************************************************/
332
333bool BipartitionList::areIdentical(size_t k1, size_t k2) const
334{
335 bool dac, padac;
336
337 if (k1 >= bitBipartitionList_.size())
338 throw Exception("Bipartition index exceeds BipartitionList size");
339 if (k2 >= bitBipartitionList_.size())
340 throw Exception("Bipartition index exceeds BipartitionList size");
341
342 dac = padac = false;
343 for (size_t j = 0; j < elements_.size(); j++)
344 {
345 if (BipartitionTools::testBit(bitBipartitionList_[k1], static_cast<int>(j)))
346 {
347 if (BipartitionTools::testBit(bitBipartitionList_[k2], static_cast<int>(j)))
348 dac = true;
349 else
350 padac = true;
351 }
352 else
353 {
354 if (BipartitionTools::testBit(bitBipartitionList_[k2], static_cast<int>(j)))
355 padac = true;
356 else
357 dac = true;
358 }
359 if (dac && padac)
360 return false;
361 }
362 return true;
363}
364
365/******************************************************************************/
366
367bool BipartitionList::areCompatible(size_t k1, size_t k2) const
368{
369 bool uu, uz, zu, zz;
370
371 if (k1 >= bitBipartitionList_.size())
372 throw Exception("Bipartition index exceeds BipartitionList size");
373 if (k2 >= bitBipartitionList_.size())
374 throw Exception("Bipartition index exceeds BipartitionList size");
375
376 uu = uz = zu = zz = false;
377
378 for (size_t j = 0; j < elements_.size(); j++)
379 {
380 if (BipartitionTools::testBit(bitBipartitionList_[k1], static_cast<int>(j)))
381 {
382 if (BipartitionTools::testBit(bitBipartitionList_[k2], static_cast<int>(j)))
383 uu = true;
384 else
385 uz = true;
386 }
387 else
388 {
389 if (BipartitionTools::testBit(bitBipartitionList_[k2], static_cast<int>(j)))
390 zu = true;
391 else
392 zz = true;
393 }
394 if (uu && uz && zu && zz)
395 return false;
396 }
397
398 return true;
399}
400
401/******************************************************************************/
402
404{
405 for (size_t i = 0; i < bitBipartitionList_.size(); i++)
406 {
407 for (size_t j = i + 1; j < bitBipartitionList_.size(); j++)
408 {
410 return false;
411 }
412 }
413 return true;
414}
415
416/******************************************************************************/
417
418bool BipartitionList::areAllCompatibleWith(map<string, bool>& bipart, bool checkElements) const
419{
420 if (checkElements && !haveSameElementsThan(bipart))
421 throw Exception("Distinct bipartition element sets");
422 size_t nbBip = bitBipartitionList_.size();
423 const_cast<BipartitionList*>(this)->addBipartition(bipart, false);
424
425 for (size_t i = 0; i < nbBip; i++)
426 {
427 if (!areCompatible(i, nbBip))
428 {
429 const_cast<BipartitionList*>(this)->deleteBipartition(nbBip);
430 return false;
431 }
432 }
433 const_cast<BipartitionList*>(this)->deleteBipartition(nbBip);
434 return true;
435}
436
437/******************************************************************************/
438
440{
441 vector<StringAndInt> relements_;
442 StringAndInt sai;
443 size_t nbbip;
444
445 for (size_t i = 0; i < elements_.size(); i++)
446 {
447 sai.str = elements_[i];
448 sai.ind = static_cast<int>(i);
449 relements_.push_back(sai);
450 }
451
452 std::sort(relements_.begin(), relements_.end());
453
454 for (size_t i = 0; i < elements_.size(); i++)
455 {
456 elements_[i] = relements_[i].str;
457 }
458
459 nbbip = bitBipartitionList_.size();
460 bitBipartitionList_.resize(2 * nbbip);
461 size_t lword = static_cast<size_t>(BipartitionTools::LWORD);
462 size_t nbword = (elements_.size() + lword - 1) / lword;
463 size_t nbint = nbword * lword / (CHAR_BIT * sizeof(int));
464
465 for (size_t j = nbbip; j < 2 * nbbip; j++)
466 {
467 bitBipartitionList_[j] = new int[nbint];
468 for (size_t k = 0; k < nbint; k++)
469 {
470 bitBipartitionList_[j][k] = 0;
471 }
472 for (size_t i = 0; i < elements_.size(); i++)
473 {
474 if (BipartitionTools::testBit(bitBipartitionList_[j - nbbip], relements_[i].ind))
475 BipartitionTools::bit1(bitBipartitionList_[j], static_cast<int>(i));
476 else
477 BipartitionTools::bit0(bitBipartitionList_[j], static_cast<int>(i));
478 }
479 }
480
481 for (size_t j = 0; j < nbbip; j++)
482 {
483 delete[] bitBipartitionList_[j];
484 }
485
486 bitBipartitionList_.erase(bitBipartitionList_.begin(), bitBipartitionList_.begin() + static_cast<ptrdiff_t>(nbbip));
487 sorted_ = true;
488}
489
490/******************************************************************************/
491
493{
494 size_t size = 0;
495 if (k >= bitBipartitionList_.size())
496 throw Exception("Bipartition index exceeds BipartitionList size");
497
498 for (size_t i = 0; i < elements_.size(); i++)
499 {
500 if (BipartitionTools::testBit(bitBipartitionList_[k], static_cast<int>(i)))
501 size++;
502 }
503
504 if (size <= elements_.size() / 2)
505 return size;
506 else
507 return elements_.size() - size;
508}
509
510/******************************************************************************/
511
513{
514 size_t size = bitBipartitionList_.size();
515 for (size_t i = size; i > 0; i--)
516 {
519 }
520}
521
522/******************************************************************************/
523
525{
526 map<string, bool> bip;
527
528 for (size_t i = 0; i < elements_.size(); i++)
529 {
530 bip[elements_[i]] = false;
531 }
532 for (size_t i = 0; i < elements_.size(); i++)
533 {
534 bip[elements_[i]] = true;
535 if (checkExisting && BipartitionList::containsBipartition(bip, false))
536 continue;
538 bip[elements_[i]] = false;
539 }
540}
541
542/******************************************************************************/
543
545{
546 vector<int*> sortedBitBipL;
547 vector<IntAndInt> iaiVec;
548 IntAndInt iai;
549
550 for (size_t i = 0; i < bitBipartitionList_.size(); i++)
551 {
552 iai.ind = i;
553 iai.val = static_cast<int>(BipartitionList::getPartitionSize(i));
554 iaiVec.push_back(iai);
555 }
556
557 std::sort(iaiVec.begin(), iaiVec.end());
558
559 for (size_t i = 0; i < bitBipartitionList_.size(); i++)
560 {
561 sortedBitBipL.push_back(bitBipartitionList_[iaiVec[i].ind]);
562 }
563
564 bitBipartitionList_ = sortedBitBipL;
565}
566
567/******************************************************************************/
568
570{
571 if (k >= bitBipartitionList_.size())
572 throw Exception("Bipartition index exceeds BipartitionList size");
573 size_t lword = static_cast<size_t>(BipartitionTools::LWORD);
574 size_t nbword = (elements_.size() + lword - 1) / lword;
575 size_t nbint = nbword * lword / (CHAR_BIT * sizeof(int));
576 int* flipbip = new int[nbint];
577 for (size_t i = 0; i < nbint; i++)
578 {
579 flipbip[i] = 0;
580 }
582 delete[] bitBipartitionList_[k];
583 bitBipartitionList_[k] = flipbip;
584}
585
586/******************************************************************************/
587
589{
590 bool deletion = true;
591
592 while (deletion)
593 {
594 deletion = false;
595 for (size_t i = 0; i < bitBipartitionList_.size(); i++)
596 {
597 for (size_t j = i + 1; j < bitBipartitionList_.size(); j++)
598 {
600 {
602 deletion = true;
603 break;
604 }
605 }
606 if (deletion)
607 break;
608 }
609 }
610}
611
612/******************************************************************************/
613
614unique_ptr<TreeTemplate<Node>> BipartitionList::toTree() const
615{
616 unique_ptr<BipartitionList> sortedBipL;
617 vector<int*> sortedBitBipL;
618 int* bip;
619 vector<Node*> vecNd, sonNd;
620 vector<bool> alive;
621 size_t lword, nbword, nbint, ii;
622
623 /* check, copy and prepare bipartition list */
624
626 throw Exception("Trying to build a tree from incompatible bipartitions");
627
628 sortedBipL.reset(dynamic_cast<BipartitionList*>(clone()));
629 for (size_t i = 0; i < sortedBipL->getNumberOfBipartitions(); i++)
630 {
631 if (sortedBipL->getPartitionSize(i) > sortedBipL->getNumberOfElements() / 2)
632 sortedBipL->flip(i);
633 }
634 sortedBipL->sortByPartitionSize();
635 sortedBipL->removeRedundantBipartitions();
636 sortedBitBipL = sortedBipL->getBitBipartitionList();
637
638 for (size_t i = 0; i < sortedBipL->getNumberOfBipartitions(); i++)
639 {
640 alive.push_back(true);
641 }
642 vecNd.resize(sortedBipL->getNumberOfBipartitions() + 1);
643 lword = static_cast<size_t>(BipartitionTools::LWORD);
644 nbword = (elements_.size() + lword - 1) / lword;
645 nbint = nbword * lword / (CHAR_BIT * sizeof(int));
646 bip = new int[1]; bip[0] = 0;
647
648 /* main loop: create one node per bipartition */
649 for (size_t i = 0; i < sortedBipL->getNumberOfBipartitions(); i++)
650 {
651 if (sortedBipL->getPartitionSize(i) == 1)
652 { // terminal
653 for (size_t j = 0; j < sortedBipL->getNumberOfElements(); j++)
654 {
655 if (BipartitionTools::testBit(sortedBitBipL[i], static_cast<int>(j)))
656 {
657 vecNd[i] = new Node(elements_[j]);
658 break;
659 }
660 }
661 }
662 else
663 { // internal
664 sonNd.clear();
665 for (size_t j = 0; j < i; j++)
666 {
667 if (alive[j])
668 {
669 for (ii = 0; ii < nbint; ii++)
670 {
671 BipartitionTools::bitOr(bip, sortedBitBipL[j] + ii, sortedBitBipL[i] + ii, 1);
672 if (bip[0] != sortedBitBipL[i][ii])
673 break;
674 }
675 if (ii == nbint)
676 {
677 sonNd.push_back(vecNd[j]);
678 alive[j] = false;
679 }
680 }
681 }
682 vecNd[i] = new Node();
683 for (size_t k = 0; k < sonNd.size(); k++)
684 {
685 vecNd[i]->addSon(sonNd[k]);
686 }
687 }
688 }
689
690 /* create last node, which joins alive bipartitions = fatherless nodes */
691 Node* rootNd = new Node();
692 for (size_t i = 0; i < sortedBipL->getNumberOfBipartitions(); i++)
693 {
694 if (alive[i])
695 rootNd->addSon(vecNd[i]);
696 }
697
698 /* construct tree and return */
699 auto tr = make_unique<TreeTemplate<Node>>(rootNd);
700 tr->resetNodesId();
701
702 return tr;
703}
704
705/******************************************************************************/
706
707vector<string> BipartitionList::buildBitBipartitions(const Node* nd, vector<int*>& bitbip, const vector<string>& elements, size_t* cpt, vector<int>* index) const
708{
709 vector<string> underelements_, retelements_;
710
711 if (nd->getNumberOfSons() == 0)
712 underelements_.push_back(nd->getName());
713
714 for (size_t i = 0; i < nd->getNumberOfSons(); i++)
715 {
716 retelements_ = BipartitionList::buildBitBipartitions(nd->getSon(i), bitbip, elements, cpt, index);
717 for (size_t j = 0; j < retelements_.size(); j++)
718 {
719 underelements_.push_back(retelements_[j]);
720 }
721 }
722
723 if (!nd->hasFather())
724 return underelements_; // root node
725
726 if (!nd->getFather()->hasFather())
727 {
728 size_t nbrootson = nd->getFather()->getNumberOfSons();
729 if (nbrootson == 2 && nd == nd->getFather()->getSon(1))
730 return underelements_; // son 2 of root node when root node has 2 sons
731 }
732
733 bool ones;
734 if (underelements_.size() <= elements.size() / 2)
735 ones = true;
736 else
737 ones = false;
738
739 for (size_t i = 0; i < elements.size(); i++)
740 {
741 if (ones)
742 BipartitionTools::bit0(bitbip[*cpt], static_cast<int>(i));
743 else
744 BipartitionTools::bit1(bitbip[*cpt], static_cast<int>(i));
745 }
746
747 for (size_t i = 0; i < underelements_.size(); i++)
748 {
749 size_t taxa_ind = 0;
750 while (underelements_[i] != elements[taxa_ind])
751 taxa_ind++;
752 if (ones)
753 BipartitionTools::bit1(bitbip[*cpt], static_cast<int>(taxa_ind));
754 else
755 BipartitionTools::bit0(bitbip[*cpt], static_cast<int>(taxa_ind));
756 }
757
758 (*cpt)++;
759
760 if (index)
761 index->push_back(nd->getId());
762
763 return underelements_;
764}
765
766/******************************************************************************/
767
769{
770 vector< map<string, bool>> bipl;
771 for (size_t i = 0; i < getNumberOfBipartitions(); i++)
772 {
773 bipl.push_back(getBipartition(i));
774 }
775
776 vector<string> el = getElementNames();
777
778 RowMatrix<int> mat(el.size(), getNumberOfBipartitions());
779
780 for (size_t j = 0; j < el.size(); j++)
781 {
782 for (size_t i = 0; i < getNumberOfBipartitions(); i++)
783 {
784 mat(j, i) = bipl[i][el[j]];
785 }
786 }
787 return mat;
788}
789
790/******************************************************************************/
bool operator<(StringAndInt sai1, StringAndInt sai2)
This class deals with the bipartitions defined by trees.
void addTrivialBipartitions(bool checkExisting)
Adds bipartitions corresponding to external branches if missing.
std::vector< int * > bitBipartitionList_
void flip(size_t i)
Replaces ones by zeros and zeros by ones in the ith bipartition.
void sortByPartitionSize()
Sort bipartitions by partition size.
void addBipartition(std::map< std::string, bool > &bipart, bool checkElements=1)
bool containsBipartition(std::map< std::string, bool > &bipart, bool checkElements=1) const
size_t getNumberOfElements() const
bool haveSameElementsThan(std::map< std::string, bool > &bipart) const
std::vector< std::string > elements_
std::map< std::string, bool > getBipartition(size_t i) const
void removeTrivialBipartitions()
Removes bipartitions corresponding to external branches (1 vs n-1)
std::unique_ptr< TreeTemplate< Node > > toTree() const
Translate into a tree.
BipartitionList(const Tree &tr, bool sorted=true, std::vector< int > *index=0)
The main constructor.
size_t getPartitionSize(size_t i) const
Returns the size of the smallest of the two partitions (e.g. 1 for external branches)
bool areIdentical(size_t k1, size_t k2) const
const std::vector< std::string > & getElementNames() const
RowMatrix< int > toMatrix() const
Create a matrix representation of the bifurcations.
const std::vector< int * > & getBitBipartitionList() const
bool areCompatible(size_t k1, size_t k2) const
Tells whether 2 bipartitions from the list are compatible.
BipartitionList * clone() const
size_t getNumberOfBipartitions() const
BipartitionList & operator=(const BipartitionList &bipl)
Assignment operator.
int * getBitBipartition(size_t i)
void deleteBipartition(size_t i)
bool areAllCompatible() const
Tells whether all bipartitions in the list are compatible with each other.
std::vector< std::string > buildBitBipartitions(const Node *nd, std::vector< int * > &bitbip, const std::vector< std::string > &elements, size_t *cpt, std::vector< int > *index) const
bool areAllCompatibleWith(std::map< std::string, bool > &bipart, bool checkElements=true) const
Tells whether all bipartitions in the list are compatible with a given bipartition.
static int LWORD
Unit length (in bits) of arrays of bits. Must be a multiple of CHAR_BIT*sizeof(int)....
static bool testBit(int *list, int num)
Tells whether bit number num in bit array list is one.
static void bit1(int *list, int num)
Sets bit number num of bit array list to one.
static void bitOr(int *listou, int *list1, int *list2, size_t len)
bit-wise logical OR between two arrays of bits
static void bitNot(int *listnon, int *list, size_t len)
bit-wise logical NOT
static void bit0(int *list, int num)
Sets bit number num of bit array plist to zero.
The phylogenetic node class.
Definition: Node.h:59
virtual std::string getName() const
Get the name associated to this node, if there is one, otherwise throw a NodeException.
Definition: Node.h:203
virtual int getId() const
Get the node's id.
Definition: Node.h:170
virtual void addSon(size_t pos, Node *node)
Definition: Node.h:386
virtual const Node * getFather() const
Get the father of this node is there is one.
Definition: Node.h:306
virtual const Node * getSon(size_t pos) const
Definition: Node.h:362
virtual bool hasFather() const
Tell if this node has a father node.
Definition: Node.h:346
virtual size_t getNumberOfSons() const
Definition: Node.h:355
The phylogenetic tree class.
Definition: TreeTemplate.h:59
virtual N * getRootNode()
Definition: TreeTemplate.h:389
Interface for phylogenetic tree objects.
Definition: Tree.h:115
virtual bool isRooted() const =0
Tell if the tree is rooted.
virtual size_t getNumberOfNodes() const =0
virtual std::vector< std::string > getLeavesNames() const =0
Defines the basic types of data flow nodes.