Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/328.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_Quad - Fatal编程技术网

Python 当要集成的函数也是整数时,scipy.integrate.quad(有时)会失败

Python 当要集成的函数也是整数时,scipy.integrate.quad(有时)会失败,python,scipy,quad,Python,Scipy,Quad,我正在使用sqipy.integrate.quad计算二重积分。基本上我想计算exp[-mu_wx_par]上的积分,其中mu_wx_par也是一个积分 我的代码大部分是有效的。但是,对于某些值,它会失败,即返回不正确的值 import numpy as np from scipy import integrate def mu_wx_par(x, year, par): """ First function to be integrated """ m = max(par[

我正在使用
sqipy.integrate.quad
计算二重积分。基本上我想计算exp[-mu_wx_par]上的积分,其中mu_wx_par也是一个积分

我的代码大部分是有效的。但是,对于某些值,它会失败,即返回不正确的值

import numpy as np
from scipy import integrate


def mu_wx_par(x, year, par):
    """ First function to be integrated """
    m = max(par['alfa'], 0) + par['beta'] * 10 ** (par['gamma'] * x)
    w = np.minimum(par['frem_a'] + par['frem_b'] * x + par['frem_c'] * x**2, 0)
    return m * (1 + w/100)**(year - par['innf_aar'])


def tpx_wx(x, t, par, year):
    """ Second function to be integrated (which contains an integral itself)"""
    result, _ = integrate.quad(lambda s: mu_wx_par(x + s, year + s, par), 0, t)
    return np.exp(-result)


def est_lifetime(x, year, par):
    """ Integral of second function. """
    result, _ = integrate.quad(lambda s: tpx_wx(x, s, par, year), 0, 125 - x)

    return result


# Test variables
par = {'alfa': 0.00019244401470947973,
       'beta': 2.420260552210541e-06,
       'gamma': 0.0525500987420195,
       'frem_a': 0.3244611019518985,
       'frem_b': -0.12382978382606026,
       'frem_c': 0.0011901237463116591,
       'innf_aar': 2018
       }


year = 2018
estimate_42 = est_lifetime(42, year, par)
estimate_43 = est_lifetime(43, year, par)
rough_estimate_42 = sum([tpx_wx(42, t, par, year) for t in range(0, 100)])

print(estimate_42)
print(estimate_43)
print(rough_estimate_42)
3.1184634065887544
46.25925442287578
47.86323490659588
估算值_42
不正确。它应该与
粗略估计值\u 42
大致相同。但是请注意,
估计值\u 43
看起来不错。这是怎么回事

我正在使用scipyv1.1.0和numpyv1.15.1以及Windows

有人认为,函数几乎在任何地方都接近于零,就像在这篇文章中一样。但情况并非如此,因为从
a=0
b=125-42
tpx_wx
x=42
的简单曲线图清楚地显示了这一点

from matplotlib import pyplot as plt

plt.plot(range(125-42), [tpx_wx(42, t, par, year) for t in range(0, 125-42)])
plt.show()

这似乎与为Windows编译
quad
后的某些Fortran代码的方式有关:在某些情况下,递归调用它可能导致失败。另见

除非使用更好的标志重新编译SciPy,否则在Windows上应该避免与
quad
嵌套集成。一种解决方法是对其中一个集成步骤使用方法。将
est\u寿命中的
quad
替换为

integrate.romberg(lambda s: tpx_wx(x, s, par, year), 0, 125 - x, divmax=20)
对于
estimate\u 42
,结果为
47.3631754795
,与Linux上的
quad
结果一致


可视化集成过程的一种方法是声明一个全局列表
eval_点
并插入
eval_点。将(t)
附加到
tpx_wx
中。使用相同版本的SciPy(本测试中为0.19.1),plt.plot(eval_points,')
的结果看起来不同

在Linux上:

在Windows上:


在Windows上,一个棘手的点60附近的邻域的迭代二分法被提前终止,并且产生的结果似乎是子区间上的部分积分。

使用SciPy 1.1.0,我得到了47.36317494751913的
估计值42
,嗯。我目前不在办公室,所以我无法检查我的版本og SciPy。但我发现,当我尝试对x的倍数进行积分时(比如对20到80之间的x进行积分),有些会失败,而另一些则可以。。。。这似乎是随机的,会失败。这不是同一个问题。如果是这样的话,你就不会得到正确的答案。这个函数一点也不奇怪。你从我这里得到不同的答案这一事实本身就令人怀疑。在另一台计算机上运行我的代码也给出了错误的答案我使用Windows顺便说一句。不知道这是否重要。我还得到了3.118。。。在Windows上运行时。奇怪。无论如何,添加
点=[(125-x)/2]
(实际上,将集成范围一分为二)解决了这个问题。哇!你真的在这里多走了一英里。非常感谢。对其中一个积分使用不同的例程可能是一种方法。再次感谢!