Python имеет следующий метод в нем:Откуда «айнв»? <code>random</code> модуль
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
При переносе кода к Java для использования, мой IDE жалуется, что есть опечатка (опечатка) для имени переменной ainv
. Откуда взялось это имя и каково его оправдание? Если кто-либо может найти справочный материал для Applied Statistics, (1977), 26, No. 1, p71-74, возможность чтения этих страниц может быть полезна.
Добавление
Это может или не может быть полезным для всех, но здесь это частичная реализация класса, который был перенесен. Код выглядит полным, но JetBrains Intellij IDEA жалуется на правописание ainv
, если он не добавлен в словарь IDE. Это привело к некоторой нерешительности в отношении того, следует ли считать это правильно. Это единственная опечатка, о которой жалуется программа.
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;
}
}
Я нашел страницу 71 [здесь] (http://www.jstor.org/stable/2346871?seq=1#page_scan_tab_contents), но похоже, что страницы 72-75 требуют, чтобы учетная запись просматривала их при полном разрешении. – Kevin