-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathintegration.py
64 lines (50 loc) · 1.35 KB
/
integration.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
def trapezoidal_rule(f, a, b, n=1000):
if type(n) == float:
n = int(n)
h = (b - a) / n
x = a
sum = 0
for i in range(n+1):
if i == 0 or i == n:
sum += f(x)
else:
sum += 2 * f(x)
x += h
return sum * h / 2
def simpsons_rule(f, a, b, n=1000):
if type(n) == float:
n = int(n)
if n % 2 == 1:
# n += 1
raise ValueError("n must be an even integer.")
h = (b - a) / n
x = a
sum = 0
for i in range(n+1):
if i == 0 or i == n:
sum += f(x)
elif i % 2 == 1:
sum += 4 * f(x)
else:
sum += 2 * f(x)
x += h
return sum * h / 3
def adaptive_simpsons_rule(f, a, b, n0=2, tol = 1e-6):
n = n0
S = [None] * 2
S[0] = simpsons_rule(f, a, b, n)
S[1] = simpsons_rule(f, a, b, 2*n)
E2 = (S[1] - S[0]) / 15
while abs(E2) >= tol:
n = n * 2
S[0] = S[1]
S[1] = simpsons_rule(f, a, b, 2*n)
E2 = (S[1] - S[0]) / 15
return S[1]
# return (16*S[1] - S[0]) / 15 # Richardson’s extrapolation further reduces the error.
if __name__ == "__main__":
import math
f = lambda x: math.sin(x) * (x ** 2)
print(trapezoidal_rule(f, 0, math.pi))
print(simpsons_rule(f, 0, math.pi))
print(adaptive_simpsons_rule(f, 0, math.pi))