quadpy IntegrationError: Tolerances (abs: 1.49e-08, rel: 1.49e-08) could not be reached with the given max_num_subintervals (= 50)
quadpy IntegrationError: Tolerances (abs: 1.49e-08, rel: 1.49e-08) could not be reached with the given max_num_subintervals (= 50)
我正在使用 quadpy 来集成 python 中的一个函数。
函数
import numpy as np
T = 2*np.pi
def ex1(t):
return np.where(np.logical_and((t%T>=0), (t%T<np.pi)), t%T, np.pi)
函数是周期性的,这是它的曲线:
x = np.linspace(0, 6*T, 1000)
plt.plot(x, ex1(x))
plt.grid(True)
plt.show()
问题
我正在尝试集成此功能:
from scipy.integrate import quad
import quadpy
print(quadpy.quad(ex1, 0, 3))
print(quad(ex1, 0, 3))
产生
(array(4.5), array(1.41692995e-19))
(4.5, 4.9960036108132044e-14)
在 0 到 3 的间隔内,一切正常。
但是,如果我将间隔增加到例如4、scipy仍然有效
print(quad(ex1, 0, 4))
产生
(7.631568411183528, 1.0717732083155035e-08)
但是
print(quadpy.quad(ex1, 0, 4))
产生
IntegrationError: Tolerances (abs: 1.49e-08, rel: 1.49e-08) could not be reached with the given max_num_subintervals (= 50).
问题
- 如何防止此错误?我尝试添加一个名为
max_num_subintervals
的参数,但这似乎不起作用。
- 我是否正确地使用了 quadpy 来完成我想做的事情?我已经开始使用它,因为我想对 scipy 不支持的复数求导,并且我希望有一个万能的解决方案,因此使用 quadpy 来处理这些 scipy 就够了。
经过更多的实验,我发现 quadpy 的 quad 方法采用与 scipys quad 方法相同的参数,可以在这里找到:
使用 epsabs, epsrel, limit
可选参数,我可以防止错误:
print(quadpy.quad(ex1, 0, 4, epsabs=1e-1, epsrel=1e-1, limit=100))
生产
(array(7.6323447), array(0.01666253))
但是 scipys quad 方法达到了 1-08
的容错度,我真的无法用 quadpy 重现,即使将限制设置为非常高的值,如 1000000
这是为什么?
更新:看来我遇到的行为是一个错误,现在报告于:https://github.com/nschloe/quadpy/issues/255
但总的来说,这个答案回答了我最初的问题。
毕竟这是一个 quadpy 错误。现已修复:
import numpy as np
from scipy.integrate import quad
import quadpy
T = 2 * np.pi
def ex1(t):
return np.where(np.logical_and((t % T >= 0), (t % T < np.pi)), t % T, np.pi)
print(quadpy.__version__)
print(quadpy.quad(ex1, 0, 4))
print(quad(ex1, 0, 4))
0.14.7
(array(7.63156841), array(1.13827355e-16))
(7.631568411183528, 1.0717732083161812e-08)
您可能使用的是过时的 quadpy 版本。
我正在使用 quadpy 来集成 python 中的一个函数。
函数
import numpy as np
T = 2*np.pi
def ex1(t):
return np.where(np.logical_and((t%T>=0), (t%T<np.pi)), t%T, np.pi)
函数是周期性的,这是它的曲线:
x = np.linspace(0, 6*T, 1000)
plt.plot(x, ex1(x))
plt.grid(True)
plt.show()
问题
我正在尝试集成此功能:
from scipy.integrate import quad
import quadpy
print(quadpy.quad(ex1, 0, 3))
print(quad(ex1, 0, 3))
产生
(array(4.5), array(1.41692995e-19))
(4.5, 4.9960036108132044e-14)
在 0 到 3 的间隔内,一切正常。 但是,如果我将间隔增加到例如4、scipy仍然有效
print(quad(ex1, 0, 4))
产生
(7.631568411183528, 1.0717732083155035e-08)
但是
print(quadpy.quad(ex1, 0, 4))
产生
IntegrationError: Tolerances (abs: 1.49e-08, rel: 1.49e-08) could not be reached with the given max_num_subintervals (= 50).
问题
- 如何防止此错误?我尝试添加一个名为
max_num_subintervals
的参数,但这似乎不起作用。 - 我是否正确地使用了 quadpy 来完成我想做的事情?我已经开始使用它,因为我想对 scipy 不支持的复数求导,并且我希望有一个万能的解决方案,因此使用 quadpy 来处理这些 scipy 就够了。
经过更多的实验,我发现 quadpy 的 quad 方法采用与 scipys quad 方法相同的参数,可以在这里找到:
使用 epsabs, epsrel, limit
可选参数,我可以防止错误:
print(quadpy.quad(ex1, 0, 4, epsabs=1e-1, epsrel=1e-1, limit=100))
生产
(array(7.6323447), array(0.01666253))
但是 scipys quad 方法达到了 1-08
的容错度,我真的无法用 quadpy 重现,即使将限制设置为非常高的值,如 1000000
这是为什么?
更新:看来我遇到的行为是一个错误,现在报告于:https://github.com/nschloe/quadpy/issues/255
但总的来说,这个答案回答了我最初的问题。
毕竟这是一个 quadpy 错误。现已修复:
import numpy as np
from scipy.integrate import quad
import quadpy
T = 2 * np.pi
def ex1(t):
return np.where(np.logical_and((t % T >= 0), (t % T < np.pi)), t % T, np.pi)
print(quadpy.__version__)
print(quadpy.quad(ex1, 0, 4))
print(quad(ex1, 0, 4))
0.14.7
(array(7.63156841), array(1.13827355e-16))
(7.631568411183528, 1.0717732083161812e-08)
您可能使用的是过时的 quadpy 版本。