Example #1
0
double CompoundMove::performMove( double &probRatio ) {
    
    if (changed) 
    {
        throw RbException("Trying to execute a Compound moves twice without accept/reject in the meantime.");
    }
    changed = true;
    
    double hr = performCompoundMove();
    
    if ( hr != hr || hr == RbConstants::Double::inf ) 
    {
        return RbConstants::Double::neginf;
    }
    
    std::set<DagNode* > affectedNodes;
    for (std::set<DagNode*>::iterator it = nodes.begin(); it != nodes.end(); it++)
    {
        // touch each node
        (*it)->touch();
    
        // calculate the probability ratio for the node we just changed
        //std::cout << (*it)->getName() << " " << (*it)->getLnProbabilityRatio() << " " << (*it)->getLnProbability() << "\n";
            
        probRatio += (*it)->getLnProbabilityRatio();
 
        if ( probRatio != RbConstants::Double::inf && probRatio != RbConstants::Double::neginf )
        {
            // should contain unique nodes, since it is a set
            (*it)->getAffectedNodes(affectedNodes);
        }
    }
    
    for (std::set<DagNode*>::iterator it = nodes.begin(); it != nodes.end(); it++)
    {
//        if ( nodes.find(oldN) == nodes.end() ) {
//            throw RbException("Cannot replace DAG node in this move because the move doesn't hold this DAG node.");
//        }
        
        affectedNodes.erase( *it );
    }
    
    if ( probRatio != RbConstants::Double::inf && probRatio != RbConstants::Double::neginf )
    {
        for (std::set<DagNode* >::iterator i=affectedNodes.begin(); i!=affectedNodes.end(); ++i)
        {
            DagNode* theAffectedNode = *i;
            
            // do not double-count the prob ratio for any elt in both theNodes and affectedNodes
            //if ( find(theNodes.begin(), theNodes.end(), *i) == theNodes.end() )
            {
                //std::cout << "  " << theAffectedNode->getName() << "  " << theAffectedNode->getLnProbabilityRatio() <<  " " << theAffectedNode->getLnProbability() << "\n";
                probRatio += theAffectedNode->getLnProbabilityRatio();
            }
        }
    }

    
    return hr;
}
double AdmixtureEdgeReplaceResidualsFNPR::performMove( double &probRatio ) {
    
    
    if (changed) {
        throw RbException("Trying to execute a simple moves twice without accept/reject in the meantime.");
    }
    changed = true;
    
    double hr = performSimpleMove();
    
    if ( hr != hr || hr == RbConstants::Double::inf ) {
        return RbConstants::Double::neginf;
    }
    
    // touch the node
    variable->touch();
    probRatio = variable->getLnProbabilityRatio();
    
    if ( probRatio != RbConstants::Double::inf && probRatio != RbConstants::Double::neginf ) {
        
        std::set<DagNode* > affectedNodes;
        variable->getAffectedNodes(affectedNodes);
        for (std::set<DagNode* >::iterator i=affectedNodes.begin(); i!=affectedNodes.end(); ++i) {
            DagNode* theNode = *i;
            probRatio += theNode->getLnProbabilityRatio();
            //std::cout << theNode->getName() << "\t" << probRatio << "\n";
        }
    }
    
    return hr;
}
/** 
 * Monitor value at generation gen 
 */
void AbstractFileMonitor::monitorVariables(unsigned long gen)
{
        
    for (std::vector<DagNode*>::iterator i = nodes.begin(); i != nodes.end(); ++i)
    {
        // add a separator before every new element
        out_stream << separator;
            
        // get the node
        DagNode *node = *i;
            
        // print the value
        node->printValueElements(out_stream, separator, -1, true, flatten);
    }
    
}
double AdmixtureNearestNeighborInterchangeAndRateShift::performMove( double &probRatio ) {
    
    //std::cout << "NNI::performMove()\n";
    
    if (changed) {
   //;     throw RbException("Trying to execute a simple moves twice without accept/reject in the meantime.");
    }
    changed = true;
    
    double hr = performSimpleMove();
    
    if ( hr != hr || hr == RbConstants::Double::inf ) {
        return RbConstants::Double::neginf;
    }
    
    // touch the node
    variable->touch();

    // calculate the probability ratio for the node we just changed
    probRatio = variable->getLnProbabilityRatio();
    //std::cout << "n\t" << variable->getName() << "\t" << probRatio << "\n";
 
    if ( probRatio != RbConstants::Double::inf && probRatio != RbConstants::Double::neginf ) {
        
        if (!failed)
        {
            // these three rates should be touched due to setValue()
            branchRates[storedChildRateIndex]->touch();
            probRatio += branchRates[storedChildRateIndex]->getLnProbabilityRatio();
            branchRates[storedBrotherRateIndex]->touch();
            probRatio += branchRates[storedBrotherRateIndex]->getLnProbabilityRatio();
           // probRatio += branchRates[storedNodeRateIndex]->getLnProbabilityRatio();
           // std::cout << probRatio << "\n";
        }
    
        std::set<DagNode* > affectedNodes;
        variable->getAffectedNodes(affectedNodes);
        for (std::set<DagNode* >::iterator i=affectedNodes.begin(); i!=affectedNodes.end(); ++i) {
            DagNode* theNode = *i;
            probRatio += theNode->getLnProbabilityRatio();
            //std::cout << "\tch\t" << theNode->getName() << "\t" << theNode->getLnProbabilityRatio() << "  " <<  probRatio << "\n";
        }
    }
    //std::cout << "pr " << probRatio << "    hr " << hr << "\n";
    
    return hr;
}
double AdmixtureShiftTreeRates::performMove( double &probRatio ) {
    
    if (changed) {
        throw RbException("Trying to execute a simple moves twice without accept/reject in the meantime.");
    }
    changed = true;
    
    double hr = performSimpleMove();
    
    if ( hr != hr || hr == RbConstants::Double::inf ) {
        return RbConstants::Double::neginf;
    }
    
    // touch the node
    treeRate->touch();
    
    // calculate the probability ratio for the node we just changed
    probRatio = treeRate->getLnProbabilityRatio();
    //std::cout << "n\t" << treeRate->getName() << "\t" << probRatio << "\n";
    
    //for (size_t i = 0; i < branchRates.size(); i++)
    for (std::map<int,double>::iterator it = storedRates.begin(); it != storedRates.end(); it++)
    {
        int idx = it->first;
        branchRates[idx]->touch();
        probRatio += branchRates[idx]->getLnProbabilityRatio();
        //std::cout << "n\t" << branchRates[idx]->getName() << " " << branchRates[idx]->getLnProbability() << " " << exp(branchRates[idx]->getLnProbability()) << " " << probRatio << "\n";
    }
    
    if ( probRatio != RbConstants::Double::inf && probRatio != RbConstants::Double::neginf ) {
        
        std::set<DagNode* > affectedNodes;
        treeRate->getAffectedNodes(affectedNodes);
        for (std::set<DagNode* >::iterator i=affectedNodes.begin(); i!=affectedNodes.end(); ++i) {
            DagNode* theNode = *i;
            probRatio += theNode->getLnProbabilityRatio();
           // std::cout << "\tch\t" << theNode->getName() << "\t" << theNode->getLnProbabilityRatio() << "  " <<  probRatio << "\n";
        }
    }
    
    return hr;
}
double AdmixtureEdgeReplaceResidualWeights::performMove( double &probRatio ) {
    
    //std::cout << "\nAdmix Edge Replace\n";
    
    if (changed) {
        throw RbException("Trying to execute a simple moves twice without accept/reject in the meantime.");
    }
    changed = true;
    
    double hr = performSimpleMove();
    
    if ( hr != hr || hr == RbConstants::Double::inf || hr == RbConstants::Double::neginf ) {
        return RbConstants::Double::neginf;
    }
    
    // touch the node
    variable->touch(); // if previously touched, this will overwrite lnProb??
    probRatio = variable->getLnProbabilityRatio();
    //probRatio = 0.0;
    
    for (std::map<int,double>::iterator it = storedBranchRates.begin(); it != storedBranchRates.end(); it++)
    {
        branchRates[it->first]->touch();
        probRatio += branchRates[it->first]->getLnProbabilityRatio();
        //std::cout << branchRates[it->first]->getLnProbabilityRatio() << "\n";
    }

    if ( probRatio != RbConstants::Double::inf && probRatio != RbConstants::Double::neginf ) {
        
        std::set<DagNode* > affectedNodes;
        variable->getAffectedNodes(affectedNodes);
        for (std::set<DagNode* >::iterator i=affectedNodes.begin(); i!=affectedNodes.end(); ++i) {
            DagNode* theNode = *i;
            probRatio += theNode->getLnProbabilityRatio();
            //std::cout << probRatio << " " << theNode->getName() << "\t" << theNode->getLnProbability() << " " << theNode->getLnProbabilityRatio() << "\n";
        }
    }
   // std::cout << probRatio << "\n";

    
    return hr;
}
/**
 * Basic destructor doing nothing.
 */
MetropolisHastingsMove::~MetropolisHastingsMove( void )
{
    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->removeMove( this );

        // decrease the DAG node reference count because we also have a pointer to it
        if ( theNode->decrementReferenceCount() == 0 )
        {
            delete theNode;
        }

    }

    delete proposal;
}
double FossilSafeScaleMove::performMove( double &probRatio ) {
    
    if (changed)
    {
        throw RbException("Trying to execute a simple move twice without accept/reject in the meantime.");
    }
    changed = true;
    
    double hr = doMove();
    
    if ( hr != hr || hr == RbConstants::Double::inf )
    {
        return RbConstants::Double::neginf;
    }
    
    // touch the node
    scaler->touch();
    tree->touch();
    
    // calculate the probability ratio for the node we just changed
    probRatio = scaler->getLnProbabilityRatio();
    probRatio += tree->getLnProbabilityRatio();
    
    if ( probRatio != RbConstants::Double::inf && probRatio != RbConstants::Double::neginf )
    {
        
        std::set<DagNode* > affectedNodes;
        scaler->getAffectedNodes(affectedNodes);
        tree->getAffectedNodes(affectedNodes);
        for (std::set<DagNode* >::iterator i=affectedNodes.begin(); i!=affectedNodes.end(); ++i)
        {
            DagNode* theAffectedNode = *i;
            if (theAffectedNode != tree && theAffectedNode != scaler) {
                //std::cout << theAffectedNode->getName() << "  " << theAffectedNode->getLnProbabilityRatio() << " " << theAffectedNode->getLnProbability() << "\n";
                probRatio += theAffectedNode->getLnProbabilityRatio();
            }
        }
    }
    
    return hr;
}
Example #9
0
/**
 * 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.
 */
AbstractMove::AbstractMove( const std::vector<DagNode*> &n, double w, bool t ) :
    nodes( n ),
    affectedNodes( ),
    weight( w ),
    autoTuning( t )
{
    
    for (std::vector<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();
        
    }
    
    
    // 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;
            }
            
        }
        
    }
    
}
/**
 * Copy constructor.
 * We need to create a deep copy of the proposal here.
 *
 * \param[in]   m   The object to copy.
 *
 */
MetropolisHastingsMove::MetropolisHastingsMove(const MetropolisHastingsMove &m) : AbstractMove(m),
    affectedNodes( m.affectedNodes ),
    nodes( m.nodes ),
    numAccepted( m.numAccepted ),
    proposal( m.proposal->clone() )
{

    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();

    }

}
Example #11
0
/**
 * Basic destructor doing nothing.
 */
AbstractMove::~AbstractMove( void )
{
    
    // clean up my pointers to the nodes
    for (size_t i = 0; i < nodes.size(); ++i)
    {
        // get the pointer to the current node
        DagNode* theNode = nodes[i];
        
        // add myself to the set of moves
        theNode->removeMove( this );
        
        // decrease the DAG node reference count because we also have a pointer to it
        if ( theNode->decrementReferenceCount() == 0 )
        {
            delete theNode;
        }
        
    }
    
}
Example #12
0
AbstractMove::AbstractMove( const AbstractMove &m ) : Move( m ),
    nodes( m.nodes ),
    affectedNodes( m.affectedNodes ),
    weight( m.weight ),
    autoTuning( m.autoTuning  )
{
    
    
    for (size_t i = 0; i < nodes.size(); ++i)
    {
        // get the pointer to the current node
        DagNode* theNode = nodes[i];
        
        // 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();
        
    }
    
}
/**
 * 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;
        }
    }
}
/**
 * Overloaded assignment operator.
 * We need a deep copy of the operator.
 */
MetropolisHastingsMove& MetropolisHastingsMove::operator=(const RevBayesCore::MetropolisHastingsMove &m)
{

    if ( this != &m )
    {
        // free memory
        delete proposal;

        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->removeMove( this );

            // decrease the DAG node reference count because we also have a pointer to it
            if ( theNode->decrementReferenceCount() == 0 )
            {
                delete theNode;
            }

        }

        affectedNodes   = m.affectedNodes;
        nodes           = m.nodes;
        numAccepted     = m.numAccepted;
        proposal        = m.proposal->clone();


        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();

        }
    }

    return *this;
}
Example #15
0
/**
 * Overloaded assignment operator.
 * We need a deep copy of the operator.
 */
AbstractMove& AbstractMove::operator=(const RevBayesCore::AbstractMove &m)
{
    
    if ( this != &m )
    {
        // delegate
        Move::operator=(m);
        
        for (size_t i = 0; i < nodes.size(); ++i)
        {
            // get the pointer to the current node
            DagNode* theNode = nodes[i];
            
            // add myself to the set of moves
            theNode->removeMove( this );
            
            // decrease the DAG node reference count because we also have a pointer to it
            if ( theNode->decrementReferenceCount() == 0 )
            {
                delete theNode;
            }
            
        }
        
        affectedNodes   = m.affectedNodes;
        nodes           = m.nodes;
        
        
        for (size_t i = 0; i < nodes.size(); ++i)
        {
            // get the pointer to the current node
            DagNode* theNode = nodes[i];
            
            // 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();
            
        }
        
    }
    
    return *this;
}
Example #16
0
/**
 * Reset the currently monitored DAG nodes by extracting the DAG nodes from the model again 
 * and store this in the set of DAG nodes.
 */
void ModelMonitor::resetDagNodes( void )
{
    
    // for savety we empty our dag nodes
    nodes.clear();
    
    if ( model != NULL )
    {
        // we only want to have each nodes once
        // this should by default happen by here we check again
        std::set<std::string> varNames;
        
        const std::vector<DagNode*> &n = model->getDagNodes();
        for (std::vector<DagNode*>::const_iterator it = n.begin(); it != n.end(); ++it) 
        {
            
            DagNode *theNode = *it;
            
            // only simple numeric variable can be monitored (i.e. only integer and real numbers)
            if ( theNode->isSimpleNumeric() && !theNode->isClamped())
            {
                if ( (!stochasticNodesOnly && !theNode->isConstant() && theNode->getName() != "" && !theNode->isHidden() && !theNode->isElementVariable() ) || ( theNode->isStochastic() && !theNode->isClamped() && theNode->isHidden() == false  && theNode->isElementVariable() == false ) )
                {
                    const std::string &name = theNode->getName();
                    if ( varNames.find( name ) == varNames.end() )
                    {
                        nodes.push_back( theNode );
                        varNames.insert( name );
                    }
                    else
                    {
                        /*
                        std::cerr << "Trying to add variable with name '" << name << "' twice." << std::endl;
                         */
                    }
                }
            }
        
        }
    }
    
}
Example #17
0
/** Monitor value at generation gen */
void ScreenMonitor::monitor(unsigned long gen) {
    
    // get the printing frequency
    unsigned long samplingFrequency = printgen;
    
    if (gen % samplingFrequency == 0) {
        // print the iteration number first
        std::cout << gen;
        
        if ( posterior ) {
            // add a separator before every new element
            std::cout << separator;
            
            const std::vector<DagNode*> &n = model->getDagNodes();
            double pp = 0.0;
            for (std::vector<DagNode*>::const_iterator it = n.begin(); it != n.end(); ++it) {
                pp += (*it)->getLnProbability();
            }
            std::cout << pp;
        }
        
        if ( likelihood ) {
            // add a separator before every new element
            std::cout << separator;
            
            const std::vector<DagNode*> &n = model->getDagNodes();
            double pp = 0.0;
            for (std::vector<DagNode*>::const_iterator it = n.begin(); it != n.end(); ++it) {
                if ( (*it)->isClamped() ) {
                    pp += (*it)->getLnProbability();
                }
            }
            std::cout << pp;
        }
        
        if ( prior ) {
            // add a separator before every new element
            std::cout << separator;
            
            const std::vector<DagNode*> &n = model->getDagNodes();
            double pp = 0.0;
            for (std::vector<DagNode*>::const_iterator it = n.begin(); it != n.end(); ++it) {
                if ( !(*it)->isClamped() ) {
                    pp += (*it)->getLnProbability();
                }
            }
            std::cout << pp;
        }
        
        for (std::vector<DagNode*>::iterator i = nodes.begin(); i != nodes.end(); ++i) {
            // add a separator before every new element
            std::cout << separator;
            
            // get the node
            DagNode *node = *i;
            
            // print the value
            node->printValue(std::cout, separator);
        }
        
        std::cout << std::endl;
        
    }
}
Example #18
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);
    
}
Example #19
0
void HillClimber::initializeSampler( void )
{
    
    std::vector<DagNode *>& dagNodes = model->getDagNodes();
    std::vector<DagNode *> orderedStochNodes = model->getOrderedStochasticNodes(  );
    
    // Get rid of previous move schedule, if any
    if ( schedule )
    {
        delete schedule;
    }
    schedule = NULL;
    
    // Get initial lnProbability of model
    
    // first we touch all nodes so that the likelihood is dirty
    for (std::vector<DagNode *>::iterator i=dagNodes.begin(); i!=dagNodes.end(); i++)
    {
        
        DagNode *the_node = *i;
        the_node->setMcmcMode( true );
        the_node->setPriorOnly( false );
        the_node->touch();
        
    }
    
    
    int numTries    = 0;
    int maxNumTries = 100;
    double lnProbability = 0.0;
    for ( ; numTries < maxNumTries; numTries ++ )
    {
        // a flag if we failed to find a valid starting value
        bool failed = false;
        
        lnProbability = 0.0;
        for (std::vector<DagNode *>::iterator i=dagNodes.begin(); i!=dagNodes.end(); i++)
        {
            DagNode* node = (*i);
            node->touch();
            
            double lnProb = node->getLnProbability();
            
            if ( !RbMath::isAComputableNumber(lnProb) )
            {
                std::stringstream ss;
                ss << "Could not compute lnProb for node " << node->getName() << "." << std::endl;
                node->printValue( ss );
                ss << std::endl;
                RBOUT( ss.str() );
                
                // set the flag
                failed = true;
                
                break;
            }
            lnProbability += lnProb;
            
        }
        
        // now we keep all nodes so that the likelihood is stored
        for (std::vector<DagNode *>::iterator i=dagNodes.begin(); i!=dagNodes.end(); i++)
        {
            (*i)->keep();
        }
        
        if ( failed == true )
        {
            std::cout << "Drawing new initial states ... " << std::endl;
            for (std::vector<DagNode *>::iterator i=orderedStochNodes.begin(); i!=orderedStochNodes.end(); i++)
            {
                
                if ( !(*i)->isClamped() && (*i)->isStochastic() )
                {
                    (*i)->redraw();
                    (*i)->reInitialized();
                    
                }
                else if ( (*i)->isClamped() )
                {
                    // make sure that the clamped node also recompute their probabilities
                    (*i)->reInitialized();
                    (*i)->touch();
                }
                
            }
        }
        else
        {
            break;
        }
        
    }
    
    if ( numTries == maxNumTries )
    {
        std::stringstream msg;
        msg << "Unable to find a starting state with computable probability";
        if ( numTries > 1 )
        {
            msg << " after " << numTries << " tries";
        }
        throw RbException( msg.str() );
        
    }
    
    // Create the move scheduler
    if ( scheduleType == "sequential" )
    {
        schedule = new SequentialMoveSchedule( &moves );
    }
    else if ( scheduleType == "single" )
    {
        schedule = new SingleRandomMoveSchedule( &moves );
    }
    else
    {
        schedule = new RandomMoveSchedule( &moves );
    }
    
    generation = 0;
}