Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/redis/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
Python 使用scipy.integrate.quad时,增加正函数的边界会降低积分!如何解决?_Python_Scipy_Integral_Integrate - Fatal编程技术网

Python 使用scipy.integrate.quad时,增加正函数的边界会降低积分!如何解决?

Python 使用scipy.integrate.quad时,增加正函数的边界会降低积分!如何解决?,python,scipy,integral,integrate,Python,Scipy,Integral,Integrate,我用scipy.integrate来计算定积分。我编写了以下代码片段来计算概率密度函数(PDF)和累积分布函数(CDF),以计算PDF中的CDF,如下所示: inf = 10000 def f_normal(m, tau): #normal pdf with mean np.sqrt(m- 1/2) and var 1/pi tmp = 1/np.sqrt(np.pi) * np.exp( - ( tau - np.sqrt(m- 1/2) )**2 ) return

我用scipy.integrate来计算定积分。我编写了以下代码片段来计算概率密度函数(PDF)和累积分布函数(CDF),以计算PDF中的CDF,如下所示:

inf = 10000

def f_normal(m, tau): #normal pdf with mean np.sqrt(m- 1/2) and var 1/pi
    tmp = 1/np.sqrt(np.pi) * np.exp(  -  ( tau - np.sqrt(m- 1/2) )**2   )
    return tmp

def F_normal(m, x): #integral of f_normal from -inf to x
    return integrate.quad(lambda tau: f_normal(m, tau), -inf, x)
但当我评估时:

m=10    
print(f_normal(m, 10))    
print(F_normal(m, inf))
我得到了
(0.0,0.0)
对于
F_normal(m,inf)
,而我真的期望1。我不明白发生了什么事。我还试图理解integrate.quad命令,因此得到了这些奇怪的值:增加边界会降低正函数PDF的定积分,因此没有意义:

integrate.quad(lambda tau: f_normal(m, tau), -10, 10)
Out[30]: (1.0, 2.2977017217085778e-09)

integrate.quad(lambda tau: f_normal(m, tau), -100, 100)
Out[31]: (1.0, 8.447041410391393e-09)

integrate.quad(lambda tau: f_normal(m, tau), -1000, 1000)
Out[32]: (0.9999934640807174, 1.857441875165816e-09)

integrate.quad(lambda tau: f_normal(m, tau), -10000, 10000)
Out[33]: (5.659684283308144e-150, 1.1253180602819657e-149)

integrate.quad(lambda tau: f_normal(m, tau), -10000, 100)
Out[34]: (0.0, 0.0)

integrate.quad(lambda tau: f_normal(m, tau), -10000, 1000000)
Out[35]: (0.0, 0.0)

我有点困惑:感谢你的帮助

问题是
inf
太大了。您正在尝试对该函数进行聚合

但是您发送到integrate.quad的是

求积例程不太可能在值本质上不是0的任何地方对该函数进行采样,从而导致错误的结果

幸运的是,使用
np.inf
,您可以告诉算法,积分在一个无限区间上,它将更智能地查找函数相关行为的位置。该代码给出了正确的积分:

def f_normal(m, tau): #normal pdf with mean np.sqrt(m- 1/2) and var 1/pi
    tmp = 1/np.sqrt(np.pi) * np.exp(  -  ( tau - np.sqrt(m- 1/2) )**2   )
    return tmp

def F_normal(m, x): #integral of f_normal from -inf to x
    return integrate.quad(lambda tau: f_normal(m, tau), -np.inf, x)

m=10    
print(f_normal(m, m-.5))    
print(F_normal(m, np.inf))
或者,您可以在函数不太接近0的位置,对较小的有限区间进行积分。在这种情况下,中心(
np.sqrt(m-1/2)
)加上或减去100是可靠的(原始长度20000的间隔太大):


谢谢你的回答-这确实解决了打印(F_normal(m,np.inf))的问题,当m很小时(更精确地说,对于m小于或等于350,它得到的积分值接近1。但随后它迅速减小:对于$m\ge 365,$m值很小,对于大的m,它趋于零,例如$m=3750,$print(F_normal)(m,np.inf))提供2.73美元.$我想知道为什么会发生这种情况:积分应该始终为1,而不是在m很大的情况下变为零。我们仍然可以遇到与原始情况相同的问题。使用无限边界,算法将函数转换为有限区间,并在那里进行求积。如果转换后的函数在所有求积中大约为0对于e点,该算法从未找到任何相关点来计算结果。将平均值从原点移开会压缩变换域中的支持度,并使此问题更加常见。将支持度保持在原点附近(变换不太明显)会更可靠。再次感谢!但对于我的问题,我真的需要让m去无穷大,所以真的没有办法获得正确的打印值(F_normal(m,x))对于如此大的m和任意的x?如果你知道pdf的支持,如果它足够小,有限的间隔将起作用。例如,你的原始代码使用inf=20。使用
m=10000
,我使用0和200的有限边界得到正确的积分。但是如果你不知道函数的支持,那么quadra真的不可避免地会在某一点上失败:该算法将对所有为0的点进行采样,并错过函数正在做一些有趣的事情的部分。是的,我使用了大约sqrt(m-1/2)+/-100作为积分边界,对于大范围的m值,它似乎接近数值精度。
def f_normal(m, tau): #normal pdf with mean np.sqrt(m- 1/2) and var 1/pi
    tmp = 1/np.sqrt(np.pi) * np.exp(  -  ( tau - np.sqrt(m- 1/2) )**2   )
    return tmp

def F_normal(m, x): #integral of f_normal from -inf to x
    return integrate.quad(lambda tau: f_normal(m, tau), np.sqrt(m- 1/2)-100, x)

m=10000
print(f_normal(m, m-.5))    
print(F_normal(m, np.sqrt(m- 1/2)+100))