Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/webpack/2.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中的梯形规则_Python_Numerical Integration - Fatal编程技术网

Python中的梯形规则

Python中的梯形规则,python,numerical-integration,Python,Numerical Integration,我试图在Python2.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(应该返

我试图在Python2.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),所以很明显我的脚本有问题。不过我看不出来。

你差了两倍。事实上,在数学课上所教的方法会使用类似于

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循环的相邻迭代的通用术语:

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
有一个很大的
/2
分数(每个术语都是
(f(i)+f(i+1))/2
,而不是
f(i)+f(i+1)
),这是您在代码中遗漏的

您已经使用了专门处理第一对和最后一对的通用优化,因此您可以使用
2*f(i)
而不是计算
f(i)
两次(一次为
f(j+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,除了这一行什么都不改变:

return s / 2.0

可能不是巧合,583.333/2=291.6665。提示:您返回的值正好是您应该返回的值的两倍。公式中有一个
/2
分数。你的代码没有。这里你已经除以2两次了(删除
2.0*
并添加一个
/2.0
,您忘记了将上一个术语除以二,并且您使用了错误的规则形式。但是,如果他这样做,他必须更改更多的代码,而且效率会低于他现在所做的,因为这需要多个函数求值。