Python中的梯形规则

时间:2014-01-15 19:33:12

标签: python numerical-integration

我正在尝试在Python 2.7.2中实现梯形规则。我写了以下函数:

def trapezoidal(f, a, b, n):
    h = float(b - a) / n
    s = 0.0
    s += h * f(a)
    for i in range(1, n):
        s += 2.0 * h * f(a + i*h)
    s += h * f(b)
    return s

然而,f(lambda x:x ** 2,5,10,100)返回583.333(它应该返回291.667),所以我的脚本显然有问题。我不能发现它。

2 个答案:

答案 0 :(得分:5)

你离开了两倍。实际上,数学课上教授的Trapezoidal Rule会使用像

这样的增量
s += h * (f(a + i*h) + f(a + (i-1)*h))/2.0

(f(a + i*h) + f(a + (i-1)*h))/2.0平均了网格上两个相邻点的函数高度。

由于每两个相邻的梯形具有共同的边缘,因此上述公式需要根据需要两次评估该函数。

更有效的实施(更接近您发布的内容)将结合for-loop的相邻迭代中的常用术语:

f(a + i*h)/2.0 + f(a + i*h)/2.0 =  f(a + i*h) 

到达:

def trapezoidal(f, a, b, n):
    h = float(b - a) / n
    s = 0.0
    s += f(a)/2.0
    for i in range(1, n):
        s += f(a + i*h)
    s += f(b)/2.0
    return s * h

print( trapezoidal(lambda x:x**2, 5, 10, 100))

产生

291.66875

答案 1 :(得分:3)

trapezoidal rule有一个很大的/2分数(每个字词为(f(i) + f(i+1))/2,而不是f(i) + f(i+1)),这是您从代码中遗漏的。

您已经使用了专门处理第一对和最后一对的常见优化,因此您可以使用2 * f(i)而不是计算f(i)两次(一次为f(j+1),一次为{{1} }}),所以你必须将f(i)添加到循环步骤以及特殊的第一步和最后一步:

/ 2

通过将s += h * f(a) / 2.0 for i in range(1, n): s += 2.0 * h * f(a + i*h) / 2.0 s += h * f(b) / 2.0 替换为2.0 * … / 2.0,您显然可以简化循环步骤。

然而,更简单的说,你可以在结尾处将整个事物除以2,只改变这一行: