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 toTrueto 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 thexarray 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 thexarray 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).