C++ 在c+中实现泊松分布+;

C++ 在c+中实现泊松分布+;,c++,distribution,factorial,poisson,C++,Distribution,Factorial,Poisson,我正试图编写一个程序,用参数lambda计算泊松分布的概率质量函数p(x=n),使用以下公式:((e^-lambda)*(lambda^n))/n 当我使用较小的lambda和较小的数字时,这种方法效果很好,但是如果我想用lambda 20计算例如p(x=30),结果是4.68903e+006,这是错误的 我认为问题在于计算n!。我实现了一个计算阶乘值的函数,并使用unsigned long long数据类型作为阶乘计算的结果,但问题是30!等于2652528598121910586308480

我正试图编写一个程序,用参数lambda计算泊松分布的概率质量函数p(x=n),使用以下公式:
((e^-lambda)*(lambda^n))/n

当我使用较小的lambda和较小的数字时,这种方法效果很好,但是如果我想用lambda 20计算例如p(x=30),结果是4.68903e+006,这是错误的

我认为问题在于计算n!。我实现了一个计算阶乘值的函数,并使用
unsigned long long
数据类型作为阶乘计算的结果,但问题是30!等于26525285981219105863084800000000,无符号long-long的最大可用数为18446744073709551615,小于30

我应该如何处理这个问题?在C++中,有没有其他的方法或函数来计算这种可编程性?
数据类型

如果只需要从泊松分布生成随机值,否则不需要知道其概率质量函数,最直接的方法是使用C++11的一部分。类似的实现也可以在Boost中找到。

试试数学

 (lambda^n))/n!
不是吗

 (lambda/n) * (lambda/(n-1) * ...

这些数字可以用double来管理,而不是计算非常大的数值

处理大n的一个解决方法是计算对数域中的分布:

X = ((e^-lambda)*(lambda^n))/n!
ln X = -lambda + n*ln(lambda) - Sum (ln(n))
return e^X

为什么要投否决票?这个问题怎么了?@Cheiron:在我们看不见的代码中很难找到bug。SO指南在这一点上相当明确。@mAlter的问题不必包含关于SO主题的代码。事实上,许多排名最高的问题都没有代码。@isarandi:我知道,我遵循Meta.SO。但请看第三段的开头:我认为问题是。。。。这就是为什么我们确实需要代码,如果它存在的话。SO指导方针还特别指出,当你对一篇文章投否决票时,应该对错误之处进行评论。这是一个糟糕的实现。计算λ^ n
是O(对数n),计算这是O(n)。实现这一点的正确方法(在
发行版之前的C++98中)是通过O(logn)实现的。(一个更好的方法首先计算
log(((e^-lambda)*(lambda^n))/n!)
,因为这很简单)它是精确的,不是近似值它将是三项内的近似值;计算机是二进制的,所以
lambda/n
lambda/n-1
lambda/n-2
试图除以三。在这种情况下,n=30时的O(n)真的那么糟糕吗?这个答案很简单。我唯一可以做的改变是这样做:double total=pow(lamda,n);对于(int i=2;我不知道有什么方法可以从
std::poisson_分布
中实际提取pmf的值。想详细说明一下吗?@T.C.:我想你可能有一点——基本均匀范围到poisson分布范围没有定义的映射。我将在这里留下答案,以防有人知道如何提取在一个给定的C++分布中起到一个PMF的作用。在很多情况下,我认为它不需要计算PMF/PDF/CDF来生成数字。例如,<代码> NojialDista[/Cord] >可以使用Box Mulle变换。Iythm <代码> n*Ln(lambda)< /> > Ln(n!)=和(Ln(n))。是的,其中
n
内部的
Sum
实际上是一个索引,而不是一个固定的
n
。也许我把它简化得太多了,我肯定有点滥用了这个符号。