Integrals
Pylians provide routines to carry out numerical integrals in a more efficient way than scipy integrate. The philosophy is that to compute the integral \(\int_a^b f(x)dx\) the user passes the integrator two arrays, one with some values of \(x\) between a and b and another with the values of \(f(x)\) at those positions. The integrator will interpolate internally the input data to evaluate the function at an arbitrary position \(x\). Pylians implements in c the fortran odeint function and wrap in python through cython.
For instance, to compute \(\int_0^5 (3x^3+2x+5) dx\) one would do
import numpy as np
import integration_library as IL
# integral value, its limits and precision parameters
yinit = np.zeros(1, dtype=np.float64)
x1 = 0.0
x2 = 5.0
eps = 1e-8
h1 = 1e-10
hmin = 0.0
# integral method and integrand function
function = 'linear'
bins = 1000
x = np.linspace(x1, x2, bins)
y = 3*x**2 + 2*x + 5
I = IL.odeint(yinit, x1, x2, eps, h1, hmin, x, y, function, verbose=True)[0]
The value of integral is stored in I
. The odeint
routine needs the following ingredients:
yinit
. The value of the integral is stored in this variable. Should be a 1D double numpy array with one single element equal to 0. If several integrals are being computed sequentially this variable need to be declared for each integral.x1
. Lower limit of the integral.x2
. Upper limit of the integral.eps
. Maximum local relative error tolerated. Typically set its value to be 1e8-1e10 lower than the value of the integral. Verify the convergence of the results by studying the dependence of the integral on this number.h1
. Initial guess for the first time step (cannot be 0).hmin
. Minimum allowerd time step (can be 0).verbose
. Set it toTrue
to print some information on the integral computation.
There are two main methods to carry out the integral, depending on how the interpolation is performed.
function = 'linear'
. The function is evaluated by interpolating linearly the input values of \(x\) and \(y=f(x)\).x
. 1D double numpy array containing the input, equally spaced, values of \(x\).y
. 1D double numpy array containing the values of \(y=f(x)\) at thex
array positions.
function = 'log'
. The function is evaluated by interpolating logaritmically the input values of \(x\) and \(y=f(x)\).x
. 1D double numpy array containing the input, equally spaced in log, values of \(\log_{10}(x)\).y
. 1D double numpy array containing the values of \(y=f(x)\) at thex
array positions.
An example of using the log-interpolation to compute the integral \(\int_1^2 e^x dx\) is this
import numpy as np
import integration_library as IL
# integral value, its limits and precision parameters
yinit = np.zeros(1, dtype=np.float64)
x1 = 1.0
x2 = 2.0
eps = 1e-10
h1 = 1e-12
hmin = 0.0
# integral method and integrand function
function = 'log'
bins = 1000
x = np.logspace(np.log10(x1), np.log10(x2), bins)
y = np.exp(x)
I = IL.odeint(yinit, x1, x2, eps, h1, hmin, np.log10(x), y,
function, verbose=True)[0]
Warning
Be careful when using the log-interpolation, since the code will crash if a zero or negative value is encounter.
The user can create its own function to avoid evaluating the integrand via interpolations. This function has to be placed in the file library/integration_library/integration_library.pyx (see linear and sigma functions as examples). After that, a new function call has to be created in the function odeint of that file (see linear and log as examples).