程序需要用预定的方式计算定义积分 精度(eps)与梯形规则和我的函数需要返回:
1.积分的近似值。
2.迭代次数。
我的代码:
from math import *
def f1(x):
return (x ** 2 - 1)**(-0.5)
def f2(x):
return (cos(x)/(x + 1))
def integral(f,a,b,eps):
n = 2
x = a
h = (b - a) / n
sum = 0.5 * (f(a) + f(b))
for i in range(n):
sum = sum + f(a + i * h)
sum_2 = h * sum
k = 0
flag = 1
while flag == 1:
n = n * 2
sum = 0
k = k + 1
x = a
h = (b - a) / n
sum = 0.5 * (f(a) + f(b))
for i in range(n):
sum = sum + f(a + i * h)
sum_new = h * sum
if eps > abs(sum_new - sum_2):
t1 = sum_new
t2 = k
return t1, t2
else:
sum_2 = sum_new
x1 = float(input("First-begin: "))
x2 = float(input("First-end: "))
y1 = float(input("Second-begin: "))
y2 = float(input("Second-end: "))
int_1 = integral(f1,x1,y1,1e-6)
int_2 = integral(f2,x2,y2,1e-6)
print(int_1)
print(int_2)
它没有正常工作。求救!
答案 0 :(得分:0)
你实现了数学错误。错误在行
中phase
for i in range(n):
sum = sum + f(a + i * h)
始终从0开始,因此在第一次迭代中,您只需再次添加range(n)
项。
如果用
f(a)
它有效。
此外,你有大量的冗余代码;你基本上编码了集成算法的核心两次。请尝试关注DRY-principle。
答案 1 :(得分:0)
梯形积分规则简单地说,积分$ \ int_a ^ b f(x)dx $的近似值为(b-a) (f(a)+f(b))/2
。该误差与(b-a)^2
成比例,因此可以使用复合规则进行更好的估算,即以较短的间隔细分初始间隔。
是否可以使用较短的间隔并仍然重复使用先前计算的函数值,从而最小化函数评估的总数?
是的,如果我们将每个区间划分为两个相等的部分,那么在阶段0
我们使用1个区间,在阶段1
2个相等的区间,并且通常在阶段{{ 1}},我们使用2 n 等间隔。
让我们从一个简单的问题开始,看看是否有可能推广这个程序...
n
通过梯形法则,初始近似值为a, b = 0, 32
L = b-a = 32
,由
I0
I0 = L * (f0+f1)/2
= L * S0
;实轴的图形表示,极间隔的坐标和评估的函数如下:
S0 = (f0+f1)/2
接下来,我们将原始间隔分成两部分,
x0 x1
01234567890123456789012345679012
f0 f1
和新近似,阶段L = L/2
x0 x2 x1
01234567890123456789012345679012
f0 f2 f1
,是使用梯形规则的两倍并应用一些代数获得的
n=1
I1 = L * (f0+f2)/2 + L * (f2+f1)/2
= L * [(f0+f1)/2 + f2]
= L * [S0 + S1]
另一个细分,阶段S1 = f2
,n=2
和
L = L/2
x0 x3 x2 x4 x1
012345678901234567890123456789012
f0 f3 f2 f4 f1
I2 = L * [(f0+f3) + (f3+f2) + (f2+f4) + (f4+f1)] / 2
= L * [(f0+f1)/2 + f2 + (f3+f4)]
= L * [S0+S1+S2]
。
鉴于这张照片,这并不难,
S2 = f3 + f4
了解我们的下一个近似值可以如下计算
x0 x5 x3 x6 x2 x7 x4 x8 x1
012345678901234567890123456789012
f0 f5 f3 f6 f2 f7 f4 f8 f1
现在,我们必须了解如何计算L = L/2
S3 = f5+f6+f7+f8
I3 = L*[S0+S1+S2+S3]
的泛化 - 对我们来说,伪代码是
Sn,
n = 1, …
对于L_n = (b-a)/2**n
list_x_n = list(a + L_n + 2*Ln*j for j=0, …, 2**n-1)
Sn = Sum(f(xj) for each xj in list_x_n)
,n = 3
,我们根据上面的公式L = (b-a)/8 = 4
,请查看图片...
现在我们已准备好用Python编写我们的算法
list_x_n = [4, 12, 20, 28]
如果您对Richardson推断感兴趣,我建议this document完全处理REP对梯形规则正交算法的应用。
如果您对def trapaezia(f, a, b, tol):
"returns integ(f, (a,b)), estimated error and number of evaluations"
from math import fsum # controls accumulation of rounding errors in sums
L = b - a
S = (f(a)+f(b))/2
I = L*S
n = 1
while True:
L = L/2
new_points = (a+L+j*L for j in range(0, n+n, 2))
delta_S = fsum(f(x) for x in new_points)
new_S = S + delta_S
new_I = L*new_S
# error is estimated using Richardson extrapolation (REP)
err = (new_I - I) * 4/3
if abs(err) > tol:
n = n+n
S, I = new_S, new_I
else:
# we return a better estimate using again REP
return (4*new_I-I)/3, err, n+n+1
感到好奇,the docs请不要过多说the link原始实施,其中还包括对所涉及的所有问题的扩展说明。< / p>