Пример #1
0
/**
 * Perform the proposal.
 *
 * An element swap simplex proposal simply selects two random elements of a simplex
 * and swaps them.
 *
 * \return The hastings ratio.
 */
double ElementSwapSimplexProposal::propose( RbVector<double> &value )
{
    
    // Get random number generator
    RandomNumberGenerator* rng     = GLOBAL_RNG;
    
    // store the value
    storedValue = value;
    
    // we need to know the number of categories
    size_t cats = value.size();
    
    // randomly draw two indices
    size_t chosen_index_1 = size_t( floor(rng->uniform01()*double(cats)) );
    size_t chosen_index_2 = size_t( floor(rng->uniform01()*double(cats)) );
    while (chosen_index_1 == chosen_index_2)
    {
        chosen_index_2 = size_t( floor(rng->uniform01()*double(cats)) );
    }
   
    // swap the values
    double value_1 = value[chosen_index_1];
    double value_2 = value[chosen_index_2];
    value[chosen_index_1] = value_2;
    value[chosen_index_2] = value_1;
    
    
    double ln_Hastins_ratio = 0;
    
    return ln_Hastins_ratio;
}
/**
 * Perform the proposal.
 *
 * A scaling Proposal draws a random uniform number u ~ unif(-0.5,0.5)
 * and scales the current vale by a scaling factor
 * sf = exp( lambda * u )
 * where lambda is the tuning parameter of the Proposal to influence the size of the proposals.
 *
 * \return The hastings ratio.
 */
double VectorSingleElementScaleProposal::doProposal( void )
{
    
    // Get random number generator
    RandomNumberGenerator* rng     = GLOBAL_RNG;
    
    RbVector<double> &val = variable->getValue();

    // choose an index
    index = size_t(rng->uniform01() * val.size());
    
    // copy value
    storedValue = val[index];
    
    // Generate new value (no reflection, so we simply abort later if we propose value here outside of support)
    double u = rng->uniform01();
    double scalingFactor = std::exp( lambda * ( u - 0.5 ) );
    val[index] *= scalingFactor;
    
    variable->addTouchedElementIndex(index);
    
    // compute the Hastings ratio
    double lnHastingsratio = log( scalingFactor );
    
    return lnHastingsratio;
}
double MatrixRealSymmetricSlideMove::performSimpleMove( void )
{
    
    // Get random number generator
    RandomNumberGenerator* rng = GLOBAL_RNG;
    
    MatrixReal& mymat = variable->getValue();
    
    size_t dim = mymat.getDim();
    size_t indexa = size_t( rng->uniform01() * dim );
    size_t indexb = size_t( rng->uniform01() * dim );
    
    stored_i = indexa;
    stored_j = indexb;
    storedValue = mymat[stored_i][stored_j];

    double u = rng->uniform01();
    double m = lambda * (u - 0.5);
    mymat[indexa][indexb] += m;
    if ( indexa != indexb )
    {
        mymat[indexb][indexa] = mymat[indexa][indexb];
    }
    
    return 0;
}
Пример #4
0
/*!
 * This function is used when generating gamma-distributed random variables.
 *
 * \brief Subfunction for gamma random variables.
 * \param s is the shape parameter of the gamma.
 * \return Returns a gamma-distributed random variable.
 * \throws Does not throw an error.
 */
double RbStatistics::Helper::rndGamma1(double s, RandomNumberGenerator& rng)
{

    double			r, x = 0.0, small = 1e-37, w;
    static double   a, p, uf, ss = 10.0, d;

    if (s != ss) {
        a  = 1.0 - s;
        p  = a / (a + s * exp(-a));
        uf = p * pow(small / a, s);
        d  = a * log(a);
        ss = s;
    }
    for (;;) {
        r = rng.uniform01();
        if (r > p)
            x = a - log((1.0 - r) / (1.0 - p)), w = a * log(x) - d;
        else if (r>uf)
            x = a * pow(r / p, 1.0 / s), w = x;
        else
            return (0.0);
        r = rng.uniform01();
        if (1.0 - r <= w && r > 0.0)
            if (r*(w + 1.0) >= 1.0 || -log(r) <= w)
                continue;
        break;
    }

    return (x);
}
Пример #5
0
/*!
 * This function is used when generating gamma-distributed random variables.
 *
 * \brief Subfunction for gamma random variables.
 * \param s is the shape parameter of the gamma.
 * \return Returns a gamma-distributed random variable.
 * \throws Does not throw an error.
 */
double RbStatistics::Helper::rndGamma2(double s, RandomNumberGenerator& rng) {

    double			r, d, f, g, x;
    static double	b, h, ss = 0.0;

    if (s != ss) {
        b  = s - 1.0;
        h  = sqrt(3.0 * s - 0.75);
        ss = s;
    }
    for (;;) {
        r = rng.uniform01();
        g = r - r * r;
        f = (r - 0.5) * h / sqrt(g);
        x = b + f;
        if (x <= 0.0)
            continue;
        r = rng.uniform01();
        d = 64.0 * r * r * g * g * g;
        if (d * x < x - 2.0 * f * f || log(d) < 2.0 * (b * log(x / b) - f))
            break;
    }

    return (x);
}
void RevBayesCore::DPPScaleCatAllocateAuxGibbs::doScaleTablesMove( void ) {
    
    // Get random number generator    
    RandomNumberGenerator* rng     = GLOBAL_RNG;
	
	DirichletProcessPriorDistribution<double>& dist = static_cast<DirichletProcessPriorDistribution<double> &>( variable->getDistribution() );
	
	dist.createRestaurantVectors();
	int numTables = dist.getNumberOfCategories();
	int numElements = dist.getNumberOfElements();
	std::vector<double> tableVals = dist.getTableParameters();
	std::vector<int> allocVec = dist.getElementAllocationVec();
	std::vector<double>& elementVals = variable->getValue();
	TypedDistribution<double>* g0 = dist.getBaseDistribution();
	
	double storedValue;
	variable->touch();
	for(int i=0; i<numTables; i++){
		
		// get old lnL
		double oldLnl = getCurrentLnProbabilityForMove();
		
		storedValue = tableVals[i];
		double u = rng->uniform01();
		double scalingFactor = std::exp( lambda * ( u - 0.5 ) );
		double newValue = storedValue * scalingFactor;
		tableVals[i] = newValue;
		
		// Assign new value to elements
		for(int j=0; j<numElements; j++){
			if(allocVec[j] == i)
				elementVals[j] = tableVals[i];
		}
		
		g0->getValue() = tableVals[i]; // new
		double priorRatio = g0->computeLnProbability(); 
		g0->getValue() = storedValue; // old
		priorRatio -= g0->computeLnProbability();
		
		variable->touch();
		double newLnl = getCurrentLnProbabilityForMove();
		double lnProbRatio = newLnl - oldLnl;
        
		double r = safeExponentiation(priorRatio + lnProbRatio + log(scalingFactor));
		u = rng->uniform01();
		if ( u < r ) //accept
			variable->keep();
		else{ // reject
			for(int j=0; j<numElements; j++){
				if(allocVec[j] == i)
					elementVals[j] = storedValue;
			}
			tableVals[i] = storedValue;
			variable->touch();
			variable->keep();
		}
	}
    dist.createRestaurantVectors();
}
/**
 * Perform the proposal.
 *
 * A Beta-simplex proposal randomly changes some values of a simplex, although the other values
 * change too because of the renormalization.
 * First, some random indices are drawn. Then, the proposal draws a new somplex
 *   u ~ Beta(val[index] * alpha)
 * where alpha is the tuning parameter.The new value is set to u.
 * The simplex is then renormalized.
 *
 * \return The hastings ratio.
 */
double SubtreeScaleProposal::doProposal( void )
{
    // Get random number generator
    RandomNumberGenerator* rng     = GLOBAL_RNG;
    
    TimeTree& tau = variable->getValue();
    
    // pick a random node which is not the root and neither the direct descendant of the root
    TopologyNode* node;
    do {
        double u = rng->uniform01();
        size_t index = size_t( std::floor(tau.getNumberOfNodes() * u) );
        node = &tau.getNode(index);
    } while ( node->isRoot() || node->isTip() );
    
    TopologyNode& parent = node->getParent();
    
    // we need to work with the times
    double parent_age  = parent.getAge();
    double my_age      = node->getAge();
    
    // now we store all necessary values
    storedNode = node;
    storedAge = my_age;
    
    // lower bound
    double min_age = 0.0;
    TreeUtilities::getOldestTip(&tau, node, min_age);
    
    // draw new ages and compute the hastings ratio at the same time
    double my_new_age = min_age + (parent_age - min_age) * rng->uniform01();
    
    double scalingFactor = my_new_age / my_age;
    
    size_t nNodes = node->getNumberOfNodesInSubtree(false);
    
    // rescale the subtrees
    TreeUtilities::rescaleSubtree(&tau, node, scalingFactor );
    
    if (min_age != 0.0)
    {
        for (size_t i = 0; i < tau.getNumberOfTips(); i++)
        {
            if (tau.getNode(i).getAge() < 0.0) {
                return RbConstants::Double::neginf;
            }
        }
    }
    
    // compute the Hastings ratio
    double lnHastingsratio = (nNodes > 1 ? log( scalingFactor ) * (nNodes-1) : 0.0 );
    
    return lnHastingsratio;
    
}
Пример #8
0
/*!
 * This function generates a Poisson-distributed random variable for
 * small values of lambda. The method is a simple calculation of the
 * probabilities of x = 1 and x = 2. Larger values are ignored.
 *
 * \brief Poisson random variables for small lambda.
 * \param lambda is the rate parameter of the Poisson.
 * \return Returns a Poisson-distributed random variable.
 * \throws Does not throw an error.
 */
int RbStatistics::Helper::poissonLow(double lambda, RandomNumberGenerator& rng) {

    double d = sqrt(lambda);
    if (rng.uniform01() >= d)
        return 0;
    double r = rng.uniform01() * d;
    if (r > lambda * (1.0 - lambda))
        return 0;
    if (r > 0.5 * lambda * lambda * (1.0 - lambda))
        return 1;
    return 2;
}
Пример #9
0
/**
 * Simulate new speciation times.
 */
double ConstantRateFossilizedBirthDeathProcess::simulateDivergenceTime(double orig, double present) const
{

    // incorrect placeholder for constant FBDP
    // previous simSpeciations did not generate trees with defined likelihoods
    
    
    // Get the rng
    RandomNumberGenerator* rng = GLOBAL_RNG;
    
    // get the parameters
    double age = present - orig;
    double b = lambda->getValue();
    double d = mu->getValue();
    double r = rho->getValue();
    
    // get a random draw
    double u = rng->uniform01();
    
    
    // compute the time for this draw
    double t = 0.0;
    if ( b > d )
    {
        t = ( log( ( (b-d) / (1 - (u)*(1-((b-d)*exp((d-b)*age))/(r*b+(b*(1-r)-d)*exp((d-b)*age) ) ) ) - (b*(1-r)-d) ) / (r * b) ) + (d-b)*age )  /  (d-b);
    }
    else
    {
        t = ( log( ( (b-d) / (1 - (u)*(1-(b-d)/(r*b*exp((b-d)*age)+(b*(1-r)-d) ) ) ) - (b*(1-r)-d) ) / (r * b) ) + (d-b)*age )  /  (d-b);
    }    
    
    //    return present - t;
    return orig + t;
}
Пример #10
0
/** Perform the move */
double OriginTimeSlide::performSimpleMove( void ) {
    
    // Get random number generator    
    RandomNumberGenerator* rng     = GLOBAL_RNG;
    
    TimeTree& tau = tree->getValue();
	
	
    
    TopologyNode& root = tau.getRoot();
    
    // we need to work with the times
    double my_age      = variable->getValue();
    
    // now we store all necessary values
    storedAge = my_age;
    
    // get the minimum age
    double child_Age   = root.getAge();
    
    
    // draw new ages and compute the hastings ratio at the same time
    // Note: the Hastings ratio needs to be there because one of the nodes might be a tip and hence not scaled!
    double u = rng->uniform01();
    double my_new_age = my_age + ( delta * ( u - 0.5 ) );
    
    // check if the new age is lower than the minimum
    if ( my_new_age < child_Age ) {
        my_new_age = child_Age - (my_new_age - child_Age);
    }
    
    variable->setValue( new double(my_new_age) );
    
    return 0.0;
}
Пример #11
0
/**
 * Perform the proposal.
 *
 *
 *
 * \return The hastings ratio.
 */
double TreeScaleProposal::doProposal( void )
{
    
    
    // Get random number generator
    RandomNumberGenerator* rng     = GLOBAL_RNG;
    
    Tree& tau = tree->getValue();
    
    TopologyNode& node = tau.getRoot();
    
    // we need to work with the times
    double my_age      = node.getAge();
    
    // now we store all necessary values
    storedAge = my_age;
    
    // draw new ages 
    double u = rng->uniform01();
    double scalingFactor = std::exp( delta * ( u - 0.5 ) );
    
    // rescale the subtrees
    TreeUtilities::rescaleSubtree(&tau, &node, scalingFactor );
    
    if ( rootAge != NULL )
    {
        rootAge->setValue( new double(my_age * scalingFactor) );
    }
    
    // compute the Hastings ratio
    double lnHastingsratio = log( scalingFactor ) * tau.getNumberOfInteriorNodes();
    
    return lnHastingsratio;
}
Пример #12
0
/*!
 * This function generates a Poisson-distributed random variable using
 * inversion by the chop down method.
 *
 * \brief Poisson random variables using the chop down method.
 * \param lambda is the rate parameter of the Poisson.
 * \return Returns a Poisson-distributed random variable.
 * \throws Does not throw an error.
 */
int RbStatistics::Helper::poissonInver(double lambda, RandomNumberGenerator& rng) {

    const int bound = 130;
    static double p_L_last = -1.0;
    static double p_f0;
    int x;

    if (lambda != p_L_last) {
        p_L_last = lambda;
        p_f0 = exp(-lambda);
    }

    while (1) {
        double r = rng.uniform01();
        x = 0;
        double f = p_f0;
        do {
            r -= f;
            if (r <= 0.0)
                return x;
            x++;
            f *= lambda;
            r *= x;
        } while (x <= bound);
    }
}
double EpisodicBirthDeathProcess::simulateDivergenceTime(double origin, double present, double rho) const
{
    
    // Get the rng
    RandomNumberGenerator* rng = GLOBAL_RNG;
    
    // get the parameters
    double age = present - origin;
    double b = lambda_rates->getValue()[0];
    double d = mu_rates->getValue()[0];
    
    
    // get a random draw
    double u = rng->uniform01();
    
    // compute the time for this draw
    double t = 0.0;
    if ( b > d )
    {
        t = ( log( ( (b-d) / (1 - (u)*(1-((b-d)*exp((d-b)*age))/(rho*b+(b*(1-rho)-d)*exp((d-b)*age) ) ) ) - (b*(1-rho)-d) ) / (rho * b) ) + (d-b)*age )  /  (d-b);
    }
    else
    {
        t = ( log( ( (b-d) / (1 - (u)*(1-(b-d)/(rho*b*exp((b-d)*age)+(b*(1-rho)-d) ) ) ) - (b*(1-rho)-d) ) / (rho * b) ) + (d-b)*age )  /  (d-b);
    }
    
    
    return present - t;
}
Пример #14
0
/** Perform the move */
double SlidingMove::performSimpleMove( void ) {

    // Get random number generator    
    RandomNumberGenerator* rng     = GLOBAL_RNG;
    
    double &val = variable->getValue();
    
    // copy all value
    storedValue = val;

    double min = variable->getMin();
    double max = variable->getMax();

    double u      = rng->uniform01();
    double newVal = val + ( delta * ( u - 0.5 ) );

    /* reflect the new value */
    do {
        if ( newVal < min )
            newVal = 2.0 * min - newVal;
        else if ( newVal > max )
            newVal = 2.0 * max - newVal;
    } while ( newVal < min || newVal > max );

    // FIXME: not the most efficient way of handling multiple reflections :-P

    val = newVal;
	
    return 0.0;
}
Пример #15
0
/**
 * Perform the proposal.
 *
 * A Uniform-simplex proposal randomly changes some values of a simplex, although the other values
 * change too because of the renormalization.
 * First, some random indices are drawn. Then, the proposal draws a new somplex
 *   u ~ Uniform(val[index] * alpha)
 * where alpha is the tuning parameter.The new value is set to u.
 * The simplex is then renormalized.
 *
 * \return The hastings ratio.
 */
double RootTimeSlideUniformProposal::doProposal( void )
{
    
    // Get random number generator
    RandomNumberGenerator* rng     = GLOBAL_RNG;
    
    Tree& tau = variable->getValue();
    
    // pick a random node which is not the root and neithor the direct descendant of the root
    TopologyNode* node = &tau.getRoot();
    
    // we need to work with the times
    double my_age      = node->getAge();
    double child_Age   = node->getChild( 0 ).getAge();
    if ( child_Age < node->getChild( 1 ).getAge())
    {
        child_Age = node->getChild( 1 ).getAge();
    }
    
    // now we store all necessary values
    storedAge = my_age;
    
    // draw new ages and compute the hastings ratio at the same time
    double my_new_age = (origin->getValue() - child_Age) * rng->uniform01() + child_Age;
    
    // set the age
    node->setAge( my_new_age );
    
    return 0.0;
    
}
Пример #16
0
/** Build random binary tree to size num_taxa. The result is a draw from the uniform distribution on histories. */
void HeterogeneousRateBirthDeath::buildRandomBinaryHistory(std::vector<TopologyNode*> &tips)
{
    
    if (tips.size() < num_taxa)
    {
        // Get the rng
        RandomNumberGenerator* rng = GLOBAL_RNG;
        
        // Randomly draw one node from the list of tips
        size_t index = static_cast<size_t>( floor(rng->uniform01()*tips.size()) );
        
        // Get the node from the list
        TopologyNode* parent = tips.at(index);
        
        // Remove the randomly drawn node from the list
        tips.erase(tips.begin()+long(index));
        
        // Add a left child
        TopologyNode* leftChild = new TopologyNode(0);
        parent->addChild(leftChild);
        leftChild->setParent(parent);
        tips.push_back(leftChild);
        
        // Add a right child
        TopologyNode* rightChild = new TopologyNode(0);
        parent->addChild(rightChild);
        rightChild->setParent(parent);
        tips.push_back(rightChild);
        
        // Recursive call to this function
        buildRandomBinaryHistory(tips);
    }
}
void AutocorrelatedBranchMatrixDistribution::recursiveSimulate(const TopologyNode& node, RbVector< RateMatrix > *values, const std::vector< double > &scaledParent) {
    
    // get the index
    size_t nodeIndex = node.getIndex();
    
    // first we simulate our value
    RandomNumberGenerator* rng = GLOBAL_RNG;
    // do we keep our parents values?
    double u = rng->uniform01();
    if ( u < changeProbability->getValue() ) {
        // change
        
        // draw a new value for the base frequencies
        std::vector<double> newParent = RbStatistics::Dirichlet::rv(scaledParent, *rng);
        std::vector<double> newScaledParent = newParent;
        
        // compute the new scaled parent
        std::vector<double>::iterator end = newScaledParent.end();
        for (std::vector<double>::iterator it = newScaledParent.begin(); it != end; ++it) {
            (*it) *= alpha->getValue();
        }
        
        RateMatrix_GTR rm = RateMatrix_GTR( newParent.size() );
        RbPhylogenetics::Gtr::computeRateMatrix( exchangeabilityRates->getValue(), newParent, &rm );
        
        uniqueBaseFrequencies.push_back( newParent );
        uniqueMatrices.push_back( rm );
        matrixIndex[nodeIndex] = uniqueMatrices.size()-1;
        values->insert(nodeIndex, rm);
        
        size_t numChildren = node.getNumberOfChildren();
        if ( numChildren > 0 ) {
            
            for (size_t i = 0; i < numChildren; ++i) {
                const TopologyNode& child = node.getChild(i);
                recursiveSimulate(child,values,newScaledParent);
            }
        }
        
    }
    else {
        // no change
        size_t parentIndex = node.getParent().getIndex();
        values->insert(nodeIndex, uniqueMatrices[ matrixIndex[ parentIndex ] ]);
        
        size_t numChildren = node.getNumberOfChildren();
        if ( numChildren > 0 ) {
            
            for (size_t i = 0; i < numChildren; ++i) {
                const TopologyNode& child = node.getChild(i);
                recursiveSimulate(child,values,scaledParent);
            }
        }
    }
    
}
Пример #18
0
/*!
 * This function generates a Poisson-distributed random variable using
 * the ratio-of-uniforms rejectin method.
 *
 * \brief Poisson random variables using the ratio-of-uniforms method.
 * \param lambda is the rate parameter of the Poisson.
 * \return Returns a Poisson-distributed random variable.
 * \throws Does not throw an error.
 * \see Stadlober, E. 1990. The ratio of uniforms approach for generating
 *      discrete random variates. Journal of Computational and Applied
 *      Mathematics 31:181-189.
 */
int RbStatistics::Helper::poissonRatioUniforms(double lambda, RandomNumberGenerator& rng) {

    static double p_L_last = -1.0;  /* previous L */
    static double p_a;              /* hat center */
    static double p_h;              /* hat width */
    static double p_g;              /* ln(L) */
    static double p_q;              /* value at mode */
    static int p_bound;             /* upper bound */
    int mode;                       /* mode */
    double u;                       /* uniform random */
    double lf;                      /* ln(f(x)) */
    double x;                       /* real sample */
    int k;                          /* integer sample */

    if (p_L_last != lambda) {
        p_L_last = lambda;
        p_a = lambda + 0.5;
        mode = (int)lambda;
        p_g  = log(lambda);
        p_q = mode * p_g - RbMath::lnFactorial(mode);
        p_h = sqrt(2.943035529371538573 * (lambda + 0.5)) + 0.8989161620588987408;
        p_bound = (int)(p_a + 6.0 * p_h);
    }

    while(1) {
        u = rng.uniform01();
        if (u == 0.0)
            continue;
        x = p_a + p_h * (rng.uniform01() - 0.5) / u;
        if (x < 0 || x >= p_bound)
            continue;
        k = (int)(x);
        lf = k * p_g - RbMath::lnFactorial(k) - p_q;
        if (lf >= u * (4.0 - u) - 3.0)
            break;
        if (u * (u - lf) > 1.0)
            continue;
        if (2.0 * log(u) <= lf)
            break;
    }
    return(k);
}
Пример #19
0
double RbStatistics::Logistic::rv(double location, double scale, RandomNumberGenerator& rng) {

    if (scale == 0){
        return (location);

    }
    else{

        double u = rng.uniform01();
        return location + scale * log(u / (1. - u));
    }
}
Пример #20
0
/**
 * Perform the proposal.
 *
 * A Uniform-simplex proposal randomly changes some values of a simplex, although the other values
 * change too because of the renormalization.
 * First, some random indices are drawn. Then, the proposal draws a new somplex
 *   u ~ Uniform(val[index] * alpha)
 * where alpha is the tuning parameter.The new value is set to u.
 * The simplex is then renormalized.
 *
 * \return The hastings ratio.
 */
double NodeTimeSlideUniformProposal::doProposal( void )
{

    // Get random number generator
    RandomNumberGenerator* rng     = GLOBAL_RNG;

    Tree& tau = variable->getValue();

    // pick a random node which is not the root and neithor the direct descendant of the root
    TopologyNode* node;
    do {
        double u = rng->uniform01();
        size_t index = size_t( std::floor(tau.getNumberOfNodes() * u) );
        node = &tau.getNode(index);
    } while ( node->isRoot() || node->isTip() );

    TopologyNode& parent = node->getParent();

    // we need to work with the times
    double parent_age  = parent.getAge();
    double my_age      = node->getAge();
    double child_Age   = node->getChild( 0 ).getAge();
    if ( child_Age < node->getChild( 1 ).getAge())
    {
        child_Age = node->getChild( 1 ).getAge();
    }

    // now we store all necessary values
    storedNode = node;
    storedAge = my_age;

    // draw new ages and compute the hastings ratio at the same time
    double my_new_age = (parent_age-child_Age) * rng->uniform01() + child_Age;

    // set the age
    tau.getNode(node->getIndex()).setAge( my_new_age );

    return 0.0;

}
Пример #21
0
/** Perform the move */
double SubtreeScale::performSimpleMove( void ) {
    
    // Get random number generator    
    RandomNumberGenerator* rng     = GLOBAL_RNG;
    
    TimeTree& tau = variable->getValue();
    
    // pick a random node which is not the root and neither the direct descendant of the root
    TopologyNode* node;
    do {
        double u = rng->uniform01();
        size_t index = size_t( std::floor(tau.getNumberOfNodes() * u) );
        node = &tau.getNode(index);
    } while ( node->isRoot() || node->isTip() );
    
    TopologyNode& parent = node->getParent();
    
    // we need to work with the times
    double parent_age  = parent.getAge();
    double my_age      = node->getAge();
    
    // now we store all necessary values
    storedNode = node;
    storedAge = my_age;
        
    // draw new ages and compute the hastings ratio at the same time
    double my_new_age = parent_age * rng->uniform01();
    
    double scalingFactor = my_new_age / my_age;
    
    size_t nNodes = node->getNumberOfNodesInSubtree(false);
    
    // rescale the subtrees
    TreeUtilities::rescaleSubtree(&tau, node, scalingFactor );
    
    // compute the Hastings ratio
    double lnHastingsratio = (nNodes > 1 ? log( scalingFactor ) * (nNodes-1) : 0.0 );
    
    return lnHastingsratio;
}
Move& SingleRandomMoveSchedule::nextMove( unsigned long gen ) {
    
    RandomNumberGenerator* rng = GLOBAL_RNG;
    double u = sumOfWeights * rng->uniform01();
    
    size_t index = 0;
    while ( weights[index] < u || !(*moves)[index].isActive( gen ) )
    {
        u -= weights[index];
        ++index;
    }
    
    return (*moves)[index];
}
Пример #23
0
/** Perform the move */
double SliderUpDownMove::performCompoundMove( void ) {
    
    // Get random number generator
    RandomNumberGenerator* rng     = GLOBAL_RNG;
    
    double sv1 = sliderVal1->getValue();
    double sv2 = sliderVal2->getValue();
    
    storedSV1 = sv1;
    storedSV2 = sv2;
    
    double min1 = sliderVal1->getMin();
    double min2 = sliderVal2->getMin();
    
    double max1 = sliderVal1->getMax();
    double max2 = sliderVal2->getMax();

    double size = max1 - min1;
    
    double u      = rng->uniform01();
    double delta  = ( slideFactor * ( u - 0.5 ) );
    
    if ( fabs(delta) > 2.0*size )
    {
        delta -= floor(delta / (2.0*size)) * (2.0*size);
    }
    double nv1 = sv1 + delta;
    double nv2 = sv2 - delta;
    
    /* reflect the new value */
    do {
        if ( nv1 < min1 )
        {
            nv1 = 2.0 * min1 - nv1;
            nv2 = sv2 - (nv1 - sv1);
        }
        else if ( nv1 > max1 )
        {
            nv1 = 2.0 * max1 - nv1;
            nv2 = sv2 - (nv1 - sv1);
        }
        
    } while ( nv1 < min1 || nv1 > max1 || nv2 < min2 || nv2 > max2);
    
    sliderVal1->setValue( new double(nv1) );
    sliderVal2->setValue( new double(nv2) );
	
	return 0.0;
}
Пример #24
0
DistributionSample
RefractiveMaterial::sampleBxDF( RandomNumberGenerator & rng,
                                const RayIntersection & intersection ) const
{
    // Perfect Fresnel refractor
    DistributionSample sample;

    const float index_in = intersection.ray.index_of_refraction;
    const float index_out = index_of_refraction;
    const Vector4 from_dir = intersection.fromDirection();

    // FIXME: HACK - This assumes that if we hit the surface of an object with the same
    //        index of refraction as the material we're in, then we are moving back into
    //        free space. This might not be true if there are numerical errors tracing
    //        abutting objects of the same material type, or for objects that are intersecting.
    if( index_out == index_in ) {
        sample.new_index_of_refraction = 1.0f;
    }

    Vector4 refracted = refract( from_dir, intersection.normal, index_in, index_out );
    float fresnel = 1.0f; // default to total internal reflection if refract() returns
    // a zero length vector
    if( refracted.magnitude() > 0.0001 ) {
        fresnel = Fresnel::Dialectric::Unpolarized( dot( from_dir, intersection.normal ),
                                                    dot( refracted, intersection.normal.negated() ),
                                                    index_in,
                                                    index_out );
    }

    const float draw = rng.uniform01();

    // Use RNG to choose whether to reflect or refract based on Fresnel coefficient.
    //   Random selection accounts for fresnel or 1-fresnel scale factor.
    if( fresnel == 1.0f || draw < fresnel ) {
        // Trace reflection (mirror ray scaled by fresnel or 1 for total internal reflection)
        sample.direction = mirror( from_dir, intersection.normal );
        // FIXME - How do we determine pdf_sample for total internal reflection?
        sample.pdf_sample = fresnel;
        sample.new_index_of_refraction = index_in;
    }
    else {
        // Trace refraction (refracted ray scaled by 1-fresnel)
        sample.direction = refracted;
        sample.pdf_sample = 1.0 - fresnel;
        sample.new_index_of_refraction = index_out;
    }

    return sample;
}
Пример #25
0
/**
 * Perform the proposal.
 *
 * A scaling Proposal draws a random uniform number u ~ unif(-0.5,0.5)
 * and Slides the current vale by a scaling factor
 * sf = exp( lambda * u )
 * where lambda is the tuning parameter of the Proposal to influence the size of the proposals.
 *
 * \return The hastings ratio.
 */
double VectorSingleElementSlideProposal::doProposal( void )
{
    
    // Get random number generator
    RandomNumberGenerator* rng     = GLOBAL_RNG;
    
    RbVector<double> &val = variable->getValue();
    
    // choose an index
    index = size_t(rng->uniform01() * val.size());
    
    // copy value
    storedValue = val[index];
    
    // Generate new value (no reflection, so we simply abort later if we propose value here outside of support)
    double u = rng->uniform01();
    double delta  = ( lambda * ( u - 0.5 ) );
    
    val[index] += delta;
    
    variable->addTouchedElementIndex(index);
    
    return 0.0;
}
Пример #26
0
double FossilSafeScaleMove::doMove( void ) {
    
    // Get random number generator
    RandomNumberGenerator* rng     = GLOBAL_RNG;
    
    double val = scaler->getValue();
    storedValue = val;
    
//    double min = scaler->getMin();
//    double max = scaler->getMax();
    
//    double size = max - min;
    
    double u      = std::exp( lambda * (rng->uniform01() - 0.5));
    double newVal = val * u;
    
    val = newVal;
    scaler->setValue( new double(val) );
    
    TimeTree& t = tree->getValue();
//    double rescale = storedValue / val;
    
    bool failed = false;
    std::vector<TopologyNode*> nodes = t.getNodes();
    
    for (size_t i = 0; i < fossilIdx.size(); i++)
    {
        const size_t nodeIdx = nodes[ fossilIdx[i] ]->getIndex();
        storedTipAges[nodeIdx] = t.getAge(nodeIdx);
        t.setAge( nodeIdx, tipAges[nodeIdx] / val );
        if ( tipAges[ nodeIdx ] > nodes[ nodeIdx ]->getParent().getAge() * val )
        {
            // reject: rescaled tree has negative branch lengths!
            // std::cout << "reject, negative brlen\n";
            failed = true;
        }
    }
    
    if (failed)
        return RbConstants::Double::neginf;
    
	return log(u);
}
/** Perform the move */
double SimplexSingleElementScale::performSimpleMove( void ) {
    
    // Get random number generator    
    RandomNumberGenerator* rng     = GLOBAL_RNG;
    
    // get the current value
    std::vector<double>& value = variable->getValue();
    
    // store the value
    storedValue = value;
    
    // we need to know the number of categories
    size_t cats = value.size();
    
    // randomly draw a new index
    size_t chosenIndex = size_t( floor(rng->uniform01()*double(cats)) );
    double currentValue = value[chosenIndex];
    
    // draw new rates and compute the hastings ratio at the same time
    double a = alpha * currentValue + 1.0;
    double b = alpha * (1.0-currentValue) + 1.0;
    double new_value = RbStatistics::Beta::rv(a, b, *rng);
    
    // set the value
    value[chosenIndex] = new_value;
    
    // rescale
    double sum = 0;
	for(size_t i=0; i<cats; i++) {
		sum += value[i];
    }
	for(size_t i=0; i<cats; i++)
		value[i] /= sum;
    
    // compute the Hastings ratio
    double forward = RbStatistics::Beta::lnPdf(a, b, new_value);
    double new_a = alpha * value[chosenIndex] + 1.0;
    double new_b = alpha * (1.0-value[chosenIndex]) + 1.0;
    double backward = RbStatistics::Beta::lnPdf(new_a, new_b, currentValue);
    
    return backward - forward;
}
Пример #28
0
/*!
 * This function generates a Multinomially-distributed random variable.
 *
 * \brief Multinomially random variable.
 * \param p is a reference to a vector of doubles containing the parameters of the Multinomial. 
 * \param n is an integer with the number of draws from the multinomial
 * \param rng is a pointer to a random number object. 
 * \return Returns a vector of integers containing the random variable.
 * \throws Does not throw an error.
 */
std::vector<int> RbStatistics::Multinomial::rv(const std::vector<double> &p, size_t n, RandomNumberGenerator& rng) {
    
    std::vector<int> x(n,0);
    for (size_t i=0; i<n; i++)
    {
        double u = rng.uniform01();
        double sum = 0.0;
        for (size_t j=0; j<p.size(); j++)
        {
            sum += p[j];
            if (u < sum)
            {
                break;
                x[i]++;
            }
            else {
                x[i]++;
            }
        }
    }
	return x;
}
Пример #29
0
size_t SpeciesTreeNodeSlideProposal::mauCanonicalSub(Tree &tree, TopologyNode *node, size_t loc, std::vector<TopologyNode*> &order, std::vector<bool>& wasSwaped)
{
    if( node->isTip() )
    {
        order[loc] = node;
        return loc + 1;
    }
    
    // Get random number generator
    RandomNumberGenerator* rng     = GLOBAL_RNG;
    
    bool swap = (rng->uniform01() > 0.5);
    
    size_t l = mauCanonicalSub(tree, &node->getChild( swap ? 1 : 0), loc, order, wasSwaped);
    
    order[l] = node;
    wasSwaped[(l-1)/2] = swap;
    
    l = mauCanonicalSub(tree, &node->getChild( swap ? 0 : 1), l+1, order, wasSwaped);
    
    return l;
}
Пример #30
0
/** Perform the move */
double RateAgeACLNMixingMove::performCompoundMove( void ) {
    
    // Get random number generator    
    RandomNumberGenerator* rng     = GLOBAL_RNG;
    
    TimeTree& tau = tree->getValue();
	std::vector<double>& nrates = rates->getValue();
	double &rootR = rootRate->getValue();
	
	
	size_t nn = tau.getNumberOfNodes();
	double u = rng->uniform01();
	double c = exp( epsilon * (u - 0.5) );
	
	for(size_t i=0; i<nn; i++){
		TopologyNode* node = &tau.getNode(i);
		if(node->isTip() == false){
			double curAge = node->getAge();
			double newAge = curAge * c;
			tau.setAge( node->getIndex(), newAge );
			if(node->isRoot()){
				storedRootAge = curAge;
			}
		}
	}
	
	size_t nr = nrates.size();
	rootR = rootR / c;
	for(size_t i=0; i<nrates.size(); i++){
        double curRt = nrates[i];
        double newRt = curRt / c;
        nrates[i] = newRt;
	}
	
	storedC = c;
	double pr = (((double)nn) - (double)nr) * log(c);
	return pr;
}