Integration by Simpson Approx

"""
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()
Algerlogo

Β© Alger 2022

About us

We are a group of programmers helping each other build new things, whether it be writing complex encryption programs, or simple ciphers. Our goal is to work together to document and model beautiful, helpful and interesting algorithms using code. We are an open-source community - anyone can contribute. We check each other's work, communicate and collaborate to solve problems. We strive to be welcoming, respectful, yet make sure that our code follows the latest programming guidelines.