Now that we’ve created the PolytomyUpdater
class, we need to insert it into the updater rotation. Start by including the polytomy_updater.hpp header near the top of the chain.hpp.
#pragma once
#include <memory>
#include <boost/format.hpp>
#include "lot.hpp"
#include "data.hpp"
#include "tree.hpp"
#include "model.hpp"
#include "likelihood.hpp"
#include "tree_manip.hpp"
#include "updater.hpp"
#include "gamma_ratevar_updater.hpp"
#include "omega_updater.hpp"
#include "pinvar_updater.hpp"
#include "statefreq_updater.hpp"
#include "exchangeability_updater.hpp"
#include "subset_relrate_updater.hpp"
#include "tree_updater.hpp"
<span style="color:#0000ff"><strong>#include "polytomy_updater.hpp"</strong></span>
#include "tree_length_updater.hpp"
In the setTreeFromNewick
function, make the last argument to buildFromNewick
equal to true so that polytomies are allowed when creating (for example) the starting tree.
inline void Chain::setTreeFromNewick(std::string & newick) {
assert(_updaters.size() > 0);
if (!_tree_manipulator)
_tree_manipulator.reset(new TreeManip);
<span style="color:#0000ff"><strong>_tree_manipulator->buildFromNewick(newick, false, true);</strong></span>
for (auto u : _updaters)
u->setTreeManip(_tree_manipulator);
}
Add the highlighted lines to the createUpdaters
function to add PolytomyUpdater
to the list of updaters potentially called during an MCMC iteration.
inline unsigned Chain::createUpdaters(Model::SharedPtr model, Lot::SharedPtr lot, Likelihood::SharedPtr likelihood) {
_model = model;
_lot = lot;
_updaters.clear();
double wstd = 1.0;
double wtreelength = 1.0;
double wtreetopology = 19.0;
<span style="color:#0000ff"><strong>double wpolytomy = 0.0;</strong></span>
double sum_weights = 0.0;
<span style="color:#0000ff"><strong>if (_model->isAllowPolytomies()) {</strong></span>
<span style="color:#0000ff"><strong>wstd = 1.0;</strong></span>
<span style="color:#0000ff"><strong>wtreelength = 2.0;</strong></span>
<span style="color:#0000ff"><strong>wtreetopology = 9.0;</strong></span>
<span style="color:#0000ff"><strong>wpolytomy = 9.0;</strong></span>
<span style="color:#0000ff"><strong>}</strong></span>
//...
// Add tree updater and tree length updater to _updaters
if (!_model->isFixedTree()) {
double tree_length_shape = 1.0;
double tree_length_scale = 10.0;
double dirichlet_param = 1.0;
Updater::SharedPtr u = TreeUpdater::SharedPtr(new TreeUpdater());
u->setLikelihood(likelihood);
u->setLot(lot);
u->setLambda(0.5);
u->setTargetAcceptanceRate(0.3);
u->setPriorParameters({tree_length_shape, tree_length_scale, dirichlet_param});
<span style="color:#0000ff"><strong>u->setTopologyPriorOptions(_model->isResolutionClassTopologyPrior(), _model->getTopologyPriorC());</strong></span>
u->setWeight(wtreetopology); sum_weights += wtreetopology;
_updaters.push_back(u);
<span style="color:#0000ff"><strong>if (_model->isAllowPolytomies()) {</strong></span>
<span style="color:#0000ff"><strong>Updater::SharedPtr u = PolytomyUpdater::SharedPtr(new PolytomyUpdater());</strong></span>
<span style="color:#0000ff"><strong>u->setLikelihood(likelihood);</strong></span>
<span style="color:#0000ff"><strong>u->setLot(lot);</strong></span>
<span style="color:#0000ff"><strong>u->setLambda(0.05);</strong></span>
<span style="color:#0000ff"><strong>u->setTargetAcceptanceRate(0.5);</strong></span>
<span style="color:#0000ff"><strong>u->setPriorParameters({tree_length_shape, tree_length_scale, dirichlet_param});</strong></span>
<span style="color:#0000ff"><strong>u->setTopologyPriorOptions(_model->isResolutionClassTopologyPrior(), _model->getTopologyPriorC());</strong></span>
<span style="color:#0000ff"><strong>u->setWeight(wpolytomy); sum_weights += wpolytomy;</strong></span>
<span style="color:#0000ff"><strong>_updaters.push_back(u);</strong></span>
<span style="color:#0000ff"><strong>}</strong></span>
u = TreeLengthUpdater::SharedPtr(new TreeLengthUpdater());
u->setLikelihood(likelihood);
u->setLot(lot);
u->setLambda(0.2);
u->setTargetAcceptanceRate(0.3);
u->setPriorParameters({tree_length_shape, tree_length_scale, dirichlet_param});
<span style="color:#0000ff"><strong>u->setTopologyPriorOptions(_model->isResolutionClassTopologyPrior(), _model->getTopologyPriorC());</strong></span>
u->setWeight(wtreelength); sum_weights += wtreelength;
_updaters.push_back(u);
}
for (auto u : _updaters) {
u->calcProb(sum_weights);
}
return (unsigned)_updaters.size();
}
We must not let either the TreeLengthUpdator
nor the PolytomyUpdater
contribute to the calculation of the joint prior because TreeUpdater
is already handling the tree topology and edge length components of the joint prior.
inline double Chain::calcLogJointPrior() const {
double lnP = 0.0;
for (auto u : _updaters) {
<span style="color:#0000ff"><strong>if (u->_name != "Tree Length" && u->_name != "Polytomies" )</strong></span>
lnP += u->calcLogPrior();
}
return lnP;
}