简体   繁体   English

“ainv”来自哪里?

[英]Where does “ainv” come from?

Python's random module has the following method in it: Python的random模块中包含以下方法:

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

While porting the code over to Java for use, my IDE has been complaining that there is a typo (misspelling) for the ainv variable name. 在将代码移植到Java以供使用时,我的IDE一直在抱怨ainv变量名称存在拼写错误(拼写错误)。 Where does this name come from, and what is the justification behind it? 这个名字来自哪里,背后的理由是什么? If anyone can find reference material for Applied Statistics, (1977), 26, No. 1, p71-74 , being able to read those pages may be helpful. 如果有人能找到应用统计学的参考资料,(1977),26,No.1,p71-74 ,那么能够阅读这些页面可能会有所帮助。

Addendum 附录

This may or may not be of use to anyone, but here is a partial implementation of the class that was ported over. 这可能对任何人都有用,也可能没用,但这里是移植过的类的部分实现。 The code appears to be complete, but JetBrains Intellij IDEA complains about ainv 's spelling if it is not added to the IDE's dictionary. 代码似乎是完整的,但JetBrains Intellij IDEA抱怨ainv的拼写如果没有添加到IDE的字典中。 This has led to some indecision as to whether or not it should be considered to be correctly spelled. 这导致了一些关于是否应该被认为是正确拼写的犹豫不决。 It is the only typo the program is complaining about. 这是该计划抱怨的唯一错字。

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;
    }
}

Not sure why the IDE thinks it's a typo, but don't you just need to declare the ainv variable? 不知道IDE为什么认为这是一个错字,但是你不需要声明ainv变量吗?

double ainv = Math.sqrt(2.0 * alpha - 1.0) ;

As for it's purpose, it looks to be just an intermediate calculation that's used in two other places. 至于它的目的,它看起来只是一个在其他两个地方使用的中间计算。

I found page 71 here , but it looks like pages 72-75 require an account to view them at full resolution. 我在这里找到了第71页,但看起来第72-75页需要一个帐户才能以全分辨率查看它们。

在此输入图像描述

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM