Beispiel #1
0
/*----------------------------------------------------------------------------------------------------------------------
|	Computes the joint log working prior over all edges in the associated tree.
*/
double TreeScalerMove::recalcWorkingPriorForMove(
  bool using_tree_length_prior,         /*< true if using the Ranalla-Yang tree length prior */
  bool using_vartopol_prior) const     /*< true if using the Holder et al. variable topology reference distribution */
	{
    double ln_ref_dist = 0.0;
    if (using_tree_length_prior)
        {
        ln_ref_dist = likelihood->getTreeLengthRefDist()->GetLnPDF(tree);
        }
    else if (using_vartopol_prior)
        {
        // Computes the log of the probability of the tree under Mark Holder's variable tree topology reference distribution
        PHYCAS_ASSERT(topo_prob_calc);
        std::pair<double, double> treeprobs = topo_prob_calc->CalcTopologyLnProb(*tree, true);
        const double ln_ref_topo = treeprobs.first;
        const double ln_ref_edges = treeprobs.second;
        ln_ref_dist = ln_ref_topo + ln_ref_edges;
        }
    else
        {
        // Loop through all EdgeLenMasterParam objects and call the recalcWorkingPrior function of each.
        // Each EdgeLenMasterParam object knows how to compute the working prior for the edge lengths it controls.
        ChainManagerShPtr p = chain_mgr.lock();
        const MCMCUpdaterVect & edge_length_params = p->getEdgeLenParams();
        for (MCMCUpdaterVect::const_iterator it = edge_length_params.begin(); it != edge_length_params.end(); ++it)
            {
            if (!(*it)->isFixed())
                ln_ref_dist += (*it)->recalcWorkingPrior();
            }
        }

	return ln_ref_dist;
	}
Beispiel #2
0
/*----------------------------------------------------------------------------------------------------------------------
|	Reverses move made in proposeNewState.
*/
void TreeScalerMove::revert()
	{
	MCMCUpdater::revert();
    tree->ScaleAllEdgeLens(reverse_scaler);

    likelihood->useAsLikelihoodRoot(NULL);
    likelihood->storeAllCLAs(tree);	// force CLAs to be recalculated

	ChainManagerShPtr p = chain_mgr.lock();
	PHYCAS_ASSERT(p);
    JointPriorManagerShPtr jpm = p->getJointPriorManager();
    jpm->allEdgeLensModified(tree);
    curr_ln_prior = jpm->getLogJointPrior();
	}
/*----------------------------------------------------------------------------------------------------------------------
|	Chooses a random edge and changes its current length m to a new length m* using the following formula, where `lambda' is
|	a tuning parameter.
|>
|	m* = m*exp(lambda*(r.Uniform() - 0.5))
|>
*/
void LargetSimonMove::starTreeProposeNewState()
	{
	// Choose edge randomly.
	//
	unsigned numEdges = tree->GetNNodes() - 1;
	unsigned k = rng->SampleUInt(numEdges);
	unsigned i = 0;
	//@POL this loop is crying out for the for_each algorithm
	for (orig_node = tree->GetFirstPreorder(); orig_node != NULL; orig_node = orig_node->GetNextPreorder())
		{
		// All nodes have an edge associated with them except for the root
		//
		if (!orig_node->IsTipRoot())
			{
			if (i == k)
				{
				orig_edge_len = orig_node->GetEdgeLen();
				break;
				}
			++i;
			}
		}

	// Modify the edge
	//
	double m		= orig_node->GetEdgeLen();
	double mstar	= m*std::exp(lambda*(rng->Uniform() - 0.5));
	orig_node->SetEdgeLen(mstar);

	// Invalidate CLAs to ensure next likelihood calculation will be correct
	orig_node->SelectNode();
	TreeNode * nd = orig_node->IsTip() ? orig_node->GetParent() : orig_node;
	PHYCAS_ASSERT(nd->IsInternal());
	likelihood->useAsLikelihoodRoot(nd);
	likelihood->invalidateAwayFromNode(*orig_node);
	likelihood->invalidateBothEnds(orig_node);

    ChainManagerShPtr p = chain_mgr.lock();
	PHYCAS_ASSERT(p);
    JointPriorManagerShPtr jpm = p->getJointPriorManager();
    jpm->allEdgeLensModified(tree);
    //jpm->externalEdgeLensModified("external_edgelen", tree);
	}
Beispiel #4
0
/*----------------------------------------------------------------------------------------------------------------------
|	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;
}
/*----------------------------------------------------------------------------------------------------------------------
|	Reverses move made in proposeNewState. Assumes ndX, ndY, and ndZ are non-NULL, which will be true if proposeNewState
|	was just called.
*/
void LargetSimonMove::revert()
	{
    ChainManagerShPtr p = chain_mgr.lock();
	PHYCAS_ASSERT(p);
    JointPriorManagerShPtr jpm = p->getJointPriorManager();

	MCMCUpdater::revert();
	if (star_tree_proposal)
		{
		orig_node->SetEdgeLen(orig_edge_len);
		TreeNode * nd = orig_node->IsTip() ? orig_node->GetParent() : orig_node;
		PHYCAS_ASSERT(nd->IsInternal());
		likelihood->useAsLikelihoodRoot(nd);
		likelihood->restoreFromCacheAwayFromNode(*orig_node);
		likelihood->restoreFromCacheParentalOnly(orig_node);

		orig_node->UnselectNode();
        jpm->allEdgeLensModified(tree);
        //jpm->externalEdgeLensModified("external_edgelen", tree);
		}
	else
		{
		PHYCAS_ASSERT(ndX != NULL);
		PHYCAS_ASSERT(ndY != NULL);
		PHYCAS_ASSERT(ndZ != NULL);
		PHYCAS_ASSERT(topol_changed ? (swap1 != NULL && swap2 != NULL) : (swap1 == NULL && swap2 == NULL));

		if (topol_changed)
			{
			if (swap2 == ndZ)
				{
				// If swap2 equals ndZ, then swap2 was a child of ndBase and we were able to use
				// the standard NNISwap function to swap the two nodes
				//
				tree_manipulator.NNISwap(swap1, swap2);
				}
			else
				{
				// If swap2 is ndZ's parent, then swap2 is ndBase (i.e. it is the "child" node below the
				// lower of the two adjacent internal nodes involved in the swap) and we had to use the
				// NNISwapSpecial function to perform the rearrangment
				//
				tree_manipulator.NNISwapSpecial(swap1);
                likelihood->swapInternalDataAndEdgeLen(ndY, ndZ);
				}
			}
		ndX->SetEdgeLen(x);
		ndY->SetEdgeLen(y);
		ndZ->SetEdgeLen(z);

		PHYCAS_ASSERT(ndY->IsInternal());
        if (!likelihood->getNoData())
            {
            likelihood->useAsLikelihoodRoot(ndY);
            likelihood->restoreFromCacheAwayFromNode(*ndY);
            likelihood->restoreFromCacheParentalOnly(ndY);
            }

		ndX->UnselectNode();
		ndY->UnselectNode();
		ndZ->UnselectNode();

        jpm->allEdgeLensModified(tree);
        if (topol_changed)
            jpm->topologyModified("tree_topology", tree);
		}

    curr_ln_prior = jpm->getLogJointPrior();

	reset();
	}
/*----------------------------------------------------------------------------------------------------------------------
|	Performs a local perturbation using a generalization of the algorithm "LOCAL Without a Molecular Clock" described by
|	Larget and Simon (1999. Mol. Biol. Evol. 16(6): 750-759). This version allows polytomies (except the case of the
|	star tree, for which the required three-contiguous-edge segment cannot be identified).
|
|	     X  c  d
|	      \ | /
|          \|/
|	  a  b  Y
|	   \ | /
|	    \|/
|	     u
|	     |
|	     Z <-- may or may not be the tip at which tree is rooted
|
|	Pick a random interior node Y whose parent is not the root (i.e. avoid the subroot node directly connected to the
|	tip node at which the tree is rooted. Let u be the parent of y. Let Z be a randomly-chosen child of u (note that in
|	this case u's parent is considered a "child" of u). In the figure above, we (by chance) chose the parent of u to be
|	Z, but we could have chosen any of u's real children (except Y). a and b are the other "children" of u, not
|	including Y. Let X be a randomly chosen child of Y (and here a "child" is really a child). c and d are the other
|	children of Y.
|
|	      a   b   c   d
|	       \ /     \ /
|	Z ===== u ===== Y ===== X
|
|	The path represented by the double line above is either contracted or expanded by a factor m*, where
|
|	m* = m*exp(lambda*(r.Uniform() - 0.5))
|
|	Then, one of {u, Y} is chosen at random to move. Let's say for illustration that u was chosen. u is moved (along
|	with a and c) to a random point along the main path from Z to X. If this makes the node u cross over node Y, then
|	the equivalent of an NNI rearrangement is effected:
|
|	    X  c  d          X  a  b
|	     \ | /            \ | /    In this case, invalidate CLAs away from u and
|         \|/              \|/     make u the likelihood root
|	 a  b  Y          c  d  u
|	  \ | /   -->      \ | /
|	   \|/              \|/
|	    u                Y
|	    |                |
|	    Z                Z
|
|	If there is no NNI rearrangement, the move will only require adjusting edge lengths. In this case, invalidate CLAs
|	away from Y and make Y the likelihood root.
*/
void LargetSimonMove::defaultProposeNewState()
	{
	double xstar, ystar, zstar;

    ChainManagerShPtr p = chain_mgr.lock();
    PHYCAS_ASSERT(p);
    JointPriorManagerShPtr jpm = p->getJointPriorManager();

	// Make sure all the necessary shared pointers have been set to something meaningful
	PHYCAS_ASSERT(rng);
	PHYCAS_ASSERT(tree);
	PHYCAS_ASSERT(model);
	PHYCAS_ASSERT(likelihood);

	// Begin by resetting all the data members involved with reverting a move
	reset();

	// Select an internal node whose parent is not the root node to serve as ndY,
    // whose branch will form the middle segment in the path of three contiguous
    // segments to be modified.
    ndY = randomInternalAboveSubroot();
	y = ndY->GetEdgeLen();

	// Set ndX equal to a randomly-chosen child of ndY
	ndX = randomChild(ndY);
	x = ndX->GetEdgeLen();

	// Set ndZ randomly to either the parent of ndY or one of ndY's sibs
    ndZ = chooseZ(ndY);
    z = ndZ->GetEdgeLen();

    // Set ndBase to the deepest affected node
	//ndBase = ndZ->GetParent();

    // Set node U to the other node (besides ndY) that could slide.
    // Note that U may or may not be equal to ndZ.
    TreeNode * ndU = ndY->GetParent();

	m = x + y + z;
    expand_contract_factor = exp(lambda*(rng->Uniform() - 0.5));
	mstar = m*expand_contract_factor;

	xstar = x*expand_contract_factor;
	ndX->SetEdgeLen(xstar);

    ystar = y*expand_contract_factor;
	ndY->SetEdgeLen(ystar);

    zstar = z*expand_contract_factor;
	ndZ->SetEdgeLen(zstar);

	double d = rng->Uniform()*mstar;

	// Decide whether to move ndY a distance d from the top, or
    // move ndU a distance d from the bottom
	bool moving_Y = true;
	if (rng->Uniform() < 0.5)
		moving_Y = false;
	bool moving_U = !moving_Y;

    // Determine whether proposed move will change the topology
    topol_changed = false;
    if (moving_Y && d >= xstar + ystar)
        topol_changed = true;
    if (moving_U && d >= ystar + zstar)
        topol_changed = true;

	if (topol_changed)
		{
        jpm->allEdgeLensModified(tree);
        jpm->topologyModified("tree_topology", tree);
        //jpm->externalEdgeLensModified("external_edgelen", tree);
        //jpm->internalEdgeLensModified("internal_edgelen", tree);
        if (moving_Y)
            {
            double f = (d - xstar - ystar)/zstar;
            if (ndU == ndZ)
                {
                which_case = 6;

                //ndX->SelectNode();
                //ndY->SelectNode();
                //ndZ->SelectNode();
                //std::string titlestr = str(boost::format("%s, %s: f = %.8f, d = %.8f, r = %.8f, x = %.8f, y = %.8f, z = %.8f") % (moving_Y ? "Y" : "U") % (topol_changed ? "nni" : "nul") % f % d % expand_contract_factor % x % y % z);
                //likelihood->startTreeViewer(tree, titlestr);

                likelihood->slideNode(-1.0, ndY, ndX);  // move all of Y's edge to base of X

                //titlestr = str(boost::format("Before NNISwapSpecial: x = %.8f, y = %.8f, z = %.8f") % ndX->GetEdgeLen() % ndY->GetEdgeLen() % ndZ->GetEdgeLen());
                //likelihood->startTreeViewer(tree, titlestr);

                swap1 = ndX;
			    swap2 = ndZ->GetParent();
			    tree_manipulator.NNISwapSpecial(swap1); // moves Y below Z
                likelihood->swapInternalDataAndEdgeLen(ndY, ndZ);

                //titlestr = str(boost::format("After NNISwapSpecial: x = %.8f, y = %.8f, z = %.8f") % ndX->GetEdgeLen() % ndY->GetEdgeLen() % ndZ->GetEdgeLen());
                //likelihood->startTreeViewer(tree, titlestr);

                likelihood->slideNode(1.0 - f, ndZ, ndY);

                //titlestr = str(boost::format("After final slideNode: x = %.8f, y = %.8f, z = %.8f") % ndX->GetEdgeLen() % ndY->GetEdgeLen() % ndZ->GetEdgeLen());
                //likelihood->startTreeViewer(tree, titlestr);
                }
            else
                {
                which_case = 3;
                likelihood->slideNode(-1.0, ndY, ndX);  // move all of Y's edge to base of X
    			swap1 = ndX;
	    		swap2 = ndZ;
    			tree_manipulator.NNISwap(swap1, swap2);  // nearest-neighbor interchange
                likelihood->slideNode(f, ndY, ndZ);  // move a fraction f of the basal part of Z's edge onto Y
                }
            }
        else
            {
            double f = (d - zstar - ystar)/xstar;   // positive f means slide ndU up past ndY toward ndX
            if (ndU == ndZ)
                {
                which_case = 12;

                //ndX->SelectNode();
                //ndY->SelectNode();
                //ndZ->SelectNode();
                //std::string titlestr = str(boost::format("%s, %s: f = %.8f, d = %.8f, r = %.8f, x = %.8f, y = %.8f, z = %.8f") % (moving_Y ? "Y" : "U") % (topol_changed ? "nni" : "nul") % f % d % expand_contract_factor % x % y % z);
                //likelihood->startTreeViewer(tree, titlestr);

                likelihood->slideNode(-1.0, ndZ, ndY);  // move all of Z's edge to base of Y
			    swap1 = ndX;
			    swap2 = ndZ->GetParent();
			    tree_manipulator.NNISwapSpecial(swap1); // moves Y below Z
                likelihood->swapInternalDataAndEdgeLen(ndY, ndZ);

                //titlestr = str(boost::format("After NNISwapSpecial: x = %.8f, y = %.8f, z = %.8f") % ndX->GetEdgeLen() % ndY->GetEdgeLen() % ndZ->GetEdgeLen());
                //likelihood->startTreeViewer(tree, titlestr);

                likelihood->slideNode(f, ndY, ndX); // move a fraction f of the basal part of X's edge onto Y

                //titlestr = str(boost::format("After slideNode: x = %.8f, y = %.8f, z = %.8f") % ndX->GetEdgeLen() % ndY->GetEdgeLen() % ndZ->GetEdgeLen());
                //likelihood->startTreeViewer(tree, titlestr);
                }
            else
                {
                which_case = 9;
                likelihood->slideNode(-1.0, ndY, ndZ);  // move all of Y's edge to base of Z
                likelihood->slideNode(f, ndY, ndX);     // move a fraction f of the basal part of X's edge onto Y
    			swap1 = ndX;
	    		swap2 = ndZ;
    			tree_manipulator.NNISwap(swap1, swap2);  // nearest-neighbor interchange
                }
            }
        }
    else    // topol_changed
        {
        jpm->allEdgeLensModified(tree);
        //jpm->externalEdgeLensModified("external_edgelen", tree);
        //jpm->internalEdgeLensModified("internal_edgelen", tree);
        if (moving_Y)
            {
            if (d < xstar)
                {
                // sliding Y up
                if (ndU == ndZ)
                    which_case = 4;
                else
                    which_case = 1;
                double f = (xstar - d)/xstar;   // positive f means slide ndY up
                likelihood->slideNode(f, ndY, ndX); // slide ndY up a fraction f into ndX's edge
                }
            else
                {
                // sliding Y down
                if (ndU == ndZ)
                    which_case = 5;
                else
                    which_case = 2;
                double f = -(d - xstar)/ystar;  // negative f means slide ndY down
                likelihood->slideNode(f, ndY, ndX); // slide ndY down a fraction f into its own edge
                }
            }
        else // moving U
            {
            if (d < zstar)
                {
                // sliding U down
                if (ndU == ndZ)
                    {
                    which_case = 11;
                    double f = -(zstar - d)/zstar;   // negative f means slide ndZ down
                    likelihood->slideNode(f, ndZ, ndY); // slide ndZ down a fraction f into its own edge
                    }
                else
                    {
                    which_case = 8;
                    double f = -(zstar - d)/zstar;  // negative f means slide ndU down
                    likelihood->slideNode(f, ndZ, ndY); // slide ndU "down" a fraction f into ndZ's edge
                    }
                }
            else
                {
                // sliding U up
                if (ndU == ndZ)
                    {
                    which_case = 10;
                    double f = (d - zstar)/ystar;   // positive f means slide ndZ up
                    likelihood->slideNode(f, ndZ, ndY); // slide ndZ up a fraction f into ndY's edge
                    }
                else
                    {
                    which_case = 7;
                    double f = (d - zstar)/ystar;   // positive f means slide ndU up

                    //ndX->SelectNode();
                    //ndY->SelectNode();
                    //ndZ->SelectNode();
                    //std::string titlestr = str(boost::format("Before slideNode: %s, %s: f = %.8f, d = %.8f, r = %.8f, x = %.8f, y = %.8f, z = %.8f") % (moving_Y ? "Y" : "U") % (topol_changed ? "nni" : "nul") % f % d % expand_contract_factor % ndX->GetEdgeLen() % ndY->GetEdgeLen() % ndZ->GetEdgeLen());
                    //likelihood->startTreeViewer(tree, titlestr);

                    likelihood->slideNode(f, ndZ, ndY); // slide ndU up a fraction f into ndY's edge

                    //titlestr = str(boost::format("After slideNode: %s, %s: f = %.8f, d = %.8f, r = %.8f, x = %.8f, y = %.8f, z = %.8f") % (moving_Y ? "Y" : "U") % (topol_changed ? "nni" : "nul") % f % d % expand_contract_factor % ndX->GetEdgeLen() % ndY->GetEdgeLen() % ndZ->GetEdgeLen());
                    //likelihood->startTreeViewer(tree, titlestr);
                    }
                }
            }
        }

	ndX->SelectNode();
	ndY->SelectNode();
	ndZ->SelectNode();
	PHYCAS_ASSERT(ndY->IsInternal());
    if (!likelihood->getNoData())
        {
        likelihood->useAsLikelihoodRoot(ndY);
        likelihood->invalidateAwayFromNode(*ndY);
        likelihood->invalidateBothEnds(ndY);

        //@POL temp
        //likelihood->invalidateBothEnds(ndZ);
        }
	}
/*----------------------------------------------------------------------------------------------------------------------
|	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;
	}
Beispiel #8
0
/*----------------------------------------------------------------------------------------------------------------------
|	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;
	}
Beispiel #9
0
/*----------------------------------------------------------------------------------------------------------------------
|	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
}
Beispiel #10
0
/*----------------------------------------------------------------------------------------------------------------------
|	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;
	}