Java 独立于Apache的Gamma分布

Java 独立于Apache的Gamma分布,java,apache,math,distribution,random-sample,Java,Apache,Math,Distribution,Random Sample,您好,我注意到Apache数学库(版本2.2)中有一些奇怪的行为,特别是在org.Apache.commons.math.distribution.GammaDistributionImpl类中,尽管我认为这可能也适用于其他发行版 我想从不同的伽马分布中取样,如下所示: public static final double[] gammaSamples(final double[] shapeParameters) { double[] samples = new double[shap

您好,我注意到Apache数学库(版本2.2)中有一些奇怪的行为,特别是在
org.Apache.commons.math.distribution.GammaDistributionImpl
类中,尽管我认为这可能也适用于其他发行版

我想从不同的伽马分布中取样,如下所示:

public static final double[] gammaSamples(final double[] shapeParameters)
{
    double[] samples = new double[shapeParameters.length];
    for (int i = 0; i < shapeParameters.length; i++)
    {
        GammaDistributionImpl gd = new GammaDistributionImpl(shapeParameters[i], 1.0d);
        try
        {
            samples[i] = gd.sample();
        }
        catch (MathException e)
        {
            e.printStackTrace();
        }
    }
    return samples;
}
public static final double[] gammaSamples(final double[] shapeParameters, final Random random)
{
    double[] samples = new double[shapeParameters.length];
    for (int i = 0; i < shapeParameters.length; i++)
    {
        GammaDistributionImpl gd = new GammaDistributionImpl(shapeParameters[i], 1.0d);
        gd.reseedRandomGenerator(random.nextLong());
        try
        {
            samples[i] = gd.sample();
        }
        catch (MathException e)
        {
            e.printStackTrace();
        }
    }
    return samples;
}
一些示例输出为:

[0.8732612631078758, 0.860967116242789, 0.8676088095186796]
[0.6099133517568643, 0.5960661621756747, 0.5960661621756747]
[2.1266766239021364, 2.209383544840242, 2.209383544840242]
[0.4292184700011395, 0.42083613304362544, 0.42083613304362544]
[2.7506981228470084, 0.49600951917542335, 6.841476090550152]
[1.7571444623500108, 1.941865982739116, 0.2611420777612158]
[6.043421570871683, 0.8852269293415297, 0.6921033738466775]
[1.3859078943455487, 0.8515111736461752, 3.690127105402944]
我认为问题是由于默认的随机数生成器对每个分布使用相同/相似的种子,我测试如下:

public static final double[] gammaSamples(final double[] shapeParameters)
{
    double[] samples = new double[shapeParameters.length];
    for (int i = 0; i < shapeParameters.length; i++)
    {
        GammaDistributionImpl gd = new GammaDistributionImpl(shapeParameters[i], 1.0d);
        try
        {
            samples[i] = gd.sample();
        }
        catch (MathException e)
        {
            e.printStackTrace();
        }
    }
    return samples;
}
public static final double[] gammaSamples(final double[] shapeParameters, final Random random)
{
    double[] samples = new double[shapeParameters.length];
    for (int i = 0; i < shapeParameters.length; i++)
    {
        GammaDistributionImpl gd = new GammaDistributionImpl(shapeParameters[i], 1.0d);
        gd.reseedRandomGenerator(random.nextLong());
        try
        {
            samples[i] = gd.sample();
        }
        catch (MathException e)
        {
            e.printStackTrace();
        }
    }
    return samples;
}
一些示例输出为:

[0.8732612631078758, 0.860967116242789, 0.8676088095186796]
[0.6099133517568643, 0.5960661621756747, 0.5960661621756747]
[2.1266766239021364, 2.209383544840242, 2.209383544840242]
[0.4292184700011395, 0.42083613304362544, 0.42083613304362544]
[2.7506981228470084, 0.49600951917542335, 6.841476090550152]
[1.7571444623500108, 1.941865982739116, 0.2611420777612158]
[6.043421570871683, 0.8852269293415297, 0.6921033738466775]
[1.3859078943455487, 0.8515111736461752, 3.690127105402944]
我的问题是:

发生什么事了?这是一个bug还是Apache Mathematics发行版打算这样做

我觉得奇怪的是,如果我创建单独的分发对象,我必须担心它们被赋予了什么种子,并确保它们足够不同

另一个小小的烦恼是,我似乎无法将这些分布传递给我自己的随机对象,而它们只允许通过reseedRandomGenerator(长种子)方法更改种子。当试图复制结果时,能够传递我自己的随机对象将非常有用


感谢您的帮助。

通过查看javadoc:

我看到有方法
public double[]sample(int-sampleSize)抛出MathException

从分布中生成随机样本。默认值 实现通过在循环中调用sample()生成示例

你试过了吗

double[] samples = sample(shapeParameters.length);
编辑:很抱歉,我看到您每次都使用一个新的
alpha
参数计算一个新的
GammaDistributionImpl
。我猜这是因为种子值是从具有有限分辨率的系统时钟派生出来的,对构造函数的关闭调用将产生相同的结果。看看这个

以下是一些可以让您进行更深入调查的输入:

  • 您可以浏览网页。
    如果可能,您应该更新到lib的v3.1。根据JIRA
  • 您可以在

谢谢,我认为你说得对,因为种子值来自系统时钟。我还刚刚查看了3.1版的库,它们有一个额外的构造函数
GammaDistribution(RandomGenerator rng,双形状,双刻度,双反转精度)
,这正是我想要的(能够通过我自己的随机数生成器)。我觉得应该有一个警告,不要在循环中创建“随机”对象,因为考虑到现代系统的速度,它们可能会被赋予相同的种子。这感觉就像种子问题,不是吗!这不仅仅是一个种子问题,它几乎肯定是一个种子问题。看看我发布的代码,原来的
gammaSamples
方法不起作用,正在使用默认种子,修改后的
gammaSamples
方法设置了自己的种子,但在其他方面是等效的,并解决了问题。