/** * 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; }
/** 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. * * \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; }
void TmrcaStatistic::update( void ) { const std::vector<TopologyNode*> &n = tree->getValue().getNodes(); size_t minCladeSize = n.size() + 2; bool found = false; if ( index != -RbConstants::Integer::max ) { TopologyNode *node = n[index]; size_t cladeSize = size_t( (node->getNumberOfNodesInSubtree(true) + 1) / 2); if ( node->containsClade( clade, false ) == true ) { if ( taxaCount == cladeSize ) { found = true; } else { minCladeSize = cladeSize; } } } if ( found == false ) { // for each node for (size_t i = 0; i < n.size(); ++i) { TopologyNode *node = n[i]; size_t cladeSize = size_t( (node->getNumberOfNodesInSubtree(true) + 1) / 2); if ( cladeSize < minCladeSize && cladeSize >= taxaCount && node->containsClade( clade, false ) ) { index = node->getIndex(); minCladeSize = cladeSize; if ( taxaCount == cladeSize ) { break; } } } } if ( index == -RbConstants::Integer::max ) { throw RbException("TMRCA-Statistics can only be applied if clade is present."); } if ( stemAge && index != tree->getValue().getRoot().getIndex() ) { size_t parentIndex = tree->getValue().getNode(index).getParent().getIndex(); double tmrca = tree->getValue().getNode( parentIndex ).getAge(); *value = tmrca; } else { double tmrca = tree->getValue().getNode( index ).getAge(); *value = tmrca; } }