add function integration, tests and docs
This commit is contained in:
151
src/numerical/integration.py
Normal file
151
src/numerical/integration.py
Normal file
@@ -0,0 +1,151 @@
|
||||
# -*- 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 <daniel.weschke@directbox.de>
|
||||
"""
|
||||
|
||||
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)
|
||||
Reference in New Issue
Block a user