【问题标题】:Can someone explain why scipy.integrate.quad gives different results for equally long ranges while integrating sin(X)?有人可以解释为什么 scipy.integrate.quad 在积分 sin(X) 的同时在同样长的范围内给出不同的结果吗?
【发布时间】:2010-10-09 12:47:36
【问题描述】:

我正在尝试在我的程序中以数字方式集成任意(我编码时已知)函数 使用数值积分方法。我正在使用 Python 2.5.2 和 SciPy 的数值集成包。为了感受一下,我决定尝试整合 sin(x) 并观察这种行为-

>>> from math import pi
>>> from scipy.integrate import quad
>>> from math import sin
>>> def integrand(x):
...     return sin(x)
... 
>>> quad(integrand, -pi, pi)
(0.0, 4.3998892617846002e-14)
>>> quad(integrand, 0, 2*pi)
(2.2579473462709165e-16, 4.3998892617846002e-14)

我觉得这种行为很奇怪,因为 -
1. 在普通积分中,在整个周期内积分为零。
2.在数值积分中,这(1)不一定是这种情况,因为你可能只是 近似曲线下的总面积。

在任何情况下,假设 1 为 True 或假设 2 为 True,我发现行为不一致。两种积分(-pi 到 pi 和 0 到 2*pi)都应该返回 0.0(元组中的第一个值是结果,第二个是错误)或返回 2.257...

有人能解释一下为什么会这样吗?这真的是矛盾吗?有人能告诉我我是否遗漏了一些关于数值方法的基本知识吗?

无论如何,在我的最终应用中,我打算使用上述方法来求函数的弧长。如果有人在这方面有经验,请告诉我在 Python 中执行此操作的最佳策略。

编辑
注意
我已经在数组中存储了范围内所有点的第一个微分值。
当前的错误是可以容忍的。
结束说明

我已经阅读了有关这方面的维基百科。正如 Dimitry 所指出的,我将整合 sqrt(1+diff(f(x), x)^2) 以获得弧长。我想问的是 - 是否有更好的近似/最佳实践(?)/更快的方法来做到这一点。如果需要更多上下文,我会单独发布/在此处发布上下文,如您所愿。

【问题讨论】:

标签: python integration scipy numerical-methods


【解决方案1】:

这个输出对我来说似乎是正确的,因为你在这里有绝对误差估计。在普通积分和数值积分中,sin(x) 的积分值确实应该在整个周期(2*pi 长度的任何间隔)中为零,并且您的结果接近该值。
要评估弧长,您应该计算 sqrt(1+diff(f(x), x)^2) 函数的积分,其中 diff(f(x), x) 是 f(x) 的导数。另见Arc length

【讨论】:

  • 感谢您的回复。我知道计算弧长。我还阅读了维基百科的文章。我将编辑我的帖子以反映这一点。
  • 再次感谢!我没有注意到答案低于错误限制。
【解决方案2】:

quad 函数是来自旧 Fortran 库的函数。它的工作原理是通过它正在积分的函数的平坦度和斜率来判断如何处理它用于数值积分的步长,以最大限度地提高效率。这意味着即使在分析上相同,您也可能会从一个区域到下一个区域得到略微不同的答案。

毫无疑问,两个积分都应该返回零。返回 1/(10 万亿)的东西非常接近于零!细微的差异是由于quad 滚动sin 并更改其步长的方式。对于您计划的任务,quad 将是您所需要的。

编辑: 对于您正在做的事情,我认为quad 很好。它快速且非常准确。我的最后声明是自信地使用它,除非你发现某些东西确实出了问题。如果它没有返回无意义的答案,那么它可能工作得很好。不用担心。

【讨论】:

  • +1。感谢您解释 quad 并指出 quad 就足够了。
【解决方案3】:

我认为这可能是机器精度,因为这两个答案实际上都是零。

如果你想从马的嘴里得到答案,我会把这个问题发到scipy discussion board

【讨论】:

  • 感谢您提供指向讨论区的链接。
【解决方案4】:

我会说一个数字 O(10^-14) 实际上为零。你的容忍度是多少?

quad 底层的算法可能不是最好的。您可以尝试另一种集成方法,看看是否可以改善情况。 5 阶 Runge-Kutta 可能是一种非常好的通用技术。

这可能只是浮点数的本质:"What Every Computer Scientist Should Know About Floating Point Arithmetic".

【讨论】:

    【解决方案5】:
    0.0 == 2.3e-16 (absolute error tolerance 4.4e-14)
    

    两个答案都相同且正确,即在给定容差范围内为零。

    【讨论】:

      【解决方案6】:

      不同之处在于 sin(x)=-sin(-x) 即使在有限精度下也是如此。而有限精度只给出了 sin(x)~sin(x+2*pi) 的近似值。当然,如果 quad 足够聪明来解决这个问题会很好,但它确实无法先验地知道您给出的两个区间上的积分是相等的,或者第一个是更好的结果。

      【讨论】:

        猜你喜欢
        • 2015-09-03
        • 2011-01-17
        • 1970-01-01
        • 2015-10-09
        • 2021-05-03
        • 1970-01-01
        • 2017-09-11
        • 2013-08-03
        • 1970-01-01
        相关资源
        最近更新 更多