|
A library for working with phylogenetic and population genetic data.
v0.32.0
|
|
Go to the documentation of this file.
45 #include <unordered_set>
61 return &( link.
next() ) == &link;
76 return &( link.
next() ) != &link;
116 }
while( lnk != &node.
link() );
128 for(
size_t i = 0; i < tree.
node_count(); ++i ) {
137 for(
size_t i = 0; i < tree.
node_count(); ++i ) {
150 if( ! isroot && ! loose ) {
171 for (
size_t i = 0; i < tree.
node_count(); ++i) {
172 auto const& n = tree.
node_at(i);
193 for(
auto const& edge : tree.
edges() ) {
194 if(
is_leaf( edge.primary_node() ) ||
is_leaf( edge.secondary_node() ) ) {
204 for(
auto const& edge : tree.
edges() ) {
205 if(
is_inner( edge.primary_node() ) &&
is_inner( edge.secondary_node() ) ) {
219 std::vector<size_t> result;
220 for(
auto const& edge : tree.
edges() ) {
221 if(
is_inner( edge.secondary_node() ) ) {
222 result.push_back( edge.index() );
230 std::vector<size_t> result;
231 for(
auto const& edge : tree.
edges() ) {
232 if(
is_leaf( edge.secondary_node() ) ) {
233 result.push_back( edge.index() );
241 std::vector<size_t> result;
242 for(
auto const& node : tree.
nodes() ) {
244 result.push_back( node.index() );
252 std::vector<size_t> result;
253 for(
auto const& node : tree.
nodes() ) {
255 result.push_back( node.index() );
273 auto traverse = [&](
TreeLink const& start_link,
size_t i,
signed char sign ){
274 auto link = &( start_link.
next() );
275 while( link != &start_link ) {
276 result( i, link->edge().index() ) = sign;
277 link = &( link->outer().next() );
284 for(
size_t i = 0; i < tree.
edge_count(); ++i ) {
297 #pragma omp parallel for
298 for(
size_t i = 0; i < tree.
node_count(); ++i ) {
299 auto const& row_node = tree.
node_at(i);
300 auto const row_index = row_node.
index();
301 auto const primary_link = &row_node.primary_link();
307 signed char const value =
is_root( row_node ) ? -1 : 1;
308 auto current_link = &( primary_link->outer() );
309 while( current_link != primary_link ) {
310 mat( row_index, current_link->node().index() ) = value;
311 current_link = &( current_link->next().outer() );
320 auto sub_link = &( primary_link->next() );
321 while( sub_link != primary_link ) {
324 current_link = &( sub_link->outer() );
325 while( current_link != sub_link ) {
326 mat( row_index, current_link->node().index() ) = -1;
327 current_link = &( current_link->next().outer() );
331 sub_link = &( sub_link->next() );
335 assert( mat( row_index, row_index ) == 0 );
348 throw std::runtime_error(
349 "Cannot caluclate subtree_size, as the given Link does not belong to the Tree."
356 std::unordered_set< TreeNode const* > visited_nodes;
358 auto cur_link = &link.
outer();
359 while( cur_link != &link ) {
360 visited_nodes.insert( &cur_link->node() );
361 cur_link = &cur_link->next().outer();
364 return visited_nodes.size();
370 throw std::runtime_error(
371 "Cannot calculate subtree_sizes(), as the given Node does not belong to the Tree."
378 std::vector<size_t> result;
385 std::vector< TreeLink const* > stack;
386 stack.push_back( &node.
link() );
394 if( &it.link().next() == stack.back() && stack.back() != &node.
link() ) {
398 auto st_size = result[ stack.back()->node().index() ];
400 result[ stack.back()->node().index() ] += st_size;
403 }
else if( &it.node() == &stack.back()->node() ) {
408 }
else if(
is_leaf( it.link() )) {
411 ++result[ stack.back()->node().index() ];
420 ++result[ stack.back()->node().index() ];
421 stack.push_back( &it.link() );
426 assert( stack.size() == 1 && stack.back() == &node.
link() );
443 throw std::runtime_error(
444 "Cannot calculate subtree_max_path_height(), "
445 "as the given Link does not belong to the Tree."
453 auto cur_link = &link.
outer();
454 while( cur_link != &link ) {
455 max = std::max( max, dists[ cur_link->node().index() ] );
456 cur_link = &cur_link->next().outer();
464 throw std::runtime_error(
465 "Cannot calculate subtree_max_path_heights(), "
466 "as the given Node does not belong to the Tree."
470 auto result = std::vector<size_t>( tree.
node_count(), 0 );
474 std::function< size_t(
TreeLink const* )> rec_subtree_height = [&](
TreeLink const* l ) {
478 link_max = std::max( link_max, 1 + rec_subtree_height( &cl->
outer() ));
482 result[ l->node().index() ] = link_max;
492 node_max = std::max( node_max, 1 + rec_subtree_height( &cur_l->
outer() ));
493 cur_l = &cur_l->
next();
494 }
while( cur_l != &node.
link() );
495 result[ node.
index() ] = node_max;
512 throw std::invalid_argument(
"Tree is not rooted. Cannot calculate its sign matrix." );
515 throw std::invalid_argument(
"Tree is not bifurcating. Cannot calculate its sign matrix." );
523 auto fill_subtree_indices = [&](
size_t row_idx,
Subtree const& st,
signed char sign ){
524 for(
auto const& it :
preorder(st) ) {
525 result( row_idx, it.node().index() ) = sign;
530 #pragma omp parallel for
531 for(
size_t i = 0; i < tree.
node_count(); ++i ) {
532 auto const& row_node = tree.
node_at(i);
533 auto const row_idx = row_node.
index();
538 assert( &row_node.link().next().next() == &row_node.link() );
539 fill_subtree_indices( row_idx,
Subtree{ row_node.
link().outer() }, +1 );
540 fill_subtree_indices( row_idx,
Subtree{ row_node.
link().next().outer() }, -1 );
545 assert( &row_node.link().next().next().next() == &row_node.link() );
546 fill_subtree_indices( row_idx,
Subtree{ row_node.
link().next().outer() }, +1 );
547 fill_subtree_indices( row_idx,
Subtree{ row_node.
link().next().next().outer() }, -1 );
562 for(
size_t r = 0; r < in_node_idcs.size(); ++r ) {
563 for(
size_t c = 0; c < lf_node_idcs.size(); ++c ) {
564 result_cmpr( r, c ) = result( in_node_idcs[r], lf_node_idcs[c] );
570 swap( result, result_cmpr );
582 std::vector< TreeLink const* >
path;
596 path.push_back( cur_link );
609 path.push_back( cur_link );
616 if( &node_a == &node_b ) {
624 assert( path_a.size() > 0 && path_b.size() > 0 );
625 assert( path_a.front() == &node_a.
link() );
626 assert( path_b.front() == &node_b.
link() );
627 assert( path_a.back() == path_b.back() );
635 path_a.at( path_a.size() - 1 ) == path_b.at( path_b.size() - 1 ) &&
636 path_a.at( path_a.size() - 2 ) == path_b.at( path_b.size() - 2 )
643 assert( path_a.size() > 0 && path_b.size() > 0 );
644 assert( path_a.back() == path_b.back() );
646 return path_a.back()->node();
651 auto const& c_node_a =
static_cast< TreeNode const&
>( node_a );
652 auto const& c_node_b =
static_cast< TreeNode const&
>( node_b );
665 #ifdef GENESIS_OPENMP
671 #pragma omp parallel for
672 for(
size_t k = 0; k < max_k; ++k ) {
676 auto const r = rc.first;
677 auto const c = rc.second;
680 res( r, c ) = lca.index();
681 res( c, r ) = lca.index();
687 #pragma omp parallel for
688 for(
size_t d = 0; d < tree.
node_count(); ++d ) {
695 for(
size_t r = 0; r < tree.
node_count(); ++r ) {
698 for(
size_t c = r; c < tree.
node_count(); ++c ) {
701 res( r, c ) = lca.index();
702 res( c, r ) = lca.index();
706 assert( res( r, r ) == r );
void swap(Sample &lhs, Sample &rhs)
TreeLink & primary_link()
Return the TreeLink of this TreeEdge that points towards the root.
size_t leaf_node_count(Tree const &tree)
Count the number of leaf Nodes of a Tree.
TreeLink const & link() const
Get the TreeLink that separates the subtree from the rest of the tree.
size_t node_count() const
Return the number of TreeNodes of the Tree.
std::vector< size_t > subtree_max_path_heights(Tree const &tree, TreeNode const &node)
double sum(const Histogram &h)
size_t inner_node_count(Tree const &tree)
Count the number of inner Nodes.
utils::Matrix< signed char > sign_matrix(Tree const &tree, bool compressed)
Compute the sign matrix or Sequential Binary Partition (SBP) of a Tree.
bool is_inner(TreeLink const &link)
Return true iff the node of the given link is an inner node.
TreeLink & next()
Return the next TreeLink within the TreeNode of this link.
TreeNode & node()
Return the TreeNode of this TreeLink.
bool is_binary(Tree const &tree, bool loose)
Alias for is_bifurcating().
TreeNode const & lowest_common_ancestor(TreeNode const &node_a, TreeNode const &node_b)
Return the lowest common ancestor of two TreeNodes.
TreeNode & node_at(size_t index)
Return the TreeNode at a certain index.
size_t subtree_max_path_height(Tree const &tree, TreeLink const &link)
Calculate the height of a subtree, that is, the maximum path length to a leaf of that subtree,...
TreeEdge & edge_at(size_t index)
Return the TreeEdge at a certain index.
utils::Range< IteratorPreorder< true > > preorder(ElementType const &element)
std::vector< size_t > inner_edge_indices(Tree const &tree)
Get a list of the edge indices of all inner edges, that is, all TreeEdges that do not lead to a leaf ...
bool belongs_to(Tree const &tree, TreeNode const &node)
Return whether the TreeNode belongs to the Tree, i.e., whether it is owned by the Tree.
size_t degree(TreeLink const &link)
Return the degree of the node for a given TreeLink, i.e. how many neighbouring nodes it has.
TreeNode & root_node()
Return the TreeNode at the current root of the Tree.
std::pair< size_t, size_t > triangular_indices(size_t k, size_t n)
Given a linear index in a upper triangular Matrix, find the corresponding Matrix indices.
size_t max_degree(Tree const &tree)
Return the highest degree of the Nodes of a Tree.
TreeLink & primary_link()
Return the TreeLink that points towards the root.
std::vector< TreeLink const * > path_to_root(TreeNode const &node)
Helper function that finds all TreeLinks between a given TreeNode and the root of the Tree.
utils::Range< IteratorPath< true > > path(ElementType const &start, ElementType const &finish)
size_t leaf_edge_count(Tree const &tree)
Return the number of Edges of a Tree that lead to a leaf Node.
Class for representing phylogenetic trees.
size_t node_count(Tree const &tree)
Return the number of Nodes of a Tree. Same as Tree::node_count().
bool empty() const
Return whether the Tree is empty (i.e., has no nodes, edges and links).
bool is_root(TreeLink const &link)
Return whether the link belongs to the root node of its Tree.
Reference to a subtree of a Tree.
Container namespace for all symbols of genesis in order to keep them separate when used as a library.
TreeLink & link()
Return the TreeLink that points towards the root.
size_t inner_edge_count(Tree const &tree)
Return the number of Edges of a Tree that do not lead to a leaf Node.
utils::Range< IteratorNodes > nodes()
utils::Range< IteratorEdges > edges()
bool is_bifurcating(Tree const &tree, bool loose)
Return whether the Tree is bifurcating.
std::vector< size_t > subtree_sizes(Tree const &tree, TreeNode const &node)
Calculate the sizes of all subtrees as seen from the given TreeNode.
std::vector< size_t > leaf_edge_indices(Tree const &tree)
Get a list of the edge indices of all leaf edges, that is, all TreeEdges that lead to a leaf TreeNode...
std::vector< size_t > leaf_node_indices(Tree const &tree)
Get a list of the node indices of all leaf TreeNodes.
bool is_rooted(Tree const &tree)
Return whether the Tree is rooted, that is, whether the root node has two neighbors.
utils::Matrix< size_t > lowest_common_ancestors(Tree const &tree)
Return the lowest common ancestor of each pair of TreeNodes for a given tree, in form of a Matrix of ...
utils::Matrix< signed char > edge_sides(Tree const &tree)
Create a Matrix that indiciaces the relative position of the Edges of a Tree, i.e....
std::vector< size_t > inner_node_indices(Tree const &tree)
Get a list of the node indices of all inner TreeNodes.
TreeLink & outer()
Return the TreeLink of the adjacent TreeNode.
utils::Range< IteratorEulertour< true > > eulertour(ElementType const &element)
size_t index() const
Return the index of this Node.
size_t subtree_size(Tree const &tree, TreeLink const &link)
Return the size of the subtree defined by the given TreeLink, measured in number of nodes.
bool is_leaf(TreeLink const &link)
Return true iff the node of the given link is a leaf node.
TreeEdge & edge()
Return the TreeEdge of this TreeLink.
Header of Tree distance methods.
size_t triangular_size(size_t n)
Calculate the number of linear indices needed for a triangular Matrix of size n.
std::vector< size_t > node_path_length_vector(Tree const &tree, TreeNode const &node)
Return a vector containing the depth of all nodes with respect to the given start node.
TreeLink & secondary_link()
Return the TreeLink of this TreeEdge that points away from the root.
size_t edge_count(Tree const &tree)
Return the number of Edges of a Tree. Same as Tree::edge_count().
utils::Matrix< signed char > node_root_direction_matrix(Tree const &tree)
Calculate a Matrix that indicates the nodes on the root side of a given node.
size_t edge_count() const
Return the number of TreeEdges of the Tree.