我正在尝试在我的程序中以数字方式集成任意(当我编码时已知)函数 使用数值积分方法。我使用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中执行此操作的最佳政策。
修改
注意
我已经在存储在数组中的范围内的所有点处具有第一个差值
目前的错误是可以忍受的
结束记录
我已经阅读了Wikipaedia。正如Dimitry指出的那样,我将整合sqrt(1 + diff(f(x),x)^ 2)来获得弧长。我想问的是 - 是否有更好的近似/最佳实践(?)/更快的方式来做到这一点。如果需要更多上下文,我会在此处单独发布/发布上下文,如您所愿。
答案 0 :(得分:10)
quad
函数是旧Fortran库中的函数。它的工作原理是通过整合功能的平坦度和斜率来整合如何处理它用于数值积分的步长,以便最大限度地提高效率。这意味着即使它们在分析上是相同的,你也可能从一个区域到另一个区域得到稍微不同的答案。
毫无疑问,两个集成都应该返回零。返回1 /(10万亿)的东西非常接近于零!稍有不同是由于quad
翻转sin
并更改其步长的方式。对于您计划的任务,quad
将是您所需要的一切。
编辑:
对于你正在做的事情,我认为quad
没问题。它快速而且非常准确。我的最后陈述是充满自信地使用它,除非你发现一些确实非常糟糕的东西。如果它没有返回荒谬的答案,那么它可能正常工作。不用担心。
答案 1 :(得分:6)
我认为它可能是机器精度,因为两个答案实际上都是零。
如果你想从马的口中得到答案,我会在scipy discussion board上发布这个问题
答案 2 :(得分:6)
我会说数字O(10 ^ -14)实际上为零。你的宽容是什么?
可能是四边形的算法不是最好的。您可以尝试其他方法进行集成,看看是否可以改进。 5阶Runge-Kutta可以是一种非常好的通用技术。
可能只是浮点数的性质:"What Every Computer Scientist Should Know About Floating Point Arithmetic".
答案 3 :(得分:4)
这个输出对我来说似乎是正确的,因为你在这里有绝对误差估计。在普通和数值积分中,sin(x)的积分值确实应该为整个周期(2 * pi长度的任何间隔)的值为零,并且您的结果接近该值。
要计算弧长,您应该计算sqrt(1 + diff(f(x),x)^ 2)函数的积分,其中diff(f(x),x)是f(x)的导数。另请参阅Arc length
答案 4 :(得分:3)
0.0 == 2.3e-16 (absolute error tolerance 4.4e-14)
两个答案都相同且正确,即在给定公差范围内为零。
答案 5 :(得分:2)
差异来自sin(x)= - sin(-x)的事实,即使在有限精度中也是如此。而有限精度仅给出sin(x)~sin(x + 2 * pi)。当然,如果四分之一足够聪明来解决这个问题会很好,但是它确实没有办法知道你给出的两个区间的积分是等价的还是第一个是更好的结果。