/*---------------------------------------------------------------------------------------------------------------------- | OmegaParam is a functor whose operator() returns a value proportional to the full-conditional posterior probability | density for a particular value of omega, the nonsynonymous/synonymous rate ratio. If the supplied omega value `w' is | out of bounds (i.e. <= 0.0), the return value is -DBL_MAX (closest we can come to a log posterior equal to negative | infinity). */ double OmegaParam::operator()( double w) /**< is a new value for the parameter omega */ { curr_ln_like = ln_zero; curr_ln_prior = 0.0; if (w > 0.0) { PHYCAS_ASSERT(codon); sendCurrValueToModel(w); likelihood->useAsLikelihoodRoot(NULL); // invalidates all CLAs curr_ln_like = (heating_power > 0.0 ? likelihood->calcLnL(tree) : 0.0); ChainManagerShPtr p = chain_mgr.lock(); PHYCAS_ASSERT(p); p->setLastLnLike(curr_ln_like); JointPriorManagerShPtr jpm = p->getJointPriorManager(); jpm->univariateModified(name, w); curr_ln_prior = jpm->getLogJointPrior(); if (is_standard_heating) if (use_ref_dist) { PHYCAS_ASSERT(ref_dist); double curr_ln_ref_dist = ref_dist->GetLnPDF(w); return heating_power*(curr_ln_like + curr_ln_prior) + (1.0 - heating_power)*curr_ln_ref_dist; } else return heating_power*(curr_ln_like + curr_ln_prior); else return heating_power*curr_ln_like + curr_ln_prior; } else return ln_zero; }
/*---------------------------------------------------------------------------------------------------------------------- | 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 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. | | We actually generate a new mapping all the time (in proposeNewState). Then we change the branch length. The branch length | change might be rejected. */ bool UnimapEdgeMove::update() { #if 1 || DISABLED_UNTIL_UNIMAP_WORKING_WITH_PARTITIONING // The only case in which is_fixed is true occurs when the user decides to fix the edge lengths. // A proposed UnimapEdgeMove cannot be accepted without changing edge lengths, so it is best to just bail out now. if (is_fixed) return false; // std::cerr << "****** UnimapEdgeMove::update" << std::endl; ChainManagerShPtr p = chain_mgr.lock(); PHYCAS_ASSERT(p); //likelihood->fullRemapping(tree, rng, true); ///@TEMP!!!! proposeNewState(); PartitionModelShPtr partModel = likelihood->getPartitionModel(); const unsigned nSubsets = partModel->getNumSubsets(); std::vector<double> uniformization_lambda(nSubsets); for (unsigned i = 0; i < nSubsets; ++i) { ModelShPtr subMod = partModel->getModel(i); uniformization_lambda[i] = subMod->calcUniformizationLambda(); } bool is_internal_edge = origNode->IsInternal(); double prev_ln_prior = (is_internal_edge ? p->calcInternalEdgeLenPriorUnnorm(origEdgelen) : p->calcExternalEdgeLenPriorUnnorm(origEdgelen)); double curr_edgelen = r*origEdgelen; double curr_ln_prior = (is_internal_edge ? p->calcInternalEdgeLenPriorUnnorm(curr_edgelen) : p->calcExternalEdgeLenPriorUnnorm(curr_edgelen)); double log_posterior_ratio = 0.0; const double log_prior_ratio = curr_ln_prior - prev_ln_prior; double log_likelihood_ratio = (double)mdot*log(r); const double edgeLenDiff = (curr_edgelen - origEdgelen); for (unsigned i = 0; i < nSubsets; ++i) { const unsigned numSites = partModel->getNumSites(i); const double ul = uniformization_lambda[i]; PHYCAS_ASSERT(ul > 0.0); log_likelihood_ratio -= numSites*ul*edgeLenDiff; } likelihood->incrementNumLikelihoodEvals(); if (is_standard_heating) log_posterior_ratio = heating_power*(log_likelihood_ratio + log_prior_ratio); else log_posterior_ratio = heating_power*log_likelihood_ratio + log_prior_ratio; double ln_accept_ratio = log_posterior_ratio + getLnHastingsRatio(); double lnu = std::log(rng->Uniform(FILE_AND_LINE)); /* std::cerr << " log_likelihood_ratio = " << log_likelihood_ratio << '\n'; std::cerr << " log_posterior_ratio = " << log_posterior_ratio << '\n'; std::cerr << " ln_accept_ratio = " << ln_accept_ratio << '\n'; */ if (ln_accept_ratio >= 0.0 || lnu <= ln_accept_ratio) { p->setLastLnPrior(p->getLastLnPrior() + log_prior_ratio); p->setLastLnLike(p->getLastLnLike() + log_likelihood_ratio); accept(); return true; } else { curr_ln_like = p->getLastLnLike(); curr_ln_prior = p->getLastLnPrior(); revert(); return false; } #else return true; #endif }
/*---------------------------------------------------------------------------------------------------------------------- | 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; }