/*---------------------------------------------------------------------------------------------------------------------- | 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; }