Module alexandria.math.integration
Numerical integration methods
Expand source code
# SPDX-FileCopyrightText: © 2021 Antonio López Rivera <antonlopezr99@gmail.com>
# SPDX-License-Identifier: GPL-3.0-only
"""
Numerical integration methods
-----------------------------
"""
import numpy as np
from scipy.integrate import quad
from scipy.interpolate import interp1d
from alexandria.data_structs.array import dx_v
class one_d:
@classmethod
def trapezoidal(cls, x, y):
"""
Trapezoidal integration.
:param x: Domain over which _f_ is integrated.
:param y: Function to be integrated.
:type x: np.ndarray
:type y: np.ndarray
:return:
- [float] Integral value
- [np.ndarray] Primitive of _f_
"""
f_prime = np.zeros(len(y))
dt_y = dx_v(x)
for i in range(y.size - 1):
f_prime[i] = dt_y[i] * (y[i] + (y[i + 1] - y[i]) / 2)
np.append(f_prime, dt_y[-2] * (y[-1] + (y[-2] - y[-1]) / 2))
return f_prime.sum(), f_prime
class two_d:
@classmethod
def Q_interp1d(cls, x1, x2, y, log=False):
"""
2 step 2D integration:
1. Interpolation and integration of the function along x2
2. Interpolation and integration of the result over x1
Methods:
- Integration: _scipy.integrate.quad_
- Interpolation: _scipy.interpolate.interp1D_
:param x1: Domain 1.
:param x2: Domain 2.
:param y: 2D array to be integrated.
:param log: Print maximum value of input array, average value
of integral over x2, and integrals over x1 and x2
:param x1: np.ndarray
:param x2: np.ndarray
:param y: np.ndarray
:return:
- [float] Integral
- [np.ndarray] Primitive over x1
"""
# Integral about x_p axis
int_z = np.empty(y.shape[1])
for i in range(x1.size):
spl_x2 = interp1d(x2, y[:, i])
int_z[i] = quad(spl_x2, x2.min(), x2.max())[0]*1000
# Integral about z_p axis
spl_x1 = interp1d(x1, int_z)
int_x1 = quad(spl_x1, x1[1], x1[-2])[0]
if log:
print(f"Maximum value of target distribution: {y.max():.5f}")
print(f"Average value over x2 axis: {np.mean(y):.5f}")
print(f"Integral over x1, x2 axes: {int_z:.5f}")
return int_x1, spl_x1
Classes
class one_d
-
Expand source code
class one_d: @classmethod def trapezoidal(cls, x, y): """ Trapezoidal integration. :param x: Domain over which _f_ is integrated. :param y: Function to be integrated. :type x: np.ndarray :type y: np.ndarray :return: - [float] Integral value - [np.ndarray] Primitive of _f_ """ f_prime = np.zeros(len(y)) dt_y = dx_v(x) for i in range(y.size - 1): f_prime[i] = dt_y[i] * (y[i] + (y[i + 1] - y[i]) / 2) np.append(f_prime, dt_y[-2] * (y[-1] + (y[-2] - y[-1]) / 2)) return f_prime.sum(), f_prime
Static methods
def trapezoidal(x, y)
-
Trapezoidal integration.
:param x: Domain over which f is integrated. :param y: Function to be integrated.
:type x: np.ndarray :type y: np.ndarray
:return: - [float] Integral value - [np.ndarray] Primitive of f
Expand source code
@classmethod def trapezoidal(cls, x, y): """ Trapezoidal integration. :param x: Domain over which _f_ is integrated. :param y: Function to be integrated. :type x: np.ndarray :type y: np.ndarray :return: - [float] Integral value - [np.ndarray] Primitive of _f_ """ f_prime = np.zeros(len(y)) dt_y = dx_v(x) for i in range(y.size - 1): f_prime[i] = dt_y[i] * (y[i] + (y[i + 1] - y[i]) / 2) np.append(f_prime, dt_y[-2] * (y[-1] + (y[-2] - y[-1]) / 2)) return f_prime.sum(), f_prime
class two_d
-
Expand source code
class two_d: @classmethod def Q_interp1d(cls, x1, x2, y, log=False): """ 2 step 2D integration: 1. Interpolation and integration of the function along x2 2. Interpolation and integration of the result over x1 Methods: - Integration: _scipy.integrate.quad_ - Interpolation: _scipy.interpolate.interp1D_ :param x1: Domain 1. :param x2: Domain 2. :param y: 2D array to be integrated. :param log: Print maximum value of input array, average value of integral over x2, and integrals over x1 and x2 :param x1: np.ndarray :param x2: np.ndarray :param y: np.ndarray :return: - [float] Integral - [np.ndarray] Primitive over x1 """ # Integral about x_p axis int_z = np.empty(y.shape[1]) for i in range(x1.size): spl_x2 = interp1d(x2, y[:, i]) int_z[i] = quad(spl_x2, x2.min(), x2.max())[0]*1000 # Integral about z_p axis spl_x1 = interp1d(x1, int_z) int_x1 = quad(spl_x1, x1[1], x1[-2])[0] if log: print(f"Maximum value of target distribution: {y.max():.5f}") print(f"Average value over x2 axis: {np.mean(y):.5f}") print(f"Integral over x1, x2 axes: {int_z:.5f}") return int_x1, spl_x1
Static methods
def Q_interp1d(x1, x2, y, log=False)
-
2 step 2D integration: 1. Interpolation and integration of the function along x2 2. Interpolation and integration of the result over x1
Methods: - Integration: scipy.integrate.quad - Interpolation: scipy.interpolate.interp1D
:param x1: Domain 1. :param x2: Domain 2. :param y: 2D array to be integrated. :param log: Print maximum value of input array, average value of integral over x2, and integrals over x1 and x2
:param x1: np.ndarray :param x2: np.ndarray :param y: np.ndarray
:return: - [float] Integral - [np.ndarray] Primitive over x1
Expand source code
@classmethod def Q_interp1d(cls, x1, x2, y, log=False): """ 2 step 2D integration: 1. Interpolation and integration of the function along x2 2. Interpolation and integration of the result over x1 Methods: - Integration: _scipy.integrate.quad_ - Interpolation: _scipy.interpolate.interp1D_ :param x1: Domain 1. :param x2: Domain 2. :param y: 2D array to be integrated. :param log: Print maximum value of input array, average value of integral over x2, and integrals over x1 and x2 :param x1: np.ndarray :param x2: np.ndarray :param y: np.ndarray :return: - [float] Integral - [np.ndarray] Primitive over x1 """ # Integral about x_p axis int_z = np.empty(y.shape[1]) for i in range(x1.size): spl_x2 = interp1d(x2, y[:, i]) int_z[i] = quad(spl_x2, x2.min(), x2.max())[0]*1000 # Integral about z_p axis spl_x1 = interp1d(x1, int_z) int_x1 = quad(spl_x1, x1[1], x1[-2])[0] if log: print(f"Maximum value of target distribution: {y.max():.5f}") print(f"Average value over x2 axis: {np.mean(y):.5f}") print(f"Integral over x1, x2 axes: {int_z:.5f}") return int_x1, spl_x1