Esempio n. 1
0
/*--------------------------------------------------------------------------------------------------------------------------
|	Called if the move is accepted.
*/
void LargetSimonMove::accept()
	{
	MCMCUpdater::accept();
	if (star_tree_proposal)
		{
		TreeNode * nd = orig_node->IsTip() ? orig_node->GetParent() : orig_node;
		PHYCAS_ASSERT(nd->IsInternal());
        if (!likelihood->getNoData())
            {
            likelihood->useAsLikelihoodRoot(nd);
            likelihood->discardCacheAwayFromNode(*orig_node);
            likelihood->discardCacheBothEnds(orig_node);
            }

		orig_node->UnselectNode();
		}
	else
		{
		PHYCAS_ASSERT(ndY->IsInternal());
        if (!likelihood->getNoData())
            {
            likelihood->useAsLikelihoodRoot(ndY);
            likelihood->discardCacheAwayFromNode(*ndY);
            likelihood->discardCacheBothEnds(ndY);
            }

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

	reset();
	}
Esempio n. 2
0
/*----------------------------------------------------------------------------------------------------------------------
|	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);
	}
Esempio n. 3
0
/*----------------------------------------------------------------------------------------------------------------------
|   Selects an internal node at random from a discrete uniform distribution with the constraint that the returned node
|   is not equal to the subroot (the sole child of the tip node serving as the root).
*/
TreeNode * LargetSimonMove::randomInternalAboveSubroot()
    {
	// Avoiding the "subroot" node (only child of the tip serving as the root), so the number of
	// acceptable nodes is one fewer than the number of internal nodes
	unsigned numAcceptableNodes = tree->GetNInternals() - 1;

	unsigned ypos = rng->SampleUInt(numAcceptableNodes);
	unsigned i = 0;
    TreeNode * nd = tree->GetFirstPreorder();
	for (; nd != NULL; nd = nd->GetNextPreorder())
		{
		if (nd->IsInternal() && !nd->GetParentConst()->IsTipRoot())
			{
			if (i == ypos)
				break;
			++i;
			}
		}
	PHYCAS_ASSERT(nd->GetLeftChild() != NULL);
	PHYCAS_ASSERT(nd->GetParentConst() != NULL);
	PHYCAS_ASSERT(!nd->GetParent()->IsTipRoot());
    return nd;
    }
Esempio n. 4
0
/*----------------------------------------------------------------------------------------------------------------------
|	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();
	}