"""Integration.
We provide a variety of non-linear equations used for testing
numerical integration algorithms.
"""
import sys
import numpy as np
def _vector_interval(x, lower, upper):
r"""Check if one value of a numeric vector is not
in a specific interval.
Parameters
----------
x : array_like
Array for which it should be checked if all values lie in the
specific interval.
lower : float
Lower bound of the interval.
upper : float
Upper bound of the interval
Returns
-------
output : bool
True if one component of the vector is not in the specified
interval.
"""
boolean = (x < lower).any() or (x > upper).any()
if boolean:
sys.exit(
f"Any component of the input vector {x} must be between {lower} and"
" {upper}",
)
[docs]def continuous(x, u, a):
r"""Continuous Integrand Family.
.. math::
f(x)=\exp{\left(-\sum_{i=1}^p a_i \mid x_i -u_i \mid \right)}
Parameters
----------
x : array_like
Input domain with dimension :math:`p` and :math:`x \in [0,1]^p`.
u : array_like
Location vector with dimension :math:`p` and :math:`u \in [0,1]^p`.
a : array_like
Weight vector with dimension :math:`p`.
Returns
-------
float
Output domain
Notes
-----
This function was proposed by Alan Genz in [G1984]_. It can be
integrated analytically quickly with high precision. Evaluated at two
dimensions, the function has a flat surface and one peak
close to the centre of the integration region. Large values
in the location vector :math:`a` result in a sharp peak and a more
difficult integration.
.. figure:: ../../docs/_static/images/fig-continuous-integrand.png
:align: center
References
----------
.. [G1984] Genz, A. (1984). Testing multidimensional integration routines.
In *Proc. of international conference on tools, methods and languages
for scientific and engineering computation* (pp. 81-94). Elsevier North-Holland.
Examples
--------
>>> import numpy as np
>>> from temfpy.integration import continuous
>>>
>>> p = np.random.randint(1,20)
>>> x = np.repeat(0.5,p)
>>> u = x
>>> a = np.repeat(5,p)
>>> np.allclose(continuous(x,u,a), 1)
True
"""
x = np.array(x)
u = np.array(u)
a = np.array(a)
_vector_interval(x, 0, 1)
_vector_interval(u, 0, 1)
fval = np.exp(-np.sum(np.abs(x - u) * a))
return fval
[docs]def corner_peak(x, a):
r"""Corner Peak Integrand Family.
.. math::
f(x)=\left(1 + \sum_{i=1}^p a_i x_i \right)^{p+1}
Parameters
----------
x : array_like
Input domain with dimension :math:`p` and :math:`x \in [0,1]^p`.
a : array_like
Weight vector with dimension :math:`p`.
Returns
-------
float
Output domain
Notes
-----
This function was proposed by Alan Genz in [G1984]_. It can be
integrated analytically quickly with high precision. Evaluated at two
dimensions, the function has a flat surface and a single sharp peak
in one corner of the integration region. Large values
in the location vector :math:`a` result in a sharper peak and a more
difficult integration.
.. figure:: ../../docs/_static/images/fig-corner-peak.png
:align: center
References
----------
.. [G1984] Genz, A. (1984). Testing multidimensional integration routines.
In *Proc. of international conference on tools, methods and languages
for scientific and engineering computation* (pp. 81-94). Elsevier North-Holland.
Examples
--------
>>> import numpy as np
>>> from temfpy.integration import corner_peak
>>>
>>> p = np.random.randint(1,20)
>>> x = np.repeat(0,p)
>>> a = np.repeat(5,p)
>>> np.allclose(corner_peak(x,a), 1)
True
"""
x = np.array(x)
a = np.array(a)
_vector_interval(x, 0, 1)
power = float(-len(x) - 1)
fval = (1 + np.sum(a * x)) ** (power)
return fval
[docs]def discontinuous(x, u, a):
r"""Discontinuous Integrand Family.
.. math::
f(x) = \begin{cases}
0, & x_1 > u_1 \text{ or } x_2 > u_2 \\
\exp{\left(\sum_{i=1}^p a_i x_i \right)}, & \text{otherwise}
\end{cases}
Parameters
----------
x : array_like
Input domain with dimension :math:`p` and :math:`x \in [0,1]^p`.
u : array_like
Location vector with dimension :math:`1`, if :math:`p = 1`, and with
dimension :math:`2`, if :math:`p > 1`, that determines in which
area the function is equal to zero.
a : array_like
Weight vector with dimension :math:`p`.
Returns
-------
float
Output domain
Notes
-----
This function was proposed by Alan Genz in [G1984]_. It can be
integrated analytically quickly with high precision. Evaluated at two
dimensions, the function has one peak close to the centre of the
integration region and is flat at zero for greater values, as specified
in :math:`u`. Large values
in the location vector :math:`a` result in a sharp peak and a more
difficult integration.
.. figure:: ../../docs/_static/images/fig-discontinuous-integrand.png
:align: center
References
----------
.. [G1984] Genz, A. (1984). Testing multidimensional integration routines.
In *Proc. of international conference on tools, methods and languages
for scientific and engineering computation* (pp. 81-94). Elsevier North-Holland.
Examples
--------
>>> import numpy as np
>>> from temfpy.integration import discontinuous
>>>
>>> p = np.random.randint(1,20)
>>> x = np.repeat(0,p)
>>> u = [0.5,0.5]
>>> a = np.repeat(5,p)
>>> np.allclose(discontinuous(x,u,a), 1)
True
"""
x = np.atleast_1d(x)
u = np.array(u)
a = np.array(a)
_vector_interval(x, 0, 1)
if len(x) > 1:
x_if = np.array([x[0], x[1]])
u_if = np.array([u[0], u[1]])
else:
x_if = x
u_if = u
if (x_if <= u_if).all():
fval = np.exp(np.sum(a * x))
else:
fval = 0
return fval
[docs]def gaussian_peak(x, u, a):
r"""Gaussian peak Integrand Family.
.. math::
f(x)=\exp{\left(-\sum_{i=1}^p a_i^2 (x_i -u_i)^2 \right)}
Parameters
----------
x : array_like
Input domain with dimension :math:`p` and :math:`x \in [0,1]^p`.
u : array_like
Location vector with dimension :math:`p` and :math:`u \in [0,1]^p`.
a : array_like
Weight vector with dimension :math:`p`.
Returns
-------
float
Output domain
Notes
-----
This function was proposed by Alan Genz in [G1984]_. It can be
integrated analytically quickly with high precision. Evaluated at two
dimensions, the function has a Gaussian peak
close to the centre of the integration region. Large values
in the location vector :math:`a` result in a sharp peak and a more
difficult integration.
.. figure:: ../../docs/_static/images/fig-gaussian-peak.png
:align: center
References
----------
.. [G1984] Genz, A. (1984). Testing multidimensional integration routines.
In *Proc. of international conference on tools, methods and languages
for scientific and engineering computation* (pp. 81-94). Elsevier North-Holland.
Examples
--------
>>> import numpy as np
>>> from temfpy.integration import gaussian_peak
>>>
>>> p = np.random.randint(1,20)
>>> x = np.repeat(0.5,p)
>>> u = x
>>> a = np.repeat(5,p)
>>> np.allclose(gaussian_peak(x,u,a), 1)
True
"""
x = np.array(x)
u = np.array(u)
a = np.array(a)
_vector_interval(x, 0, 1)
_vector_interval(u, 0, 1)
fval = np.exp(-np.sum(np.abs(x - u) ** 2 * a ** 2))
return fval
[docs]def oscillatory(x, a, b):
r"""Oscillatory Integrand Family.
.. math::
f(x)= \cos\left(2 \pi b + \sum_{i=1}^p a_i x_i \right)
Parameters
----------
x : array_like
Input domain with dimension :math:`p` and :math:`x \in [0,1]^p`.
a : array_like
Weight vector with dimension :math:`p`.
b : int
Scale value that influences the location of the oscillatory.
Returns
-------
float
Output domain
Notes
-----
This function was proposed by Alan Genz in [G1984]_. It can be
integrated analytically quickly with high precision. Large values
in the location vector :math:`a` result in a higher frequency of
oscillations and a more difficult integration.
.. figure:: ../../docs/_static/images/fig-oscillatory-integrand.png
:align: center
References
----------
.. [G1984] Genz, A. (1984). Testing multidimensional integration routines.
In *Proc. of international conference on tools, methods and languages
for scientific and engineering computation* (pp. 81-94). Elsevier North-Holland.
Examples
--------
>>> import numpy as np
>>> from temfpy.integration import oscillatory
>>>
>>> p = np.random.randint(1,20)
>>> x = np.repeat(np.pi/4,p)
>>> a = np.repeat(-6/p,p)
>>> b = 1
>>> np.allclose(oscillatory(x,a,b), 0)
True
"""
x = np.array(x)
a = np.array(a)
_vector_interval(x, 0, 1)
fval = np.cos(2 * np.pi * b + np.sum(a * x))
return fval
[docs]def product(x, u, a):
r"""Product Peak Integrand Family.
.. math::
f(x)=\prod \frac{1}{\sum_{i=1}^p a_i^{-2} (x_i -u_i)^2}
Parameters
----------
x : array_like
Input domain with dimension :math:`p` and :math:`x \in [0,1]^p`.
u : array_like
Location vector with dimension :math:`p` and :math:`u \in [0,1]^p`.
a : array_like
Weight vector with dimension :math:`p`.
Returns
-------
float
Output domain
Notes
-----
This function was proposed by Alan Genz in [G1984]_. It can be
integrated analytically quickly with high precision. Evaluated at two
dimensions, the function has a peak
in the centre of the integration region. Large values
in the location vector :math:`a` result in a larger peak and a more
difficult integration.
.. figure:: ../../docs/_static/images/fig-product-integrand.png
:align: center
References
----------
.. [G1984] Genz, A. (1984). Testing multidimensional integration routines.
In *Proc. of international conference on tools, methods and languages
for scientific and engineering computation* (pp. 81-94). Elsevier North-Holland.
Examples
--------
>>> import numpy as np
>>> from temfpy.integration import product
>>>
>>> p = np.random.randint(1,20)
>>> x = np.repeat(0.5,p)
>>> u = x
>>> a = np.repeat(1,p)
>>> np.allclose(product(x,u,a), 1)
True
"""
x = np.array(x)
u = np.array(u)
a = np.array(a)
_vector_interval(x, 0, 1)
_vector_interval(u, 0, 1)
fval = np.prod((a ** (float(-2)) + (x - u) ** 2) ** (float(-1)))
return fval