/** Build random binary tree to size num_taxa. The result is a draw from the uniform distribution on histories. */ void HeterogeneousRateBirthDeath::buildRandomBinaryHistory(std::vector<TopologyNode*> &tips) { if (tips.size() < num_taxa) { // Get the rng RandomNumberGenerator* rng = GLOBAL_RNG; // Randomly draw one node from the list of tips size_t index = static_cast<size_t>( floor(rng->uniform01()*tips.size()) ); // Get the node from the list TopologyNode* parent = tips.at(index); // Remove the randomly drawn node from the list tips.erase(tips.begin()+long(index)); // Add a left child TopologyNode* leftChild = new TopologyNode(0); parent->addChild(leftChild); leftChild->setParent(parent); tips.push_back(leftChild); // Add a right child TopologyNode* rightChild = new TopologyNode(0); parent->addChild(rightChild); rightChild->setParent(parent); tips.push_back(rightChild); // Recursive call to this function buildRandomBinaryHistory(tips); } }
void StitchTreeFunction::recursivelyStitchPatchClades(TopologyNode* node, size_t& index) { // stich patch clade to matching tip taxon if (node->isTip()) { for (size_t i = 0; i < patchTaxa.size(); i++) { if (node->getTaxon() == stitchTaxon[i]) { // remove the node TopologyNode* parent = &node->getParent(); parent->removeChild(node); node->setParent(NULL); delete node; // add the patch clade const Tree& t = patchClades->getValue()[i]; // this memory is freed when the stitch tree is deleted in updateStitchTree() TopologyNode* patchRoot = new TopologyNode( t.getRoot() ); // prune out non-patch taxa std::set<Taxon> remainingTaxa = prunedTaxa[i]; recursivelyCleanPatchClade(patchRoot, patchRoot, remainingTaxa, index, i); recursivelyIndexPatchClade(patchRoot, index, i); // add patch clade to base tree parent->addChild(patchRoot); patchRoot->setParent(parent); return; } } } // recurse towards tips std::vector<TopologyNode*> children = node->getChildren(); for (size_t i = 0; i < children.size(); i++) { recursivelyStitchPatchClades(children[i], index); } // assign index for first update only if (!haveIndex) { stitchTreeIndex[numPatches][node->getIndex()] = index++; } // set index as needed size_t old_index = node->getIndex(); node->setIndex( stitchTreeIndex[numPatches][old_index] ); return; }
void SpeciesNarrowExchangeProposal::prune( TopologyNode *node, TopologyNode *child ) { // get the parent and brother node TopologyNode &parent = node->getParent(); TopologyNode *brother = &node->getChild( 0 ); if ( brother == child ) { brother = &node->getChild( 1 ); } // prune parent.removeChild( node ); node->removeChild( brother ); parent.addChild( brother ); brother->setParent( &parent ); }
/** * Perform the proposal. * * \return The hastings ratio. */ double SpeciesNarrowExchangeProposal::doProposal( void ) { // empty the previous vectors storedGeneTreeNodes.clear(); storedOldBrothers.clear(); // Get random number generator RandomNumberGenerator* rng = GLOBAL_RNG; Tree& tau = speciesTree->getValue(); // pick a random node which is not the root and neithor a direct descendant of the root TopologyNode* node; do { double u = rng->uniform01(); size_t index = size_t( std::floor(tau.getNumberOfNodes() * u) ); node = &tau.getNode(index); } while ( node->isRoot() || node->getParent().isRoot() ); TopologyNode& parent = node->getParent(); TopologyNode& grandparent = parent.getParent(); TopologyNode* uncle = &grandparent.getChild( 0 ); // check if we got the correct child if ( uncle == &parent ) { uncle = &grandparent.getChild( 1 ); } TopologyNode* brother = &parent.getChild( 0 ); // check if we got the correct child if ( brother == node ) { brother = &parent.getChild( 1 ); } // we need to work with the times double parent_age = parent.getAge(); double uncles_age = uncle->getAge(); if( uncles_age < parent_age ) { failed = false; double lnHastingsRatio = 0.0; // now we store all necessary values storedChoosenNode = node; storedUncle = uncle; // now we need to find for each gene tree the nodes that need to be moved as well // only nodes that have a coalescent event within the lifetime of the parents populations // from lineages belonging to the chosen node with lineages belonging to the brother population // need to be changed for ( size_t i=0; i<geneTrees.size(); ++i ) { // get the i-th gene tree Tree& geneTree = geneTrees[i]->getValue(); std::vector<TopologyNode*> nodes = getNodesToChange(geneTree, *node, *brother ); // get the set of nodes in my uncles populations // these are the nodes that are possible re-attachment points std::set<TopologyNode*> new_siblings = getOldestSubtreesNodesInPopulation(geneTree, *uncle); std::set<TopologyNode*> old_siblings = getOldestSubtreesNodesInPopulation(geneTree, *brother); for (size_t j=0; j<nodes.size(); ++j) { TopologyNode *the_gene_node = nodes[i]; // first we need to compute the backward probability std::set<TopologyNode*> old_candidate_siblings = getPossibleSiblings(the_gene_node, old_siblings); // add the backward probability to the hastings ratio lnHastingsRatio += log( old_siblings.size() ); // then we need to compute the forward probability std::set<TopologyNode*> new_candidate_siblings = getPossibleSiblings(the_gene_node, new_siblings); // add the forward probability to the hastings ratio lnHastingsRatio += log( new_candidate_siblings.size() ); // actually pick a new sibling size_t new_index = size_t( floor(rng->uniform01() * new_candidate_siblings.size() ) ); std::set<TopologyNode*>::iterator it = new_candidate_siblings.begin(); std::advance(it,new_index); TopologyNode *new_child = *it; // store nodes storedGeneTreeNodes.push_back( the_gene_node ); TopologyNode &the_parent = the_gene_node->getParent(); TopologyNode *old_brother = &the_parent.getChild( 0 ); if ( old_brother == the_gene_node ) { old_brother = &the_parent.getChild( 1 ); } storedOldBrothers.push_back( old_brother ); // perform a prune and regraft move prune( &the_parent, the_gene_node ); regraft( the_gene_node, new_child ); } // Sebastian: This is only for debugging. It makes the code slower. Hopefully it is not necessary anymore. // geneTrees[i]->touch( true ); } // now exchange the two nodes grandparent.removeChild( uncle ); parent.removeChild( node ); grandparent.addChild( node ); parent.addChild( uncle ); node->setParent( &grandparent ); uncle->setParent( &parent ); return 0.0; } else { failed = true; return RbConstants::Double::neginf; } }
TopologyNode* NewickConverter::createNode(const std::string &n, std::vector<TopologyNode*> &nodes, std::vector<double> &brlens) { // create a string-stream and throw the string into it std::stringstream ss (std::stringstream::in | std::stringstream::out); ss << n; char c; ss.get(c); // the initial character has to be '(' if ( c != '(') { throw Exception("Error while converting Newick tree. We expected an opening parenthesis, but didn't get one."); } TopologyNode *node = new TopologyNode(); while ( ss.good() && ss.peek() != ')' ) { TopologyNode *childNode; if (ss.peek() == '(' ) { // we received an internal node int depth = 0; std::string child = ""; do { ss.get(c); child += c; if ( c == '(' ) { depth++; } else if ( c == ')' ) { depth--; } } while ( ss.good() && depth > 0 ); // construct the child node childNode = createNode( child, nodes, brlens ); } else { // construct the node childNode = new TopologyNode(); } // set the parent child relationship node->addChild( childNode ); childNode->setParent( node ); // read the optional label std::string lbl = ""; while ( ss.good() && (c = ss.peek()) != ':' && c != '[' && c != ';' && c != ',' && c != ')') { lbl += ss.get(); } childNode->setName( lbl ); // read the optional node parameters if ( ss.peek() == '[' ) { ss.ignore(); do { // ignore the '&' before parameter name if ( ss.peek() == '&') { ss.ignore(); } // read the parameter name std::string paramName = ""; while ( ss.good() && (c = ss.peek()) != '=' && c != ',') { paramName += ss.get(); } // ignore the equal sign between parameter name and value if ( ss.peek() == '=') { ss.ignore(); } // read the parameter name std::string paramValue = ""; while ( ss.good() && (c = ss.peek()) != ']' && c != ',') { paramValue += ss.get(); } // \todo: Needs implementation // childNode->addNodeParameter(paramName, paramValue); if(paramName == "index") childNode->setIndex(atoi(paramValue.c_str())); } while ( (c = ss.peek()) == ',' ); // ignore the final ']' if ( (c = ss.peek()) == ']' ) { ss.ignore(); } } // read the optional branch length if ( ss.peek() == ':' ) { ss.ignore(); std::string time = ""; while ( ss.good() && (c = ss.peek()) != ';' && c != ',' && c != ')' && c != ')' && c != '[') { time += ss.get(); } std::istringstream stm; stm.str(time); double d; stm >> d; if(d < 1E-10 ) d = 0.0; nodes.push_back( childNode ); brlens.push_back( d ); }else{