/*---------------------------------------------------------------------------------------------------------------------- | Calls the sample() member function of the `slice_sampler' data member. */ bool TreeScalerMove::update() { if (is_fixed) return false; ChainManagerShPtr p = chain_mgr.lock(); PHYCAS_ASSERT(p); JointPriorManagerShPtr jpm = p->getJointPriorManager(); bool using_tree_length_prior = jpm->isTreeLengthPrior(); // If first edge length master param returns false for useWorkingPrior(), then we are using // Mark Holder's variable tree topology reference distribution (see _provideRefDistToUpdaters in MCMCImpl.py) MCMCUpdaterVect::const_iterator it = p->getEdgeLenParams().begin(); bool using_vartopol_prior = !(*it)->useWorkingPrior(); double prev_ln_prior = jpm->getLogJointPrior(); double prev_ln_like = p->getLastLnLike(); double prev_ln_ref_dist = (use_ref_dist ? recalcWorkingPriorForMove(using_tree_length_prior, using_vartopol_prior) : 0.0); proposeNewState(); if (jpm->isTreeLengthPrior()) jpm->treeLengthModified("tree_length", tree); else jpm->allEdgeLensModified(tree); curr_ln_prior = jpm->getLogJointPrior(); likelihood->useAsLikelihoodRoot(NULL); // invalidates all CLAs double curr_ln_like = (heating_power > 0.0 ? likelihood->calcLnL(tree) : 0.0); double curr_ln_ref_dist = (use_ref_dist ? recalcWorkingPriorForMove(using_tree_length_prior, using_vartopol_prior) : 0.0); double prev_posterior = 0.0; double curr_posterior = 0.0; if (is_standard_heating) { prev_posterior = heating_power*(prev_ln_like + prev_ln_prior); curr_posterior = heating_power*(curr_ln_like + curr_ln_prior); if (use_ref_dist) { prev_posterior += (1.0 - heating_power)*prev_ln_ref_dist; curr_posterior += (1.0 - heating_power)*curr_ln_ref_dist; } } else { prev_posterior = heating_power*prev_ln_like + prev_ln_prior; curr_posterior = heating_power*curr_ln_like + curr_ln_prior; } double ln_hastings = getLnHastingsRatio(); double ln_accept_ratio = curr_posterior - prev_posterior + ln_hastings; double lnu = std::log(rng->Uniform()); bool accepted = false; if (ln_accept_ratio >= 0.0 || lnu <= ln_accept_ratio) { if (save_debug_info) { debug_info = boost::str(boost::format("ACCEPT, forward_scaler = %.5f, prev_ln_prior = %.5f, curr_ln_prior = %.5f, prev_ln_like = %.5f, curr_ln_like = %.5f, lnu = %.5f, ln_accept_ratio = %.5f") % forward_scaler % prev_ln_prior % curr_ln_prior % prev_ln_like % curr_ln_like % lnu % ln_accept_ratio); } p->setLastLnLike(curr_ln_like); accept(); accepted = true; } else { if (save_debug_info) { debug_info = boost::str(boost::format("REJECT, forward_scaler = %.5f, prev_ln_prior = %.5f, curr_ln_prior = %.5f, prev_ln_like = %.5f, curr_ln_like = %.5f, lnu = %.5f, ln_accept_ratio = %.5f") % forward_scaler % prev_ln_prior % curr_ln_prior % prev_ln_like % curr_ln_like % lnu % ln_accept_ratio); } curr_ln_like = p->getLastLnLike(); revert(); accepted = false; } //POLTMP lambda = p->adaptUpdater(lambda, nattempts, accepted); return accepted; }
/*---------------------------------------------------------------------------------------------------------------------- | Calls proposeNewState(), then decides whether to accept or reject the proposed new state, calling accept() or | revert(), whichever is appropriate. */ bool LargetSimonMove::update() { // The only case in which is_fixed is true occurs when the user decides to fix the edge lengths. // A proposed LargetSimonMove cannot be accepted without changing edge lengths, so it is best to bail out now. if (is_fixed) return false; tree->renumberInternalNodes(tree->GetNTips()); //@POL this should be somewhere else tree->RecalcAllSplits(tree->GetNTips()); ChainManagerShPtr p = chain_mgr.lock(); PHYCAS_ASSERT(p); JointPriorManagerShPtr jpm = p->getJointPriorManager(); // compute the likelihood before proposing a new state double prev_ln_like = p->getLastLnLike(); double prev_ln_prior = jpm->getLogJointPrior(); TreeNode * prev_likelihood_root = likelihood->getLikelihoodRoot(); double prev_ln_ref_dist = 0.0; if (use_ref_dist) { prev_ln_ref_dist = recalcWorkingPrior(); } //likelihood->startTreeViewer(tree, boost::str(boost::format("LS move BEFORE: %.5f") % prev_ln_like)); proposeNewState(); curr_ln_like = (heating_power > 0.0 ? likelihood->calcLnL(tree) : 0.0); //likelihood->startTreeViewer(tree, boost::str(boost::format("LS move AFTER: %.5f") % curr_ln_like)); curr_ln_prior = jpm->getLogJointPrior(); double curr_ln_ref_dist = 0.0; if (likelihood->getTreeLengthPrior()) { PHYCAS_ASSERT(!use_ref_dist); // not ready for this yet curr_ln_prior = likelihood->getTreeLengthPrior()->GetLnPDF(tree); } else { if (use_ref_dist) { curr_ln_ref_dist = recalcWorkingPrior(); } } double prev_posterior = 0.0; double curr_posterior = 0.0; if (is_standard_heating) { prev_posterior = heating_power*(prev_ln_like + prev_ln_prior); curr_posterior = heating_power*(curr_ln_like + curr_ln_prior); if (use_ref_dist) { prev_posterior += (1.0 - heating_power)*prev_ln_ref_dist; curr_posterior += (1.0 - heating_power)*curr_ln_ref_dist; } } else { prev_posterior = heating_power*prev_ln_like + prev_ln_prior; curr_posterior = heating_power*curr_ln_like + curr_ln_prior; } double ln_accept_ratio = curr_posterior - prev_posterior + getLnHastingsRatio() + getLnJacobian(); double lnu = DBL_MAX; bool accepted = (ln_accept_ratio >= 0.0); if (!accepted) { double u = rng->Uniform(); lnu = std::log(u); accepted = (lnu <= ln_accept_ratio); } if (save_debug_info) { if (star_tree_proposal) { debug_info = str(boost::format("LS: %.5f -> %.5f (%s)") % orig_edge_len % orig_node->GetEdgeLen() % (accepted ? "accepted" : "rejected")); } else { debug_info = boost::str(boost::format("%s, prev_ln_like = %.5f, getLastLnLike() = %.5f, curr_ln_like = %.5f, topology %s, case = %d, x=%f, y=%f, z=%f, newX=%f, newY=%f, newZ=%f, lnu = %.5f, lnr = %.5f, curr = %.5f, prev = %.5f") % (accepted ? "ACCEPT" : "REJECT") % prev_ln_like % p->getLastLnLike() % curr_ln_like % (topol_changed ? "changed" : "unchanged") % which_case % x % y % z % (ndX->GetEdgeLen()) % (ndY->GetEdgeLen()) % (ndZ->GetEdgeLen()) % (lnu == DBL_MAX ? -1.0 : lnu) % ln_accept_ratio % curr_posterior % prev_posterior); if (is_standard_heating) { if (use_ref_dist) { debug_info += boost::str(boost::format("\n prev_posterior = %g = %g*(%g + %g) + (1.0 - %g)*%g") % prev_posterior % heating_power % prev_ln_like % prev_ln_prior % heating_power % prev_ln_ref_dist ); debug_info += boost::str(boost::format("\n curr_posterior = %g = %g*(%g + %g) + (1.0 - %g)*%g") % curr_posterior % heating_power % curr_ln_like % curr_ln_prior % heating_power % curr_ln_ref_dist ); } else { debug_info += boost::str(boost::format("\n prev_posterior = %g = %g*(%g + %g)") % prev_posterior % heating_power % prev_ln_like % prev_ln_prior ); debug_info += boost::str(boost::format("\n curr_posterior = %g = %g*(%g + %g)") % curr_posterior % heating_power % curr_ln_like % curr_ln_prior ); } } else { debug_info += boost::str(boost::format("\n prev_posterior = %g = %g*%g + %g") % prev_posterior % heating_power % prev_ln_like % prev_ln_prior ); debug_info += boost::str(boost::format("\n curr_posterior = %g = %g*%g + %g") % curr_posterior % heating_power % curr_ln_like % curr_ln_prior ); } if (!prev_likelihood_root) debug_info += "\n prev_likelihood_root = NULL"; else debug_info += boost::str(boost::format("\n prev_likelihood_root = %g") % prev_likelihood_root->GetNodeNumber()); TreeNode * tmp_curr_likelihood_root = likelihood->getLikelihoodRoot(); if (!tmp_curr_likelihood_root) debug_info += "\n curr_likelihood_root = NULL"; else debug_info += boost::str(boost::format("\n curr_likelihood_root = %g") % tmp_curr_likelihood_root->GetNodeNumber()); } } if (accepted) { p->setLastLnLike(curr_ln_like); accept(); } else { curr_ln_like = p->getLastLnLike(); revert(); PHYCAS_ASSERT(!prev_likelihood_root || prev_likelihood_root->IsInternal()); likelihood->useAsLikelihoodRoot(prev_likelihood_root); } //POLTMP lambda = p->adaptUpdater(lambda, nattempts, accepted); //std::cerr << boost::str(boost::format("~~~> log(lambda) = %.5f <~~~") % log(lambda)) << std::endl; return accepted; }
/*---------------------------------------------------------------------------------------------------------------------- | Calls proposeNewState(), then decides whether to accept or reject the proposed new state, calling accept() or | revert(), whichever is appropriate. */ bool EdgeMove::update() { // The only case in which is_fixed is true occurs when the user decides to fix the edge lengths. // A proposed EdgeMove cannot be accepted without changing edge lengths, so it is best to just bail out now. if (is_fixed) return false; ChainManagerShPtr p = chain_mgr.lock(); PHYCAS_ASSERT(p); double prev_ln_like = p->getLastLnLike(); PHYCAS_ASSERT(!likelihood->getTreeLengthPrior()); // not ready for this yet proposeNewState(); bool is_internal_edge = origNode->IsInternal(); double prev_ln_prior = (is_internal_edge ? p->calcInternalEdgeLenPriorUnnorm(origEdgelen) : p->calcExternalEdgeLenPriorUnnorm(origEdgelen)); double prev_ln_ref_dist = 0.0; double curr_ln_like = (heating_power > 0.0 ? likelihood->calcLnL(tree) : 0.0); double curr_edgelen = origNode->GetEdgeLen(); double curr_ln_prior = (is_internal_edge ? p->calcInternalEdgeLenPriorUnnorm(curr_edgelen) : p->calcExternalEdgeLenPriorUnnorm(curr_edgelen)); double curr_ln_ref_dist = 0.0; double prev_posterior = 0.0; double curr_posterior = 0.0; if (is_standard_heating) { prev_posterior = heating_power*(prev_ln_like + prev_ln_prior); curr_posterior = heating_power*(curr_ln_like + curr_ln_prior); if (use_ref_dist) { prev_posterior += (1.0 - heating_power)*prev_ln_ref_dist; curr_posterior += (1.0 - heating_power)*curr_ln_ref_dist; } } else { prev_posterior = heating_power*prev_ln_like + prev_ln_prior; curr_posterior = heating_power*curr_ln_like + curr_ln_prior; } double ln_hastings = getLnHastingsRatio(); double ln_accept_ratio = curr_posterior - prev_posterior + ln_hastings; double lnu = std::log(rng->Uniform()); bool accepted = false; if (ln_accept_ratio >= 0.0 || lnu <= ln_accept_ratio) { p->setLastLnLike(curr_ln_like); accept(); accepted = true; } else { curr_ln_like = p->getLastLnLike(); revert(); accepted = false; } //POLTMP lambda = p->adaptUpdater(lambda, nattempts, accepted); return accepted; }