Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/amazon-s3/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 如何近似泊松分布$P(n,λ)$_C_Approximation_Numerical Analysis - Fatal编程技术网

C 如何近似泊松分布$P(n,λ)$

C 如何近似泊松分布$P(n,λ)$,c,approximation,numerical-analysis,C,Approximation,Numerical Analysis,我必须实现一个算法来计算泊松函数的总和,每个函数都有相乘常数: 如果C(k)是正常数那么,一个简单的改进就是手动计算,并缓存lambda^k和(k+1)!,因为它们在上一次迭代中的值可以用于快速计算当前迭代中的相应值,使用O(1)计算 另外,由于1.0/exp(lambda)是一个常数,因此您应该提前1次计算它 #包括 ... //lambda和c[k]的定义。。。 恒长双e_系数=1.0/expq(λ); 长双inv_k_阶乘=1.0l; 长双lambda_功率k=1.0升; 长双和=0.0

我必须实现一个算法来计算泊松函数的总和,每个函数都有相乘常数:


如果C(k)是正常数那么,一个简单的改进就是手动计算,并缓存lambda^k和(k+1)!,因为它们在上一次迭代中的值可以用于快速计算当前迭代中的相应值,使用O(1)计算

另外,由于
1.0/exp(lambda)
是一个常数,因此您应该提前1次计算它

#包括
... //lambda和c[k]的定义。。。
恒长双e_系数=1.0/expq(λ);
长双inv_k_阶乘=1.0l;
长双lambda_功率k=1.0升;
长双和=0.0l;
对于(int k=0;k
现在,这三个函数调用及其各自的开销已经从循环中完全消失了

现在,我尝试使用与您在编写问题时相同的数据类型。由于您的评论表明lambda大于1.0(我认为,由于lambda_pow_k
迅速减小,因此没有相对误差增长),因此此处失去的任何意义将取决于
长双精度
的限制,这取决于您的具体需要,可能是好的,也可能是坏的


  • 现在的编译器很聪明。所以它可以像那样进行优化,但我认为最好将不太明显的优化留给优化器。即使交给非优化编译器,代码的性能也不会受到影响

  • 由于泊松概率服从简单递推

    P(k,lam) = lam/k * P(k-1,lam)
    
    一种可能是对多项式使用霍纳法则。即:

    Sum{k|C[k]*P(k,lam)} = exp(-lam)*(C[0]+(lam/1)*(C[1]+(lam/2)*(..))..)
    


    你能解释一下“不太满意”是什么意思吗?因为我的截止值至少应该是4西格玛,当λ等于50时,处理器必须按照我的代码计算50^75/75!,我担心这可能是一个重大错误的来源……在评论中,他表示,他担心大价值可能导致不准确。你能解决这个问题吗。我不认为这应该是一个长双的问题,但它会扩大你的答案。尽管如此,做得很好+1@KamiKaze-增加一段。但我可能会有一些错误的假设,所以任何更正都将受到赞赏。是的,这非常聪明!这是实现泊松分布求和的更有效的方法吗?@FrancescoDiLauro-我不能肯定地告诉你。在我看来,它应该在执行速度方面提供一些改进(通常的技巧是用一些内存换取时间)。您必须验证结果是否与原始循环一样重要。由于lambda肯定大于1(您说的是50),我认为只要x!lambda^x没有达到变量类型的可能数字空间的界限,在这里应该很好。乘法和除法非常精确“问题”出现在值的加法中第一个和最后一个值可能会被你的中间地带(50+-(~25))所“掩盖”,因为这些值非常大,而末尾的数字相比之下非常小,它们可能会在加法中丢失。然后再次强调,这对最终的总和没有多大影响,因为这些数字也是有限的,并且是递减的@这和我的回答有什么不同?除了去掉Horner的名字,这很好。两个问题:为什么Horner规则比递归规则更好?根据定义,这种算法比泊松分布的直接实现更精确吗?一般来说,霍纳规则比其他方法更有效、更精确。值得一看。@StoryTeller您的代码在每个循环迭代中进行3次乘法(尽管您可以通过组合inv_k_factorial和lambda_pow_j将其减少到2次);我的1@dmuir,可以肯定的是,如果我的和从k=1开始,循环在k达到1时停止,对吗?所以它有点像for(k=cutoff-1;k>1;k--)
    P(k,lam) = lam/k * P(k-1,lam)
    
    Sum{k|C[k]*P(k,lam)} = exp(-lam)*(C[0]+(lam/1)*(C[1]+(lam/2)*(..))..)
    
    P = c[cut]
    for k=cut-1 .. 0
      P = P*lam/(k+1) + C[k]
    P *= exp(-lam)