mirror of
http://43.156.76.180:8026/YuuMJ/EukPhylo.git
synced 2025-12-28 07:10:24 +08:00
74 lines
2.2 KiB
C++
74 lines
2.2 KiB
C++
// $Id: talRandom.cpp 962 2006-11-07 15:13:34Z privmane $
|
|
|
|
#include "talRandom.h"
|
|
|
|
RandintTal talRandom::r = static_cast<long>(time(0)) ;
|
|
|
|
MDOUBLE talRandom::DblGammaGreaterThanOne(MDOUBLE dblAlpha) {
|
|
// Code adopted from David Heckerman
|
|
//-----------------------------------------------------------
|
|
// DblGammaGreaterThanOne(dblAlpha)
|
|
//
|
|
// routine to generate a gamma random variable with unit scale and
|
|
// alpha > 1
|
|
// reference: Ripley, Stochastic Simulation, p.90
|
|
// Chang and Feast, Appl.Stat. (28) p.290
|
|
//-----------------------------------------------------------
|
|
MDOUBLE rgdbl[6];
|
|
|
|
rgdbl[1] = dblAlpha - 1.0;
|
|
rgdbl[2] = (dblAlpha - (1.0 / (6.0 * dblAlpha))) / rgdbl[1];
|
|
rgdbl[3] = 2.0 / rgdbl[1];
|
|
rgdbl[4] = rgdbl[3] + 2.0;
|
|
rgdbl[5] = 1.0 / sqrt(dblAlpha);
|
|
|
|
for (;;)
|
|
{
|
|
MDOUBLE dblRand1;
|
|
MDOUBLE dblRand2;
|
|
do
|
|
{
|
|
dblRand1 = giveRandomNumberBetweenZeroAndEntry(1.0);
|
|
dblRand2 = giveRandomNumberBetweenZeroAndEntry(1.0);
|
|
|
|
if (dblAlpha > 2.5)
|
|
dblRand1 = dblRand2 + rgdbl[5] * (1.0 - 1.86 * dblRand1);
|
|
|
|
} while (!(0.0 < dblRand1 && dblRand1 < 1.0));
|
|
|
|
MDOUBLE dblTemp = rgdbl[2] * dblRand2 / dblRand1;
|
|
|
|
if (rgdbl[3] * dblRand1 + dblTemp + 1.0 / dblTemp <= rgdbl[4] ||
|
|
rgdbl[3] * log(dblRand1) + dblTemp - log(dblTemp) < 1.0)
|
|
{
|
|
return dblTemp * rgdbl[1];
|
|
}
|
|
}
|
|
assert(false);
|
|
return 0.0;
|
|
}
|
|
|
|
MDOUBLE talRandom::DblGammaLessThanOne(MDOUBLE dblAlpha){
|
|
//routine to generate a gamma random variable with
|
|
//unit scale and alpha < 1
|
|
//reference: Ripley, Stochastic Simulation, p.88
|
|
MDOUBLE dblTemp;
|
|
const MDOUBLE dblexp = exp(1.0);
|
|
for (;;){
|
|
MDOUBLE dblRand0 = giveRandomNumberBetweenZeroAndEntry(1.0);
|
|
MDOUBLE dblRand1 = giveRandomNumberBetweenZeroAndEntry(1.0);
|
|
if (dblRand0 <= (dblexp / (dblAlpha + dblexp))){
|
|
dblTemp = pow(((dblAlpha + dblexp) * dblRand0) /
|
|
dblexp, 1.0 / dblAlpha);
|
|
if (dblRand1 <= exp(-1.0 * dblTemp)) return dblTemp;
|
|
} else {
|
|
dblTemp = -1.0 * log((dblAlpha + dblexp) * (1.0 - dblRand0) /
|
|
(dblAlpha * dblexp));
|
|
if (dblRand1 <= pow(dblTemp,dblAlpha - 1.0)) return dblTemp;
|
|
}
|
|
}
|
|
assert(false);
|
|
return 0.0;
|
|
} // DblGammaLessThanOne
|
|
|