forked from TheAlgorithms/Python
-
Notifications
You must be signed in to change notification settings - Fork 0
/
integration_by_simpson_approx.py
121 lines (93 loc) · 3.79 KB
/
integration_by_simpson_approx.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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
"""
Author : Syed Faizan ( 3rd Year IIIT Pune )
Github : faizan2700
Purpose : You have one function f(x) which takes float integer and returns
float you have to integrate the function in limits a to b.
The approximation proposed by Thomas Simpsons in 1743 is one way to calculate
integration.
( read article : https://cp-algorithms.com/num_methods/simpson-integration.html )
simpson_integration() takes function,lower_limit=a,upper_limit=b,precision and
returns the integration of function in given limit.
"""
# constants
# the more the number of steps the more accurate
N_STEPS = 1000
def f(x: float) -> float:
return x * x
"""
Summary of Simpson Approximation :
By simpsons integration :
1. integration of fxdx with limit a to b is =
f(x0) + 4 * f(x1) + 2 * f(x2) + 4 * f(x3) + 2 * f(x4)..... + f(xn)
where x0 = a
xi = a + i * h
xn = b
"""
def simpson_integration(function, a: float, b: float, precision: int = 4) -> float:
"""
Args:
function : the function which's integration is desired
a : the lower limit of integration
b : upper limit of integration
precision : precision of the result,error required default is 4
Returns:
result : the value of the approximated integration of function in range a to b
Raises:
AssertionError: function is not callable
AssertionError: a is not float or integer
AssertionError: function should return float or integer
AssertionError: b is not float or integer
AssertionError: precision is not positive integer
>>> simpson_integration(lambda x : x*x,1,2,3)
2.333
>>> simpson_integration(lambda x : x*x,'wrong_input',2,3)
Traceback (most recent call last):
...
AssertionError: a should be float or integer your input : wrong_input
>>> simpson_integration(lambda x : x*x,1,'wrong_input',3)
Traceback (most recent call last):
...
AssertionError: b should be float or integer your input : wrong_input
>>> simpson_integration(lambda x : x*x,1,2,'wrong_input')
Traceback (most recent call last):
...
AssertionError: precision should be positive integer your input : wrong_input
>>> simpson_integration('wrong_input',2,3,4)
Traceback (most recent call last):
...
AssertionError: the function(object) passed should be callable your input : ...
>>> simpson_integration(lambda x : x*x,3.45,3.2,1)
-2.8
>>> simpson_integration(lambda x : x*x,3.45,3.2,0)
Traceback (most recent call last):
...
AssertionError: precision should be positive integer your input : 0
>>> simpson_integration(lambda x : x*x,3.45,3.2,-1)
Traceback (most recent call last):
...
AssertionError: precision should be positive integer your input : -1
"""
assert callable(
function
), f"the function(object) passed should be callable your input : {function}"
assert isinstance(a, (float, int)), f"a should be float or integer your input : {a}"
assert isinstance(function(a), (float, int)), (
"the function should return integer or float return type of your function, "
f"{type(a)}"
)
assert isinstance(b, (float, int)), f"b should be float or integer your input : {b}"
assert (
isinstance(precision, int) and precision > 0
), f"precision should be positive integer your input : {precision}"
# just applying the formula of simpson for approximate integration written in
# mentioned article in first comment of this file and above this function
h = (b - a) / N_STEPS
result = function(a) + function(b)
for i in range(1, N_STEPS):
a1 = a + h * i
result += function(a1) * (4 if i % 2 else 2)
result *= h / 3
return round(result, precision)
if __name__ == "__main__":
import doctest
doctest.testmod()