Python scipy.stats中cdf的精度

Python scipy.stats中cdf的精度,python,numpy,scipy,precision,cdf,Python,Numpy,Scipy,Precision,Cdf,我将分布作为一个模拟系统的理论问题 对于给定的区间,我需要将此分布估计为定义为该区间内PDF积分的PMF。该值应接近间隔中心处PDF的值,但可能略有不同,具体取决于PDF的形状 以下是我的工作: import numpy from scipy.stats import chi2 dist = chi2(10) nbins = 120 F = dist.cdf(numpy.arange(nbins+1)) pmf = F[1:] - F[:-1] # surface inside the in

我将分布作为一个模拟系统的理论问题

对于给定的区间,我需要将此分布估计为定义为该区间内PDF积分的PMF。该值应接近间隔中心处PDF的值,但可能略有不同,具体取决于PDF的形状

以下是我的工作:

import numpy
from scipy.stats import chi2

dist = chi2(10)
nbins = 120

F = dist.cdf(numpy.arange(nbins+1))
pmf = F[1:] - F[:-1] # surface inside the interval
pmf /= pmf.sum() # Normalisation
问题是
chi2.cdf(100,10)
及以上给出的正好是1.0。所以我能得到的最小值大约是1.11e-16。但是chi2.pdf(100,10)并不完全是0(大约是2.5e-17)


我的问题是:如何获得更高精度的pmf估计值(可能高达1e-25)?为什么cdf函数的精度不如pdf函数?

cdf在浮点精度范围内等于1,但sf接近于零,因此微小的差异1e-20不会被大1所掩盖。(见JABS参考资料)


我不知道sf的精确范围有多远,即scipy.special.chdtrc(df,x),cdf在浮点精度等于1的范围内,但sf接近于零,因此微小的差异1e-20不会被大的1所掩盖。(见JABS参考资料)


我不知道sf的精确范围有多远,即scipy.special.chdtrc(df,x),通常每当我遇到精度问题时,我使用的第一个工具是mpmath。90%的时间它只是工作(tm),足够快。在这种情况下,我们可以写:

import mpmath
mpmath.mp.dps = 50 # decimal digits of precision

def pdf(x,k):
    x,k = mpmath.mpf(x), mpmath.mpf(k)
    if x < 0: return 0
    return 1/(2**(k/2) * mpmath.gamma(k/2)) * (x**(k/2-1)) * mpmath.exp(-x/2)

def cdf(x,k): 
    x,k = mpmath.mpf(x), mpmath.mpf(k) 
    return mpmath.gammainc(k/2, 0, x/2, regularized=True)

def cdf_via_quad(s,k):
    return mpmath.quad(lambda x: pdf(x,k), [0, s])

应该可以直接使用quad来获得所需的任何规格化。

通常每当我遇到精度问题时,我使用的第一个工具是mpmath。90%的时间它只是工作(tm),足够快。在这种情况下,我们可以写:

import mpmath
mpmath.mp.dps = 50 # decimal digits of precision

def pdf(x,k):
    x,k = mpmath.mpf(x), mpmath.mpf(k)
    if x < 0: return 0
    return 1/(2**(k/2) * mpmath.gamma(k/2)) * (x**(k/2-1)) * mpmath.exp(-x/2)

def cdf(x,k): 
    x,k = mpmath.mpf(x), mpmath.mpf(k) 
    return mpmath.gammainc(k/2, 0, x/2, regularized=True)

def cdf_via_quad(s,k):
    return mpmath.quad(lambda x: pdf(x,k), [0, s])

应该可以直接使用quad来获得所需的任何规格化。

谢谢!这正是我想要的。作为奖励,你向我展示了我不知道的diff函数。谢谢!这正是我想要的。另外,你给我展示了我不知道的微分函数。
>>> pdf(2,10)
mpf('0.0076641550244050483665734118783637680717877318964951605')
>>> cdf(2,10)
mpf('0.003659846827343712345456455812710150667594853455628779')
>>> cdf_via_quad(2,10)
mpf('0.003659846827343712345456455812710150667594853455628779')
>>> F[2]
0.0036598468273437131
>>> pdf(100,10)
mpf('2.5113930312030179466371651256862142900427508479560716e-17')
>>> cdf(100,10)
mpf('0.99999999999999994550298017079470664906667698474760744')
>>> cdf_via_quad(100,10)
mpf('0.99999999999999994550298017079470664906667698474760744')
>>> F[100]
1.0