所有可能导致 NaN 输出的情况是什么?(Java 中)

问题描述 投票:0回答:0

我正在尝试制作一个生成正态分布数字的随机数生成器,我有一个 CDF 方法来计算任何给定 x 的 CDF,然后我有一个 invNorm 方法,它使用牛顿法进行超过 30 次迭代,接受所需的值,并且它找到 x 使得 CDF(x)=desired。

This is the formula for estimation of CDF that ive implemented

This is the Newton's method formula I have used(on evaluation the denominator {\Phi '(x)} simplifies and can brought to the numerator

public double cdf(double x){
        double out=0;
        for(int k=0;k<30;k++){
            out+=Math.pow(-1,k)*Math.pow(x,(2*k)+1)/(Math.pow(2,k)*factorial(k)*((2*k)+1));
        }
        return 0.5+(out/Math.sqrt(2*Math.PI));
    }
    public double invNorm(double desired){
        double x=0;
        double dx;
        for(int i=0;i<30;i++){
            dx=(cdf(x)-desired)*Math.exp(x*x*0.5)*Math.sqrt(2*Math.PI);
            x-=dx;
        } 
        return x;
    }

但是这段代码有 10% 的时间给出 NaN。当我运行代码创建一个包含 100 个随机数的数组并包含这一行“while(Double.isNaN(arr[i])) arr[i]=Misc.invNorm(Math.random());”时如果 arr[i] 被评估为 NaN,则重新分配 arr[i],代码运行完美,并在第一个标准差之间给出 70% 的值,在第二个标准差之间给出 97,在第三个标准差之间给出 100。cdf 函数绝对不是问题,因为我检查了cdf 函数通过使用随机数 cdf 打印 100 的数组,并且其中没有一个是 NaN,但 invNorm 根本没有任何除法,所有幂都是整数,并且没有三角函数。我考虑了 Math.exp 返回正无穷大和 (cdf(x)-desired) 返回 0 的可能性,但 e^450 不是正无穷大并且 cdf(x) 等于所需值的情况非常罕见。

当我们讨论这个主题时,有人可以帮助我实现 CDF 的递归函数吗?我尝试像这样实现它,其中 cdf_n 是第 n 个近似值,我认为 x0=0,所以 CDF(x0)=0.5,但这几乎 60% 的时间给出了 NaN。

public double cdf_n(double x,int n){
        if(n==0){
            return 0.5;
        }
        else if(n==1){
            return 1/Math.sqrt(2*Math.PI);
        }
        else{
            return (2-n)*cdf_n(x, n-2);
        }
    }
    public double cdf(double x){
        int n=0;
        double out;
        double cdf=0;
        do{
            out=cdf_n(x,n)*Math.pow(x,n)/factorial(n);
            cdf+=out;
            n++;
        } while(Math.abs(out)>Math.pow(10.0,-15.0));
        return cdf;
    }  

This is the recursive formula

java recursion random nan
© www.soinside.com 2019 - 2024. All rights reserved.