/**
 * Constructor
 *
 * Here we simply allocate and initialize the move object.
 *
 * \param[in]    w   The weight how often the proposal will be used (per iteration).
 * \param[in]    t   If auto tuning should be used.
 */
MetropolisHastingsMove::MetropolisHastingsMove( Proposal *p, double w, bool t ) : AbstractMove(w,t),
    affectedNodes(),
    nodes(),
    numAccepted( 0 ),
    proposal( p )
{
    nodes = proposal->getNodes();

    for (std::set<DagNode*>::iterator it = nodes.begin(); it != nodes.end(); ++it)
    {
        // get the pointer to the current node
        DagNode* theNode = *it;

        // add myself to the set of moves
        theNode->addMove( this );

        // increase the DAG node reference count because we also have a pointer to it
        theNode->incrementReferenceCount();

        // get the affected nodes if we would update this node
        // then we don't need to get the affected nodes every time again
        theNode->getAffectedNodes( affectedNodes );
    }

    // remove all "core" nodes from affectedNodes so their probabilities are not double-counted
    for (size_t i = 0; i < affectedNodes.size(); ++i)
    {
        std::set<DagNode*>::iterator it = affectedNodes.begin();
        std::advance(it, i);

        if ( nodes.find(*it) != nodes.end() )
        {
            affectedNodes.erase(*it);
            --i;
        }
    }
}
Esempio n. 2
0
/**
 * Swap the current variable for a new one.
 *
 * \param[in]     oldN     The old variable that needs to be replaced.
 * \param[in]     newN     The new variable.
 */
void AbstractMove::swapNode(DagNode *oldN, DagNode *newN)
{
    
    // find the old node
    
    for (size_t i = 0; i < nodes.size(); ++i)
    {
        // get the pointer to the current node
        DagNode* theNode = nodes[i];
        if ( theNode == oldN )
        {
            nodes[i] = newN;
        }
        
    }
    
    // remove myself from the old node and add myself to the new node
    oldN->removeMove( this );
    newN->addMove( this );
    
    // increment and decrement the reference counts
    newN->incrementReferenceCount();
    if ( oldN->decrementReferenceCount() == 0 )
    {
        throw RbException("Memory leak in Metropolis-Hastings move. Please report this bug to Sebastian.");
    }
    
    affectedNodes.clear();
    
    for (std::vector<DagNode*>::iterator it = nodes.begin(); it != nodes.end(); ++it)
    {
        // get the pointer to the current node
        DagNode* theNode = *it;
        
        // get the affected nodes if we would update this node
        // then we don't need to get the affected nodes every time again
        theNode->getAffectedNodes( affectedNodes );
    }
    
    // remove all "core" nodes from affectedNodes so their probabilities are not double-counted
    for (size_t i = 0; i < affectedNodes.size(); ++i)
    {
        RbOrderedSet<DagNode*>::iterator it = affectedNodes.begin();
        std::advance(it, i);
        
        for (size_t j = 0; j < nodes.size(); ++j)
        {
            if ( nodes[j] == *it )
            {
                affectedNodes.erase(*it);
                --i;
                break;
            }
            
        }
        
    }
    
    swapNodeInternal(oldN, newN);
    
}