如何计算Java中正态分布下的面积?

时间:2014-11-24 01:47:55

标签: java math

我正在尝试计算曲线下面积的正态分布。通常,我可以参考计算器或z表。但是,我该如何编码呢?我有z,mu,sigma和边界的值。我在网上看到了多个代码,但没有一个代码解释它背后的逻辑。我想学习它是如何工作的,而不是使用外部方法,然后为它编写代码。

如果有人可以使用z,mu,sigma和边界来计算曲线下的面积,而没有任何复杂的细节,那将是一个很好的帮助。

由于

1 个答案:

答案 0 :(得分:3)

您可以像使用其他任何语言一样进行操作!

正态分布定义为具有如下概率:

enter image description here

您需要做的是整合它。首先,将概率分布转化为方法。我们可以通过使用mu = 0和sigma = 1来简化它。

/** 
 * Returns the height of the normal distribution at the specified z-score
 */
double getNormalProbabilityAtZ(double z) {
    return Math.exp(-Math.pow(z, 2) / 2) / Math.sqrt(2 * Math.PI);
}

接下来,我们需要一种方法来进行整合。我们的想法是将它分成一堆微小部分,在每个部分得到y值,然后乘以矩形的宽度。 Here's more reading on Riemann Sums,以防您不熟悉。

/**
  * Returns the area under the normal curve between the z-scores z1 and z2
  */
double getAreaUnderNormalCurve(double z1, double z2) {
    double area = 0.0;
    final int rectangles = 100000; // more rectangles = more precise, less rectangles = quicker execution
    final double width = (z2 - z1) / rectangles;
    for(int i = 0; i < rectangles; i++)
        area += width * getNormalProbabilityAtZ(width * i + z1);
    return area;
}

你有它!

如果您需要找到正态分布下的区域,让我们说z分数为1到无穷大,只需像getAreaUnderNormalCurve(1, 5)那样执行1到5之类的操作。为什么?因为在z=3之后,钟形曲线下面积非常小。在z=5之后,它甚至可以忽略不计甚至不值得整合。

免责声明:如果您需要最快的速度和精确度,您不应该自己实施。使用已存在的库,例如Apache Commons Error Function。您可以通过以下关系normalCdf(x) = 1/2 + 1/2 * erf(x / sqrt(2))

从错误函数中获取正常累积分布

快乐编码OP,如果仍然没有意义,请发表评论,我很乐意编辑我的答案。