Example #1
0
RevBayesCore::TypedFunction<RevBayesCore::RateMap>* Func_generalRateMap::createFunction() const
{
    
    RevBayesCore::TypedDagNode<RevBayesCore::RateGenerator>* rm = static_cast<const RateGenerator&>( this->args[0].getVariable()->getRevObject() ).getDagNode();
    RevBayesCore::TypedDagNode<RevBayesCore::RbVector<double> >* rf = static_cast<const Simplex &>( this->args[1].getVariable()->getRevObject() ).getDagNode();
    unsigned nc = static_cast<const Natural&>( this->args[2].getVariable()->getRevObject() ).getValue();
    size_t ns = rm->getValue().getNumberOfStates();

    RevBayesCore::GeneralRateMapFunction* f = new RevBayesCore::GeneralRateMapFunction(ns, nc);
        
    if ( this->args[3].getVariable()->getRevObject().isType( ModelVector<RealPos>::getClassTypeSpec() ) )
    {
        RevBayesCore::TypedDagNode< RevBayesCore::RbVector<double> >* clockRates = static_cast<const ModelVector<RealPos> &>( this->args[3].getVariable()->getRevObject() ).getDagNode();
        
        //        // sanity check
        //        if ( (nNodes-1) != clockRates->getValue().size() )
        //        {
        //            throw RbException( "The number of clock rates does not match the number of branches" );
        //        }
        
        f->setClockRate( clockRates );
    }
    else
    {
        RevBayesCore::TypedDagNode<double>* clockRate = static_cast<const RealPos &>( this->args[3].getVariable()->getRevObject() ).getDagNode();
        f->setClockRate( clockRate );
    }
    
    f->setRateMatrix(rm);
    f->setRootFrequencies(rf);
    
    
    return f;
}
Example #2
0
/**
 * Create a new internal distribution object.
 *
 * This function simply dynamically allocates a new internal distribution object that can be 
 * associated with the variable. The internal distribution object is created by calling its
 * constructor and passing the distribution-parameters (other DAG nodes) as arguments of the 
 * constructor. The distribution constructor takes care of the proper hook-ups.
 *
 * \return A new internal distribution object.
 */
RevBayesCore::MultispeciesCoalescent* Dist_constPopMultispCoal::createDistribution( void ) const 
{
    
    // Get the parameters
    RevBayesCore::TypedDagNode<RevBayesCore::Tree>* st = static_cast<const TimeTree &>( species_tree->getRevObject() ).getDagNode();
    const std::vector<RevBayesCore::Taxon>      &t  = static_cast<const ModelVector<Taxon> &>( taxa->getRevObject() ).getValue();
    
    // get the number of nodes for the tree
    size_t n_nodes = st->getValue().getNumberOfNodes();
    
    
    RevBayesCore::MultispeciesCoalescent*   d = new RevBayesCore::MultispeciesCoalescent( st, t );
    
    if ( Ne->getRequiredTypeSpec().isDerivedOf( ModelVector<RealPos>::getClassTypeSpec() ) )
    {
        RevBayesCore::TypedDagNode< RevBayesCore::RbVector<double> >* ne_node = static_cast<const ModelVector<RealPos> &>( Ne->getRevObject() ).getDagNode();
        
        // sanity check
        if ( n_nodes != ne_node->getValue().size() )
        {
            throw RbException( "The number of effective population sizes does not match the number of branches." );
        }
        
        d->setNes( ne_node );
    }
    else
    {
        RevBayesCore::TypedDagNode<double>* ne_node = static_cast<const RealPos &>( Ne->getRevObject() ).getDagNode();
        d->setNe( ne_node );
    }
    d->redrawValue();
    
    return d;
}
RevBayesCore::InverseWishartDistribution* Dist_inverseWishart::createDistribution( void ) const {
    
    // get the parameters
    RevBayesCore::TypedDagNode<RevBayesCore::MatrixRealSymmetric>* sg = static_cast<const RealSymmetricMatrix &>( sigma->getRevObject() ).getDagNode();
    RevBayesCore::TypedDagNode<std::vector<double> >* dv = static_cast<const ModelVector<RealPos> &>( diagonal->getRevObject() ).getDagNode();
    RevBayesCore::TypedDagNode<double>* ka = static_cast<const RealPos&>( kappa->getRevObject() ).getDagNode();
    RevBayesCore::TypedDagNode<int>* deg = static_cast<const Natural &>( df->getRevObject()).getDagNode();
    RevBayesCore::TypedDagNode<int>* dm = static_cast<const Natural &>( dim->getRevObject()).getDagNode();
    
    RevBayesCore::InverseWishartDistribution* w    =  0;

    if (! sg->getValue().isNull())   {
        // parameter is sigma
        w = new RevBayesCore::InverseWishartDistribution( sg, deg );
    }
    else if (dm->getValue() == 0)    {
        // parameter is Diagonal(kappaVector))
        w = new RevBayesCore::InverseWishartDistribution( dv, deg );
    }
    else    { 
        // parameter is kappa * Id
        w = new RevBayesCore::InverseWishartDistribution( dm, ka, deg );
    }
    return w;
}
void Move_ElementSlide::constructInternalObject( void ) {
    // we free the memory first
    delete value;
    
    // now allocate a new vector-slide move
    double l = static_cast<const RealPos &>( delta->getRevObject() ).getValue();
    double w = static_cast<const RealPos &>( weight->getRevObject() ).getValue();
    RevBayesCore::TypedDagNode<RevBayesCore::RbVector<double> >* tmp = static_cast<const ModelVector<RealPos> &>( x->getRevObject() ).getDagNode();
    std::set<const RevBayesCore::DagNode*> p = tmp->getParents();
    std::vector< RevBayesCore::StochasticNode<double> *> n;
    for (std::set<const RevBayesCore::DagNode*>::const_iterator it = p.begin(); it != p.end(); ++it)
    {
        const RevBayesCore::StochasticNode<double> *theNode = dynamic_cast< const RevBayesCore::StochasticNode<double>* >( *it );
        if ( theNode != NULL )
        {
            n.push_back( const_cast< RevBayesCore::StochasticNode<double>* >( theNode ) );
        }
        else
        {
            throw RbException("Could not create a mvElementSlide because the node isn't a vector of stochastic nodes.");
        }
    }
    
    bool t = static_cast<const RlBoolean &>( tune->getRevObject() ).getValue();
    
    RevBayesCore::Proposal *prop = new RevBayesCore::ElementSlideProposal(n,l);
    value = new RevBayesCore::MetropolisHastingsMove(prop,w,t);
}
Example #5
0
RevBayesCore::InverseWishartDistribution* Dist_inverseWishart::createDistribution( void ) const
{
    
    // get the parameters
    RevBayesCore::TypedDagNode<RevBayesCore::MatrixReal>* sg = NULL;
    RevBayesCore::TypedDagNode<RevBayesCore::RbVector<double> >* dv = NULL;
    RevBayesCore::TypedDagNode<double>* ka = NULL;
    RevBayesCore::TypedDagNode<int>* deg = NULL;
    RevBayesCore::TypedDagNode<int>* dm = NULL;
    
    if ( sigma->getRevObject() != RevNullObject::getInstance() )
    {
        sg = static_cast<const MatrixRealSymmetric &>( sigma->getRevObject() ).getDagNode();
    }
    
    if ( diagonal->getRevObject() != RevNullObject::getInstance() )
    {
        dv = static_cast<const ModelVector<RealPos> &>( diagonal->getRevObject() ).getDagNode();
    }
    
    if ( kappa->getRevObject() != RevNullObject::getInstance() )
    {
        ka = static_cast<const RealPos&>( kappa->getRevObject() ).getDagNode();
    }
    
    if ( df->getRevObject() != RevNullObject::getInstance() )
    {
        deg = static_cast<const Natural &>( df->getRevObject()).getDagNode();
    }

    if ( dim->getRevObject() != RevNullObject::getInstance() )
    {
        dm = static_cast<const Natural &>( dim->getRevObject()).getDagNode();
    }
    
    RevBayesCore::InverseWishartDistribution* w =  NULL;

    if ( sg != NULL && sg->getValue().getDim() != 0 )
    {
        // parameter is sigma
        w = new RevBayesCore::InverseWishartDistribution( sg, deg );
    }
    else if (dm == NULL || dm->getValue() == 0)
    {
        // parameter is Diagonal(kappaVector))
        w = new RevBayesCore::InverseWishartDistribution( dv, deg );
    }
    else
    {
        // parameter is kappa * Id
        w = new RevBayesCore::InverseWishartDistribution( dm, ka, deg );
    }
    
    return w;
}
Example #6
0
void Move_SynchronizedVectorFixedSingleElementSlide::constructInternalObject( void )
{
    
    // we free the memory first
    delete value;
    
    // now allocate a new sliding move
    double l = static_cast<const RealPos &>( lambda->getRevObject() ).getValue();
    double w = static_cast<const RealPos &>( weight->getRevObject() ).getValue();
    
    RevBayesCore::TypedDagNode<RevBayesCore::RbVector<RevBayesCore::RbVector<double> > >* tmp = static_cast<const ModelVector<ModelVector<RealPos> > &>( v->getRevObject() ).getDagNode();
    std::vector<const RevBayesCore::DagNode*> par = tmp->getParents();
    std::vector< RevBayesCore::StochasticNode<RevBayesCore::RbVector<double> > *> n;
    for (std::vector<const RevBayesCore::DagNode*>::const_iterator it = par.begin(); it != par.end(); ++it)
    {
        const RevBayesCore::StochasticNode<RevBayesCore::RbVector<double> > *the_node = dynamic_cast< const RevBayesCore::StochasticNode<RevBayesCore::RbVector<double> >* >( *it );
        if ( the_node != NULL )
        {
            n.push_back( const_cast< RevBayesCore::StochasticNode<RevBayesCore::RbVector<double> >* >( the_node ) );
        }
        else
        {
            throw RbException("Could not create a mvElementScale because the node isn't a vector of stochastic nodes.");
        }
    }
    
    
    bool t = static_cast<const RlBoolean &>( tune->getRevObject() ).getValue();
    
    std::vector<int> e;
    if ( which_element->getRevObject().isType( ModelVector<Natural>::getClassTypeSpec() ) )
    {
        e = static_cast<const ModelVector<Natural> &>( which_element->getRevObject() ).getValue();
    }
    else
    {
        int index = static_cast<const Natural &>( which_element->getRevObject() ).getValue();
        e.push_back( index );
    }
    
    // we need to offset the indices
    for (size_t i=0; i<e.size(); ++i)
    {
        --e[i];
    }

    
    RevBayesCore::Proposal *prop = new RevBayesCore::SynchronizedVectorFixedSingleElementSlideProposal(n, l, e);
    value = new RevBayesCore::MetropolisHastingsMove(prop, w, t);
    
}
/* Map calls to member methods */
RevLanguage::RevPtr<RevVariable> MultivariateRealNodeValTree::executeMethod(std::string const &name, const std::vector<Argument> &args, bool &found)
{
    
    if (name == "newick")
    {
        found = true;
        
        RevBayesCore::TypedDagNode< int >* k = static_cast<const Integer &>( args[0].getVariable()->getRevObject() ).getDagNode();
        std::string newick = this->dagNode->getValue().getNewick(k->getValue());
        return new RevVariable( new RlString( newick ) );
    }
    else if ( name == "clampAt" )
    {
        found = true;
        
        RevBayesCore::TypedDagNode< RevBayesCore::ContinuousCharacterData >* data = static_cast<const ContinuousCharacterData &>( args[0].getVariable()->getRevObject() ).getDagNode();
        RevBayesCore::TypedDagNode< int >* k = static_cast<const Integer &>( args[1].getVariable()->getRevObject() ).getDagNode();
        RevBayesCore::TypedDagNode< int >* l = static_cast<const Integer &>( args[2].getVariable()->getRevObject() ).getDagNode();
        RevBayesCore::ContinuousCharacterData* c = & data->getValue();
        
        this->dagNode->getValue().clampAt(c, k->getValue(), l->getValue());   
        return new RevVariable( new Real( 0 ) );
    }

    return ModelObject<RevBayesCore::MultivariateRealNodeContainer>::executeMethod( name, args, found );
}
Example #8
0
RevBayesCore::TypedFunction< RevBayesCore::RateGenerator >* Func_hky::createFunction( void ) const
{
    
    RevBayesCore::TypedDagNode< double >* ka = static_cast<const RealPos &>( this->args[0].getVariable()->getRevObject() ).getDagNode();
    RevBayesCore::TypedDagNode< RevBayesCore::RbVector<double> >* bf = static_cast<const Simplex &>( this->args[1].getVariable()->getRevObject() ).getDagNode();
    
    if ( bf->getValue().size() != 4 )
    {
        throw RbException("The HKY rate matrix can only use 4 base fequencies.");
    }
    
    RevBayesCore::HkyRateMatrixFunction* f = new RevBayesCore::HkyRateMatrixFunction( ka, bf );
    
    return f;
}
Example #9
0
/* Map calls to member methods */
RevLanguage::RevPtr<Variable> RealNodeValTree::executeMethod(std::string const &name, const std::vector<Argument> &args) {
    
    if ( name == "clampAt" )
    {
        RevBayesCore::TypedDagNode< RevBayesCore::AbstractCharacterData >* data = static_cast<const AbstractCharacterData &>( args[0].getVariable()->getRevObject() ).getDagNode();
        RevBayesCore::TypedDagNode< int >* k = static_cast<const Integer &>( args[1].getVariable()->getRevObject() ).getDagNode();
        RevBayesCore::AbstractCharacterData* d = & data->getValue();
        RevBayesCore::ContinuousCharacterData* c = static_cast<RevBayesCore::ContinuousCharacterData*>(d);
        
        this->dagNode->getValue().clampAt(c, k->getValue());   
        return new Variable( new Real( 0 ) );
    }

    return ModelObject<RevBayesCore::RealNodeContainer>::executeMethod( name, args );
}
Example #10
0
RevBayesCore::TypedFunction< RevBayesCore::RateGenerator >* Func_gtr::createFunction( void ) const
{
    
    RevBayesCore::TypedDagNode<RevBayesCore::RbVector<double> >* er = static_cast<const Simplex &>( this->args[0].getVariable()->getRevObject() ).getDagNode();
    RevBayesCore::TypedDagNode<RevBayesCore::RbVector<double> >* bf = static_cast<const Simplex &>( this->args[1].getVariable()->getRevObject() ).getDagNode();
    
    if ( er->getValue().size() != (bf->getValue().size() * (bf->getValue().size()-1) / 2.0) )
    {
        throw RbException("The dimension betwee the base frequencies and the substitution rates does not match.");
    }
    
    RevBayesCore::GtrRateMatrixFunction* f = new RevBayesCore::GtrRateMatrixFunction( er, bf );
    
    return f;
}
Example #11
0
RevBayesCore::TypedFunction< RevBayesCore::RateGenerator >* Func_epoch::createFunction( void ) const
{
    RevBayesCore::TypedDagNode< RevBayesCore::RbVector<RevBayesCore::RateGenerator> >* rm = static_cast<const ModelVector<RateGenerator> &>( this->args[0].getVariable()->getRevObject() ).getDagNode();
    RevBayesCore::TypedDagNode<RevBayesCore::RbVector<double> >* t = static_cast<const ModelVector<RealPos> &>( this->args[1].getVariable()->getRevObject() ).getDagNode();
    RevBayesCore::TypedDagNode<RevBayesCore::RbVector<double> >* r = static_cast<const ModelVector<RealPos> &>( this->args[2].getVariable()->getRevObject() ).getDagNode();

    
    // sanity check
    if ( t->getValue().size() != rm->getValue().size() )
    {
        throw RbException( "The number of rate matrices and epochs do not match" );
    }
    
    RevBayesCore::EpochRateMatrixFunction* f = new RevBayesCore::EpochRateMatrixFunction( rm, t, r );
    
    return f;
}
Example #12
0
RevBayesCore::TypedFunction< RevBayesCore::CladogeneticProbabilityMatrix >* Func_MixtureCladoProbs::createFunction( void ) const
{
    
    // supplied arguments
    RevBayesCore::TypedDagNode<RevBayesCore::RbVector<RevBayesCore::CladogeneticProbabilityMatrix> >* cp = static_cast<const ModelVector<CladogeneticProbabilityMatrix> &>( this->args[0].getVariable()->getRevObject() ).getDagNode();
    RevBayesCore::TypedDagNode<RevBayesCore::RbVector<double> >* ep = static_cast<const Simplex &>( this->args[1].getVariable()->getRevObject() ).getDagNode();
    
    size_t n_mixture = cp->getValue().size();
    if (n_mixture > 0) {
        for (size_t i = 1; i < n_mixture; i++)
        {
            if (cp->getValue()[i].size() != cp->getValue()[i-1].size())
            {
                throw RbException("All cladogenetic probability functions must be of equal size.");
            }
            
        }
    }
    
    if (ep->getValue().size() != cp->getValue().size())
    {
        throw RbException("mixtureProbabilities and cladogeneticProbabilities must be of equal size.");
    }
    
//    size_t nc = cp->getValue()[0].size();

    // create P matrix
    RevBayesCore::MixtureCladogeneticStateFunction* f = NULL;
    f = new RevBayesCore::MixtureCladogeneticStateFunction( ep, cp, 0, 0 );
    
    return f;
}
Example #13
0
RevBayesCore::TypedFunction< double >* Func_WattersonTheta::createFunction( void ) const
{
    
    RevBayesCore::TypedDagNode<RevBayesCore::AbstractHomologousDiscreteCharacterData >* d = static_cast<const AbstractHomologousDiscreteCharacterData &>( this->args[0].getVariable()->getRevObject() ).getDagNode();
    RevBayesCore::TypedDagNode<RevBayesCore::Boolean >* ps = static_cast<const RlBoolean &>( this->args[1].getVariable()->getRevObject() ).getDagNode();
    RevBayesCore::WattersonThetaFunction* f = new RevBayesCore::WattersonThetaFunction( d, ps->getValue() );
    
    return f;
}
Example #14
0
RevBayesCore::TypedFunction< RevBayesCore::RbVector<double> >* Func_DECRoot::createFunction( void ) const
{
    
    RevBayesCore::TypedDagNode< RevBayesCore::RbVector<double> >* rf = static_cast<const ModelVector<RealPos> &>( this->args[0].getVariable()->getRevObject() ).getDagNode();

    RevBayesCore::TypedDagNode<RevBayesCore::RbVector<double> >* rs = NULL;
    if ( this->args[1].getVariable() != NULL && this->args[1].getVariable()->getRevObject() != RevNullObject::getInstance()) {
        rs = static_cast<const Simplex&>( this->args[1].getVariable()->getRevObject() ).getDagNode();
    }
    else {
        size_t n = log2(rf->getValue().size()) + 1;
        double p = 1.0 / n;
        rs = new RevBayesCore::ConstantNode<RevBayesCore::RbVector<double> >("", new RevBayesCore::RbVector<double>(n,p));
    }
    
//    RevBayesCore::TypedDagNode<int>* mrs = static_cast<const Natural&>( this->args[2].getVariable()->getRevObject() ).getDagNode();
    
    RevBayesCore::DispersalExtinctionRootStructureFunction* f = new RevBayesCore::DispersalExtinctionRootStructureFunction( rf,rs );
    
    return f;
}
Example #15
0
/** Execute function */
RevPtr<RevVariable> Func_readPomoCountFile::execute( void )
{

	// get the information from the arguments for reading the file
	const RlString& fn = static_cast<const RlString&>( args[0].getVariable()->getRevObject() );
	RevBayesCore::TypedDagNode<int>* virtualPopulationSize = static_cast<const Integer &>( this->args[1].getVariable()->getRevObject() ).getDagNode();

	RevBayesCore::PomoCountFileReader* pcfr = new RevBayesCore::PomoCountFileReader( fn.getValue(), virtualPopulationSize->getValue(), ' ' );

	AbstractHomologousDiscreteCharacterData pomoAln = pcfr->getMatrix();

	return new RevVariable( new AbstractHomologousDiscreteCharacterData(pomoAln) );
}
RevPtr<RevVariable> Func_pomoStateConverter::execute() {

    const RevBayesCore::TypedDagNode<RevBayesCore::AbstractDiscreteCharacterData>* aln = static_cast<const AbstractDiscreteCharacterData&>( this->args[0].getVariable()->getRevObject() ).getDagNode();

    RevBayesCore::TypedDagNode< int >* n = static_cast<const Natural &>( this->args[1].getVariable()->getRevObject() ).getDagNode();


    RevBayesCore::PomoStateConverter* c = new RevBayesCore::PomoStateConverter(  );

    RevBayesCore::TypedDagNode< RevBayesCore::RbVector<RevBayesCore::Taxon> >* taxa  = static_cast< const ModelVector<Taxon> &>( this->args[2].getVariable()->getRevObject() ).getDagNode();

    std::map <std::string, std::string > gene2species;

    for (RevBayesCore::RbIterator<RevBayesCore::Taxon> it=taxa->getValue().begin(); it!=taxa->getValue().end(); ++it)
    {
        gene2species[it->getName()] = it->getSpeciesName();
    }

    AbstractDiscreteCharacterData PomoAln = c->convertData( aln->getValue(), n->getValue(), gene2species ) ;

    return new RevVariable( new AbstractDiscreteCharacterData( PomoAln ) );
}
RevBayesCore::TypedFunction< RevBayesCore::MatrixReal >* Func_varianceCovarianceMatrix::createFunction(void) const {

    RevBayesCore::TypedDagNode<RevBayesCore::RbVector<double> >* sd = static_cast<const ModelVector<RealPos>& >( this->args[0].getVariable()->getRevObject() ).getDagNode();
    RevBayesCore::TypedDagNode<RevBayesCore::RbVector<double> >* ce = static_cast<const ModelVector<Real>& >( this->args[1].getVariable()->getRevObject() ).getDagNode();
    if ( sd->getValue().size() != (ce->getValue().size() * (ce->getValue().size()-1) / 2.0) )
        {
        throw RbException("The dimension between the standard deviations and the correlation coefficients does not match.");
        }
    for (int i=0; i<ce->getValue().size(); i++)
        {
        if ( ce->getValue()[i] < -1.0 || ce->getValue()[i] > 1.0)
            {
            throw RbException("A correlation coefficient is out-of-bounds (-1,+1).");
            }
        }
    RevBayesCore::VarianceCovarianceFunction* f = new RevBayesCore::VarianceCovarianceFunction( sd, ce );
    return f;
}
RevBayesCore::TypedFunction< RevBayesCore::RateGenerator >* Func_DECRateMatrix::createFunction( void ) const
{
    
    RevBayesCore::TypedDagNode<RevBayesCore::RbVector<RevBayesCore::RbVector<double> > >* dr;
    dr = static_cast<const ModelVector<ModelVector<RealPos> > &>( this->args[0].getVariable()->getRevObject() ).getDagNode();
    RevBayesCore::TypedDagNode<RevBayesCore::RbVector<double> >* er;
    er = static_cast<const ModelVector<RealPos> &>( this->args[1].getVariable()->getRevObject() ).getDagNode();
    
    size_t numStatesEr = er->getValue().size();
    std::vector<size_t> numStatesDr;
    for (size_t i = 0; i < dr->getValue().size(); i++)
    {
        numStatesDr.push_back( dr->getValue()[i].size() );
        if (numStatesDr[i] != numStatesEr)
        {
            throw RbException("The dimension between dispersal and extirpation rates does not match.");
        }
        for (size_t j = 0; j < i; j++)
        {
            if (numStatesDr[i] != numStatesDr[j])
            {
                throw RbException("The dispersal matrix is not square.");
            }
        }
    }
    if (dr->getValue().size() != numStatesEr)
    {
        throw RbException("The dimension between dispersal and extirpation rates does not match.");
    }

    RevBayesCore::TypedDagNode<RevBayesCore::RbVector<double> >* rs = NULL;
    if ( this->args[2].getVariable() != NULL && this->args[2].getVariable()->getRevObject() != RevNullObject::getInstance()) {
        rs = static_cast<const Simplex&>( this->args[2].getVariable()->getRevObject() ).getDagNode();
    }
    else {
        size_t n = numStatesEr+1;
        double p = 1.0 / n;
        rs = new RevBayesCore::ConstantNode<RevBayesCore::RbVector<double> >("", new RevBayesCore::RbVector<double>(n,p));
    }
//    RevBayesCore::TypedDagNode<int>* mrs = static_cast<const Natural&>( this->args[3].getVariable()->getRevObject() ).getDagNode();
    
    RevBayesCore::DECRateMatrixFunction* f = new RevBayesCore::DECRateMatrixFunction( dr, er, rs );
    
    return f;
}
Example #19
0
RevBayesCore::TypedFunction< RevBayesCore::RateGenerator >* Func_DECStationaryFrequencies::createFunction( void ) const
{
    
    // dispersal rates
    RevBayesCore::TypedDagNode<RevBayesCore::RbVector<RevBayesCore::RbVector<double> > >* dr;
    dr = static_cast<const ModelVector<ModelVector<RealPos> > &>( this->args[0].getVariable()->getRevObject() ).getDagNode();
    
    // extirpation rates
    RevBayesCore::TypedDagNode<RevBayesCore::RbVector<double> >* er;
    er = static_cast<const ModelVector<RealPos> &>( this->args[1].getVariable()->getRevObject() ).getDagNode();
    
    size_t num_statesEr = er->getValue().size();
    std::vector<size_t> num_statesDr;
    for (size_t i = 0; i < dr->getValue().size(); i++)
    {
        num_statesDr.push_back( dr->getValue()[i].size() );
        if (num_statesDr[i] != num_statesEr)
        {
            throw RbException("The dimension between dispersal and extirpation rates does not match.");
        }
        for (size_t j = 0; j < i; j++)
        {
            if (num_statesDr[i] != num_statesDr[j])
            {
                throw RbException("The dispersal matrix is not square.");
            }
        }
    }
    if (dr->getValue().size() != num_statesEr)
    {
        throw RbException("The dimension between dispersal and extirpation rates does not match.");
    }
    
    // range size probabilities
    RevBayesCore::TypedDagNode<RevBayesCore::RbVector<double> >* rs = NULL;
    if ( this->args[2].getVariable() != NULL && this->args[2].getVariable()->getRevObject() != RevNullObject::getInstance()) {
        
        rs = static_cast<const Simplex&>( this->args[2].getVariable()->getRevObject() ).getDagNode();
        if (rs->getValue().size() != num_statesEr && rs->getValue().size() > 0) {
            throw RbException("The probabilities of range sizes must equal the number of areas.");
        }
        else {
            size_t n = num_statesEr;
            double p = 1.0 / n;
            rs = new RevBayesCore::ConstantNode<RevBayesCore::RbVector<double> >("", new RevBayesCore::RbVector<double>(n,p));
        }
    }
    else {
        size_t n = num_statesEr+1;
        double p = 1.0 / n;
        rs = new RevBayesCore::ConstantNode<RevBayesCore::RbVector<double> >("", new RevBayesCore::RbVector<double>(n,p));
    }
    
    std::string nullRangeStr = static_cast<const RlString &>( this->args[3].getVariable()->getRevObject() ).getValue();
//    bool cs = nullRangeStr=="CondSurv";
//    bool ex = nullRangeStr=="Exclude";
    //    std::cout << nullRangeStr << " " << cs << " " << ex << "\n";
    
//    bool os = static_cast<const RlBoolean&>(this->args[4].getVariable()->getRevObject() ).getValue();
    
//    bool uc = false;
    RevBayesCore::DECRateMatrixFunction* f = NULL;// = new RevBayesCore::DECRateMatrixFunction( dr, er, rs, cs, ex, os, uc );
//    RevBayesCore::DECStationaryFrequenciesFunction* f; // = new RevBayesCore::DECStationaryFrequenciesFunction(dr, er, rs, cs, ex, os, uc);
    
    return f;
}