void RateAgeACLNMixingMove::rejectCompoundMove( void ) { // undo the proposal TimeTree& tau = tree->getValue(); std::vector<double>& nrates = rates->getValue(); double &rootR = rootRate->getValue(); size_t nn = tau.getNumberOfNodes(); double c = storedC; for(size_t i=0; i<nn; i++){ TopologyNode* node = &tau.getNode(i); if(node->isTip() == false){ double curAge = node->getAge(); double undoAge = curAge / c; tau.setAge( node->getIndex(), undoAge ); } } size_t nr = nrates.size(); rootR = rootR * c; for(size_t i=0; i<nr; i++){ double curRt = nrates[i]; double undoRt = curRt * c; nrates[i] = undoRt; } #ifdef ASSERTIONS_TREE if ( fabs(storedRootAge - tau.getRoot().getAge()) > 1E-8 ) { throw RbException("Error while rejecting RateAgeACLNMixingMove proposal: Node ages were not correctly restored!"); } #endif }
void RealNodeContainer::recursiveClampAt(const TopologyNode& from, const ContinuousCharacterData* data, size_t l) { if (from.isTip()) { // get taxon index size_t index = from.getIndex(); std::string taxon = tree->getTipNames()[index]; size_t dataindex = data->getIndexOfTaxon(taxon); if (data->getCharacter(dataindex,l) != -1000) { (*this)[index] = data->getCharacter(dataindex,l); clampVector[index] = true; //std::cerr << "taxon : " << index << '\t' << taxon << " trait value : " << (*this)[index] << '\n'; } else { std::cerr << "taxon : " << taxon << " is missing for trait " << l+1 << '\n'; } } // propagate forward size_t numChildren = from.getNumberOfChildren(); for (size_t i = 0; i < numChildren; ++i) { recursiveClampAt(from.getChild(i),data,l); } }
std::set<TopologyNode*> SpeciesNarrowExchangeProposal::getOldestSubtreesNodesInPopulation( Tree &tau, TopologyNode &n ) { // I need all the oldest nodes/subtrees that have the same tips. // Those nodes need to be scaled too. // get the beginning and ending age of the population double max_age = -1.0; if ( n.isRoot() == false ) { max_age = n.getParent().getAge(); } // get all the taxa from the species tree that are descendants of node i std::vector<TopologyNode*> species_taxa; TreeUtilities::getTaxaInSubtree( &n, species_taxa ); // get all the individuals std::set<TopologyNode*> individualTaxa; for (size_t i = 0; i < species_taxa.size(); ++i) { const std::string &name = species_taxa[i]->getName(); std::vector<TopologyNode*> ind = tau.getTipNodesWithSpeciesName( name ); for (size_t j = 0; j < ind.size(); ++j) { individualTaxa.insert( ind[j] ); } } // create the set of the nodes within this population std::set<TopologyNode*> nodesInPopulationSet; // now go through all nodes in the gene while ( individualTaxa.empty() == false ) { std::set<TopologyNode*>::iterator it = individualTaxa.begin(); individualTaxa.erase( it ); TopologyNode *geneNode = *it; // add this node to our list of node we need to scale, if: // a) this is the root node // b) this is not the root and the age of the parent node is larger than the parent's age of the species node if ( geneNode->isRoot() == false && ( max_age == -1.0 || max_age > geneNode->getParent().getAge() ) ) { // push the parent to our current list individualTaxa.insert( &geneNode->getParent() ); } else if ( geneNode->isTip() == false ) { // add this node if it is within the age of our population nodesInPopulationSet.insert( geneNode ); } } return nodesInPopulationSet; }
/** * Perform the proposal. * * A Beta-simplex proposal randomly changes some values of a simplex, although the other values * change too because of the renormalization. * First, some random indices are drawn. Then, the proposal draws a new somplex * u ~ Beta(val[index] * alpha) * where alpha is the tuning parameter.The new value is set to u. * The simplex is then renormalized. * * \return The hastings ratio. */ double SubtreeScaleProposal::doProposal( void ) { // Get random number generator RandomNumberGenerator* rng = GLOBAL_RNG; TimeTree& tau = variable->getValue(); // pick a random node which is not the root and neither the 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->isTip() ); TopologyNode& parent = node->getParent(); // we need to work with the times double parent_age = parent.getAge(); double my_age = node->getAge(); // now we store all necessary values storedNode = node; storedAge = my_age; // lower bound double min_age = 0.0; TreeUtilities::getOldestTip(&tau, node, min_age); // draw new ages and compute the hastings ratio at the same time double my_new_age = min_age + (parent_age - min_age) * rng->uniform01(); double scalingFactor = my_new_age / my_age; size_t nNodes = node->getNumberOfNodesInSubtree(false); // rescale the subtrees TreeUtilities::rescaleSubtree(&tau, node, scalingFactor ); if (min_age != 0.0) { for (size_t i = 0; i < tau.getNumberOfTips(); i++) { if (tau.getNode(i).getAge() < 0.0) { return RbConstants::Double::neginf; } } } // compute the Hastings ratio double lnHastingsratio = (nNodes > 1 ? log( scalingFactor ) * (nNodes-1) : 0.0 ); return lnHastingsratio; }
/** * Recursive call to attach ordered interior node times to the time tree psi. Call it initially with the * root of the tree. */ void HeterogeneousRateBirthDeath::attachTimes(Tree* psi, std::vector<TopologyNode *> &nodes, size_t index, const std::vector<double> &interiorNodeTimes, double originTime ) { if (index < num_taxa-1) { // Get the rng RandomNumberGenerator* rng = GLOBAL_RNG; // Randomly draw one node from the list of nodes size_t node_index = static_cast<size_t>( floor(rng->uniform01()*nodes.size()) ); // Get the node from the list TopologyNode* parent = nodes.at(node_index); psi->getNode( parent->getIndex() ).setAge( originTime - interiorNodeTimes[index] ); // Remove the randomly drawn node from the list nodes.erase(nodes.begin()+long(node_index)); // Add the left child if an interior node TopologyNode* leftChild = &parent->getChild(0); if ( !leftChild->isTip() ) { nodes.push_back(leftChild); } // Add the right child if an interior node TopologyNode* rightChild = &parent->getChild(1); if ( !rightChild->isTip() ) { nodes.push_back(rightChild); } // Recursive call to this function attachTimes(psi, nodes, index+1, interiorNodeTimes, originTime); } }
void RealNodeContainer::recursiveGetStatsOverTips(const TopologyNode& from, double& e1, double& e2, int& n) const { if(from.isTip()) { double tmp = (*this)[from.getIndex()]; n++; e1 += tmp; e2 += tmp * tmp; } // propagate forward size_t numChildren = from.getNumberOfChildren(); for (size_t i = 0; i < numChildren; ++i) { recursiveGetStatsOverTips(from.getChild(i),e1,e2,n); } }
void RealNodeContainer::recursiveGetTipValues(const TopologyNode& from, ContinuousCharacterData& nameToVal) const { if(from.isTip()) { double tmp = (*this)[from.getIndex()]; std::string name = tree->getTipNames()[from.getIndex()]; ContinuousTaxonData dataVec = ContinuousTaxonData(name); double contObs = tmp; dataVec.addCharacter( contObs ); nameToVal.addTaxonData( dataVec ); return; } // propagate forward size_t numChildren = from.getNumberOfChildren(); for (size_t i = 0; i < numChildren; ++i) { recursiveGetTipValues(from.getChild(i), nameToVal ); } }
std::string RealNodeContainer::recursiveGetNewick(const TopologyNode& from) const { std::ostringstream s; if (from.isTip()) { s << getTimeTree()->getTipNames()[from.getIndex()] << "_"; // std::cerr << from.getIndex() << '\t' << getTimeTree()->getTipNames()[from.getIndex()] << "_"; // std::cerr << (*this)[from.getIndex()] << '\n'; // exit(1); } else { s << "("; // propagate forward size_t numChildren = from.getNumberOfChildren(); for (size_t i = 0; i < numChildren; ++i) { s << recursiveGetNewick(from.getChild(i)); if (i < numChildren-1) { s << ","; } } s << ")"; } s << (*this)[from.getIndex()]; /* if (from.isTip() && (! isClamped(from.getIndex()))) { std::cerr << "leaf is not clamped\n"; // get taxon index size_t index = from.getIndex(); std::cerr << "index : " << index << '\n'; std::string taxon = tree->getTipNames()[index]; std::cerr << "taxon : " << index << '\t' << taxon << '\n'; std::cerr << " trait value : " << (*this)[index] << '\n'; exit(1); }*/ // if (!from.isRoot()) { s << ":"; s << getTimeTree()->getBranchLength(from.getIndex()); // } return s.str(); }
/** Perform the move */ double SubtreeScale::performSimpleMove( void ) { // Get random number generator RandomNumberGenerator* rng = GLOBAL_RNG; TimeTree& tau = variable->getValue(); // pick a random node which is not the root and neither the 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->isTip() ); TopologyNode& parent = node->getParent(); // we need to work with the times double parent_age = parent.getAge(); double my_age = node->getAge(); // now we store all necessary values storedNode = node; storedAge = my_age; // draw new ages and compute the hastings ratio at the same time double my_new_age = parent_age * rng->uniform01(); double scalingFactor = my_new_age / my_age; size_t nNodes = node->getNumberOfNodesInSubtree(false); // rescale the subtrees TreeUtilities::rescaleSubtree(&tau, node, scalingFactor ); // compute the Hastings ratio double lnHastingsratio = (nNodes > 1 ? log( scalingFactor ) * (nNodes-1) : 0.0 ); return lnHastingsratio; }
/** * Perform the proposal. * * A Uniform-simplex proposal randomly changes some values of a simplex, although the other values * change too because of the renormalization. * First, some random indices are drawn. Then, the proposal draws a new somplex * u ~ Uniform(val[index] * alpha) * where alpha is the tuning parameter.The new value is set to u. * The simplex is then renormalized. * * \return The hastings ratio. */ double NodeTimeSlideUniformProposal::doProposal( void ) { // Get random number generator RandomNumberGenerator* rng = GLOBAL_RNG; Tree& tau = variable->getValue(); // pick a random node which is not the root and neithor the 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->isTip() ); TopologyNode& parent = node->getParent(); // we need to work with the times double parent_age = parent.getAge(); double my_age = node->getAge(); double child_Age = node->getChild( 0 ).getAge(); if ( child_Age < node->getChild( 1 ).getAge()) { child_Age = node->getChild( 1 ).getAge(); } // now we store all necessary values storedNode = node; storedAge = my_age; // draw new ages and compute the hastings ratio at the same time double my_new_age = (parent_age-child_Age) * rng->uniform01() + child_Age; // set the age tau.getNode(node->getIndex()).setAge( my_new_age ); return 0.0; }
/** Perform the move */ double RateAgeACLNMixingMove::performCompoundMove( void ) { // Get random number generator RandomNumberGenerator* rng = GLOBAL_RNG; TimeTree& tau = tree->getValue(); std::vector<double>& nrates = rates->getValue(); double &rootR = rootRate->getValue(); size_t nn = tau.getNumberOfNodes(); double u = rng->uniform01(); double c = exp( epsilon * (u - 0.5) ); for(size_t i=0; i<nn; i++){ TopologyNode* node = &tau.getNode(i); if(node->isTip() == false){ double curAge = node->getAge(); double newAge = curAge * c; tau.setAge( node->getIndex(), newAge ); if(node->isRoot()){ storedRootAge = curAge; } } } size_t nr = nrates.size(); rootR = rootR / c; for(size_t i=0; i<nrates.size(); i++){ double curRt = nrates[i]; double newRt = curRt / c; nrates[i] = newRt; } storedC = c; double pr = (((double)nn) - (double)nr) * log(c); return pr; }
void PhyloBrownianProcessREML::recursiveComputeLnProbability( const TopologyNode &node, size_t nodeIndex ) { // check for recomputation if ( node.isTip() == false && dirtyNodes[nodeIndex] ) { // mark as computed dirtyNodes[nodeIndex] = false; std::vector<double> &p_node = this->partialLikelihoods[this->activeLikelihood[nodeIndex]][nodeIndex]; std::vector<double> &mu_node = this->contrasts[this->activeLikelihood[nodeIndex]][nodeIndex]; // get the number of children size_t num_children = node.getNumberOfChildren(); for (size_t j = 1; j < num_children; ++j) { size_t leftIndex = nodeIndex; const TopologyNode *left = &node; if ( j == 1 ) { left = &node.getChild(0); leftIndex = left->getIndex(); recursiveComputeLnProbability( *left, leftIndex ); } const TopologyNode &right = node.getChild(j); size_t rightIndex = right.getIndex(); recursiveComputeLnProbability( right, rightIndex ); const std::vector<double> &p_left = this->partialLikelihoods[this->activeLikelihood[leftIndex]][leftIndex]; const std::vector<double> &p_right = this->partialLikelihoods[this->activeLikelihood[rightIndex]][rightIndex]; // get the per node and site contrasts const std::vector<double> &mu_left = this->contrasts[this->activeLikelihood[leftIndex]][leftIndex]; const std::vector<double> &mu_right = this->contrasts[this->activeLikelihood[rightIndex]][rightIndex]; // get the propagated uncertainties double delta_left = this->contrastUncertainty[this->activeLikelihood[leftIndex]][leftIndex]; double delta_right = this->contrastUncertainty[this->activeLikelihood[rightIndex]][rightIndex]; // get the scaled branch lengths double v_left = 0; if ( j == 1 ) { v_left = this->computeBranchTime(leftIndex, left->getBranchLength()); } double v_right = this->computeBranchTime(rightIndex, right.getBranchLength()); // add the propagated uncertainty to the branch lengths double t_left = v_left + delta_left; double t_right = v_right + delta_right; // set delta_node = (t_l*t_r)/(t_l+t_r); this->contrastUncertainty[this->activeLikelihood[nodeIndex]][nodeIndex] = (t_left*t_right) / (t_left+t_right); double stdev = sqrt(t_left+t_right); for (int i=0; i<this->numSites; i++) { mu_node[i] = (mu_left[i]*t_right + mu_right[i]*t_left) / (t_left+t_right); // get the site specific rate of evolution double standDev = this->computeSiteRate(i) * stdev; // compute the contrasts for this site and node double contrast = mu_left[i] - mu_right[i]; // compute the probability for the contrasts at this node double lnl_node = RbStatistics::Normal::lnPdf(0, standDev, contrast); // sum up the probabilities of the contrasts p_node[i] = lnl_node + p_left[i] + p_right[i]; } // end for-loop over all sites } // end for-loop over all children } // end if we need to compute something for this node. }
std::vector<TopologyNode*> TreeNodeAgeUpdateProposal::getNodesInPopulation( Tree &tau, TopologyNode &n ) { // I need all the oldest nodes/subtrees that have the same tips. // Those nodes need to be scaled too. // get the beginning and ending age of the population double max_age = -1.0; if ( n.isRoot() == false ) { max_age = n.getParent().getAge(); } // get all the taxa from the species tree that are descendants of node i double min_age_left = n.getChild(0).getAge(); std::vector<TopologyNode*> speciesTaxa_left; TreeUtilities::getTaxaInSubtree( &n.getChild(0), speciesTaxa_left ); // get all the individuals std::set<TopologyNode*> individualTaxa_left; for (size_t i = 0; i < speciesTaxa_left.size(); ++i) { const std::string &name = speciesTaxa_left[i]->getName(); std::vector<TopologyNode*> ind = tau.getTipNodesWithSpeciesName( name ); for (size_t j = 0; j < ind.size(); ++j) { individualTaxa_left.insert( ind[j] ); } } // create the set of the nodes within this population std::set<TopologyNode*> nodesInPopulationSet; // now go through all nodes in the gene while ( individualTaxa_left.empty() == false ) { // get the first element std::set<TopologyNode*>::iterator it = individualTaxa_left.begin(); // store the pointer TopologyNode *geneNode = *it; // and now remove the element from the list individualTaxa_left.erase( it ); // add this node to our list of node we need to scale, if: // a) this is the root node // b) this is not the root and the age of the parent node is larger than the parent's age of the species node if ( geneNode->getAge() > min_age_left && geneNode->getAge() < max_age && geneNode->isTip() == false ) { // add this node if it is within the age of our population nodesInPopulationSet.insert( geneNode ); } if ( geneNode->isRoot() == false && ( max_age == -1.0 || max_age > geneNode->getParent().getAge() ) ) { // push the parent to our current list individualTaxa_left.insert( &geneNode->getParent() ); } } // get all the taxa from the species tree that are descendants of node i double min_age_right = n.getChild(1).getAge(); std::vector<TopologyNode*> speciesTaxa_right; TreeUtilities::getTaxaInSubtree( &n.getChild(1), speciesTaxa_right ); // get all the individuals std::set<TopologyNode*> individualTaxa_right; for (size_t i = 0; i < speciesTaxa_right.size(); ++i) { const std::string &name = speciesTaxa_right[i]->getName(); std::vector<TopologyNode*> ind = tau.getTipNodesWithSpeciesName( name ); for (size_t j = 0; j < ind.size(); ++j) { individualTaxa_right.insert( ind[j] ); } } // now go through all nodes in the gene while ( individualTaxa_right.empty() == false ) { // get the first element std::set<TopologyNode*>::iterator it = individualTaxa_right.begin(); // store the pointer TopologyNode *geneNode = *it; // and now remove the element from the list individualTaxa_right.erase( it ); // add this node to our list of node we need to scale, if: // a) this is the root node // b) this is not the root and the age of the parent node is larger than the parent's age of the species node if ( geneNode->getAge() > min_age_right && geneNode->getAge() < max_age && geneNode->isTip() == false ) { // add this node if it is within the age of our population nodesInPopulationSet.insert( geneNode ); } if ( geneNode->isRoot() == false && ( max_age == -1.0 || max_age > geneNode->getParent().getAge() ) ) { // push the parent to our current list individualTaxa_right.insert( &geneNode->getParent() ); } } // convert the set into a vector std::vector<TopologyNode*> nodesInPopulation; for (std::set<TopologyNode*>::iterator it = nodesInPopulationSet.begin(); it != nodesInPopulationSet.end(); ++it) { nodesInPopulation.push_back( *it ); } return nodesInPopulation; }
/** * Perform the proposal. * * \return The hastings ratio. */ double TreeNodeAgeUpdateProposal::doProposal( void ) { // Get random number generator RandomNumberGenerator* rng = GLOBAL_RNG; Tree& tau = speciesTree->getValue(); // pick a random node which is not the root and neither the 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->isTip() ); TopologyNode& parent = node->getParent(); // we need to work with the times double parent_age = parent.getAge(); double my_age = node->getAge(); double child_Age = node->getChild( 0 ).getAge(); if ( child_Age < node->getChild( 1 ).getAge()) { child_Age = node->getChild( 1 ).getAge(); } // now we store all necessary values storedNode = node; storedAge = my_age; // draw new ages and compute the hastings ratio at the same time double my_new_age = (parent_age-child_Age) * rng->uniform01() + child_Age; // Sebastian: This is for debugging to test if the proposal's acceptance rate is 1.0 as it should be! // my_new_age = my_age; int upslideNodes = 0; int downslideNodes = 0; for ( size_t i=0; i<geneTrees.size(); ++i ) { // get the i-th gene tree Tree& geneTree = geneTrees[i]->getValue(); std::vector<TopologyNode*> nodes = getNodesInPopulation(geneTree, *node ); for (size_t j=0; j<nodes.size(); ++j) { double a = nodes[j]->getAge(); double new_a = a; if ( a > my_age ) { ++upslideNodes; new_a = parent_age - (parent_age - my_new_age)/(parent_age - my_age) * (parent_age - a); } else { ++downslideNodes; new_a = child_Age + (my_new_age - child_Age)/(my_age - child_Age) * (a - child_Age); } // set the new age of this gene tree node geneTree.getNode( nodes[j]->getIndex() ).setAge( new_a ); } // Sebastian: This is only for debugging. It makes the code slower. Hopefully it is not necessary anymore. // geneTrees[i]->touch( true ); } // Sebastian: We need to work on a mechanism to make these proposal safe for non-ultrametric trees! // if (min_age != 0.0) // { // for (size_t i = 0; i < tau.getNumberOfTips(); i++) // { // if (tau.getNode(i).getAge() < 0.0) // { // return RbConstants::Double::neginf; // } // } // } // set the age of the species tree node tau.getNode( node->getIndex() ).setAge( my_new_age ); // compute the Hastings ratio double lnHastingsratio = upslideNodes * log( (parent_age - my_new_age)/(parent_age - my_age) ) + downslideNodes * log( (my_new_age - child_Age)/(my_age - child_Age) ); return lnHastingsratio; }
/** Perform the move */ void RateAgeBetaShift::performMcmcMove( double lHeat, double pHeat ) { // Get random number generator RandomNumberGenerator* rng = GLOBAL_RNG; Tree& tau = tree->getValue(); RbOrderedSet<DagNode*> affected; tree->getAffectedNodes( affected ); double oldLnLike = 0.0; bool checkLikelihoodShortcuts = rng->uniform01() < 0.001; if ( checkLikelihoodShortcuts == true ) { for (RbOrderedSet<DagNode*>::iterator it = affected.begin(); it != affected.end(); ++it) { (*it)->touch(); oldLnLike += (*it)->getLnProbability(); } } // pick a random node which is not the root and neithor the direct descendant of the root TopologyNode* node; size_t nodeIdx = 0; do { double u = rng->uniform01(); nodeIdx = size_t( std::floor(tau.getNumberOfNodes() * u) ); node = &tau.getNode(nodeIdx); } while ( node->isRoot() || node->isTip() ); TopologyNode& parent = node->getParent(); // we need to work with the times double parent_age = parent.getAge(); double my_age = node->getAge(); double child_Age = node->getChild( 0 ).getAge(); if ( child_Age < node->getChild( 1 ).getAge()) { child_Age = node->getChild( 1 ).getAge(); } // now we store all necessary values storedNode = node; storedAge = my_age; storedRates[nodeIdx] = rates[nodeIdx]->getValue(); for (size_t i = 0; i < node->getNumberOfChildren(); i++) { size_t childIdx = node->getChild(i).getIndex(); storedRates[childIdx] = rates[childIdx]->getValue(); } // draw new ages and compute the hastings ratio at the same time double m = (my_age-child_Age) / (parent_age-child_Age); double a = delta * m + 1.0; double b = delta * (1.0-m) + 1.0; double new_m = RbStatistics::Beta::rv(a, b, *rng); double my_new_age = (parent_age-child_Age) * new_m + child_Age; // compute the Hastings ratio double forward = RbStatistics::Beta::lnPdf(a, b, new_m); double new_a = delta * new_m + 1.0; double new_b = delta * (1.0-new_m) + 1.0; double backward = RbStatistics::Beta::lnPdf(new_a, new_b, m); // set the age tau.getNode(nodeIdx).setAge( my_new_age ); // touch the tree so that the likelihoods are getting stored tree->touch(); // get the probability ratio of the tree double treeProbRatio = tree->getLnProbabilityRatio(); // set the rates double pa = node->getParent().getAge(); double my_new_rate =(pa - my_age) * storedRates[nodeIdx] / (pa - my_new_age); // now we set the new value // this will automcatically call a touch rates[nodeIdx]->setValue( new double( my_new_rate ) ); // get the probability ratio of the new rate double ratesProbRatio = rates[nodeIdx]->getLnProbabilityRatio(); for (size_t i = 0; i < node->getNumberOfChildren(); i++) { size_t childIdx = node->getChild(i).getIndex(); double a = node->getChild(i).getAge(); double child_new_rate = (my_age - a) * storedRates[childIdx] / (my_new_age - a); // now we set the new value // this will automcatically call a touch rates[childIdx]->setValue( new double( child_new_rate ) ); // get the probability ratio of the new rate ratesProbRatio += rates[childIdx]->getLnProbabilityRatio(); } if ( checkLikelihoodShortcuts == true ) { double lnProbRatio = 0; double newLnLike = 0; for (RbOrderedSet<DagNode*>::iterator it = affected.begin(); it != affected.end(); ++it) { double tmp = (*it)->getLnProbabilityRatio(); lnProbRatio += tmp; newLnLike += (*it)->getLnProbability(); } if ( fabs(lnProbRatio) > 1E-8 ) { double lnProbRatio2 = 0; double newLnLike2 = 0; for (RbOrderedSet<DagNode*>::iterator it = affected.begin(); it != affected.end(); ++it) { double tmp2 = (*it)->getLnProbabilityRatio(); lnProbRatio2 += tmp2; newLnLike2 += (*it)->getLnProbability(); } throw RbException("Likelihood shortcut computation failed in rate-age-proposal."); } } double hastingsRatio = backward - forward; double ln_acceptance_ratio = lHeat * pHeat * (treeProbRatio + ratesProbRatio) + hastingsRatio; if (ln_acceptance_ratio >= 0.0) { numAccepted++; tree->keep(); rates[nodeIdx]->keep(); for (size_t i = 0; i < node->getNumberOfChildren(); i++) { size_t childIdx = node->getChild(i).getIndex(); rates[childIdx]->keep(); } } else if (ln_acceptance_ratio < -300.0) { reject(); tree->restore(); rates[nodeIdx]->restore(); for (size_t i = 0; i < node->getNumberOfChildren(); i++) { size_t childIdx = node->getChild(i).getIndex(); rates[childIdx]->restore(); } } else { double r = exp(ln_acceptance_ratio); // Accept or reject the move double u = GLOBAL_RNG->uniform01(); if (u < r) { numAccepted++; //keep tree->keep(); rates[nodeIdx]->keep(); for (size_t i = 0; i < node->getNumberOfChildren(); i++) { size_t childIdx = node->getChild(i).getIndex(); rates[childIdx]->keep(); } } else { reject(); tree->restore(); rates[nodeIdx]->restore(); for (size_t i = 0; i < node->getNumberOfChildren(); i++) { size_t childIdx = node->getChild(i).getIndex(); rates[childIdx]->restore(); } } } }
/** Perform the move */ void RateAgeBetaShift::performMove( double heat, bool raiseLikelihoodOnly ) { // Get random number generator RandomNumberGenerator* rng = GLOBAL_RNG; TimeTree& tau = tree->getValue(); // pick a random node which is not the root and neithor the direct descendant of the root TopologyNode* node; size_t nodeIdx = 0; do { double u = rng->uniform01(); nodeIdx = size_t( std::floor(tau.getNumberOfNodes() * u) ); node = &tau.getNode(nodeIdx); } while ( node->isRoot() || node->isTip() ); TopologyNode& parent = node->getParent(); // we need to work with the times double parent_age = parent.getAge(); double my_age = node->getAge(); double child_Age = node->getChild( 0 ).getAge(); if ( child_Age < node->getChild( 1 ).getAge()) { child_Age = node->getChild( 1 ).getAge(); } // now we store all necessary values storedNode = node; storedAge = my_age; storedRates[nodeIdx] = rates[nodeIdx]->getValue(); for (size_t i = 0; i < node->getNumberOfChildren(); i++) { size_t childIdx = node->getChild(i).getIndex(); storedRates[childIdx] = rates[childIdx]->getValue(); } // draw new ages and compute the hastings ratio at the same time double m = (my_age-child_Age) / (parent_age-child_Age); double a = delta * m + 1.0; double b = delta * (1.0-m) + 1.0; double new_m = RbStatistics::Beta::rv(a, b, *rng); double my_new_age = (parent_age-child_Age) * new_m + child_Age; // compute the Hastings ratio double forward = RbStatistics::Beta::lnPdf(a, b, new_m); double new_a = delta * new_m + 1.0; double new_b = delta * (1.0-new_m) + 1.0; double backward = RbStatistics::Beta::lnPdf(new_a, new_b, m); // set the age tau.setAge( node->getIndex(), my_new_age ); tree->touch(); double treeProbRatio = tree->getLnProbabilityRatio(); // set the rates rates[nodeIdx]->setValue( new double((node->getParent().getAge() - my_age) * storedRates[nodeIdx] / (node->getParent().getAge() - my_new_age))); double ratesProbRatio = rates[nodeIdx]->getLnProbabilityRatio(); for (size_t i = 0; i < node->getNumberOfChildren(); i++) { size_t childIdx = node->getChild(i).getIndex(); rates[childIdx]->setValue( new double((my_age - node->getChild(i).getAge()) * storedRates[childIdx] / (my_new_age - node->getChild(i).getAge()))); ratesProbRatio += rates[childIdx]->getLnProbabilityRatio(); } std::set<DagNode*> affected; tree->getAffectedNodes( affected ); double lnProbRatio = 0; for (std::set<DagNode*>::iterator it = affected.begin(); it != affected.end(); ++it) { (*it)->touch(); lnProbRatio += (*it)->getLnProbabilityRatio(); } if ( fabs(lnProbRatio) > 1E-6 ) { // throw RbException("Likelihood shortcut computation failed in rate-age-proposal."); std::cout << "Likelihood shortcut computation failed in rate-age-proposal." << std::endl; } double hastingsRatio = backward - forward; double lnAcceptanceRatio = treeProbRatio + ratesProbRatio + hastingsRatio; if (lnAcceptanceRatio >= 0.0) { numAccepted++; tree->keep(); rates[nodeIdx]->keep(); for (size_t i = 0; i < node->getNumberOfChildren(); i++) { size_t childIdx = node->getChild(i).getIndex(); rates[childIdx]->keep(); } } else if (lnAcceptanceRatio < -300.0) { reject(); tree->restore(); rates[nodeIdx]->restore(); for (size_t i = 0; i < node->getNumberOfChildren(); i++) { size_t childIdx = node->getChild(i).getIndex(); rates[childIdx]->restore(); } } else { double r = exp(lnAcceptanceRatio); // Accept or reject the move double u = GLOBAL_RNG->uniform01(); if (u < r) { numAccepted++; //keep tree->keep(); rates[nodeIdx]->keep(); for (size_t i = 0; i < node->getNumberOfChildren(); i++) { size_t childIdx = node->getChild(i).getIndex(); rates[childIdx]->keep(); } } else { reject(); tree->restore(); rates[nodeIdx]->restore(); for (size_t i = 0; i < node->getNumberOfChildren(); i++) { size_t childIdx = node->getChild(i).getIndex(); rates[childIdx]->restore(); } } } }
/** * Perform the proposal. * * \return The hastings ratio. */ double SpeciesSubtreeScaleBetaProposal::doProposal( void ) { // Get random number generator RandomNumberGenerator* rng = GLOBAL_RNG; Tree& tau = speciesTree->getValue(); // pick a random node which is not the root and neither the 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->isTip() ); TopologyNode& parent = node->getParent(); // we need to work with the times double parent_age = parent.getAge(); double my_age = node->getAge(); // now we store all necessary values storedNode = node; storedAge = my_age; // lower bound double min_age = 0.0; TreeUtilities::getOldestTip(&tau, node, min_age); // draw new ages double current_value = my_age / (parent_age - min_age); double a = alpha + 1.0; double b = (a-1.0) / current_value - a + 2.0; double new_value = RbStatistics::Beta::rv(a, b, *rng); // Sebastian: This is for debugging to test if the proposal's acceptance rate is 1.0 as it should be! // new_value = current_value; double my_new_age = new_value * (parent_age - min_age); double scaling_factor = my_new_age / my_age; size_t num_nodes = node->getNumberOfNodesInSubtree( false ); for ( size_t i=0; i<geneTrees.size(); ++i ) { // get the i-th gene tree Tree& gene_tree = geneTrees[i]->getValue(); std::vector<TopologyNode*> nodes = getOldestNodesInPopulation(gene_tree, *node ); for (size_t j=0; j<nodes.size(); ++j) { // add the number of nodes that we are going to scale in the subtree num_nodes += nodes[j]->getNumberOfNodesInSubtree( false ); if ( nodes[j]->isTip() == true ) { std::cerr << "Trying to scale a tip\n"; } if ( nodes[j]->isRoot() == true ) { std::cerr << "Trying to scale the root\n"; } // rescale the subtree of this gene tree TreeUtilities::rescaleSubtree(&gene_tree, nodes[j], scaling_factor ); } // Sebastian: This is only for debugging. It makes the code slower. Hopefully it is not necessary anymore. // geneTrees[i]->touch( true ); } // Sebastian: We need to work on a mechanism to make these proposal safe for non-ultrametric trees! // if (min_age != 0.0) // { // for (size_t i = 0; i < tau.getNumberOfTips(); i++) // { // if (tau.getNode(i).getAge() < 0.0) // { // return RbConstants::Double::neginf; // } // } // } // rescale the subtree of the species tree TreeUtilities::rescaleSubtree(&tau, node, scaling_factor ); // compute the Hastings ratio double forward = RbStatistics::Beta::lnPdf(a, b, new_value); double new_a = alpha + 1.0; double new_b = (a-1.0) / new_value - a + 2.0; double backward = RbStatistics::Beta::lnPdf(new_a, new_b, current_value); double lnHastingsratio = (backward - forward) * (num_nodes-1); return lnHastingsratio; }
std::string PhylowoodNhxMonitor::buildNhxString(void) { std::stringstream nhxStrm; // begin nexus file nhxStrm << "#NEXUS" << "\n\n"; // phylowood settings block nhxStrm << "Begin phylowood;\n"; nhxStrm << "\tdrawtype pie\n"; nhxStrm << "\tmodeltype biogeography\n"; nhxStrm << "\tareatype discrete\n"; nhxStrm << "\tmaptype clean\n"; nhxStrm << "\tpieslicestyle even\n"; nhxStrm << "\tpiefillstyle outwards\n"; nhxStrm << "\ttimestart -" << tree->getValue().getRoot().getAge() << "\n"; nhxStrm << "\tmarkerradius " << 200 << "\n"; nhxStrm << "\tminareaval " << 0.1 << "\n"; nhxStrm << "End;\n\n"; // bayarea-fig block nhxStrm << "Begin bayarea-fig;\n"; nhxStrm << "\tmapheight\t100\n"; nhxStrm << "\tmapwidth\t150\n"; nhxStrm << "\tcanvasheight\t2000\n"; nhxStrm << "\tcanvaswidth\t1000\n"; nhxStrm << "\tminareaval\t0.15\n"; nhxStrm << "\tareacolors black\n"; nhxStrm << "\tareatypes"; for (unsigned i = 0; i < numCharacters; i++) nhxStrm << " 1"; nhxStrm << "\n"; nhxStrm << "\tareanames Default\n"; nhxStrm << "End;\n\n"; // taxa block nhxStrm << "Begin taxa;\n"; nhxStrm << "\tDimensions ntax=" << tree->getValue().getNumberOfTips() << ";\n"; nhxStrm << "\tTaxlabels\n"; for (unsigned i = 0; i < tree->getValue().getNumberOfNodes(); i++) { TopologyNode* p = &tree->getValue().getNode(i); if (p->isTip()) { nhxStrm << "\t\t" << p->getName() << "\n"; } } nhxStrm << "\t\t;\n"; nhxStrm << "End;\n\n"; // geo block nhxStrm << "Begin geo;\n"; nhxStrm << "\tDimensions ngeo=" << numCharacters << ";\n"; nhxStrm << "\tCoords\n"; for (unsigned i = 0; i < numCharacters; i++) { nhxStrm << "\t\t" << i << "\t" << geographicCoordinates[i][0] << "\t" << geographicCoordinates[i][1]; if (i < (numCharacters - 1)) nhxStrm << ","; nhxStrm << "\n"; } nhxStrm << "\t\t;\n"; nhxStrm << "End;\n\n"; // tree block nhxStrm << "Begin trees;\n"; nhxStrm << "\tTranslate\n"; for (unsigned i = 0; i < tree->getValue().getNumberOfNodes(); i++) { TopologyNode* p = &tree->getValue().getNode(i); if (p->isTip()) { nhxStrm << "\t\t" << p->getIndex() << "\t" << p->getName(); if (i < (tree->getValue().getNumberOfNodes() - 1)) nhxStrm << ","; nhxStrm << "\n"; } } nhxStrm << "\t\t;\n"; // write tree string std::string treeStr = ""; treeStr = buildExtendedNewick(); //buildExtendedNewick(&tree->getValue().getRoot()); std::cout << treeStr << "\n"; std::cout << "nhxStr\n" << treeStr << "\n"; nhxStrm << "tree TREE1 = " << treeStr << ";\n"; nhxStrm << "End;\n"; std::cout << "["; for (size_t i = 0; i < numCharacters; i++) { if (i != 0) std::cout << ","; std::cout << (double)childCharacterCounts[0][i] / numSamples; } std::cout << "]\n"; return nhxStrm.str(); }
void StateDependentSpeciationExtinctionProcess::recursivelyDrawJointConditionalAncestralStates(const TopologyNode &node, std::vector<size_t>& startStates, std::vector<size_t>& endStates) { size_t node_index = node.getIndex(); if ( node.isTip() == true ) { const AbstractHomologousDiscreteCharacterData& data = static_cast<TreeDiscreteCharacterData*>(this->value)->getCharacterData(); const AbstractDiscreteTaxonData& taxon_data = data.getTaxonData( node.getName() ); const DiscreteCharacterState &char_state = taxon_data.getCharacter(0); // we need to treat ambiguous state differently if ( char_state.isAmbiguous() == false ) { endStates[node_index] = char_state.getStateIndex(); } else { // initialize the conditional likelihoods for this branch state_type branch_conditional_probs = std::vector<double>(2 * num_states, 0); size_t start_state = startStates[node_index]; branch_conditional_probs[ num_states + start_state ] = 1.0; // first calculate extinction likelihoods via a backward time pass double end_age = node.getParent().getAge(); numericallyIntegrateProcess(branch_conditional_probs, 0, end_age, true, true); // now calculate conditional likelihoods along branch in forward time end_age = node.getParent().getAge() - node.getAge(); numericallyIntegrateProcess(branch_conditional_probs, 0, end_age, false, false); double total_prob = 0.0; for (size_t i = 0; i < num_states; ++i) { if ( char_state.isMissingState() == true || char_state.isGapState() == true || char_state.isStateSet(i) == true ) { total_prob += branch_conditional_probs[i]; } } RandomNumberGenerator* rng = GLOBAL_RNG; size_t u = rng->uniform01() * total_prob; for (size_t i = 0; i < num_states; ++i) { if ( char_state.isMissingState() == true || char_state.isGapState() == true || char_state.isStateSet(i) == true ) { u -= branch_conditional_probs[i]; if ( u <= 0.0 ) { endStates[node_index] = i; break; } } } } } else { // sample characters by their probability conditioned on the branch's start state going to end states // initialize the conditional likelihoods for this branch state_type branch_conditional_probs = std::vector<double>(2 * num_states, 0); size_t start_state = startStates[node_index]; branch_conditional_probs[ num_states + start_state ] = 1.0; // first calculate extinction likelihoods via a backward time pass double end_age = node.getParent().getAge(); numericallyIntegrateProcess(branch_conditional_probs, 0, end_age, true, true); // now calculate conditional likelihoods along branch in forward time end_age = node.getParent().getAge() - node.getAge(); numericallyIntegrateProcess(branch_conditional_probs, 0, end_age, false, false); // TODO: if character mapping compute likelihoods for each time slice.... // double current_time_slice = floor(begin_age / dt); // bool computed_at_least_one = false; // // // first iterate forward along the branch subtending this node to get the // // probabilities of the end states conditioned on the start state // while (current_time_slice * dt >= end_age || !computed_at_least_one) // { // double begin_age_slice = current_time_slice * dt; // double end_age_slice = (current_time_slice + 1) * dt; // numericallyIntegrateProcess(branch_conditional_probs, begin_age_slice, end_age_slice, false); // // computed_at_least_one = true; // current_time_slice--; // } std::map<std::vector<unsigned>, double> event_map; std::vector<double> speciation_rates; if ( use_cladogenetic_events == true ) { // get cladogenesis event map (sparse speciation rate matrix) const DeterministicNode<MatrixReal>* cpn = static_cast<const DeterministicNode<MatrixReal>* >( cladogenesis_matrix ); const TypedFunction<MatrixReal>& tf = cpn->getFunction(); const AbstractCladogenicStateFunction* csf = dynamic_cast<const AbstractCladogenicStateFunction*>( &tf ); event_map = csf->getEventMap(); } else { speciation_rates = lambda->getValue(); } // get likelihoods of descendant nodes const TopologyNode &left = node.getChild(0); size_t left_index = left.getIndex(); state_type left_likelihoods = partial_likelihoods[left_index][active_likelihood[left_index]]; const TopologyNode &right = node.getChild(1); size_t right_index = right.getIndex(); state_type right_likelihoods = partial_likelihoods[right_index][active_likelihood[right_index]]; std::map<std::vector<unsigned>, double> sample_probs; double sample_probs_sum = 0.0; std::map<std::vector<unsigned>, double>::iterator it; // calculate probabilities for each state if ( use_cladogenetic_events == true ) { // iterate over each cladogenetic event possible // and initialize probabilities for each clado event for (it = event_map.begin(); it != event_map.end(); it++) { const std::vector<unsigned>& states = it->first; double speciation_rate = it->second; // we need to sample from the ancestor, left, and right states jointly, // so keep track of the probability of each clado event double prob = left_likelihoods[num_states + states[1]] * right_likelihoods[num_states + states[2]]; prob *= speciation_rate * branch_conditional_probs[num_states + states[0]]; sample_probs[ states ] = prob; sample_probs_sum += prob; } } else { for (size_t i = 0; i < num_states; i++) { double prob = left_likelihoods[num_states + i] * right_likelihoods[num_states + i] * speciation_rates[i]; prob *= branch_conditional_probs[num_states + i]; std::vector<unsigned> states = boost::assign::list_of(i)(i)(i); sample_probs[ states ] = prob; sample_probs_sum += prob; } } // finally, sample ancestor, left, and right character states from probs size_t a, l, r; if (sample_probs_sum == 0) { RandomNumberGenerator* rng = GLOBAL_RNG; size_t u = rng->uniform01() * sample_probs.size(); size_t v = 0; for (it = sample_probs.begin(); it != sample_probs.end(); it++) { if (u < v) { const std::vector<unsigned>& states = it->first; a = states[0]; l = states[1]; r = states[2]; endStates[node_index] = a; startStates[left_index] = l; startStates[right_index] = r; break; } v++; } } else { RandomNumberGenerator* rng = GLOBAL_RNG; double u = rng->uniform01() * sample_probs_sum; for (it = sample_probs.begin(); it != sample_probs.end(); it++) { u -= it->second; if (u < 0.0) { const std::vector<unsigned>& states = it->first; a = states[0]; l = states[1]; r = states[2]; endStates[node_index] = a; startStates[left_index] = l; startStates[right_index] = r; break; } } } // recurse towards tips recursivelyDrawJointConditionalAncestralStates(left, startStates, endStates); recursivelyDrawJointConditionalAncestralStates(right, startStates, endStates); } }
void CharacterDependentCladoBirthDeathProcess::recursivelyDrawJointConditionalAncestralStates(const TopologyNode &node, std::vector<size_t>& startStates, std::vector<size_t>& endStates) { size_t node_index = node.getIndex(); if ( node.isTip() == true ) { const AbstractHomologousDiscreteCharacterData& data = static_cast<TreeDiscreteCharacterData*>(this->value)->getCharacterData(); const AbstractDiscreteTaxonData& taxon_data = data.getTaxonData( node.getName() ); endStates[node_index] = taxon_data.getCharacter(0).getStateIndex(); } else { const TopologyNode &left = node.getChild(0); size_t left_index = left.getIndex(); state_type left_likelihoods = partial_likelihoods[left_index]; const TopologyNode &right = node.getChild(1); size_t right_index = right.getIndex(); state_type right_likelihoods = partial_likelihoods[right_index]; // sample characters by their probability conditioned on the branch's start state going to end states state_type branch_conditional_probs = std::vector<double>(2 * num_states, 0); size_t start_state = startStates[node_index]; branch_conditional_probs[ num_states + start_state ] = 1.0; double dt = root_age->getValue() / NUM_TIME_SLICES; double endAge = node.getAge(); double beginAge = node.getParent().getAge(); double current_time_slice = floor(beginAge / dt); bool computed_at_least_one = false; // get cladogenesis event map (sparse speciation rate matrix) const DeterministicNode<MatrixReal>* cpn = static_cast<const DeterministicNode<MatrixReal>* >( cladogenesis_matrix ); const TypedFunction<MatrixReal>& tf = cpn->getFunction(); const AbstractCladogenicStateFunction* csf = dynamic_cast<const AbstractCladogenicStateFunction*>( &tf ); std::map<std::vector<unsigned>, double> eventMap = csf->getEventMap(); // first iterate forward along the branch subtending this node to get the // probabilities of the end states conditioned on the start state while (current_time_slice * dt >= endAge || !computed_at_least_one) { // populate pre-computed extinction probs into branch_conditional_probs if (current_time_slice > 0) { for (size_t i = 0; i < num_states; i++) { branch_conditional_probs[i] = extinction_probabilities[current_time_slice - 1][i]; } } CDCladoSEObserved ode = CDCladoSEObserved(extinction_rates, &Q->getValue(), eventMap, rate->getValue()); boost::numeric::odeint::bulirsch_stoer< state_type > stepper(1E-8, 0.0, 0.0, 0.0); boost::numeric::odeint::integrate_adaptive( stepper, ode , branch_conditional_probs , current_time_slice * dt , (current_time_slice + 1) * dt, dt ); computed_at_least_one = true; current_time_slice--; } std::map<std::vector<unsigned>, double> sample_probs; double sample_probs_sum = 0.0; std::map<std::vector<unsigned>, double>::iterator it; // iterate over each cladogenetic event possible for (it = eventMap.begin(); it != eventMap.end(); it++) { const std::vector<unsigned>& states = it->first; double speciation_rate = it->second; sample_probs[ states ] = 0.0; // we need to sample from the ancestor, left, and right states jointly, // so keep track of the probability of each clado event double prob = left_likelihoods[num_states + states[1]] * right_likelihoods[num_states + states[2]]; prob *= speciation_rate * branch_conditional_probs[num_states + states[0]]; sample_probs[ states ] += prob; sample_probs_sum += prob; } // finally, sample ancestor, left, and right character states from probs size_t a, l, r; RandomNumberGenerator* rng = GLOBAL_RNG; double u = rng->uniform01() * sample_probs_sum; for (it = sample_probs.begin(); it != sample_probs.end(); it++) { u -= it->second; if (u < 0.0) { const std::vector<unsigned>& states = it->first; a = states[0]; l = states[1]; r = states[2]; endStates[node_index] = a; startStates[left_index] = l; startStates[right_index] = r; break; } } // recurse towards tips recursivelyDrawJointConditionalAncestralStates(left, startStates, endStates); recursivelyDrawJointConditionalAncestralStates(right, startStates, endStates); } }