正态分布函数

时间:2009-03-18 03:40:28

标签: objective-c algorithm math

修改

所以基于到目前为止的答案(感谢您抽出时间),我感觉我可能不会寻找正态分布函数。也许我会尝试重新描述我想要做的事情。

假设我有一个返回0到10的对象。该数字控制“速度”。然而,不是10是最高速度,我需要5来成为最高速度,而任何更低或更高的东西都会相应减速。 (缓和,因此钟形曲线)

我希望更清楚; /


- 原始问题
这些是我希望我记得数学课上的一些东西。

我正在试图找出如何在obj-C中编写函数,我在其中定义边界,ex(0 - 10)然后如果x = foo y =? ....其中x运行类似0,1,2,3,4,5,6,7,8,9,10和y运行0,1,2,3,4,5,4,3,2 ,1,0但只在曲线上

像附图一样的东西。

我尝试使用谷歌搜索正常分布,但它超越了我的头脑。我希望找到一些网站列出一些有用的算法,但不是很成功。

那么有人可以帮助我吗?如果有一些好的网站显示有用的数学函数,我很乐意检查它们。

TIA !!!

- 增加
我不是在寻找一个随机数,我正在寻找..例如:如果x = 0 y应该是0,如果x = 5 y应该是5,如果x = 10 y应该是0 ....所有那些在数字之间不那么明显的人

alt text http://dizy.cc/slider.gif

8 个答案:

答案 0 :(得分:3)

您要绘制的内容是正态分布的概率密度函数(pdf)。您可以在the mighty Wikipedia上找到它。

幸运的是,正常分发的pdf并不难实现 - 其他一些相关功能因为需要错误功能而更加糟糕。

要获得您所显示的情节,您需要平均值为5,标准偏差约为1.5。中位数显然是中心,并且考虑到左边和下边线,找出适当的标准偏差。正确的界限并不是特别困难。

在给定x坐标,标准差和平均值的情况下计算pdf的y值的函数可能如下所示:

double normal_pdf(double x, double mean, double std_dev) {
    return( 1.0/(sqrt(2*PI)*std_dev) *
            exp(-(x-mean)*(x-mean)/(2*std_dev*std_dev)) );
}

答案 1 :(得分:3)

好的,你的编辑确实澄清了事情。你不是在寻找与正态分布有关的任何东西,只是一个很好的平滑的小斜坡函数。 one Paul provides会做得很好,但修改其他值很棘手。它可以更灵活一些(我的代码示例在Python中,它应该很容易翻译成任何其他语言):

def quarticRamp(x, b=10, peak=5):
    if not 0 <= x <= b:
        raise ValueError   #or return 0
    return peak*x*x*(x-b)*(x-b)*16/(b*b*b*b)

参数b是您想要斜率的区域的上限(在您的示例中为10),而peak是您希望它有多高的区域(5,在例子)。

就个人而言,我喜欢二次样条方法,这种方法在计算上稍微便宜一些,并且与它有不同的曲线(这条曲线非常适合在几个对你来说根本不重要的特殊应用中使用):

def quadraticSplineRamp(x, a=0, b=10, peak=5):
    if not a <= x <= b:
        raise ValueError   #or return 0
    if x > (b+a)/2:
        x = a + b - x
    z = 2*(x-a)/b
    if z > 0.5:
        return peak * (1 - 2*(z-1)*(z-1))
    else:
        return peak * (2*z*z)

这与其他函数类似,但采用下限a(在您的示例中为0)。逻辑稍微复杂一点,因为它是分段函数的某种优化实现。

两条曲线的形状略有不同;你可能不在乎确切的形状是什么,所以也可以选择。有无限数量的斜坡函数符合您的标准;这些是两个简单的,但它们可以像你想要的那样得到巴洛克式。

答案 2 :(得分:2)

正态分布永远不会等于0。 请确保您想要绘制的内容确实是一个 正态分布。

如果你只是寻找这种钟形(有切线和一切) 您可以使用以下公式:

x^2*(x-10)^2 for x between 0 and 10
                0 elsewhere

(如果您需要查看5,请除以125.)

double bell(double x) {
    if ((x < 10) && (x>0))
        return x*x*(x-10.)*(x-10.)/125.;
    else
        return 0.;
}

答案 3 :(得分:0)

当然,有很好的旧维基百科。并Mathworld

你想要的是"generating normally distributed random deviates"的随机数生成器。由于Objective C可以调用常规C库,因此您需要像GNU Scientific Library这样的C可调用库,或者为此,您可以按照描述here自行编写。

答案 4 :(得分:0)

尝试通过生成1到6之间的随机数来模拟骰子卷。如果您从5个独立的骰子卷中添加卷,您将获得与正态分布相比非常好的近似值。如果你愿意,你可以滚动更多骰子,你会得到更好的近似值。

这是一个article,解释了为什么会这样做。它可能比您想要的更多数学细节,但您可以向某人展示以证明您的方法是合理的。

答案 5 :(得分:0)

如果你想要的是概率密度函数的值,p(x),平均μ的正态(高斯)分布和x处的标准偏差西格玛,公式是

p(x) = exp( ((x-mu)^2)/(2*sigma^2) ) / (sigma * 2 * sqrt(pi))

其中pi是圆的面积除以其半径的平方(约3.14159 ......)。使用C标准库math.h,这是:

#include <math>

double normal_pdf(double x, double mu, double sigma) {
  double n = sigma * 2 * sqrt(M_PI); //normalization factor
  p = exp( -pow(x-mu, 2) / (2 * pow(sigma, 2)) ); // unnormalized pdf

  return p / n;
}

当然,你可以在Objective-C中做同样的事情。

如需参考,请参阅WikipediaMathWorld文章。

答案 6 :(得分:0)

听起来你想写一个能产生特定形状曲线的函数。类似于y = f(x),对于[0:10]中的x​​。你对y的最大值有一个约束,并且你想要曲线看起来像是一个大概的想法(有点钟形,x范围边缘y = 0,x = 5时y = 5)。粗略地说,你可以用x范围迭代地调用你的函数,其中一个步骤可以让你有足够的点来让你的曲线看起来很漂亮。

所以你真的不需要随机数,这与概率无关,除非你想要它(因为你希望你的曲线看起来像正态分布的轮廓或沿着这些线的东西)

如果你清楚地知道什么函数会产生你想要的曲线,那么代码是微不足道的 - 一个计算f(x)的函数和一个for循环来调用它所需的x值所需的次数。绘制x,y对,你就完成了。这就是你的算法 - 在for循环中调用一个函数。

实现该功能的例程的内容将取决于您希望曲线的具体情况。如果您需要有关可能返回类似于样本的曲线的函数的帮助,我会引导您阅读其他答案中的阅读材料。 :)但是,我怀疑这实际上是某种类型的赋值,并且您已经获得了一个函数。如果你实际上是在自己学习这个,那么我再次回应其他阅读建议。

答案 7 :(得分:0)

Y = -1 * ABS(X-5)5