# -*- coding: utf-8 -*- """Numerical integration, numerical quadrature. de: numerische Integration, numerische Quadratur. :Date: 2015-10-15 .. module:: integration :platform: *nix, Windows :synopsis: Numerical integration. .. moduleauthor:: Daniel Weschke """ from __future__ import division from numpy import linspace, trapz, zeros def trapez(f, a=0, b=1, N=10, x=None, verbose=False, save_values=False): r""" Integration of :math:`f(x)` using the trapezoidal rule (Simpson's rule, Kepler's rule). de: Trapezregel, Simpsonregel (Thomas Simpson), Keplersche Fassregel (Johannes Kepler) :param f: function to integrate. :type f: function or list :param a: lower limit of integration (default = 0). :type a: float :param b: upper limit of integration (default = 1). :type b: float :param N: specify the number of subintervals. :type N: int :param x: variable of integration, necessary if f is a list (default = None). :type x: list :param verbose: print information (default = False) :type verbose: bool :returns: the definite integral as approximated by trapezoidal rule. :rtype: float The trapezoidal rule approximates the integral by the area of a trapezoid with base h=b-a and sides equal to the values of the integrand at the two end points. .. math:: f_n(x) = f(a)+\frac{f(b)-f(a)}{b-a}(x-a) .. math:: I &= \int\limits_a^b f(x) \,\mathrm{d}x \\ I &\approx \int\limits_a^b f_n(x) \,\mathrm{d}x \\ &= \int\limits_a^b \left( f(a)+\frac{f(b)-f(a)}{b-a}(x-a) \right) \mathrm{d}x \\ &= \left.\left( f(a)-a\frac{f(b)-f(a)}{b-a} \right) x \right\vert_a^b + \left. \frac{f(b)-f(a)}{b-a} \frac{x^2}{2} \right\vert_a^b \\ &= \frac{b-a}{2}\left[f(a)+f(b)\right] The composite trapezium rule. If the interval is divided into n segments (not necessarily equal) .. math:: a = x_0 \leq x_1 \leq x_2 \leq \ldots \leq x_n = b .. math:: I &\approx \sum\limits_{i=0}^{n-1} \frac{1}{2} (x_{i+1}-x_i) \left[f(x_{i+1})+f(x_i)\right] \\ Special Case (Equaliy spaced base points) .. math:: x_{i+1}-x_i = h \quad \forall i .. math:: I \approx h \left\{ \frac{1}{2} \left[f(x_0)+f(x_n)\right] + \sum\limits_{i=1}^{n-1} f(x_i) \right\} .. rubric:: Example .. math:: I &= \int\limits_a^b f(x) \,\mathrm{d}x \\ f(x) &= x^2 \\ a &= 0 \\ b &= 1 analytical solution .. math:: I = \int\limits_{0}^{1} x^2 \,\mathrm{d}x = \left. \frac{1}{3} x^3 \right\vert_0^1 = \frac{1}{3} numerical solution >>> f = lambda(x): x**2 >>> trapez(f, 0, 1, 1) 0.5 >>> trapez(f, 0, 1, 10) 0.3350000000000001 >>> trapez(f, 0, 1, 100) 0.33335000000000004 """ N = int(N) # f is function or list if hasattr(f, '__call__'): # h width of each subinterval h = (b-a)/N # x variable of integration x = linspace(a, b, N+1) if save_values: # ff contribution from the points ff = zeros((N+1)) for n in linspace(0, N, N+1): ff[n] = f(x[n]) T = (ff[0]/2.+sum(ff[1:N])+ff[N]/2.)*h else: TL = f(x[0]) TR = f(x[N]) TI = 0 for n in range(1, N): TI = TI + f(x[n]) T = (TL/2.+TI+TR/2.)*h else: N = len(f)-1 T = 0 for n in range(N): T = T + (x[n+1]-x[n])/2*(f[n+1]+f[n]) if verbose: print(T) return T if __name__ == '__main__': func = lambda x: x**2 trapez(func, 0, 1, 1e6, verbose=True) #print(trapz(func, linspace(0,1,10))) trapez([0,1,4,9], x=[0,1,2,3], verbose=True) #print(trapz([0,1,4,9])) trapez([2,2], x=[-1,1], verbose=True) trapez([-1,1,1,-1], x=[-1,-1,1,1], verbose=True)