random
Moduls Python hat die folgende Methode darin:Woher kommt "ainv"?
def gammavariate(self, alpha, beta):
"""Gamma distribution. Not the gamma function!
Conditions on the parameters are alpha > 0 and beta > 0.
The probability distribution function is:
x ** (alpha - 1) * math.exp(-x/beta)
pdf(x) = --------------------------------------
math.gamma(alpha) * beta ** alpha
"""
# alpha > 0, beta > 0, mean is alpha*beta, variance is alpha*beta**2
# Warning: a few older sources define the gamma distribution in terms
# of alpha > -1.0
if alpha <= 0.0 or beta <= 0.0:
raise ValueError('gammavariate: alpha and beta must be > 0.0')
random = self.random
if alpha > 1.0:
# Uses R.C.H. Cheng, "The generation of Gamma
# variables with non-integral shape parameters",
# Applied Statistics, (1977), 26, No. 1, p71-74
ainv = _sqrt(2.0 * alpha - 1.0)
bbb = alpha - LOG4
ccc = alpha + ainv
while 1:
u1 = random()
if not 1e-7 < u1 < .9999999:
continue
u2 = 1.0 - random()
v = _log(u1/(1.0-u1))/ainv
x = alpha*_exp(v)
z = u1*u1*u2
r = bbb+ccc*v-x
if r + SG_MAGICCONST - 4.5*z >= 0.0 or r >= _log(z):
return x * beta
elif alpha == 1.0:
# expovariate(1)
u = random()
while u <= 1e-7:
u = random()
return -_log(u) * beta
else: # alpha is between 0 and 1 (exclusive)
# Uses ALGORITHM GS of Statistical Computing - Kennedy & Gentle
while 1:
u = random()
b = (_e + alpha)/_e
p = b*u
if p <= 1.0:
x = p ** (1.0/alpha)
else:
x = -_log((b-p)/alpha)
u1 = random()
if p > 1.0:
if u1 <= x ** (alpha - 1.0):
break
elif u1 <= _exp(-x):
break
return x * beta
Während des Codes über Java für die Portierung, hat meine IDE beschwert, dass es ein Tippfehler (falsche Schreibweise) für die Variable ainv
Name ist. Woher kommt dieser Name und was ist die Begründung dafür? Wenn jemand Referenzmaterial für Applied Statistics, (1977), 26, Nr. 1, S.71-74 finden kann, kann es hilfreich sein, diese Seiten lesen zu können.
Nachtrag
Dies kann oder kann nicht von Nutzen für jeden sein, aber hier ist eine teilweise Umsetzung der Klasse, die über portiert wurde. Der Code scheint vollständig zu sein, aber JetBrains Intellij IDEA beschwert sich über die Schreibweise ainv
, wenn sie nicht zum Wörterbuch der IDE hinzugefügt wird. Dies hat zu einer gewissen Unentschiedenheit darüber geführt, ob es als richtig buchstabiert angesehen werden sollte oder nicht. Es ist der einzige Tippfehler, über den sich das Programm beschwert.
import java.util.Random;
class XRandom extends Random {
static final double LOG4 = Math.log(4);
static final double SG_MAGIC_CONST = 1 + Math.log(4.5);
double gammaVariate(double alpha, double beta) {
if (alpha <= 0 || beta <= 0)
throw new RuntimeException("gammaVariate: alpha and beta must be > 0");
if (alpha > 1) {
double ainv, bbb, ccc, u1, v, x, z, r;
ainv = Math.sqrt(2 * alpha - 1);
bbb = alpha - LOG4;
ccc = alpha + ainv;
while (true) {
u1 = this.nextDouble();
if (u1 <= 1e-7 || u1 >= .9999999)
continue;
v = Math.log(u1/(1 - u1))/ainv;
x = alpha * Math.exp(v);
z = u1 * u1 * (1 - this.nextDouble());
r = bbb + ccc * v - x;
if (r + SG_MAGIC_CONST - 4.5 * z >= 0 || r >= Math.log(z))
return x * beta;
}
}
if (alpha < 1) {
double b, p, x, u1;
while (true) {
b = (Math.E + alpha)/Math.E;
p = b * this.nextDouble();
x = p <= 1 ? Math.pow(p, 1/alpha) : -Math.log((b - p)/alpha);
u1 = this.nextDouble();
if (p > 1) {
if (u1 <= Math.pow(x, alpha - 1))
break;
} else if (u1 <= Math.exp(-x))
break;
}
return x * beta;
}
double u;
do {
u = this.nextDouble();
} while (u <= 1e-7);
return -Math.log(u) * beta;
}
}
Ich fand Seite 71 [hier] (http://www.jstor.org/stable/2346871?seq=1#page_scan_tab_contents), aber es sieht so aus, als ob Seiten 72-75 ein Konto benötigen, um sie in voller Auflösung anzuzeigen. – Kevin