double RateMap_Biogeography::getRate(const TopologyNode& node, std::vector<CharacterEvent*> from, CharacterEvent* to, unsigned* count, double age) const { double rate = 0.0; int s = to->getState(); if (from[ to->getIndex() ]->getState() == to->getState()) { std::cout << count[0] << " " << count[1] << "\n"; std::cout << node.getIndex() << " problem...\n"; ; } // rate to extinction cfg is 0 if (count[1] == 1 && s == 0 && forbidExtinction) return 0.0; // rate according to binary rate matrix Q(node) if (branchHeterogeneousGainLossRates) rate = heterogeneousGainLossRates[node.getIndex()][s]; else rate = homogeneousGainLossRates[s]; if (branchHeterogeneousClockRates) rate *= heterogeneousClockRates[node.getIndex()]; else rate *= homogeneousClockRate; // apply rate modifiers if (useGeographyRateModifier) // want this to take in age as an argument... rate *= geographyRateModifier->computeRateModifier(node, from, to, age); return rate; }
double RateMap_Biogeography::getSiteRate(const TopologyNode& node, CharacterEvent* from, CharacterEvent* to, double age) const { double rate = 0.0; int s = to->getState(); // int charIdx = to->getIndex(); // int epochIdx = getEpochIndex(age); // rate according to binary rate matrix Q(node) if (branchHeterogeneousGainLossRates) rate = heterogeneousGainLossRates[node.getIndex()][s]; else rate = homogeneousGainLossRates[s]; if (branchHeterogeneousClockRates) rate *= heterogeneousClockRates[node.getIndex()]; else rate *= homogeneousClockRate; // area effects if (useGeographyRateModifier) rate *= geographyRateModifier->computeSiteRateModifier(node,from,to,age); return rate; }
void AutocorrelatedLognormalRateBranchwiseVarDistribution::recursiveSimulate(const TopologyNode& node, double parentRate) { // get the index size_t nodeIndex = node.getIndex(); // compute the variance along the branch double scale = scaleValue->getValue(); double variance = sigma->getValue()[nodeIndex] * node.getBranchLength() * scale; double mu = log(parentRate) - (variance * 0.5); double stDev = sqrt(variance); // simulate a new rate RandomNumberGenerator* rng = GLOBAL_RNG; double nodeRate = RbStatistics::Lognormal::rv( mu, stDev, *rng ); // we store this rate here (*value)[nodeIndex] = nodeRate; // simulate the rate for each child (if any) size_t numChildren = node.getNumberOfChildren(); for (size_t i = 0; i < numChildren; ++i) { const TopologyNode& child = node.getChild(i); recursiveSimulate(child,nodeRate); } }
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)); } }
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 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 MultivariateBrownianPhyloProcess::recursiveCorruptAll(const TopologyNode& from) { dirtyNodes[from.getIndex()] = true; for (size_t i = 0; i < from.getNumberOfChildren(); ++i) { recursiveCorruptAll(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 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); } }
double AutocorrelatedLognormalRateBranchwiseVarDistribution::recursiveLnProb( const TopologyNode& n ) { // get the index size_t nodeIndex = n.getIndex(); double lnProb = 0.0; size_t numChildren = n.getNumberOfChildren(); double scale = scaleValue->getValue(); if ( numChildren > 0 ) { double parentRate = log( (*value)[nodeIndex] ); for (size_t i = 0; i < numChildren; ++i) { const TopologyNode& child = n.getChild(i); lnProb += recursiveLnProb(child); size_t childIndex = child.getIndex(); // compute the variance double variance = sigma->getValue()[childIndex] * child.getBranchLength() * scale; double childRate = (*value)[childIndex]; // the mean of the LN dist is parentRate = exp[mu + (variance / 2)], // where mu is the location param of the LN dist (see Kishino & Thorne 2001) double mu = parentRate - (variance * 0.5); double stDev = sqrt(variance); lnProb += RbStatistics::Lognormal::lnPdf(mu, stDev, childRate); } } return lnProb; }
double RateMap_Biogeography::getUnnormalizedSumOfRates(const TopologyNode& node, std::vector<CharacterEvent*> from, unsigned* counts, double age) const { size_t nodeIndex = node.getIndex(); size_t epochIdx = getEpochIndex(age); // apply ctmc for branch const std::vector<double>& glr = ( branchHeterogeneousGainLossRates ? heterogeneousGainLossRates[nodeIndex] : homogeneousGainLossRates ); // get sum of rates double sum = 0.0; for (size_t i = 0; i < from.size(); i++) { unsigned s = from[i]->getState(); double v = availableAreaVector[ epochIdx * this->numCharacters + i ]; if (forbidExtinction && s == 1 && counts[1] == 1) sum += 0.0; else if (s == 1 && v > 0) sum += glr[0]; else if (s == 1 && v == 0) sum += 10e10; else if (s == 0) sum += glr[1] * v; } // apply rate for branch if (branchHeterogeneousClockRates) sum *= heterogeneousClockRates[nodeIndex]; else sum *= homogeneousClockRate; return sum; }
void AutocorrelatedBranchMatrixDistribution::recursiveSimulate(const TopologyNode& node, RbVector< RateMatrix > *values, const std::vector< double > &scaledParent) { // get the index size_t nodeIndex = node.getIndex(); // first we simulate our value RandomNumberGenerator* rng = GLOBAL_RNG; // do we keep our parents values? double u = rng->uniform01(); if ( u < changeProbability->getValue() ) { // change // draw a new value for the base frequencies std::vector<double> newParent = RbStatistics::Dirichlet::rv(scaledParent, *rng); std::vector<double> newScaledParent = newParent; // compute the new scaled parent std::vector<double>::iterator end = newScaledParent.end(); for (std::vector<double>::iterator it = newScaledParent.begin(); it != end; ++it) { (*it) *= alpha->getValue(); } RateMatrix_GTR rm = RateMatrix_GTR( newParent.size() ); RbPhylogenetics::Gtr::computeRateMatrix( exchangeabilityRates->getValue(), newParent, &rm ); uniqueBaseFrequencies.push_back( newParent ); uniqueMatrices.push_back( rm ); matrixIndex[nodeIndex] = uniqueMatrices.size()-1; values->insert(nodeIndex, rm); size_t numChildren = node.getNumberOfChildren(); if ( numChildren > 0 ) { for (size_t i = 0; i < numChildren; ++i) { const TopologyNode& child = node.getChild(i); recursiveSimulate(child,values,newScaledParent); } } } else { // no change size_t parentIndex = node.getParent().getIndex(); values->insert(nodeIndex, uniqueMatrices[ matrixIndex[ parentIndex ] ]); size_t numChildren = node.getNumberOfChildren(); if ( numChildren > 0 ) { for (size_t i = 0; i < numChildren; ++i) { const TopologyNode& child = node.getChild(i); recursiveSimulate(child,values,scaledParent); } } } }
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 ); } }
size_t SpeciesTreeNodeSlideProposal::fillPreorderIndices(TopologyNode &node, size_t loc, std::vector<size_t> &indices) { if ( node.isInternal() == true ) { size_t l = fillPreorderIndices(node.getChild( 0 ), loc, indices); indices[node.getIndex()] = l; loc = fillPreorderIndices(node.getChild( 1 ), l + 1, indices); } return loc; }
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(); }
void RealNodeContainer::recursiveGetStats(const TopologyNode& from, double& e1, double& e2, int& n) const { 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) { recursiveGetStats(from.getChild(i),e1,e2,n); } }
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; }
double AutocorrelatedBranchMatrixDistribution::recursiveLnProb( const TopologyNode& n ) { // get the index size_t nodeIndex = n.getIndex(); double lnProb = 0.0; size_t numChildren = n.getNumberOfChildren(); if ( numChildren > 0 ) { std::vector<double> parent = (*value)[nodeIndex].getStationaryFrequencies(); std::vector<double>::iterator end = parent.end(); for (std::vector<double>::iterator it = parent.begin(); it != end; ++it) { (*it) *= alpha->getValue(); } for (size_t i = 0; i < numChildren; ++i) { const TopologyNode& child = n.getChild(i); lnProb += recursiveLnProb(child); size_t childIndex = child.getIndex(); // RateMatrix& rm = (*value)[childIndex]; // compare if the child has a different matrix if ( matrixIndex[nodeIndex] == matrixIndex[childIndex] ) { // no change -> just the probability of no change lnProb += log( 1.0 - changeProbability->getValue() ); } else { // change: // probability of change lnProb += log( changeProbability->getValue() ); const std::vector<double>& descendant = (*value)[childIndex].getStationaryFrequencies(); // const std::vector<double>& descendant = uniqueMatrices[ matrixIndex[childIndex] ].getStationaryFrequencies(); // probability of new descendant values double p = RbStatistics::Dirichlet::lnPdf(parent, descendant); lnProb += p; } } } return lnProb; }
double RateMap_Biogeography::getSumOfRates(const TopologyNode& node, std::vector<CharacterEvent*> from, unsigned* counts, double age) const { if (useUnnormalizedRates) return getUnnormalizedSumOfRates(node, from, counts, age); size_t nodeIndex = node.getIndex(); // get rate away away from currState unsigned n0 = counts[0]; unsigned n1 = counts[1]; // forbid extinction events if (counts[1] == 1 && forbidExtinction) n1 = 0; // get characters in each state double r0 = n1; double r1 = n0; // apply ctmc for branch if (branchHeterogeneousGainLossRates) { r0 *= heterogeneousGainLossRates[nodeIndex][0]; r1 *= heterogeneousGainLossRates[nodeIndex][1]; } else { r0 *= homogeneousGainLossRates[0]; r1 *= homogeneousGainLossRates[1]; } // apply rate for branch. double sum = r0 + r1; if (branchHeterogeneousClockRates) { sum *= heterogeneousClockRates[nodeIndex]; } else { sum *= homogeneousClockRate; } return sum; }
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; }
/** * 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; }
/** * 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 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); } }
/** * 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; }
void TmrcaStatistic::update( void ) { const std::vector<TopologyNode*> &n = tree->getValue().getNodes(); size_t minCaldeSize = n.size() + 2; bool found = false; if ( index != RbConstants::Size_t::nan ) { TopologyNode *node = n[index]; std::vector<std::string> taxa; node->getTaxaStringVector( taxa ); size_t cladeSize = taxa.size(); if ( node->containsClade( clade, false ) && taxaCount == cladeSize ) { found = true; } else { minCaldeSize = cladeSize; } } if ( found == false ) { for (size_t i = tree->getValue().getNumberOfTips(); i < n.size(); ++i) { TopologyNode *node = n[i]; std::vector<std::string> taxa; node->getTaxaStringVector( taxa ); size_t cladeSize = taxa.size(); if ( cladeSize < minCaldeSize && cladeSize >= taxaCount && node->containsClade( clade, false ) ) { index = node->getIndex(); minCaldeSize = cladeSize; if ( taxaCount == cladeSize ) { break; } } } } if ( index == RbConstants::Size_t::nan ) { throw RbException("TMRCA-Statistics can only be applied if clade is present."); } if ( stemAge ) { size_t parentIndex = tree->getValue().getNode(index).getParent().getIndex(); double tmrca = tree->getValue().getAge(parentIndex); *value = tmrca; } else { double tmrca = tree->getValue().getAge(index); *value = tmrca; } }
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; } } }