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; }
void PhyloWhiteNoiseProcess::recursiveSimulate(const TopologyNode& from) { if (! from.isRoot()) { // get the index size_t index = from.getIndex(); // compute the variance along the branch double mean = 1.0; double stdev = sigma->getValue() / sqrt(from.getBranchLength()); double alpha = mean * mean / (stdev * stdev); double beta = mean / (stdev * stdev); // simulate a new Val RandomNumberGenerator* rng = GLOBAL_RNG; double v = RbStatistics::Gamma::rv( alpha,beta, *rng); // we store this val here (*value)[index] = v; } // simulate the val for each child (if any) size_t numChildren = from.getNumberOfChildren(); for (size_t i = 0; i < numChildren; ++i) { const TopologyNode& child = from.getChild(i); recursiveSimulate(child); } }
void MultivariateBrownianPhyloProcess::recursiveSimulate(const TopologyNode& from) { size_t index = from.getIndex(); if (from.isRoot()) { std::vector<double>& val = (*value)[index]; for (size_t i=0; i<getDim(); i++) { val[i] = 0; } } else { // x ~ normal(x_up, sigma^2 * branchLength) std::vector<double>& val = (*value)[index]; sigma->getValue().drawNormalSampleCovariance((*value)[index]); size_t upindex = from.getParent().getIndex(); std::vector<double>& upval = (*value)[upindex]; for (size_t i=0; i<getDim(); i++) { val[i] += upval[i]; } } // propagate forward size_t numChildren = from.getNumberOfChildren(); for (size_t i = 0; i < numChildren; ++i) { recursiveSimulate(from.getChild(i)); } }
void PhyloBrownianProcessREML::recursivelyFlagNodeDirty( const TopologyNode &n ) { // we need to flag this node and all ancestral nodes for recomputation size_t index = n.getIndex(); // if this node is already dirty, the also all the ancestral nodes must have been flagged as dirty if ( !dirtyNodes[index] ) { // the root doesn't have an ancestor if ( !n.isRoot() ) { recursivelyFlagNodeDirty( n.getParent() ); } // set the flag dirtyNodes[index] = true; // if we previously haven't touched this node, then we need to change the active likelihood pointer if ( changedNodes[index] == false ) { activeLikelihood[index] = (activeLikelihood[index] == 0 ? 1 : 0); changedNodes[index] = true; } } }
double BrownianPhyloProcess::recursiveLnProb( const TopologyNode& from ) { double lnProb = 0.0; size_t index = from.getIndex(); double val = (*value)[index]; if (! from.isRoot()) { // x ~ normal(x_up, sigma^2 * branchLength) size_t upindex = from.getParent().getIndex(); double standDev = sigma->getValue() * sqrt(from.getBranchLength()); double mean = (*value)[upindex] + drift->getValue() * from.getBranchLength(); lnProb += RbStatistics::Normal::lnPdf(val, standDev, mean); } // propagate forward size_t numChildren = from.getNumberOfChildren(); for (size_t i = 0; i < numChildren; ++i) { lnProb += recursiveLnProb(from.getChild(i)); } return lnProb; }
void BrownianPhyloProcess::recursiveSimulate(const TopologyNode& from) { size_t index = from.getIndex(); if (! from.isRoot()) { // x ~ normal(x_up, sigma^2 * branchLength) size_t upindex = from.getParent().getIndex(); double standDev = sigma->getValue() * sqrt(from.getBranchLength()); double mean = (*value)[upindex] + drift->getValue() * from.getBranchLength(); // simulate the new Val RandomNumberGenerator* rng = GLOBAL_RNG; (*value)[index] = RbStatistics::Normal::rv( mean, standDev, *rng); } // propagate forward size_t numChildren = from.getNumberOfChildren(); for (size_t i = 0; i < numChildren; ++i) { recursiveSimulate(from.getChild(i)); } }
/** * 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; }
double MultivariateBrownianPhyloProcess::recursiveLnProb( const TopologyNode& from ) { double lnProb = 0.0; size_t index = from.getIndex(); std::vector<double> val = (*value)[index]; if (! from.isRoot()) { if (1) { // if (dirtyNodes[index]) { // x ~ normal(x_up, sigma^2 * branchLength) size_t upindex = from.getParent().getIndex(); std::vector<double> upval = (*value)[upindex]; const MatrixReal& om = sigma->getValue().getInverse(); double s2 = 0; for (size_t i = 0; i < getDim(); i++) { double tmp = 0; for (size_t j = 0; j < getDim(); j++) { tmp += om[i][j] * (val[j] - upval[j]); } s2 += (val[i] - upval[i]) * tmp; } double logprob = 0; logprob -= 0.5 * s2 / from.getBranchLength(); logprob -= 0.5 * (sigma->getValue().getLogDet() + sigma->getValue().getDim() * log(from.getBranchLength())); nodeLogProbs[index] = logprob; dirtyNodes[index] = false; } lnProb += nodeLogProbs[index]; } // propagate forward size_t numChildren = from.getNumberOfChildren(); for (size_t i = 0; i < numChildren; ++i) { lnProb += recursiveLnProb(from.getChild(i)); } return lnProb; }
void RateMap_Biogeography::calculateTransitionProbabilities(const TopologyNode& node, TransitionProbabilityMatrix &P) const { double branchLength = node.getBranchLength(); double r = ( branchHeterogeneousClockRates ? heterogeneousClockRates[node.getIndex()] : homogeneousClockRate ); const std::vector<double>& glr = ( branchHeterogeneousGainLossRates ? heterogeneousGainLossRates[node.getIndex()] : homogeneousGainLossRates ); if (node.isRoot()) branchLength = 1e10; double expPart = exp( -(glr[0] + glr[1]) * r * branchLength); double p = glr[0] / (glr[0] + glr[1]); double q = 1.0 - p; P[0][0] = p + q * expPart; P[0][1] = q - q * expPart; P[1][0] = p - p * expPart; P[1][1] = q + p * expPart; }
/** * Compute the diversity of the tree at time t. * * \param[in] t time at which we want to know the diversity. * * \return The diversity (number of species in the reconstructed tree). */ int PiecewiseConstantSerialSampledBirthDeathProcess::survivors(double t) const { const std::vector<TopologyNode*>& nodes = value->getNodes(); int survivors = 0; for (std::vector<TopologyNode*>::const_iterator it = nodes.begin(); it != nodes.end(); ++it) { TopologyNode* n = *it; if ( n->getAge() < t ) { if ( n->isRoot() || n->getParent().getAge() > t ) { survivors++; } } } return survivors; }
/** 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; }
double PhyloWhiteNoiseProcess::recursiveLnProb(const TopologyNode &from) { double lnProb = 0.0; if (! from.isRoot()) { // compute the variance double mean = 1.0; double stdev = sigma->getValue() / sqrt(from.getBranchLength()); double alpha = mean * mean / (stdev * stdev); double beta = mean / (stdev * stdev); double v = (*value)[from.getIndex()]; lnProb += log( RbStatistics::Gamma::lnPdf(alpha,beta,v) ); } size_t numChildren = from.getNumberOfChildren(); for (size_t i = 0; i < numChildren; ++i) { const TopologyNode& child = from.getChild(i); lnProb += recursiveLnProb(child); } return lnProb; }
/** 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; }
/** Perform the move */ double GibbsPruneAndRegraft::performSimpleMove( void ) { // Get random number generator RandomNumberGenerator* rng = GLOBAL_RNG; TimeTree& tau = variable->getValue(); // potential affected nodes for likelihood computation std::set<DagNode *> affected; variable->getAffectedNodes( affected ); double backwardLikelihood = variable->getLnProbability(); for (std::set<DagNode*>::const_iterator it = affected.begin(); it != affected.end(); ++it) { backwardLikelihood += (*it)->getLnProbability(); } int offset = (int) -backwardLikelihood; double backward = exp(backwardLikelihood + offset); // 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->getParent().isRoot() ); TopologyNode* parent = &node->getParent(); TopologyNode& grandparent = parent->getParent(); TopologyNode& brother = parent->getChild( 0 ); // check if we got the correct child if ( &brother == node ) { brother = parent->getChild( 1 ); } // collect the possible reattachement points std::vector<TopologyNode*> new_brothers; findNewBrothers(new_brothers, *parent, &tau.getRoot()); std::vector<double> weights = std::vector<double>(new_brothers.size(), 0.0); double sumOfWeights = 0.0; for (size_t i = 0; i<new_brothers.size(); ++i) { // get the new brother TopologyNode* newBro = new_brothers[i]; // do the proposal TopologyNode *newGrandparent = pruneAndRegraft(&brother, newBro, parent, grandparent); // flag for likelihood recomputation variable->touch(); // compute the likelihood of the new value double priorRatio = variable->getLnProbability(); double likelihoodRatio = 0.0; for (std::set<DagNode*>::const_iterator it = affected.begin(); it != affected.end(); ++it) { likelihoodRatio += (*it)->getLnProbability(); } weights[i] = exp(priorRatio + likelihoodRatio + offset); sumOfWeights += weights[i]; // undo proposal pruneAndRegraft(newBro, &brother, parent, *newGrandparent); // restore the previous likelihoods; variable->restore(); } if (sumOfWeights <= 1E-100) { // hack // the proposals have such a small likelihood that they can be neglected // throw new OperatorFailedException("Couldn't find another proposal with a decent likelihood."); return 0.0; } double ran = rng->uniform01() * sumOfWeights; size_t index = 0; while (ran > 0.0) { ran -= weights[index]; index++; } index--; TopologyNode* newBro = new_brothers[index]; // now we store all necessary values storedBrother = &brother; storedNewBrother = newBro; pruneAndRegraft(&brother, newBro, parent, grandparent); double forward = weights[index]; double forwardProb = (forward / sumOfWeights); double backwardProb = (backward / (sumOfWeights - forward + backward)); double hastingsRatio = log(backwardProb / forwardProb); return hastingsRatio; }
/** * 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::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 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; } }
std::set<TopologyNode*> SpeciesNarrowExchangeProposal::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 the node double min_age = n.getAge(); std::vector<TopologyNode*> species_taxa; TreeUtilities::getTaxaInSubtree( &n, species_taxa ); // get all the individuals std::set<TopologyNode*> individual_taxa; 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) { individual_taxa.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 ( individual_taxa.empty() == false ) { std::set<TopologyNode*>::iterator it = individual_taxa.begin(); individual_taxa.erase( it ); TopologyNode *gene_node = *it; if ( gene_node->getAge() < min_age ) { // the age of the node is younger than the populations start age // -> add the node to the current working set individual_taxa.insert( &gene_node->getParent() ); } else if ( gene_node->getAge() < max_age || max_age == -1.0 ) { // the age of the node is within the population // -> add the node to the current return set nodesInPopulationSet.insert( gene_node ); // if this is not the root then we need to add the parent node to the working set if ( gene_node->isRoot() == false ) { individual_taxa.insert( &gene_node->getParent() ); } } } return nodesInPopulationSet; }
/** 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(); } } } }
void RateMap_Biogeography::calculateTransitionProbabilities(const TopologyNode& node, TransitionProbabilityMatrix &P, size_t charIdx) const { double startAge = ( node.isRoot() ? 1e10 : node.getParent().getAge() ); double endAge = node.getAge(); double currAge = startAge; double r = ( branchHeterogeneousClockRates ? heterogeneousClockRates[node.getIndex()] : homogeneousClockRate ); const std::vector<double>& glr = ( branchHeterogeneousGainLossRates ? heterogeneousGainLossRates[node.getIndex()] : homogeneousGainLossRates ); // start at earliest epoch int epochIdx = getEpochIndex(startAge); // initialize P = I P[0][0] = 1.0; P[0][1] = 0.0; P[1][0] = 0.0; P[1][1] = 1.0; bool stop = false; while (!stop) { // get dispersal and extinction rates for site size_t idx = this->numCharacters * epochIdx + charIdx; double dispersalRate = ( (availableAreaVector[ idx ] > 0) ? 1.0 : 0.0); double extinctionRate = ( (availableAreaVector[ idx ] > 0) ? 1.0 : 1e10); // get age of start of next oldest epoch double epochAge = epochs[ epochIdx ]; // get next oldest age boundary (node or epoch) double incrAge = epochAge; // no more epochs, exit loop after computation if (endAge >= epochAge) { incrAge = endAge; stop = true; } // get branch length double diffAge = currAge - incrAge; // transition probabilities w/ sum-product double glr0 = glr[0] * extinctionRate; double glr1 = glr[1] * dispersalRate; double expPart = exp( -(glr0 + glr1) * r * diffAge); double p = glr0 / (glr0 + glr1); double q = 1.0 - p; double p00 = (p + q * expPart); double p01 = (q - q * expPart); double p10 = (p - p * expPart); double p11 = (q + p * expPart); double q00 = P[0][0]; double q01 = P[0][1]; double q10 = P[1][0]; double q11 = P[1][1]; P[0][0] = p00 * q00 + p01 * q10; P[0][1] = p00 * q01 + p01 * q11; P[1][0] = p10 * q00 + p11 * q10; P[1][1] = p10 * q01 + p11 * q11; // std::cout << P[0][0] << "," << P[0][1] << ";" << P[1][0] << "," << P[1][1] << "\n"; if (!stop) { epochIdx += 1; currAge = epochAge; } } }