|
| 1 | +""" |
| 2 | +Author : Syed Faizan ( 3rd Year IIIT Pune ) |
| 3 | +Github : faizan2700 |
| 4 | +
|
| 5 | +Purpose : You have one function f(x) which takes float integer and returns |
| 6 | +float you have to integrate the function in limits a to b. |
| 7 | +The approximation proposed by Thomas Simpsons in 1743 is one way to calculate integration. |
| 8 | +
|
| 9 | +( read article : https://cp-algorithms.com/num_methods/simpson-integration.html ) |
| 10 | +
|
| 11 | +simpson_integration() takes function,lower_limit=a,upper_limit=b,precision and |
| 12 | +returns the integration of function in given limit. |
| 13 | +""" |
| 14 | + |
| 15 | +# constants |
| 16 | +# the more the number of steps the more accurate |
| 17 | +N_STEPS = 1000 |
| 18 | + |
| 19 | + |
| 20 | +def f(x: float) -> float: |
| 21 | + return x * x |
| 22 | + |
| 23 | + |
| 24 | +""" |
| 25 | +Summary of Simpson Approximation : |
| 26 | +
|
| 27 | +By simpsons integration : |
| 28 | +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) |
| 29 | +where x0 = a |
| 30 | +xi = a + i * h |
| 31 | +xn = b |
| 32 | +""" |
| 33 | + |
| 34 | + |
| 35 | +def simpson_integration(function, a: float, b: float, precision: int = 4) -> float: |
| 36 | + |
| 37 | + """ |
| 38 | + Args: |
| 39 | + function : the function which's integration is desired |
| 40 | + a : the lower limit of integration |
| 41 | + b : upper limit of integraion |
| 42 | + precision : precision of the result,error required default is 4 |
| 43 | +
|
| 44 | + Returns: |
| 45 | + result : the value of the approximated integration of function in range a to b |
| 46 | + |
| 47 | + Raises: |
| 48 | + AssertionError: function is not callable |
| 49 | + AssertionError: a is not float or integer |
| 50 | + AssertionError: function should return float or integer |
| 51 | + AssertionError: b is not float or integer |
| 52 | + AssertionError: precision is not positive integer |
| 53 | + |
| 54 | + >>> simpson_integration(lambda x : x*x,1,2,3) |
| 55 | + 2.333 |
| 56 | +
|
| 57 | + >>> simpson_integration(lambda x : x*x,'wrong_input',2,3) |
| 58 | + Traceback (most recent call last): |
| 59 | + ... |
| 60 | + AssertionError: a should be float or integer your input : wrong_input |
| 61 | +
|
| 62 | + >>> simpson_integration(lambda x : x*x,1,'wrong_input',3) |
| 63 | + Traceback (most recent call last): |
| 64 | + ... |
| 65 | + AssertionError: b should be float or integer your input : wrong_input |
| 66 | +
|
| 67 | + >>> simpson_integration(lambda x : x*x,1,2,'wrong_input') |
| 68 | + Traceback (most recent call last): |
| 69 | + ... |
| 70 | + AssertionError: precision should be positive integer your input : wrong_input |
| 71 | + >>> simpson_integration('wrong_input',2,3,4) |
| 72 | + Traceback (most recent call last): |
| 73 | + ... |
| 74 | + AssertionError: the function(object) passed should be callable your input : wrong_input |
| 75 | + |
| 76 | + >>> simpson_integration(lambda x : x*x,3.45,3.2,1) |
| 77 | + -2.8 |
| 78 | +
|
| 79 | + >>> simpson_integration(lambda x : x*x,3.45,3.2,0) |
| 80 | + Traceback (most recent call last): |
| 81 | + ... |
| 82 | + AssertionError: precision should be positive integer your input : 0 |
| 83 | +
|
| 84 | + >>> simpson_integration(lambda x : x*x,3.45,3.2,-1) |
| 85 | + Traceback (most recent call last): |
| 86 | + ... |
| 87 | + AssertionError: precision should be positive integer your input : -1 |
| 88 | + |
| 89 | + """ |
| 90 | + assert callable( |
| 91 | + function |
| 92 | + ), f"the function(object) passed should be callable your input : {function}" |
| 93 | + assert isinstance(a, float) or isinstance( |
| 94 | + a, int |
| 95 | + ), f"a should be float or integer your input : {a}" |
| 96 | + assert isinstance(function(a), float) or isinstance( |
| 97 | + function(a), int |
| 98 | + ), f"the function should return integer or float return type of your function, {type(a)}" |
| 99 | + assert isinstance(b, float) or isinstance( |
| 100 | + b, int |
| 101 | + ), f"b should be float or integer your input : {b}" |
| 102 | + assert ( |
| 103 | + isinstance(precision, int) and precision > 0 |
| 104 | + ), f"precision should be positive integer your input : {precision}" |
| 105 | + |
| 106 | + # just applying the formula of simpson for approximate integraion written in |
| 107 | + # mentioned article in first comment of this file and above this function |
| 108 | + |
| 109 | + h = (b - a) / N_STEPS |
| 110 | + result = function(a) + function(b) |
| 111 | + |
| 112 | + for i in range(1, N_STEPS): |
| 113 | + a1 = a + h * i |
| 114 | + result += function(a1) * (4 if i%2 else 2) |
| 115 | + |
| 116 | + result *= h / 3 |
| 117 | + return round(result, precision) |
| 118 | + |
| 119 | + |
| 120 | +if __name__ == "__main__": |
| 121 | + import doctest |
| 122 | + |
| 123 | + doctest.testmod() |
0 commit comments