# -*- coding: utf-8 -*-
r"""
Module Summary
--------------
Interfaces for the NAG Mark 30.3 `specfun` Chapter.
``specfun`` - Approximations of Special Functions
This module is concerned with the provision of some commonly occurring physical and mathematical functions.
See Also
--------
``naginterfaces.library.examples.specfun`` :
This subpackage contains examples for the ``specfun`` module.
See also the :ref:`library_specfun_ex` subsection.
Functionality Index
-------------------
**Airy function**
:math:`{\mathrm{Bi}^{\prime }}`, real argument
scalar: :meth:`airy_bi_deriv`
vectorized: :meth:`airy_bi_deriv_vector`
:math:`\mathrm{Ai}^{\prime }`, real argument
scalar: :meth:`airy_ai_deriv`
vectorized: :meth:`airy_ai_deriv_vector`
:math:`\mathrm{Ai}`, real argument
scalar: :meth:`airy_ai_real`
vectorized: :meth:`airy_ai_real_vector`
:math:`\mathrm{Ai}` or :math:`\mathrm{Ai}^{\prime }`, complex argument, optionally scaled: :meth:`airy_ai_complex`
:math:`\mathrm{Bi}`, real argument
scalar: :meth:`airy_bi_real`
vectorized: :meth:`airy_bi_real_vector`
:math:`\mathrm{Bi}` or :math:`{\mathrm{Bi}^{\prime }}`, complex argument, optionally scaled: :meth:`airy_bi_complex`
**Arccos**
inverse circular cosine: :meth:`arccos`
**Arccosh**
inverse hyperbolic cosine: :meth:`arccosh`
**Arcsin**
inverse circular sine: :meth:`arcsin`
**Arcsinh**
inverse hyperbolic sine: :meth:`arcsinh`
**Arctanh**
inverse hyperbolic tangent: :meth:`arctanh`
**Bessel function**
:math:`I_{\nu }`, complex argument, optionally scaled: :meth:`bessel_i_complex`
:math:`I_0`, real argument
scalar: :meth:`bessel_i0_real`
vectorized: :meth:`bessel_i0_real_vector`
:math:`I_1`, real argument
scalar: :meth:`bessel_i1_real`
vectorized: :meth:`bessel_i1_real_vector`
:math:`J_{{\alpha \pm n}}\left(z\right)`, complex argument: :meth:`bessel_j_seq_complex`
:math:`J_{\nu }`, complex argument, optionally scaled: :meth:`bessel_j_complex`
:math:`J_0`, real argument
scalar: :meth:`bessel_j0_real`
vectorized: :meth:`bessel_j0_real_vector`
:math:`J_1`, real argument
scalar: :meth:`bessel_j1_real`
vectorized: :meth:`bessel_j1_real_vector`
:math:`K_{\nu }`, complex argument, optionally scaled: :meth:`bessel_k_complex`
:math:`K_0`, real argument
scalar: :meth:`bessel_k0_real`
vectorized: :meth:`bessel_k0_real_vector`
:math:`K_1`, real argument
scalar: :meth:`bessel_k1_real`
vectorized: :meth:`bessel_k1_real_vector`
:math:`Y_{\nu }`, complex argument, optionally scaled: :meth:`bessel_y_complex`
:math:`Y_0`, real argument
scalar: :meth:`bessel_y0_real`
vectorized: :meth:`bessel_y0_real_vector`
:math:`Y_1`, real argument
scalar: :meth:`bessel_y1_real`
vectorized: :meth:`bessel_y1_real_vector`
**beta function**
regularized incomplete
scalar: :meth:`beta_incomplete`
vectorized: :meth:`beta_incomplete_vector`
**Complement of the Cumulative Normal distribution**
scalar: :meth:`compcdf_normal`
vectorized: :meth:`compcdf_normal_vector`
**Complement of the Error function**
complex argument, scaled
scalar: :meth:`erfc_complex`
vectorized: :meth:`erfc_complex_vector`
real argument
scalar: :meth:`erfc_real`
vectorized: :meth:`erfc_real_vector`
real argument, scaled
scalar: :meth:`erfcx_real`
vectorized: :meth:`erfcx_real_vector`
**Cosine**
hyperbolic: :meth:`cosh`
Cosine Integral: :meth:`integral_cos`
**Cumulative Normal distribution function**
scalar: :meth:`cdf_normal`
vectorized: :meth:`cdf_normal_vector`
**Dawson's Integral**
scalar: :meth:`dawson`
vectorized: :meth:`dawson_vector`
Digamma function, scaled: :meth:`polygamma_deriv`
**Elliptic functions, Jacobian, sn, cn, dn**
complex argument: :meth:`jacellip_complex`
real argument: :meth:`jacellip_real`
**Elliptic integral**
general
of 2nd kind, :math:`F\left(z, k^{\prime }, a, b\right)`: :meth:`ellipint_general_2`
Legendre form
complete of 1st kind, :math:`K\left(m\right)`: :meth:`ellipint_complete_1`
complete of 2nd kind, :math:`E\left({m}\right)`: :meth:`ellipint_complete_2`
of 1st kind, :math:`F\left(\phi | m\right)`: :meth:`ellipint_legendre_1`
of 2nd kind, :math:`E\left({\phi | m}\right)`: :meth:`ellipint_legendre_2`
of 3rd kind, :math:`\Pi \left({n;\phi | m}\right)`: :meth:`ellipint_legendre_3`
symmetrised
degenerate of 1st kind, :math:`R_C`: :meth:`ellipint_symm_1_degen`
of 1st kind, :math:`R_F`: :meth:`ellipint_symm_1`
of 2nd kind, :math:`R_D`: :meth:`ellipint_symm_2`
of 3rd kind, :math:`R_J`: :meth:`ellipint_symm_3`
**Erf**
real argument
scalar: :meth:`erf_real`
vectorized: :meth:`erf_real_vector`
**Erfc**
complex argument, scaled
scalar: :meth:`erfc_complex`
vectorized: :meth:`erfc_complex_vector`
real argument
scalar: :meth:`erfc_real`
vectorized: :meth:`erfc_real_vector`
**erfcx**
real argument
scalar: :meth:`erfcx_real`
vectorized: :meth:`erfcx_real_vector`
**Exponential**
complex: :meth:`exp_complex`
Exponential Integral: :meth:`integral_exp`
**Fresnel integral**
:math:`C`
scalar: :meth:`fresnel_c`
vectorized: :meth:`fresnel_c_vector`
:math:`S`
scalar: :meth:`fresnel_s`
vectorized: :meth:`fresnel_s_vector`
**Gamma function**
incomplete
scalar: :meth:`gamma_incomplete`
vectorized: :meth:`gamma_incomplete_vector`
scalar: :meth:`gamma`
vectorized: :meth:`gamma_vector`
**Generalized factorial function**
scalar: :meth:`gamma`
vectorized: :meth:`gamma_vector`
**Hankel function** :math:`H_{\nu }^{\left(1\right)}` **or** :math:`H_{\nu }^{\left(2\right)}`
complex argument, optionally scaled: :meth:`hankel_complex`
**Hypergeometric functions**
:math:`{}_1 F_1 \left(a; b; x\right)`, confluent, real argument: :meth:`hyperg_confl_real`
:math:`{}_1 F_1 \left(a; b; x\right)`, confluent, real argument, scaled form: :meth:`hyperg_confl_real_scaled`
:math:`{}_2 F_1 \left(a,b;c;x\right)`, Gauss, real argument: :meth:`hyperg_gauss_real`
:math:`{}_2 F_1 \left(a,b;c;x\right)`, Gauss, real argument, scaled form: :meth:`hyperg_gauss_real_scaled`
**Jacobian theta functions** :math:`\theta_k\left(x, q\right)`
real argument: :meth:`jactheta_real`
**Kelvin function**
:math:`\mathrm{bei}\left(x\right)`
scalar: :meth:`kelvin_bei`
vectorized: :meth:`kelvin_bei_vector`
:math:`\mathrm{ber}\left(x\right)`
scalar: :meth:`kelvin_ber`
vectorized: :meth:`kelvin_ber_vector`
:math:`\mathrm{kei}\left(x\right)`
scalar: :meth:`kelvin_kei`
vectorized: :meth:`kelvin_kei_vector`
:math:`\mathrm{ker}\left(x\right)`
scalar: :meth:`kelvin_ker`
vectorized: :meth:`kelvin_ker_vector`
Legendre functions of 1st kind :math:`P_n^m\left(x\right)`, :math:`\overline{P_n^m}\left(x\right)`: :meth:`legendre_p`
Logarithm of :math:`1+x`: :meth:`log_shifted`
**Logarithm of beta function**
real
scalar: :meth:`beta_log_real`
vectorized: :meth:`beta_log_real_vector`
**Logarithm of gamma function**
complex: :meth:`gamma_log_complex`
real
scalar: :meth:`gamma_log_real`
vectorized: :meth:`gamma_log_real_vector`
real, scaled: :meth:`gamma_log_scaled_real`
**Mathieu function (angular)**
periodic, real
vectorized: :meth:`mathieu_ang_periodic_real`
**Modified Struve function**
:math:`I_0-L_0`, real argument
scalar: :meth:`struve_i0ml0`
:math:`I_1-L_1`, real argument
scalar: :meth:`struve_i1ml1`
:math:`L_0`, real argument
scalar: :meth:`struve_l0`
:math:`L_1`, real argument
scalar: :meth:`struve_l1`
**Option Pricing**
American option, Bjerksund and Stensland option price: :meth:`opt_amer_bs_price`
Asian option, geometric continuous average rate price: :meth:`opt_asian_geom_price`
Asian option, geometric continuous average rate price with Greeks: :meth:`opt_asian_geom_greeks`
binary asset-or-nothing option price: :meth:`opt_binary_aon_price`
binary asset-or-nothing option price with Greeks: :meth:`opt_binary_aon_greeks`
binary cash-or-nothing option price: :meth:`opt_binary_con_price`
binary cash-or-nothing option price with Greeks: :meth:`opt_binary_con_greeks`
Black--Scholes implied volatility: :meth:`opt_imp_vol`
Black--Scholes--Merton option price: :meth:`opt_bsm_price`
Black--Scholes--Merton option price with Greeks: :meth:`opt_bsm_greeks`
European option, option prices, using Merton jump-diffusion model: :meth:`opt_jumpdiff_merton_price`
European option, option price with Greeks, using Merton jump-diffusion model: :meth:`opt_jumpdiff_merton_greeks`
floating-strike lookback option price: :meth:`opt_lookback_fls_price`
floating-strike lookback option price with Greeks: :meth:`opt_lookback_fls_greeks`
Heston's model option price: :meth:`opt_heston_price`
Heston's model option price with Greeks: :meth:`opt_heston_greeks`
Heston's model option price with Greeks, sensitivities of model parameters and negative rates: :meth:`opt_heston_more_greeks`
Heston's model with term structure: :meth:`opt_heston_term`
standard barrier option price: :meth:`opt_barrier_std_price`
**Polygamma function**
:math:`\psi^{\left(n\right)}\left(x\right)`, real :math:`x`: :meth:`psi_deriv_real`
:math:`\psi^{\left(n\right)}\left(z\right)`, complex :math:`z`: :meth:`psi_deriv_complex`
psi function: :meth:`polygamma`
psi function derivatives, scaled: :meth:`polygamma_deriv`
**Scaled modified Bessel function(s)**
:math:`e^{{-\left\lvert x\right\rvert }}I_0\left(x\right)`, real argument
scalar: :meth:`bessel_i0_scaled`
vectorized: :meth:`bessel_i0_scaled_vector`
:math:`e^{{-\left\lvert x\right\rvert }}I_1\left(x\right)`, real argument
scalar: :meth:`bessel_i1_scaled`
vectorized: :meth:`bessel_i1_scaled_vector`
:math:`e^xK_0\left(x\right)`, real argument
scalar: :meth:`bessel_k0_scaled`
vectorized: :meth:`bessel_k0_scaled_vector`
:math:`e^xK_1\left(x\right)`, real argument
scalar: :meth:`bessel_k1_scaled`
vectorized: :meth:`bessel_k1_scaled_vector`
**Sine**
hyperbolic: :meth:`sinh`
Sine Integral: :meth:`integral_sin`
**Struve function**
:math:`H_0`, real argument
scalar: :meth:`struve_h0`
:math:`H_1`, real argument
scalar: :meth:`struve_h1`
**Tangent**
circular: :meth:`tan`
hyperbolic: :meth:`tanh`
Trigamma function, scaled: :meth:`polygamma_deriv`
**Zeros of Bessel functions** :math:`J_{\alpha }\left(x\right)` **,** :math:`J_{\alpha }^{\prime }\left(x\right)` **,** :math:`Y_{\alpha }\left(x\right)` **,** :math:`Y_{\alpha }^{\prime }\left(x\right)`
scalar: :meth:`bessel_zeros`
For full information please refer to the NAG Library document
https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/sintro.html
"""
# NAG Copyright 2017-2024.
from __future__ import absolute_import
from math import sqrt
from ..library import machine
[docs]def log_shifted(x):
r"""
``log_shifted`` returns a value of the shifted logarithmic function, :math:`\mathrm{ln}\left(1+x\right)`.
.. _s01ba-py2-py-doc:
For full information please refer to the NAG Library document for s01ba
https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s01baf.html
.. _s01ba-py2-py-parameters:
**Parameters**
**x** : float
The argument :math:`x` of the function.
**Returns**
**lnx1** : float
The value of the shifted logarithmic function, :math:`\mathrm{ln}\left(1+x\right)`.
.. _s01ba-py2-py-errors:
**Raises**
**NagValueError**
(`errno` :math:`1`)
On entry, :math:`\mathrm{x} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{x} > {-1.0}`.
.. _s01ba-py2-py-notes:
**Notes**
``log_shifted`` computes values of :math:`\mathrm{ln}\left(1+x\right)`, retaining full relative precision even when :math:`\left\lvert x\right\rvert` is small.
The function is based on the Chebyshev expansion
.. math::
\mathrm{ln}\left(\frac{{1+p^2+2p\bar{x}}}{{1+p^2-2p\bar{x}}}\right) = 4\sum_{{k = 0}}^{\infty }\frac{{p^{{2k+1}}}}{{2k+1}}T_{{2k+1}}\left(\bar{x}\right)\text{.}
Setting :math:`\bar{x} = \frac{{x\left(1+p^2\right)}}{{2p\left(x+2\right)}}`, and choosing :math:`p = \frac{{q-1}}{{q+1}}`, :math:`q = \sqrt[4]{2}` the expansion is valid in the domain :math:`x \in \left[\frac{1}{\sqrt{2}}-1,\sqrt{2}-1\right]`.
Outside this domain, :math:`\mathrm{ln}\left(1+x\right)` is computed by the standard logarithmic function.
.. _s01ba-py2-py-references:
**References**
Lyusternik, L A, Chervonenkis, O A and Yanpolskii, A R, 1965, `Handbook for Computing Elementary Functions`, p. 57, Pergamon Press
"""
raise NotImplementedError
[docs]def exp_complex(z):
r"""
``exp_complex`` evaluates the exponential function :math:`e^z`, for `complex` :math:`z`.
.. _s01ea-py2-py-doc:
For full information please refer to the NAG Library document for s01ea
https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s01eaf.html
.. _s01ea-py2-py-parameters:
**Parameters**
**z** : complex
The argument :math:`z` of the function.
**Returns**
**ez** : complex
The value of the exponential function.
.. _s01ea-py2-py-errors:
**Raises**
**NagValueError**
(`errno` :math:`5`)
The imaginary part of argument :math:`\mathrm{z}` is so large that the result has no precision: :math:`\mathrm{z} = \left({\langle\mathit{\boldsymbol{value}}\rangle}, {\langle\mathit{\boldsymbol{value}}\rangle}\right)`.
**Warns**
**NagAlgorithmicWarning**
(`errno` :math:`1`)
Argument :math:`\mathrm{z}` causes overflow in real part of result: :math:`\mathrm{z} = \left({\langle\mathit{\boldsymbol{value}}\rangle}, {\langle\mathit{\boldsymbol{value}}\rangle}\right)`.
(`errno` :math:`2`)
Argument :math:`\mathrm{z}` causes overflow in imaginary part of result: :math:`\mathrm{z} = \left({\langle\mathit{\boldsymbol{value}}\rangle}, {\langle\mathit{\boldsymbol{value}}\rangle}\right)`.
(`errno` :math:`3`)
Argument :math:`\mathrm{z}` causes overflow in both real and imaginary parts of result: :math:`\mathrm{z} = \left({\langle\mathit{\boldsymbol{value}}\rangle}, {\langle\mathit{\boldsymbol{value}}\rangle}\right)`.
(`errno` :math:`4`)
The imaginary part of argument :math:`\mathrm{z}` is so large that the result is accurate to less than half precision: :math:`\mathrm{z} = \left({\langle\mathit{\boldsymbol{value}}\rangle}, {\langle\mathit{\boldsymbol{value}}\rangle}\right)`.
.. _s01ea-py2-py-notes:
**Notes**
`No equivalent traditional C interface for this routine exists in the NAG Library.`
``exp_complex`` evaluates the exponential function :math:`e^z`, taking care to avoid machine overflow, and giving a warning if the result cannot be computed to more than half precision.
The function is evaluated as :math:`e^z = e^x\left(\cos\left(y\right)+i\sin\left(y\right)\right)`, where :math:`x` and :math:`y` are the real and imaginary parts respectively of :math:`z`.
Since :math:`\cos\left(y\right)` and :math:`\sin\left(y\right)` are less than or equal to :math:`1` in magnitude, it is possible that :math:`e^x` may overflow although :math:`e^x\cos\left(y\right)` or :math:`e^x\sin\left(y\right)` does not.
In this case the alternative formula :math:`\mathrm{sign}\left(\cos\left(y\right)\right)e^{{x+\mathrm{ln}\left(\left\lvert \cos\left(y\right)\right\rvert \right)}}` is used for the real part of the result, and :math:`\mathrm{sign}\left(\sin\left(y\right)\right)e^{{x+\mathrm{ln}\left(\left\lvert \sin\left(y\right)\right\rvert \right)}}` for the imaginary part.
If either part of the result still overflows, a warning is returned through argument :math:`\textit{errno}`.
If :math:`\mathrm{Im}\left(z\right)` is too large, precision may be lost in the evaluation of :math:`\sin\left(y\right)` and :math:`\cos\left(y\right)`.
Again, a warning is returned through :math:`\textit{errno}`.
"""
raise NotImplementedError
[docs]def tan(x):
r"""
``tan`` returns the value of the circular tangent, :math:`\tan\left(x\right)`.
.. _s07aa-py2-py-doc:
For full information please refer to the NAG Library document for s07aa
https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s07aaf.html
.. _s07aa-py2-py-parameters:
**Parameters**
**x** : float
The argument :math:`x` of the function.
**Returns**
**tx** : float
The value of the circular tangent, :math:`\tan\left(x\right)`.
.. _s07aa-py2-py-errors:
**Raises**
**NagValueError**
(`errno` :math:`1`)
On entry, :math:`\mathrm{x} = \langle\mathit{\boldsymbol{value}}\rangle` and the constant :math:`F_1 = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\left\lvert \mathrm{x}\right\rvert \leq F_1`.
**Warns**
**NagAlgorithmicWarning**
(`errno` :math:`2`)
On entry, :math:`\mathrm{x} = \langle\mathit{\boldsymbol{value}}\rangle` and the constant :math:`F_2 = \langle\mathit{\boldsymbol{value}}\rangle`.
The function has been called with an argument that is too close to an odd multiple of :math:`\pi /2`, at which the function is infinite; the function has returned a value with the correct sign but a more or less arbitrary but large magnitude.
.. _s07aa-py2-py-notes:
**Notes**
`No equivalent traditional C interface for this routine exists in the NAG Library.`
``tan`` calculates an approximate value for the circular tangent of its argument, :math:`\tan\left(x\right)`.
It is based on the Chebyshev expansion
.. math::
\tan\left(\theta \right) = \theta y\left(t\right) = \theta {\sum^\prime}_{{r = 0}}c_rT_r\left(t\right)
where :math:`{-\frac{\pi }{4}} < \theta < \frac{\pi }{4}` and :math:`{-1} < t < +1\text{, }\quad t = 2\left(\frac{{4\theta }}{\pi }\right)^2-1`.
The reduction to the standard range is accomplished by taking
.. math::
x = N\pi /2+\theta
where :math:`N` is an integer and :math:`{-\frac{\pi }{4}} < \theta < \frac{\pi }{4}`,
i.e., :math:`\theta = x-\left(\frac{{2x}}{\pi }\right)\frac{\pi }{2}` where :math:`N = \left[\frac{{2x}}{\pi }\right] = \text{ the nearest integer to }\frac{{2x}}{\pi }`.
From the properties of :math:`\tan\left(x\right)` it follows that
.. math::
\tan\left(x\right) = \left\{\begin{array}{rr}\tan\left(\theta \right)\text{,}&N\mathrm{even}\\{-1}/\tan\left(\theta \right)\text{,}&N\mathrm{odd}\end{array}\right\}
.. _s07aa-py2-py-references:
**References**
NIST Digital Library of Mathematical Functions
"""
raise NotImplementedError
[docs]def arcsin(x):
r"""
``arcsin`` returns the value of the inverse circular sine, :math:`\arcsin\left(x\right)`.
The value is in the principal range :math:`\left({-\pi /2}, {\pi /2}\right)`.
.. _s09aa-py2-py-doc:
For full information please refer to the NAG Library document for s09aa
https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s09aaf.html
.. _s09aa-py2-py-parameters:
**Parameters**
**x** : float
The argument :math:`x` of the function.
**Returns**
**asx** : float
The value of the inverse circular sine, :math:`\arcsin\left(x\right)`.
.. _s09aa-py2-py-errors:
**Raises**
**NagValueError**
(`errno` :math:`1`)
On entry, :math:`\mathrm{x} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\left\lvert \mathrm{x}\right\rvert \leq 1`.
.. _s09aa-py2-py-notes:
**Notes**
`No equivalent traditional C interface for this routine exists in the NAG Library.`
``arcsin`` calculates an approximate value for the inverse circular sine, :math:`\arcsin\left(x\right)`.
It is based on the Chebyshev expansion
.. math::
\arcsin\left(x\right) = x\times y\left(x\right) = x{\sum^\prime}_{{r = 0}}a_rT_r\left(t\right)
where :math:`{-\frac{1}{\sqrt{2}}}\leq x\leq \frac{1}{\sqrt{2}}` and :math:`t = 4x^2-1`.
For :math:`x^2\leq \frac{1}{2}\text{, }\quad \arcsin\left(x\right) = x\times y\left(x\right)`.
For :math:`\frac{1}{2} < x^2\leq 1\text{, }\quad \arcsin\left(x\right) = \mathrm{sign}\left(x\right)\left\{\frac{\pi }{2}-\arcsin\left(\sqrt{1-x^2}\right)\right\}`.
For :math:`x^2 > 1\text{, }\quad \arcsin\left(x\right)` is undefined and the function fails.
.. _s09aa-py2-py-references:
**References**
NIST Digital Library of Mathematical Functions
"""
raise NotImplementedError
[docs]def arccos(x):
r"""
``arccos`` returns the value of the inverse circular cosine, :math:`\arccos\left(x\right)`; the result is in the principal range :math:`\left(0, \pi \right)`.
.. _s09ab-py2-py-doc:
For full information please refer to the NAG Library document for s09ab
https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s09abf.html
.. _s09ab-py2-py-parameters:
**Parameters**
**x** : float
The argument :math:`x` of the function.
**Returns**
**acx** : float
The value of the inverse circular cosine, :math:`\arccos\left(x\right)`.
.. _s09ab-py2-py-errors:
**Raises**
**NagValueError**
(`errno` :math:`1`)
On entry, :math:`\mathrm{x} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\left\lvert \mathrm{x}\right\rvert \leq 1`.
.. _s09ab-py2-py-notes:
**Notes**
`No equivalent traditional C interface for this routine exists in the NAG Library.`
``arccos`` calculates an approximate value for the inverse circular cosine, :math:`\arccos\left(x\right)`.
It is based on the Chebyshev expansion
.. math::
\arcsin\left(x\right) = x\times y\left(t\right) = x{\sum^\prime}_{{r = 0}}a_rT_r\left(t\right)
where :math:`\frac{{-1}}{\sqrt{2}}\leq x\leq \frac{1}{\sqrt{2}}\text{, and }\quad t = 4x^2-1`.
For :math:`x^2\leq \frac{1}{2}\text{, }\quad \arccos\left(x\right) = \frac{\pi }{2}-\arcsin\left(x\right)`.
For :math:`{-1}\leq x < \frac{{-1}}{\sqrt{2}}\text{, }\quad \arccos\left(x\right) = \pi -\arcsin\left(\sqrt{1-x^2}\right)`.
For :math:`\frac{1}{\sqrt{2}} < x\leq 1\text{, }\quad \arccos\left(x\right) = \arcsin\left(\sqrt{1-x^2}\right)`.
For :math:`\left\lvert x\right\rvert > 1\text{, }\quad \arccos\left(x\right)` is undefined and the function fails.
.. _s09ab-py2-py-references:
**References**
NIST Digital Library of Mathematical Functions
"""
raise NotImplementedError
[docs]def tanh(x):
r"""
``tanh`` returns a value for the hyperbolic tangent, :math:`\tanh\left(x\right)`.
.. _s10aa-py2-py-doc:
For full information please refer to the NAG Library document for s10aa
https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s10aaf.html
.. _s10aa-py2-py-parameters:
**Parameters**
**x** : float
The argument :math:`x` of the function.
**Returns**
**thx** : float
The value of the hyperbolic tangent, :math:`\tanh\left(x\right)`.
.. _s10aa-py2-py-notes:
**Notes**
``tanh`` calculates an approximate value for the hyperbolic tangent of its argument, :math:`\tanh\left(x\right)`.
For :math:`\left\lvert x\right\rvert \leq 1` it is based on the Chebyshev expansion
.. math::
\tanh\left(x\right) = x\times y\left(t\right) = x{\sum^\prime}_{{r = 0}}a_rT_r\left(t\right)
where :math:`{-1}\leq x\leq 1\text{, }\quad -1\leq t\leq 1\text{, and }\quad t = 2x^2-1`.
For :math:`1 < \left\lvert x\right\rvert < E_1`
.. math::
\tanh\left(x\right) = \frac{{e^{{2x}}-1}}{{e^{{2x}}+1}}\text{.}
For :math:`\left\lvert x\right\rvert \geq E_1`, :math:`\tanh\left(x\right) = \mathrm{sign}\left(x\right)` to within the representation accuracy of the machine and so this approximation is used.
.. _s10aa-py2-py-references:
**References**
NIST Digital Library of Mathematical Functions
"""
raise NotImplementedError
[docs]def sinh(x):
r"""
``sinh`` returns the value of the hyperbolic sine, :math:`\sinh\left(x\right)`.
.. _s10ab-py2-py-doc:
For full information please refer to the NAG Library document for s10ab
https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s10abf.html
.. _s10ab-py2-py-parameters:
**Parameters**
**x** : float
The argument :math:`x` of the function.
**Returns**
**shx** : float
The value of the hyperbolic sine, :math:`\sinh\left(x\right)`.
.. _s10ab-py2-py-errors:
**Warns**
**NagAlgorithmicWarning**
(`errno` :math:`1`)
On entry, :math:`\mathrm{x} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\left\lvert \mathrm{x}\right\rvert \leq E_1`.
The function has been called with an argument too large in absolute magnitude. There is a danger of overflow. The result returned is the value of :math:`\sinh\left(x\right)` at the closest argument for which a valid call could be made.
.. _s10ab-py2-py-notes:
**Notes**
``sinh`` calculates an approximate value for the hyperbolic sine of its argument, :math:`\sinh\left(x\right)`.
For :math:`\left\lvert x\right\rvert \leq 1` it uses the Chebyshev expansion
.. math::
\sinh\left(x\right) = x\times y\left(t\right) = x{\sum^\prime}_{{r = 0}}a_rT_r\left(t\right)
where :math:`t = 2x^2-1`.
For :math:`1 < \left\lvert x\right\rvert \leq E_1\text{, }\quad \sinh\left(x\right) = \frac{1}{2}\left(e^x-e^{{-x}}\right)`
where :math:`E_1` is a machine-dependent constant.
For :math:`\left\lvert x\right\rvert > E_1`, the function fails owing to the danger of setting overflow in calculating :math:`e^x`.
The result returned for such calls is :math:`\sinh\left(\mathrm{sign}\left(x\right)E_1\right)`, i.e., it returns the result for the nearest valid argument.
.. _s10ab-py2-py-references:
**References**
NIST Digital Library of Mathematical Functions
"""
raise NotImplementedError
[docs]def cosh(x):
r"""
``cosh`` returns the value of the hyperbolic cosine, :math:`\cosh\left(x\right)`.
.. _s10ac-py2-py-doc:
For full information please refer to the NAG Library document for s10ac
https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s10acf.html
.. _s10ac-py2-py-parameters:
**Parameters**
**x** : float
The argument :math:`x` of the function.
**Returns**
**chx** : float
The value of the hyperbolic cosine, :math:`\cosh\left(x\right)`.
.. _s10ac-py2-py-errors:
**Warns**
**NagAlgorithmicWarning**
(`errno` :math:`1`)
On entry, :math:`\mathrm{x} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\left\lvert \mathrm{x}\right\rvert \leq E_1`.
The function has been called with an argument too large in absolute magnitude. There is a danger of overflow. The result returned is the value of :math:`\cosh\left(x\right)` at the nearest valid argument.
.. _s10ac-py2-py-notes:
**Notes**
``cosh`` calculates an approximate value for the hyperbolic cosine, :math:`\cosh\left(x\right)`.
For :math:`\left\lvert x\right\rvert \leq E_1\text{, }\quad \cosh\left(x\right) = \frac{1}{2}\left(e^x+e^{{-x}}\right)`.
For :math:`\left\lvert x\right\rvert > E_1`, the function fails owing to danger of setting overflow in calculating :math:`e^x`.
The result returned for such calls is :math:`\cosh\left(E_1\right)`, i.e., it returns the result for the nearest valid argument.
.. _s10ac-py2-py-references:
**References**
NIST Digital Library of Mathematical Functions
"""
raise NotImplementedError
[docs]def arctanh(x):
r"""
``arctanh`` returns the value of the inverse hyperbolic tangent, :math:`\mathrm{arctanh}\left(x\right)`.
.. _s11aa-py2-py-doc:
For full information please refer to the NAG Library document for s11aa
https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s11aaf.html
.. _s11aa-py2-py-parameters:
**Parameters**
**x** : float
The argument :math:`x` of the function.
**Returns**
**athx** : float
The value of the inverse hyperbolic tangent, :math:`\mathrm{arctanh}\left(x\right)`.
.. _s11aa-py2-py-errors:
**Raises**
**NagValueError**
(`errno` :math:`1`)
On entry, :math:`\mathrm{x} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\left\lvert \mathrm{x}\right\rvert < 1`.
The function has been called with an argument greater than or equal to :math:`1.0` in magnitude, for which :math:`\mathrm{arctanh}` is not defined.
.. _s11aa-py2-py-notes:
**Notes**
``arctanh`` calculates an approximate value for the inverse hyperbolic tangent of its argument, :math:`\mathrm{arctanh}\left(x\right)`.
For :math:`x^2\leq \frac{1}{2}` it is based on the Chebyshev expansion
.. math::
\mathrm{arctanh}\left(x\right) = x\times y\left(t\right) = x{\sum^\prime}_{{r = 0}}a_rT_r\left(t\right)
where :math:`{-\frac{1}{\sqrt{2}}}\leq x\leq \frac{1}{\sqrt{2}}`, :math:`\quad \text{ }\quad -1\leq t\leq 1`, :math:`\quad \text{ and }\quad t = 4x^2-1`.
For :math:`\frac{1}{2} < x^2 < 1`, it uses
.. math::
\mathrm{arctanh}\left(x\right) = \frac{1}{2}\mathrm{ln}\left(\frac{{1+x}}{{1-x}}\right)\text{.}
For :math:`\left\lvert x\right\rvert \geq 1`, the function fails as :math:`\mathrm{arctanh}\left(x\right)` is undefined.
.. _s11aa-py2-py-references:
**References**
NIST Digital Library of Mathematical Functions
"""
raise NotImplementedError
[docs]def arcsinh(x):
r"""
``arcsinh`` returns the value of the inverse hyperbolic sine, :math:`\mathrm{arcsinh}\left(x\right)`.
.. _s11ab-py2-py-doc:
For full information please refer to the NAG Library document for s11ab
https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s11abf.html
.. _s11ab-py2-py-parameters:
**Parameters**
**x** : float
The argument :math:`x` of the function.
**Returns**
**ashx** : float
The value of the inverse hyperbolic sine, :math:`\mathrm{arcsinh}\left(x\right)`.
.. _s11ab-py2-py-notes:
**Notes**
``arcsinh`` calculates an approximate value for the inverse hyperbolic sine of its argument, :math:`\mathrm{arcsinh}\left(x\right)`.
For :math:`\left\lvert x\right\rvert \leq 1` it is based on the Chebyshev expansion
.. math::
\mathrm{arcsinh}\left(x\right) = x\times y\left(t\right) = x{\sum^\prime}_{{r = 0}}c_rT_r\left(t\right)\text{, where }t = 2x^2-1\text{.}
For :math:`\left\lvert x\right\rvert > 1` it uses the fact that
.. math::
\mathrm{arcsinh}\left(x\right) = \mathrm{sign}\left(x\right)\times \mathrm{ln}\left(\left\lvert x\right\rvert +\sqrt{x^2+1}\right)\text{.}
This form is used directly for :math:`1 < \left\lvert x\right\rvert < 10^k`, where :math:`k = n/2+1`, and the machine uses approximately :math:`n` decimal place arithmetic.
For :math:`\left\lvert x\right\rvert \geq 10^k`, :math:`\sqrt{x^2+1}` is equal to :math:`\left\lvert x\right\rvert` to within the accuracy of the machine and hence we can guard against premature overflow and, without loss of accuracy, calculate
.. math::
\mathrm{arcsinh}\left(x\right) = \mathrm{sign}\left(x\right)\times \left(\mathrm{ln}\left(2\right)+\mathrm{ln}\left(\left\lvert x\right\rvert \right)\right)\text{.}
.. _s11ab-py2-py-references:
**References**
NIST Digital Library of Mathematical Functions
"""
raise NotImplementedError
[docs]def arccosh(x):
r"""
``arccosh`` returns the value of the inverse hyperbolic cosine, :math:`\mathrm{arccosh}\left(x\right)`.
The result is in the principal positive branch.
.. _s11ac-py2-py-doc:
For full information please refer to the NAG Library document for s11ac
https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s11acf.html
.. _s11ac-py2-py-parameters:
**Parameters**
**x** : float
The argument :math:`x` of the function.
**Returns**
**achx** : float
The value of the inverse hyperbolic cosine, :math:`\mathrm{arccosh}\left(x\right)`.
.. _s11ac-py2-py-errors:
**Raises**
**NagValueError**
(`errno` :math:`1`)
On entry, :math:`\mathrm{x} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{x}\geq 1.0`.
The function has been called with an argument less than :math:`1.0`, for which :math:`\mathrm{arccosh}\left(x\right)` is not defined.
.. _s11ac-py2-py-notes:
**Notes**
``arccosh`` calculates an approximate value for the inverse hyperbolic cosine, :math:`\mathrm{arccosh}\left(x\right)`.
It is based on the relation
.. math::
\mathrm{arccosh}\left(x\right) = \mathrm{ln}\left(x+\sqrt{x^2-1}\right)\text{.}
This form is used directly for :math:`1 < x < 10^k`, where :math:`k = n/2+1`, and the machine uses approximately :math:`n` decimal place arithmetic.
For :math:`x\geq 10^k`, :math:`\sqrt{x^2-1}` is equal to :math:`\sqrt{x}` to within the accuracy of the machine and hence we can guard against premature overflow and, without loss of accuracy, calculate
.. math::
\mathrm{arccosh}\left(x\right) = \mathrm{ln}\left(2\right)+\mathrm{ln}\left(x\right)\text{.}
.. _s11ac-py2-py-references:
**References**
NIST Digital Library of Mathematical Functions
"""
raise NotImplementedError
[docs]def integral_exp(x):
r"""
``integral_exp`` returns the value of the exponential integral :math:`E_1\left(x\right)`.
.. _s13aa-py2-py-doc:
For full information please refer to the NAG Library document for s13aa
https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s13aaf.html
.. _s13aa-py2-py-parameters:
**Parameters**
**x** : float
The argument :math:`x` of the function.
**Returns**
**e1x** : float
The value of the exponential integral :math:`E_1\left(x\right)`.
.. _s13aa-py2-py-errors:
**Raises**
**NagValueError**
(`errno` :math:`2`)
On entry, :math:`\mathrm{x} = \langle\mathit{\boldsymbol{value}}\rangle` and the constant :math:`x_{\mathrm{hi}} = \langle\mathit{\boldsymbol{value}}\rangle`. The evaluation has been abandoned due to the likelihood of overflow.
Constraint: :math:`\mathrm{x}\geq {-x_{\mathrm{hi}}}`.
**Warns**
**NagAlgorithmicWarning**
(`errno` :math:`1`)
On entry, :math:`\mathrm{x} = 0.0` and the function is infinite.
.. _s13aa-py2-py-notes:
**Notes**
``integral_exp`` calculates an approximate value for
.. math::
E_1\left(x\right) = -\mathrm{Ei}\left(-x\right) = \int_x^{\infty }\frac{e^{{-u}}}{u}{du}\text{.}
using Chebyshev expansions, where :math:`x` is real.
For :math:`x < 0`, the real part of the principal value of the integral is taken.
The value :math:`E_1\left(0\right)` is infinite, and so, when :math:`x = 0`, ``integral_exp`` exits with an error and returns the largest representable machine number.
For :math:`0 < x\leq 4`,
.. math::
E_1\left(x\right) = y\left(t\right)-\mathrm{ln}\left(x\right) = {\sum^\prime}_ra_rT_r\left(t\right)-\mathrm{ln}\left(x\right)\text{,}
where :math:`t = \frac{1}{2}x-1`.
For :math:`x > 4`,
.. math::
E_1\left(x\right) = \frac{e^{{-x}}}{x}y\left(t\right) = \frac{e^{{-x}}}{x}{\sum^\prime}_ra_rT_r\left(t\right)\text{,}
where :math:`t = {-1.0}+\frac{14.5}{\left(x+3.25\right)} = \frac{{11.25-x}}{{3.25+x}}`.
In both cases, :math:`{-1}\leq t\leq +1`.
For :math:`x < 0`, the approximation is based on expansions proposed by Cody and Thatcher Jr. (1969).
Precautions are taken to maintain good relative accuracy in the vicinity of :math:`x_0≈{-0.372507}\ldots \text{}`, which corresponds to a simple zero of Ei(:math:`{-x}`).
``integral_exp`` guards against producing underflows and overflows by using the argument :math:`x_{\mathrm{hi}}`.
To guard against overflow, if :math:`x < -x_{\mathrm{hi}}` the function terminates and returns the negative of the largest representable machine number.
To guard against underflow, if :math:`x > x_{\mathrm{hi}}` the result is set directly to zero.
.. _s13aa-py2-py-references:
**References**
NIST Digital Library of Mathematical Functions
Cody, W J and Thatcher Jr., H C, 1969, `Rational Chebyshev approximations for the exponential integral Ei` :math:`\left(x\right)`, Math. Comp. (23), 289--303
"""
raise NotImplementedError
[docs]def integral_cos(x):
r"""
``integral_cos`` returns the value of the cosine integral
.. math::
\mathrm{Ci}\left(x\right) = \gamma +\mathrm{ln}\left(x\right)+\int_0^x\frac{{\cos\left(u\right)-1}}{u}{du}\text{, }\quad x > 0
where :math:`\gamma` denotes Euler's constant.
.. _s13ac-py2-py-doc:
For full information please refer to the NAG Library document for s13ac
https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s13acf.html
.. _s13ac-py2-py-parameters:
**Parameters**
**x** : float
The argument :math:`x` of the function.
**Returns**
**cix** : float
The value of the cosine integral
.. math::
\mathrm{Ci}\left(x\right) = \gamma +\mathrm{ln}\left(x\right)+\int_0^x\frac{{\cos\left(u\right)-1}}{u}{du}\text{, }\quad x > 0\text{.}
.. _s13ac-py2-py-errors:
**Raises**
**NagValueError**
(`errno` :math:`1`)
On entry, :math:`\mathrm{x} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{x} > 0.0`.
The function has been called with an argument less than or equal to zero for which :math:`\mathrm{Ci}\left(x\right)` is not defined.
.. _s13ac-py2-py-notes:
**Notes**
``integral_cos`` calculates an approximate value for :math:`\mathrm{Ci}\left(x\right)`.
For :math:`0 < x\leq 16` it is based on the Chebyshev expansion
.. math::
\mathrm{Ci}\left(x\right) = \mathrm{ln}\left(x\right)+\sum_{{r = 0}}^{\prime }a_rT_r\left(t\right),t = 2\left(\frac{x}{16}\right)^2-1\text{.}
For :math:`16 < x < x_{\mathrm{hi}}`,
.. math::
\mathrm{Ci}\left(x\right) = \frac{{f\left(x\right)\sin\left(x\right)}}{x}-\frac{{g\left(x\right)\cos\left(x\right)}}{x^2}
where :math:`f\left(x\right) = {\sum^\prime}_{{r = 0}}f_rT_r\left(t\right)` and :math:`g\left(x\right) = {\sum^\prime}_{{r = 0}}g_rT_r\left(t\right)`, :math:`t = 2\left(\frac{16}{x}\right)^2-1`.
For :math:`x\geq x_{\mathrm{hi}}`, :math:`\mathrm{Ci}\left(x\right) = 0` to within the accuracy possible (see `Accuracy <https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s13acf.html#accuracy>`__).
.. _s13ac-py2-py-references:
**References**
NIST Digital Library of Mathematical Functions
"""
raise NotImplementedError
[docs]def integral_sin(x):
r"""
``integral_sin`` returns the value of the sine integral
.. math::
\mathrm{Si}\left(x\right) = \int_0^x\frac{{\sin\left(u\right)}}{u}{du}\text{,}
.
.. _s13ad-py2-py-doc:
For full information please refer to the NAG Library document for s13ad
https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s13adf.html
.. _s13ad-py2-py-parameters:
**Parameters**
**x** : float
The argument :math:`x` of the function.
**Returns**
**six** : float
The value of the sine integral
.. math::
\mathrm{Si}\left(x\right) = \int_0^x\frac{{\sin\left(u\right)}}{u}{du}\text{.}
.. _s13ad-py2-py-notes:
**Notes**
``integral_sin`` calculates an approximate value for :math:`\mathrm{Si}\left(x\right)`.
For :math:`\left\lvert x\right\rvert \leq 16.0` it is based on the Chebyshev expansion
.. math::
\mathrm{Si}\left(x\right) = x\sum_{{r = 0}}^{\prime }a_rT_r\left(t\right),t = 2\left(\frac{x}{16}\right)^2-1\text{.}
For :math:`16 < \left\lvert x\right\rvert < x_{\mathrm{hi}}`, where :math:`x_{\mathrm{hi}}` is an implementation-dependent number,
.. math::
\mathrm{Si}\left(x\right) = {\mathrm{sign}\left(x\right)}\left\{\frac{\pi }{2}-\frac{{f\left(x\right)\cos\left(x\right)}}{x}-\frac{{g\left(x\right)\sin\left(x\right)}}{x^2}\right\}
where :math:`f\left(x\right) = {\sum^\prime}_{{r = 0}}f_rT_r\left(t\right)` and :math:`g\left(x\right) = {\sum^\prime}_{{r = 0}}g_rT_r\left(t\right)`, :math:`t = 2\left(\frac{16}{x}\right)^2-1`.
For :math:`\left\lvert x\right\rvert \geq x_{\mathrm{hi}}`, :math:`\mathrm{Si}\left(x\right) = \frac{1}{2}\pi \mathrm{sign}\left(x\right)` to within machine precision.
.. _s13ad-py2-py-references:
**References**
NIST Digital Library of Mathematical Functions
"""
raise NotImplementedError
[docs]def gamma(x):
r"""
``gamma`` returns the value of the gamma function :math:`\Gamma \left(x\right)`.
.. _s14aa-py2-py-doc:
For full information please refer to the NAG Library document for s14aa
https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s14aaf.html
.. _s14aa-py2-py-parameters:
**Parameters**
**x** : float
The argument :math:`x` of the function.
**Returns**
**gx** : float
The value of the gamma function :math:`\Gamma \left(x\right)`.
.. _s14aa-py2-py-errors:
**Raises**
**NagValueError**
(`errno` :math:`1`)
On entry, :math:`\mathrm{x} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{x}\leq \langle\mathit{\boldsymbol{value}}\rangle`.
The argument is too large, the function returns the approximate value of :math:`\Gamma \left(x\right)` at the nearest valid argument.
(`errno` :math:`2`)
On entry, :math:`\mathrm{x} = \langle\mathit{\boldsymbol{value}}\rangle`. The function returns zero.
Constraint: :math:`\mathrm{x}\geq \langle\mathit{\boldsymbol{value}}\rangle`.
The argument is too large and negative, the function returns zero.
**Warns**
**NagAlgorithmicWarning**
(`errno` :math:`3`)
On entry, :math:`\mathrm{x} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\left\lvert \mathrm{x}\right\rvert \geq \langle\mathit{\boldsymbol{value}}\rangle`.
The argument is too close to zero, the function returns the approximate value of :math:`\Gamma \left(x\right)` at the nearest valid argument.
(`errno` :math:`4`)
On entry, :math:`\mathrm{x} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{x}` must not be a negative integer.
The argument is a negative integer, at which values :math:`\Gamma \left(x\right)` is infinite. The function returns a large positive value.
.. _s14aa-py2-py-notes:
**Notes**
``gamma`` evaluates an approximation to the gamma function :math:`\Gamma \left(x\right)`.
The function is based on the Chebyshev expansion:
.. math::
\Gamma \left(1+u\right) = \sum_{{r = 0}}^{\prime }a_rT_r\left(t\right)
where :math:`0\leq u < 1,t = 2u-1\text{,}` and uses the property :math:`\Gamma \left(1+x\right) = x\Gamma \left(x\right)`.
If :math:`x = N+1+u` where :math:`N` is integral and :math:`0\leq u < 1` then it follows that:
.. rst-class:: nag-rules-none nag-align-left
+------------------+--------------------------------------------------------------------------------------------------------------------------------+
|for :math:`N > 0`,|:math:`\Gamma \left(x\right) = \left(x-1\right)\left(x-2\right) \cdots \left(x-N\right)\Gamma \left(1+u\right)`, |
+------------------+--------------------------------------------------------------------------------------------------------------------------------+
|for :math:`N = 0`,|:math:`\Gamma \left(x\right) = \Gamma \left(1+u\right)`, |
+------------------+--------------------------------------------------------------------------------------------------------------------------------+
|for :math:`N < 0`,|:math:`\Gamma \left(x\right) = \frac{{\Gamma \left(1+u\right)}}{{x\left(x+1\right)\left(x+2\right) \cdots \left(x-N-1\right)}}`.|
+------------------+--------------------------------------------------------------------------------------------------------------------------------+
There are four possible failures for this function:
(i) if :math:`x` is too large, there is a danger of overflow since :math:`\Gamma \left(x\right)` could become too large to be represented in the machine;
(#) if :math:`x` is too large and negative, there is a danger of underflow;
(#) if :math:`x` is equal to a negative integer, :math:`\Gamma \left(x\right)` would overflow since it has poles at such points;
(#) if :math:`x` is too near zero, there is again the danger of overflow on some machines. For small :math:`x`, :math:`\Gamma \left(x\right)\simeq 1/x`, and on some machines there exists a range of nonzero but small values of :math:`x` for which :math:`1/x` is larger than the greatest representable value.
.. _s14aa-py2-py-references:
**References**
NIST Digital Library of Mathematical Functions
"""
raise NotImplementedError
[docs]def gamma_log_real(x):
r"""
``gamma_log_real`` returns the value of the logarithm of the gamma function, :math:`\mathrm{ln}\left(\Gamma \right)\left(x\right)`.
.. _s14ab-py2-py-doc:
For full information please refer to the NAG Library document for s14ab
https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s14abf.html
.. _s14ab-py2-py-parameters:
**Parameters**
**x** : float
The argument :math:`x` of the function.
**Returns**
**lgx** : float
The value of :math:`\mathrm{ln}\left(\Gamma \right)\left(x\right)`.
.. _s14ab-py2-py-errors:
**Raises**
**NagValueError**
(`errno` :math:`1`)
On entry, :math:`\mathrm{x} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{x} > 0.0`.
**Warns**
**NagAlgorithmicWarning**
(`errno` :math:`2`)
On entry, :math:`\mathrm{x} = \langle\mathit{\boldsymbol{value}}\rangle` and the constant :math:`x_{\mathrm{big}} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{x}\leq x_{\mathrm{big}}`.
.. _s14ab-py2-py-notes:
**Notes**
``gamma_log_real`` calculates an approximate value for :math:`\mathrm{ln}\left(\Gamma \right)\left(x\right)`.
It is based on rational Chebyshev expansions.
Denote by :math:`R_{{n,m}}^i\left(x\right) = P_n^i\left(x\right)/Q_m^i\left(x\right)` a ratio of polynomials of degree :math:`n` in the numerator and :math:`m` in the denominator.
Then:
for :math:`0 < x\leq 1/2`,
.. math::
\mathrm{ln}\left(\Gamma \right)\left(x\right)≈-\mathrm{ln}\left(x\right)+xR_{{n,m}}^1\left(x+1\right)\text{;}
for :math:`1/2 < x\leq 3/2`,
.. math::
\mathrm{ln}\left(\Gamma \right)\left(x\right)≈\left(x-1\right)R_{{n,m}}^1\left(x\right)\text{;}
for :math:`3/2 < x\leq 4`,
.. math::
\mathrm{ln}\left(\Gamma \right)\left(x\right)≈\left(x-2\right)R_{{n,m}}^2\left(x\right)\text{;}
for :math:`4 < x\leq 12`,
.. math::
\mathrm{ln}\left(\Gamma \right)\left(x\right)≈R_{{n,m}}^3\left(x\right)\text{;}
and for :math:`12 < x`,
.. math::
\mathrm{ln}\left(\Gamma \right)\left(x\right)≈\left(x-\frac{1}{2}\right)\mathrm{ln}\left(x\right)-x+\mathrm{ln}\left(\sqrt{2π}\right)+\frac{1}{x}R_{{n,m}}^4\left(1/x^2\right)\text{.}
For each expansion, the specific values of :math:`n` and :math:`m` are selected to be minimal such that the maximum relative error in the expansion is of the order :math:`10^{{-d}}`, where :math:`d` is the maximum number of decimal digits that can be accurately represented for the particular implementation (see :meth:`machine.decimal_digits <naginterfaces.library.machine.decimal_digits>`).
Let :math:`\epsilon` denote machine precision and let :math:`x_{\mathrm{huge}}` denote the largest positive model number (see :meth:`machine.real_largest <naginterfaces.library.machine.real_largest>`).
For :math:`x < 0.0` the value :math:`\mathrm{ln}\left(\Gamma \right)\left(x\right)` is not defined; ``gamma_log_real`` returns zero and exits with :math:`\mathrm{errno}` = 1.
It also exits with :math:`\mathrm{errno}` = 1 when :math:`x = 0.0`, and in this case the value :math:`x_{\mathrm{huge}}` is returned.
For :math:`x` in the interval :math:`\left(0.0, \epsilon \right]`, the function :math:`\mathrm{ln}\left(\Gamma \right)\left(x\right) = -\mathrm{ln}\left(x\right)` to machine accuracy.
Now denote by :math:`x_{\mathrm{big}}` the largest allowable argument for :math:`\mathrm{ln}\left(\Gamma \right)\left(x\right)` on the machine.
For :math:`\left(x_{\mathrm{big}}\right)^{{1/4}} < x\leq x_{\mathrm{big}}` the :math:`R_{{n,m}}^4\left(1/x^2\right)` term in Equation `(1) <https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s14abf.html#eqn1>`__ is negligible.
For :math:`x > x_{\mathrm{big}}` there is a danger of setting overflow, and so ``gamma_log_real`` exits with :math:`\mathrm{errno}` = 2 and returns :math:`x_{\mathrm{huge}}`.
.. _s14ab-py2-py-references:
**References**
NIST Digital Library of Mathematical Functions
Cody, W J and Hillstrom, K E, 1967, `Chebyshev approximations for the natural logarithm of the gamma function`, Math.Comp. (21), 198--203
"""
raise NotImplementedError
[docs]def polygamma(x):
r"""
``polygamma`` returns a value of the function :math:`\psi \left(x\right)-\mathrm{ln}\left(x\right)`, where :math:`\psi` is the psi function :math:`\psi \left(x\right) = \frac{d}{{dx}}\mathrm{ln}\left(\Gamma \right)\left(x\right) = \frac{{\Gamma^{\prime }\left(x\right)}}{{\Gamma \left(x\right)}}`.
.. _s14ac-py2-py-doc:
For full information please refer to the NAG Library document for s14ac
https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s14acf.html
.. _s14ac-py2-py-parameters:
**Parameters**
**x** : float
The argument :math:`x` of the function.
**Returns**
**pgx** : float
The value of the function :math:`\psi \left(x\right)-\mathrm{ln}\left(x\right)`, where :math:`\psi` is the psi function :math:`\psi \left(x\right) = \frac{d}{{dx}}\mathrm{ln}\left(\Gamma \right)\left(x\right) = \frac{{\Gamma^{\prime }\left(x\right)}}{{\Gamma \left(x\right)}}`.
.. _s14ac-py2-py-errors:
**Raises**
**NagValueError**
(`errno` :math:`1`)
On entry, :math:`\mathrm{x} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{x} > 0.0`.
(`errno` :math:`2`)
Computation halted due to likelihood of underflow. :math:`\mathrm{x}` may be too large. :math:`\mathrm{x} = \langle\mathit{\boldsymbol{value}}\rangle`.
(`errno` :math:`3`)
Computation halted due to likelihood of overflow. :math:`\mathrm{x}` may be too small. :math:`\mathrm{x} = \langle\mathit{\boldsymbol{value}}\rangle`.
.. _s14ac-py2-py-notes:
**Notes**
``polygamma`` returns a value of the function :math:`\psi \left(x\right)-\mathrm{ln}\left(x\right)`.
The psi function is computed without the logarithmic term so that when :math:`x` is large, sums or differences of psi functions may be computed without unnecessary loss of precision, by analytically combining the logarithmic terms.
For example, the difference :math:`d = \psi \left(x+\frac{1}{2}\right)-\psi \left(x\right)` has an asymptotic behaviour for large :math:`x` given by :math:`d\sim \mathrm{ln}\left(x+\frac{1}{2}\right)-\mathrm{ln}\left(x\right)+\mathrm{O}\left(\frac{1}{x^2}\right)\sim \mathrm{ln}\left(1+\frac{1}{{2x}}\right)\sim \frac{1}{{2x}}`.
Computing :math:`d` directly would amount to subtracting two large numbers which are close to :math:`\mathrm{ln}\left(x+\frac{1}{2}\right)` and :math:`\mathrm{ln}\left(x\right)` to produce a small number close to :math:`\frac{1}{{2x}}`, resulting in a loss of significant digits.
However, using this function to compute :math:`f\left(x\right) = \psi \left(x\right)-\mathrm{ln}\left(x\right)`, we can compute :math:`d = f\left(x+\frac{1}{2}\right)-f\left(x\right)+\mathrm{ln}\left(1+\frac{1}{{2x}}\right)`, and the dominant logarithmic term may be computed accurately from its power series when :math:`x` is large.
Thus we avoid the unnecessary loss of precision.
The function is derived from the function PSIFN in Amos (1983).
.. _s14ac-py2-py-references:
**References**
NIST Digital Library of Mathematical Functions
Amos, D E, 1983, `Algorithm 610: A portable FORTRAN subroutine for derivatives of the psi function`, ACM Trans. Math. Software (9), 494--502
"""
raise NotImplementedError
[docs]def polygamma_deriv(x, n, m):
r"""
``polygamma_deriv`` returns a sequence of values of scaled derivatives of the psi function :math:`\psi \left(x\right)` (also known as the digamma function).
.. _s14ad-py2-py-doc:
For full information please refer to the NAG Library document for s14ad
https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s14adf.html
.. _s14ad-py2-py-parameters:
**Parameters**
**x** : float
The argument :math:`x` of the function.
**n** : int
The index of the first member :math:`n` of the sequence of functions.
**m** : int
The number of members :math:`m` required in the sequence :math:`w\left(\textit{k}, x\right)`, for :math:`\textit{k} = n,\ldots,n+m-1`.
**Returns**
**ans** : float, ndarray, shape :math:`\left(\mathrm{m}\right)`
The first :math:`m` elements of :math:`\mathrm{ans}` contain the required values :math:`w\left(\textit{k}, x\right)`, for :math:`\textit{k} = n,\ldots,n+m-1`.
.. _s14ad-py2-py-errors:
**Raises**
**NagValueError**
(`errno` :math:`1`)
On entry, :math:`\mathrm{x} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{x} > 0.0`.
(`errno` :math:`2`)
On entry, :math:`\mathrm{n} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{n}\geq 0`.
(`errno` :math:`3`)
On entry, :math:`\mathrm{m} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{m}\geq 1`.
(`errno` :math:`4`)
Computation abandoned due to the likelihood of underflow.
(`errno` :math:`5`)
Computation abandoned due to the likelihood of overflow.
(`errno` :math:`6`)
There is not enough internal workspace to continue computation. :math:`\mathrm{m}` is probably too large.
.. _s14ad-py2-py-notes:
**Notes**
``polygamma_deriv`` computes :math:`m` values of the function
.. math::
w\left(k, x\right) = \frac{{\left(-1\right)^{{k+1}}\psi^{\left(k\right)}\left(x\right)}}{{k!}}\text{,}
for :math:`x > 0`, :math:`k = n`, :math:`n+1,\ldots,n+m-1`, where :math:`\psi` is the psi function
.. math::
\psi \left(x\right) = \frac{d}{{dx}}\mathrm{ln}\left(\Gamma \right)\left(x\right) = \frac{{\Gamma^{\prime }\left(x\right)}}{{\Gamma \left(x\right)}}\text{,}
and :math:`\psi^{\left(k\right)}` denotes the :math:`k`\ th derivative of :math:`\psi`.
The function is derived from the function PSIFN in Amos (1983).
The basic method of evaluation of :math:`w\left(k, x\right)` is the asymptotic series
.. math::
w\left(k, x\right)\sim \epsilon \left(k, x\right)+\frac{1}{{2x^{{k+1}}}}+\frac{1}{x^k}\sum_{{j = 1}}^{\infty }B_{{2j}}\frac{{\left(2j+k-1\right)!}}{{\left(2j\right)!k!x^{{2j}}}}
for large :math:`x` greater than a machine-dependent value :math:`x_{\mathrm{min}}`, followed by backward recurrence using
.. math::
w\left(k, x\right) = w\left(k, {x+1}\right)+x^{{-k-1}}
for smaller values of :math:`x`, where :math:`\epsilon \left(k, x\right) = -\mathrm{ln}\left(x\right)` when :math:`k = 0`, :math:`\epsilon \left(k, x\right) = \frac{1}{{kx^k}}` when :math:`k > 0`, and :math:`B_{{2j}}`, :math:`j = 1,2,\ldots`, are the Bernoulli numbers.
When :math:`k` is large, the above procedure may be inefficient, and the expansion
.. math::
w\left(k, x\right) = \sum_{{j = 1}}^{\infty }\frac{1}{\left(x+j\right)^{{k+1}}}\text{,}
which converges rapidly for large :math:`k`, is used instead.
.. _s14ad-py2-py-references:
**References**
NIST Digital Library of Mathematical Functions
Amos, D E, 1983, `Algorithm 610: A portable FORTRAN subroutine for derivatives of the psi function`, ACM Trans. Math. Software (9), 494--502
"""
raise NotImplementedError
[docs]def psi_deriv_real(x, k):
r"""
``psi_deriv_real`` returns the value of the :math:`k`\ th derivative of the psi function :math:`\psi \left(x\right)` for real :math:`x` and :math:`k = 0,1,\ldots,6`.
.. _s14ae-py2-py-doc:
For full information please refer to the NAG Library document for s14ae
https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s14aef.html
.. _s14ae-py2-py-parameters:
**Parameters**
**x** : float
The argument :math:`x` of the function.
**k** : int
The function :math:`\psi^{\left(k\right)}\left(x\right)` to be evaluated.
**Returns**
**pkx** : float
The value of the :math:`k`\ th derivative of the psi function :math:`\psi \left(x\right)` for real :math:`x` and :math:`k = 0,1,\ldots,6`.
.. _s14ae-py2-py-errors:
**Raises**
**NagValueError**
(`errno` :math:`1`)
On entry, :math:`\mathrm{x}` is 'too close' to a non-positive integer: :math:`\mathrm{x} = \langle\mathit{\boldsymbol{value}}\rangle` and :math:`\mathrm{nint}\left(\mathrm{x}\right) = \langle\mathit{\boldsymbol{value}}\rangle`.
(`errno` :math:`1`)
On entry, :math:`\mathrm{k} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{k}\leq 6`.
(`errno` :math:`1`)
On entry, :math:`\mathrm{k} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{k}\geq 0`.
(`errno` :math:`2`)
Evaluation abandoned due to likelihood of underflow.
(`errno` :math:`3`)
Evaluation abandoned due to likelihood of overflow.
.. _s14ae-py2-py-notes:
**Notes**
``psi_deriv_real`` evaluates an approximation to the :math:`k`\ th derivative of the psi function :math:`\psi \left(x\right)` given by
.. math::
\psi^{\left(k\right)}\left(x\right) = \frac{d^k}{{dx^k}}\psi \left(x\right) = \frac{d^k}{{dx^k}}\left(\frac{d}{{dx}}\mathrm{loge}\left({\Gamma \left(x\right)}\right)\right)\text{,}
where :math:`x` is real with :math:`x\neq 0,-1,-2,\ldots \text{}` and :math:`k = 0,1,\ldots,6`.
For negative noninteger values of :math:`x`, the recurrence relationship
.. math::
\psi^{\left(k\right)}\left(x+1\right) = \psi^{\left(k\right)}\left(x\right)+\frac{d^k}{{dx^k}}\left(\frac{1}{x}\right)
is used.
The value of :math:`\frac{{\left(-1\right)^{{k+1}}\psi^{\left(k\right)}\left(x\right)}}{{k!}}` is obtained by a call to :meth:`polygamma_deriv`, which is based on the function PSIFN in Amos (1983).
Note that :math:`\psi^{\left(k\right)}\left(x\right)` is also known as the `polygamma` function.
Specifically, :math:`\psi^{\left(0\right)}\left(x\right)` is often referred to as the `digamma` function and :math:`\psi^{\left(1\right)}\left(x\right)` as the `trigamma` function in the literature.
Further details can be found in Abramowitz and Stegun (1972).
.. _s14ae-py2-py-references:
**References**
Abramowitz, M and Stegun, I A, 1972, `Handbook of Mathematical Functions`, (3rd Edition), Dover Publications
Amos, D E, 1983, `Algorithm 610: A portable FORTRAN subroutine for derivatives of the psi function`, ACM Trans. Math. Software (9), 494--502
"""
raise NotImplementedError
[docs]def psi_deriv_complex(z, k):
r"""
``psi_deriv_complex`` returns the value of the :math:`k`\ th derivative of the psi function :math:`\psi \left(z\right)` for complex :math:`z` and :math:`k = 0,1,\ldots,4`.
.. _s14af-py2-py-doc:
For full information please refer to the NAG Library document for s14af
https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s14aff.html
.. _s14af-py2-py-parameters:
**Parameters**
**z** : complex
The argument :math:`z` of the function.
**k** : int
The function :math:`\psi^{\left(k\right)}\left(z\right)` to be evaluated.
**Returns**
**pkz** : complex
The value of the :math:`k`\ th derivative of the psi function.
.. _s14af-py2-py-errors:
**Raises**
**NagValueError**
(`errno` :math:`1`)
On entry, :math:`\mathrm{Re}\left(\mathrm{z}\right)` is 'too close' to a non-positive integer when :math:`\mathrm{Im}\left(\mathrm{z}\right) = 0.0`: :math:`\mathrm{Re}\left(\mathrm{z}\right) = \langle\mathit{\boldsymbol{value}}\rangle`, :math:`\mathrm{nint}\left(\mathrm{Re}\left(\mathrm{z}\right)\right) = \langle\mathit{\boldsymbol{value}}\rangle`.
(`errno` :math:`1`)
On entry, :math:`\mathrm{k} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{k}\leq 4`.
(`errno` :math:`1`)
On entry, :math:`\mathrm{k} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{k}\geq 0`.
(`errno` :math:`2`)
Evaluation abandoned due to likelihood of overflow.
.. _s14af-py2-py-notes:
**Notes**
``psi_deriv_complex`` evaluates an approximation to the :math:`k`\ th derivative of the psi function :math:`\psi \left(z\right)` given by
.. math::
\psi^{\left(k\right)}\left(z\right) = \frac{d^k}{{dz^k}}\psi \left(z\right) = \frac{d^k}{{dz^k}}\left(\frac{d}{{dz}}\mathrm{loge}\left({\Gamma \left(z\right)}\right)\right)\text{,}
where :math:`z = x+iy` is complex provided :math:`y\neq 0` and :math:`k = 0,1,\ldots,4`.
If :math:`y = 0`, :math:`z` is real and thus :math:`\psi^{\left(k\right)}\left(z\right)` is singular when :math:`z = 0,-1,-2,\ldots \text{}`.
Note that :math:`\psi^{\left(k\right)}\left(z\right)` is also known as the `polygamma` function.
Specifically, :math:`\psi^{\left(0\right)}\left(z\right)` is often referred to as the `digamma` function and :math:`\psi^{\left(1\right)}\left(z\right)` as the `trigamma` function in the literature.
Further details can be found in Abramowitz and Stegun (1972).
``psi_deriv_complex`` is based on a modification of the method proposed by Kölbig (1972).
To obtain the value of :math:`\psi^{\left(k\right)}\left(z\right)` when :math:`z` is real, :meth:`psi_deriv_real` can be used.
.. _s14af-py2-py-references:
**References**
Abramowitz, M and Stegun, I A, 1972, `Handbook of Mathematical Functions`, (3rd Edition), Dover Publications
Kölbig, K S, 1972, `Programs for computing the logarithm of the gamma function, and the digamma function, for complex arguments`, Comp. Phys. Comm. (4), 221--226
"""
raise NotImplementedError
[docs]def gamma_log_complex(z):
r"""
``gamma_log_complex`` returns the value of the logarithm of the gamma function :math:`\mathrm{ln}\left(\Gamma \right)\left(z\right)` for complex :math:`z`, .
.. _s14ag-py2-py-doc:
For full information please refer to the NAG Library document for s14ag
https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s14agf.html
.. _s14ag-py2-py-parameters:
**Parameters**
**z** : complex
The argument :math:`z` of the function.
**Returns**
**lngz** : complex
The value of :math:`\mathrm{ln}\left(\Gamma \right)\left(z\right)`.
.. _s14ag-py2-py-errors:
**Raises**
**NagValueError**
(`errno` :math:`1`)
On entry, :math:`\mathrm{Re}\left(\mathrm{z}\right)` is 'too close' to a non-positive integer when :math:`\mathrm{Im}\left(\mathrm{z}\right) = 0.0`.
.. _s14ag-py2-py-notes:
**Notes**
``gamma_log_complex`` evaluates an approximation to the logarithm of the gamma function :math:`\mathrm{ln}\left(\Gamma \right)\left(z\right)` defined for :math:`\mathrm{Re}\left(z\right) > 0` by
.. math::
\mathrm{ln}\left(\Gamma \right)\left(z\right) = \mathrm{ln}\left(\int_0^{\infty }\right)e^{{-t}}t^{{z-1}}{dt}
where :math:`z = x+iy` is complex.
It is extended to the rest of the complex plane by analytic continuation unless :math:`y = 0`, in which case :math:`z` is real and each of the points :math:`z = 0,-1,-2,\ldots \text{}` is a singularity and a branch point.
``gamma_log_complex`` is based on the method proposed by Kölbig (1972) in which the value of :math:`\mathrm{ln}\left(\Gamma \right)\left(z\right)` is computed in the different regions of the :math:`z` plane by means of the formulae
.. math::
\begin{array}{llll}\mathrm{ln}\left(\Gamma \right)\left(z\right)& = &\left(z-\frac{1}{2}\right)\mathrm{ln}\left(z\right)-z+\frac{1}{2}\mathrm{ln}\left(2\right)\pi +z\sum_{{k = 1}}^K\frac{B_{{2k}}}{{2k\left(2k-1\right)}}z^{{-2k}}+R_K\left(z\right)&\text{if }x\geq x_0\geq 0\text{,}\\& = &\mathrm{ln}\left(\Gamma \right)\left(z+n\right)-\mathrm{ln}\left({\prod_{{\nu = 0}}^{{n-1}}}\right)\left(z+\nu \right)&\text{if }x_0 > x\geq 0\text{,}\\\\& = &\mathrm{ln}\left(\pi \right)-\mathrm{ln}\left(\Gamma \right)\left(1-z\right)-\mathrm{ln}\left(\sin\left({\pi z}\right)\right)&\text{if }x < 0\text{,}\end{array}
where :math:`n = \left[x_0\right]-\left[x\right]`, :math:`\left\{B_{{2k}}\right\}` are Bernoulli numbers (see Abramowitz and Stegun (1972)) and :math:`\left[x\right]` is the largest integer :math:`\text{}\leq x`.
Note that care is taken to ensure that the imaginary part is computed correctly, and not merely modulo :math:`2\pi`.
The function uses the values :math:`K = 10` and :math:`x_0 = 7`.
The remainder term :math:`R_K\left(z\right)` is discussed in `Accuracy <https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s14agf.html#accuracy>`__.
To obtain the value of :math:`\mathrm{ln}\left(\Gamma \right)\left(z\right)` when :math:`z` is real and positive, :meth:`gamma_log_real` can be used.
.. _s14ag-py2-py-references:
**References**
Abramowitz, M and Stegun, I A, 1972, `Handbook of Mathematical Functions`, (3rd Edition), Dover Publications
Kölbig, K S, 1972, `Programs for computing the logarithm of the gamma function, and the digamma function, for complex arguments`, Comp. Phys. Comm. (4), 221--226
"""
raise NotImplementedError
[docs]def gamma_log_scaled_real(x):
r"""
``gamma_log_scaled_real`` returns the value of :math:`\mathrm{ln}\left({G\left(x\right)}\right)`, the scaled logarithm of the gamma function :math:`\Gamma \left(x\right)`.
.. _s14ah-py2-py-doc:
For full information please refer to the NAG Library document for s14ah
https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s14ahf.html
.. _s14ah-py2-py-parameters:
**Parameters**
**x** : float
The argument :math:`x` of the function.
**Returns**
**slgx** : float
The value of :math:`\mathrm{ln}\left({G\left(x\right)}\right)`, the scaled logarithm of the gamma function :math:`\Gamma \left(x\right)`.
.. _s14ah-py2-py-errors:
**Raises**
**NagValueError**
(`errno` :math:`1`)
On entry, :math:`\mathrm{x}\leq 0.0`. On failure, the function value returned is zero.
.. _s14ah-py2-py-notes:
**Notes**
``gamma_log_scaled_real`` calculates an approximate value for :math:`\mathrm{ln}\left({G\left(x\right)}\right)`, where :math:`G\left(x\right) = \Gamma \left(x+1\right)/\left(\frac{x}{e}\right)^x`.
This is a variant of the :math:`\mathrm{ln}\left({\Gamma \left(x\right)}\right)` function (see also :meth:`gamma_log_real`), which avoids rounding problems for very large arguments by computing :math:`\mathrm{ln}\left({\Gamma \left(x\right)}\right)` with the Stirling approximation factored out.
For :math:`0 < x < 15`, :math:`\mathrm{ln}\left({G\left(x\right)}\right) = \mathrm{ln}\left({\Gamma \left(x+1\right)}\right)-x\mathrm{ln}\left(x\right)+x`;
and for :math:`15\leq x`, :math:`\mathrm{ln}\left({G\left(x\right)}\right) = \frac{1}{2}\mathrm{ln}\left(x\right)+\mathrm{ln}\left(\sqrt{2\pi }\right)+\frac{1}{x}R\left(1/x^2\right)`, where :math:`R` is a suitable Remez approximation.
For :math:`x\leq 0.0`, the value :math:`\mathrm{ln}\left({G\left(x\right)}\right)` is undefined; ``gamma_log_scaled_real`` returns zero and exits with :math:`\mathrm{errno}` = 1.
.. _s14ah-py2-py-references:
**References**
NIST Digital Library of Mathematical Functions
"""
raise NotImplementedError
[docs]def gamma_vector(x):
r"""
``gamma_vector`` returns an array of values of the gamma function :math:`\Gamma \left(x\right)`.
.. _s14an-py2-py-doc:
For full information please refer to the NAG Library document for s14an
https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s14anf.html
.. _s14an-py2-py-parameters:
**Parameters**
**x** : float, array-like, shape :math:`\left(n\right)`
The argument :math:`x_{\textit{i}}` of the function, for :math:`\textit{i} = 1,2,\ldots,n`.
**Returns**
**f** : float, ndarray, shape :math:`\left(n\right)`
:math:`\Gamma \left(x_i\right)`, the function values.
**ivalid** : int, ndarray, shape :math:`\left(n\right)`
:math:`\mathrm{ivalid}[\textit{i}-1]` contains the error code for :math:`x_{\textit{i}}`, for :math:`\textit{i} = 1,2,\ldots,n`.
:math:`\mathrm{ivalid}[i-1] = 0`
No error.
:math:`\mathrm{ivalid}[i-1] = 1`
:math:`x_i` is too large and positive. :math:`\mathrm{f}[\textit{i}-1]` contains the approximate value of :math:`\Gamma \left(x_i\right)` at the nearest valid argument. The threshold value is the same as for :math:`\mathrm{errno}` = 1 in :meth:`gamma`.
:math:`\mathrm{ivalid}[i-1] = 2`
:math:`x_i` is too large and negative. :math:`\mathrm{f}[\textit{i}-1]` contains zero. The threshold value is the same as for :math:`\mathrm{errno}` = 2 in :meth:`gamma`.
:math:`\mathrm{ivalid}[i-1] = 3`
:math:`x_i` is too close to zero. :math:`\mathrm{f}[\textit{i}-1]` contains the approximate value of :math:`\Gamma \left(x_i\right)` at the nearest valid argument. The threshold value is the same as for :math:`\mathrm{errno}` = 2 in :meth:`gamma`.
:math:`\mathrm{ivalid}[i-1] = 4`
:math:`x_i` is a negative integer, at which values :math:`\Gamma \left(x_i\right)` are infinite. :math:`\mathrm{f}[\textit{i}-1]` contains a large positive value.
.. _s14an-py2-py-errors:
**Raises**
**NagValueError**
(`errno` :math:`2`)
On entry, :math:`n = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`n\geq 0`.
**Warns**
**NagAlgorithmicWarning**
(`errno` :math:`1`)
On entry, at least one value of :math:`\mathrm{x}` was invalid.
Check :math:`\mathrm{ivalid}` for more information.
.. _s14an-py2-py-notes:
**Notes**
``gamma_vector`` evaluates an approximation to the gamma function :math:`\Gamma \left(x\right)` for an array of arguments :math:`x_{\textit{i}}`, for :math:`\textit{i} = 1,2,\ldots,n`.
The function is based on the Chebyshev expansion:
.. math::
\Gamma \left(1+u\right) = \sum_{{r = 0}}^{\prime }a_rT_r\left(t\right)
where :math:`0\leq u < 1,t = 2u-1\text{,}` and uses the property :math:`\Gamma \left(1+x\right) = x\Gamma \left(x\right)`.
If :math:`x = N+1+u` where :math:`N` is integral and :math:`0\leq u < 1` then it follows that:
.. rst-class:: nag-rules-none nag-align-left
+------------------+--------------------------------------------------------------------------------------------------------------------------------+
|for :math:`N > 0`,|:math:`\Gamma \left(x\right) = \left(x-1\right)\left(x-2\right) \cdots \left(x-N\right)\Gamma \left(1+u\right)`, |
+------------------+--------------------------------------------------------------------------------------------------------------------------------+
|for :math:`N = 0`,|:math:`\Gamma \left(x\right) = \Gamma \left(1+u\right)`, |
+------------------+--------------------------------------------------------------------------------------------------------------------------------+
|for :math:`N < 0`,|:math:`\Gamma \left(x\right) = \frac{{\Gamma \left(1+u\right)}}{{x\left(x+1\right)\left(x+2\right) \cdots \left(x-N-1\right)}}`.|
+------------------+--------------------------------------------------------------------------------------------------------------------------------+
There are four possible failures for this function:
(i) if :math:`x` is too large, there is a danger of overflow since :math:`\Gamma \left(x\right)` could become too large to be represented in the machine;
(#) if :math:`x` is too large and negative, there is a danger of underflow;
(#) if :math:`x` is equal to a negative integer, :math:`\Gamma \left(x\right)` would overflow since it has poles at such points;
(#) if :math:`x` is too near zero, there is again the danger of overflow on some machines. For small :math:`x`, :math:`\Gamma \left(x\right)\simeq 1/x`, and on some machines there exists a range of nonzero but small values of :math:`x` for which :math:`1/x` is larger than the greatest representable value.
.. _s14an-py2-py-references:
**References**
NIST Digital Library of Mathematical Functions
"""
raise NotImplementedError
[docs]def gamma_log_real_vector(x):
r"""
``gamma_log_real_vector`` returns an array of values of the logarithm of the gamma function, :math:`\mathrm{ln}\left(\Gamma \right)\left(x\right)`.
.. _s14ap-py2-py-doc:
For full information please refer to the NAG Library document for s14ap
https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s14apf.html
.. _s14ap-py2-py-parameters:
**Parameters**
**x** : float, array-like, shape :math:`\left(n\right)`
The argument :math:`x_{\textit{i}}` of the function, for :math:`\textit{i} = 1,2,\ldots,n`.
**Returns**
**f** : float, ndarray, shape :math:`\left(n\right)`
:math:`\mathrm{ln}\left(\Gamma \right)\left(x_i\right)`, the function values.
**ivalid** : int, ndarray, shape :math:`\left(n\right)`
:math:`\mathrm{ivalid}[\textit{i}-1]` contains the error code for :math:`x_{\textit{i}}`, for :math:`\textit{i} = 1,2,\ldots,n`.
:math:`\mathrm{ivalid}[i-1] = 0`
No error.
:math:`\mathrm{ivalid}[i-1] = 1`
:math:`x_i\leq 0`.
:math:`\mathrm{ivalid}[i-1] = 2`
:math:`x_i` is too large and positive. The threshold value is the same as for :math:`\mathrm{errno}` = 2 in :meth:`gamma_log_real`.
.. _s14ap-py2-py-errors:
**Raises**
**NagValueError**
(`errno` :math:`2`)
On entry, :math:`n = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`n\geq 0`.
**Warns**
**NagAlgorithmicWarning**
(`errno` :math:`1`)
On entry, at least one value of :math:`\mathrm{x}` was invalid.
Check :math:`\mathrm{ivalid}` for more information.
.. _s14ap-py2-py-notes:
**Notes**
``gamma_log_real_vector`` calculates an approximate value for :math:`\mathrm{ln}\left(\Gamma \right)\left(x\right)` for an array of arguments :math:`x_{\textit{i}}`, for :math:`\textit{i} = 1,2,\ldots,n`.
It is based on rational Chebyshev expansions.
Denote by :math:`R_{{n,m}}^i\left(x\right) = P_n^i\left(x\right)/Q_m^i\left(x\right)` a ratio of polynomials of degree :math:`n` in the numerator and :math:`m` in the denominator.
Then:
for :math:`0 < x\leq 1/2`,
.. math::
\mathrm{ln}\left(\Gamma \right)\left(x\right)≈-\mathrm{ln}\left(x\right)+xR_{{n,m}}^1\left(x+1\right)\text{;}
for :math:`1/2 < x\leq 3/2`,
.. math::
\mathrm{ln}\left(\Gamma \right)\left(x\right)≈\left(x-1\right)R_{{n,m}}^1\left(x\right)\text{;}
for :math:`3/2 < x\leq 4`,
.. math::
\mathrm{ln}\left(\Gamma \right)\left(x\right)≈\left(x-2\right)R_{{n,m}}^2\left(x\right)\text{;}
for :math:`4 < x\leq 12`,
.. math::
\mathrm{ln}\left(\Gamma \right)\left(x\right)≈R_{{n,m}}^3\left(x\right)\text{;}
and for :math:`12 < x`,
.. math::
\mathrm{ln}\left(\Gamma \right)\left(x\right)≈\left(x-\frac{1}{2}\right)\mathrm{ln}\left(x\right)-x+\mathrm{ln}\left(\sqrt{2π}\right)+\frac{1}{x}R_{{n,m}}^4\left(1/x^2\right)\text{.}
For each expansion, the specific values of :math:`n` and :math:`m` are selected to be minimal such that the maximum relative error in the expansion is of the order :math:`10^{{-d}}`, where :math:`d` is the maximum number of decimal digits that can be accurately represented for the particular implementation (see :meth:`machine.decimal_digits <naginterfaces.library.machine.decimal_digits>`).
Let :math:`\epsilon` denote machine precision and let :math:`x_{\mathrm{huge}}` denote the largest positive model number (see :meth:`machine.real_largest <naginterfaces.library.machine.real_largest>`).
For :math:`x < 0.0` the value :math:`\mathrm{ln}\left(\Gamma \right)\left(x\right)` is not defined; ``gamma_log_real_vector`` returns zero and exits with :math:`\mathrm{errno}` = 1.
It also exits with :math:`\mathrm{errno}` = 1 when :math:`x = 0.0`, and in this case the value :math:`x_{\mathrm{huge}}` is returned.
For :math:`x` in the interval :math:`\left(0.0, \epsilon \right]`, the function :math:`\mathrm{ln}\left(\Gamma \right)\left(x\right) = -\mathrm{ln}\left(x\right)` to machine accuracy.
Now denote by :math:`x_{\mathrm{big}}` the largest allowable argument for :math:`\mathrm{ln}\left(\Gamma \right)\left(x\right)` on the machine.
For :math:`\left(x_{\mathrm{big}}\right)^{{1/4}} < x\leq x_{\mathrm{big}}` the :math:`R_{{n,m}}^4\left(1/x^2\right)` term in Equation `(1) <https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s14apf.html#eqn1>`__ is negligible.
For :math:`x > x_{\mathrm{big}}` there is a danger of setting overflow, and so ``gamma_log_real_vector`` exits with :math:`\mathrm{errno}` = 2 and returns :math:`x_{\mathrm{huge}}`.
.. _s14ap-py2-py-references:
**References**
NIST Digital Library of Mathematical Functions
Cody, W J and Hillstrom, K E, 1967, `Chebyshev approximations for the natural logarithm of the gamma function`, Math.Comp. (21), 198--203
"""
raise NotImplementedError
[docs]def gamma_incomplete(a, x, tol):
r"""
``gamma_incomplete`` computes values for the incomplete gamma functions :math:`P\left(a, x\right)` and :math:`Q\left(a, x\right)`.
.. _s14ba-py2-py-doc:
For full information please refer to the NAG Library document for s14ba
https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s14baf.html
.. _s14ba-py2-py-parameters:
**Parameters**
**a** : float
The argument :math:`a` of the functions.
**x** : float
The argument :math:`x` of the functions.
**tol** : float
The relative accuracy required by you in the results. If ``gamma_incomplete`` is entered with :math:`\mathrm{tol}` greater than :math:`1.0` or less than machine precision, then the value of machine precision is used instead.
**Returns**
**p** : float
The value of :math:`P\left(a, x\right)`
**q** : float
The value of :math:`P\left(a, x\right)`
.. _s14ba-py2-py-errors:
**Raises**
**NagValueError**
(`errno` :math:`1`)
On entry, :math:`\mathrm{a} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{a} > 0.0`.
(`errno` :math:`2`)
On entry, :math:`\mathrm{x} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{x}\geq 0.0`.
(`errno` :math:`3`)
Algorithm fails to terminate in :math:`\langle\mathit{\boldsymbol{value}}\rangle` iterations.
.. _s14ba-py2-py-notes:
**Notes**
``gamma_incomplete`` evaluates the incomplete gamma functions in the normalized form
.. math::
P\left(a, x\right) = \frac{1}{{\Gamma \left(a\right)}}\int_0^xt^{{a-1}}e^{{-t}}{dt}\text{,}
.. math::
Q\left(a, x\right) = \frac{1}{{\Gamma \left(a\right)}}\int_x^{\infty }t^{{a-1}}e^{{-t}}{dt}\text{,}
with :math:`x\geq 0` and :math:`a > 0`, to a user-specified accuracy.
With this normalization, :math:`P\left(a, x\right)+Q\left(a, x\right) = 1`.
Several methods are used to evaluate the functions depending on the arguments :math:`a` and :math:`x`, the methods including Taylor expansion for :math:`P\left(a, x\right)`, Legendre's continued fraction for :math:`Q\left(a, x\right)`, and power series for :math:`Q\left(a, x\right)`.
When both :math:`a` and :math:`x` are large, and :math:`a\simeq x`, the uniform asymptotic expansion of Temme (1987) is employed for greater efficiency -- specifically, this expansion is used when :math:`a\geq 20` and :math:`0.7a\leq x\leq 1.4a`.
Once either :math:`P` or :math:`Q` is computed, the other is obtained by subtraction from :math:`1`.
In order to avoid loss of relative precision in this subtraction, the smaller of :math:`P` and :math:`Q` is computed first.
This function is derived from the function GAM in Gautschi (1979b).
.. _s14ba-py2-py-references:
**References**
Gautschi, W, 1979, `A computational procedure for incomplete gamma functions`, ACM Trans. Math. Software (5), 466--481
Gautschi, W, 1979, `Algorithm 542: Incomplete gamma functions`, ACM Trans. Math. Software (5), 482--489
Temme, N M, 1987, `On the computation of the incomplete gamma functions for large values of the parameters`, Algorithms for Approximation, (eds J C Mason and M G Cox), Oxford University Press
"""
raise NotImplementedError
[docs]def gamma_incomplete_vector(a, x, tol):
r"""
``gamma_incomplete_vector`` computes an array of values for the incomplete gamma functions :math:`P\left(a, x\right)` and :math:`Q\left(a, x\right)`.
.. _s14bn-py2-py-doc:
For full information please refer to the NAG Library document for s14bn
https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s14bnf.html
.. _s14bn-py2-py-parameters:
**Parameters**
**a** : float, array-like, shape :math:`\left(n\right)`
The argument :math:`a_{\textit{i}}` of the function, for :math:`\textit{i} = 1,2,\ldots,n`.
**x** : float, array-like, shape :math:`\left(n\right)`
The argument :math:`x_{\textit{i}}` of the function, for :math:`\textit{i} = 1,2,\ldots,n`.
**tol** : float
The relative accuracy required by you in the results. If ``gamma_incomplete_vector`` is entered with :math:`\mathrm{tol}` greater than :math:`1.0` or less than machine precision, then the value of machine precision is used instead.
**Returns**
**p** : float, ndarray, shape :math:`\left(n\right)`
:math:`P\left(a_i, x_i\right)`, the function values.
**q** : float, ndarray, shape :math:`\left(n\right)`
:math:`Q\left(a_i, x_i\right)`, the function values.
**ivalid** : int, ndarray, shape :math:`\left(n\right)`
:math:`\mathrm{ivalid}[\textit{i}-1]` contains the error code for :math:`a_{\textit{i}}` and :math:`x_{\textit{i}}`, for :math:`\textit{i} = 1,2,\ldots,n`.
:math:`\mathrm{ivalid}[i-1] = 0`
No error.
:math:`\mathrm{ivalid}[i-1] = 1`
:math:`a_i\leq 0`.
:math:`\mathrm{ivalid}[i-1] = 2`
:math:`x_i < 0`.
:math:`\mathrm{ivalid}[i-1] = 3`
Algorithm fails to terminate.
.. _s14bn-py2-py-errors:
**Raises**
**NagValueError**
(`errno` :math:`2`)
On entry, :math:`n = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`n\geq 0`.
**Warns**
**NagAlgorithmicWarning**
(`errno` :math:`1`)
On entry, at least one value of :math:`\mathrm{x}` was invalid.
Check :math:`\mathrm{ivalid}` for more information.
.. _s14bn-py2-py-notes:
**Notes**
``gamma_incomplete_vector`` evaluates the incomplete gamma functions in the normalized form, for an array of arguments :math:`a_{\textit{i}},x_{\textit{i}}`, for :math:`\textit{i} = 1,2,\ldots,n`.
.. math::
P\left(a, x\right) = \frac{1}{{\Gamma \left(a\right)}}\int_0^xt^{{a-1}}e^{{-t}}{dt}\text{,}
.. math::
Q\left(a, x\right) = \frac{1}{{\Gamma \left(a\right)}}\int_x^{\infty }t^{{a-1}}e^{{-t}}{dt}\text{,}
with :math:`x\geq 0` and :math:`a > 0`, to a user-specified accuracy.
With this normalization, :math:`P\left(a, x\right)+Q\left(a, x\right) = 1`.
Several methods are used to evaluate the functions depending on the arguments :math:`a` and :math:`x`, the methods including Taylor expansion for :math:`P\left(a, x\right)`, Legendre's continued fraction for :math:`Q\left(a, x\right)`, and power series for :math:`Q\left(a, x\right)`.
When both :math:`a` and :math:`x` are large, and :math:`a\simeq x`, the uniform asymptotic expansion of Temme (1987) is employed for greater efficiency -- specifically, this expansion is used when :math:`a\geq 20` and :math:`0.7a\leq x\leq 1.4a`.
Once either :math:`P` or :math:`Q` is computed, the other is obtained by subtraction from :math:`1`.
In order to avoid loss of relative precision in this subtraction, the smaller of :math:`P` and :math:`Q` is computed first.
This function is derived from the function GAM in Gautschi (1979b).
.. _s14bn-py2-py-references:
**References**
Gautschi, W, 1979, `A computational procedure for incomplete gamma functions`, ACM Trans. Math. Software (5), 466--481
Gautschi, W, 1979, `Algorithm 542: Incomplete gamma functions`, ACM Trans. Math. Software (5), 482--489
Temme, N M, 1987, `On the computation of the incomplete gamma functions for large values of the parameters`, Algorithms for Approximation, (eds J C Mason and M G Cox), Oxford University Press
"""
raise NotImplementedError
[docs]def beta_log_real(a, b):
r"""
``beta_log_real`` returns the value of the logarithm of the beta function, :math:`\mathrm{ln}\left(B\right)\left(a, b\right)`.
.. _s14cb-py2-py-doc:
For full information please refer to the NAG Library document for s14cb
https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s14cbf.html
.. _s14cb-py2-py-parameters:
**Parameters**
**a** : float
The argument :math:`a` of the function.
**b** : float
The argument :math:`b` of the function.
**Returns**
**lbab** : float
The value of the logarithm of the beta function, :math:`\mathrm{ln}\left(B\right)\left(a, b\right)`.
.. _s14cb-py2-py-errors:
**Raises**
**NagValueError**
(`errno` :math:`1`)
On entry, :math:`\mathrm{b} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{b} > 0.0`.
(`errno` :math:`1`)
On entry, :math:`\mathrm{a} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{a} > 0.0`.
.. _s14cb-py2-py-notes:
**Notes**
``beta_log_real`` calculates values for :math:`\mathrm{ln}\left(B\right)\left(a, b\right)` where :math:`B` is the beta function given by
.. math::
B\left(a, b\right) = \int_0^1t^{{a-1}}\left(1-t\right)^{{b-1}}\textit{dt}
or equivalently
.. math::
B\left(a, b\right) = \frac{{\Gamma \left(a\right)\Gamma \left(b\right)}}{{\Gamma \left(a+b\right)}}
and :math:`\Gamma \left(x\right)` is the gamma function.
Note that the beta function is symmetric, so that :math:`B\left(a, b\right) = B\left(b, a\right)`.
In order to efficiently obtain accurate results several methods are used depending on the parameters :math:`a` and :math:`b`.
Let :math:`a_0 = \mathrm{min}\left(a, b\right)` and :math:`b_0 = \mathrm{max}\left(a, b\right)`.
Then:
for :math:`a_0\geq 8`,
.. math::
\begin{array}{ccc}\mathrm{ln}\left(B\right)& = & 0.5 \mathrm{ln}\left({\left(2\pi \right)-0.5}\right) \mathrm{ln}\left(b_0\right) + \Delta \left(a_0\right) + \Delta \left(b_0\right) - \Delta \left(a_0+b_0\right) - u - v \text{;} \end{array}
where
:math:`\Delta \left(a_0\right) = \mathrm{ln}\left({\Gamma \left(a_0\right)}\right)-\left(a_0-0.5\right)\mathrm{ln}\left(a_0\right)+a_0-0.5\mathrm{ln}\left(2\pi \right)`,
:math:`u = -\left(a_0-0.5\right)\mathrm{ln}\left[\frac{a_0}{{a_0+b_0}}\right]` and
:math:`v = b_0\mathrm{ln}\left(1+\frac{a_0}{b_0}\right)`.
for :math:`a_0 < 1`,
for :math:`b_0\geq 8`,
.. math::
\mathrm{ln}\left(B\right) = \mathrm{ln}\left(\Gamma \right)\left(a_0\right)+\mathrm{ln}\left(\frac{{\Gamma \left(b_0\right)}}{{\Gamma \left(a_0+b_0\right)}}\right)\text{;}
for :math:`b_0 < 8`,
.. math::
\mathrm{ln}\left(B\right) = \mathrm{ln}\left(\Gamma \right)\left(a_0\right)+\mathrm{ln}\left(\Gamma \right)\left(b_0\right)-\mathrm{ln}\left(\Gamma \right)\left(a_0+b_0\right)\text{;}
for :math:`2 < a_0 < 8`, :math:`a_0` is reduced to the interval :math:`\left[1, 2\right]` by :math:`B\left(a, b\right) = \frac{{a_0-1}}{{a_0+b_0-1}}B\left({a_0-1}, b_0\right)`;
for :math:`1\leq a_0\leq 2`,
for :math:`b_0\geq 8`,
.. math::
\mathrm{ln}\left(B\right) = \mathrm{ln}\left(\Gamma \right)\left(a_0\right)+\mathrm{ln}\left(\frac{{\Gamma \left(b_0\right)}}{{\Gamma \left(a_0+b_0\right)}}\right)\text{;}
for :math:`2 < b_0 < 8`, :math:`b_0` is reduced to the interval :math:`\left[1, 2\right]`;
for :math:`b_0\leq 2`,
.. math::
\mathrm{ln}\left(B\right) = \mathrm{ln}\left(\Gamma \right)\left(a_0\right)+\mathrm{ln}\left(\Gamma \right)\left(b_0\right)-\mathrm{ln}\left(\Gamma \right)\left(a_0+b_0\right)\text{.}
``beta_log_real`` is derived from BETALN in DiDonato and Morris (1992).
.. _s14cb-py2-py-references:
**References**
DiDonato, A R and Morris, A H, 1992, `Algorithm 708: Significant digit computation of the incomplete beta function ratios`, ACM Trans. Math. Software (18), 360--373
"""
raise NotImplementedError
[docs]def beta_incomplete(a, b, x):
r"""
``beta_incomplete`` computes values for the regularized incomplete beta function :math:`I_x\left(a, b\right)` and its complement :math:`1-I_x\left(a, b\right)`.
.. _s14cc-py2-py-doc:
For full information please refer to the NAG Library document for s14cc
https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s14ccf.html
.. _s14cc-py2-py-parameters:
**Parameters**
**a** : float
The argument :math:`a` of the function.
**b** : float
The argument :math:`b` of the function.
**x** : float
:math:`x`, upper limit of integration.
**Returns**
**w** : float
The value of the incomplete beta function :math:`I_x\left(a, b\right)` evaluated from zero to :math:`x`.
**w1** : float
The value of the complement of the incomplete beta function :math:`1-I_x\left(a, b\right)`, i.e., the incomplete beta function evaluated from :math:`x` to one.
.. _s14cc-py2-py-errors:
**Raises**
**NagValueError**
(`errno` :math:`1`)
On entry, :math:`\mathrm{b} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{b}\geq 0.0`.
(`errno` :math:`1`)
On entry, :math:`\mathrm{a} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{a}\geq 0.0`.
(`errno` :math:`2`)
On entry, :math:`\mathrm{a}` and :math:`\mathrm{b}` were zero.
Constraint: :math:`\mathrm{a}` or :math:`\mathrm{b}` must be nonzero.
(`errno` :math:`3`)
On entry, :math:`\mathrm{x} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`0.0\leq \mathrm{x}\leq 1.0`.
(`errno` :math:`4`)
On entry, :math:`\mathrm{x}` and :math:`\mathrm{a}` were zero.
Constraint: :math:`\mathrm{x}` or :math:`\mathrm{a}` must be nonzero.
(`errno` :math:`5`)
On entry, :math:`1.0-\mathrm{x}` and :math:`\mathrm{b}` were zero.
Constraint: :math:`1.0-\mathrm{x}` or :math:`\mathrm{b}` must be nonzero.
.. _s14cc-py2-py-notes:
**Notes**
``beta_incomplete`` evaluates the regularized incomplete beta function and its complement in the normalized form
.. math::
\begin{array}{ccc} I_x\left(a, b\right) & = & \frac{1}{{B\left(a, b\right)}} \int_0^x t^{{a-1}} \left(1-t\right)^{{b-1}} dt \\ 1-I_x \left(a, b\right) & = & I_y \left(b, a\right) \text{, where } y = 1-x \text{,} \end{array}
with
:math:`0\leq x\leq 1`,
:math:`a\geq 0` and :math:`b\geq 0`,
and the beta function :math:`B\left(a, b\right)` is defined as :math:`B\left(a, b\right) = \int_0^1t^{{a-1}}\left(1-t\right)^{{b-1}}dt = \frac{{\Gamma \left(a\right)\Gamma \left(b\right)}}{{\Gamma \left(a+b\right)}}` where :math:`\Gamma \left(y\right)` is the gamma function.
Several methods are used to evaluate the functions depending on the arguments :math:`a`, :math:`b` and :math:`x`.
The methods include Wise's asymptotic expansion (see Wise (1950)) when :math:`a > b`, continued fraction derived by DiDonato and Morris (1992) when :math:`a`, :math:`b > 1`, and power series when :math:`b\leq 1` or :math:`b\times x\leq 0.7`.
When both :math:`a` and :math:`b` are large, specifically :math:`a`, :math:`b\geq 15`, the DiDonato and Morris (1992) asymptotic expansion is employed for greater efficiency.
Once either :math:`I_x\left(a, b\right)` or :math:`I_y\left(b, a\right)` is computed, the other is obtained by subtraction from :math:`1`.
In order to avoid loss of relative precision in this subtraction, the smaller of :math:`I_x\left(a, b\right)` and :math:`I_y\left(b, a\right)` is computed first.
``beta_incomplete`` is derived from BRATIO in DiDonato and Morris (1992).
.. _s14cc-py2-py-references:
**References**
DiDonato, A R and Morris, A H, 1992, `Algorithm 708: Significant digit computation of the incomplete beta function ratios`, ACM Trans. Math. Software (18), 360--373
Wise, M E, 1950, `The incomplete beta function as a contour integral and a quickly converging series for its inverse`, Biometrika (37), 208--218
"""
raise NotImplementedError
[docs]def beta_log_real_vector(a, b):
r"""
``beta_log_real_vector`` returns an array of values of the logarithm of the beta function, :math:`\mathrm{ln}\left(B\right)\left(a, b\right)`.
.. _s14cp-py2-py-doc:
For full information please refer to the NAG Library document for s14cp
https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s14cpf.html
.. _s14cp-py2-py-parameters:
**Parameters**
**a** : float, array-like, shape :math:`\left(n\right)`
The argument :math:`a_{\textit{i}}` of the function, for :math:`\textit{i} = 1,2,\ldots,n`.
**b** : float, array-like, shape :math:`\left(n\right)`
The argument :math:`b_{\textit{i}}` of the function, for :math:`\textit{i} = 1,2,\ldots,n`.
**Returns**
**f** : float, ndarray, shape :math:`\left(n\right)`
:math:`\mathrm{ln}\left(B\right)\left(a_i, b_i\right)`, the function values.
**ivalid** : int, ndarray, shape :math:`\left(n\right)`
:math:`\mathrm{ivalid}[\textit{i}-1]` contains the error code for :math:`a_{\textit{i}}` and :math:`b_{\textit{i}}`, for :math:`\textit{i} = 1,2,\ldots,n`.
:math:`\mathrm{ivalid}[i-1] = 0`
No error.
:math:`\mathrm{ivalid}[i-1] = 1`
:math:`a_i\text{ or }b_i\leq 0`.
.. _s14cp-py2-py-errors:
**Raises**
**NagValueError**
(`errno` :math:`2`)
On entry, :math:`n = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`n\geq 0`.
**Warns**
**NagAlgorithmicWarning**
(`errno` :math:`1`)
On entry, at least one value of :math:`\mathrm{a}` or :math:`\mathrm{b}` was invalid.
Check :math:`\mathrm{ivalid}` for more information.
.. _s14cp-py2-py-notes:
**Notes**
``beta_log_real_vector`` calculates values for :math:`\mathrm{ln}\left(B\right)\left(a, b\right)`, for arrays of arguments :math:`a_{\textit{i}}` and :math:`b_{\textit{i}}`, for :math:`\textit{i} = 1,2,\ldots,n`, where :math:`B` is the beta function given by
.. math::
B\left(a, b\right) = \int_0^1t^{{a-1}}\left(1-t\right)^{{b-1}}\textit{dt}
or equivalently
.. math::
B\left(a, b\right) = \frac{{\Gamma \left(a\right)\Gamma \left(b\right)}}{{\Gamma \left(a+b\right)}}
and :math:`\Gamma \left(x\right)` is the gamma function.
Note that the beta function is symmetric, so that :math:`B\left(a, b\right) = B\left(b, a\right)`.
In order to efficiently obtain accurate results several methods are used depending on the parameters :math:`a` and :math:`b`.
Let :math:`a_0 = \mathrm{min}\left(a, b\right)` and :math:`b_0 = \mathrm{max}\left(a, b\right)`.
Then:
for :math:`a_0\geq 8`,
.. math::
\begin{array}{ccc}\mathrm{ln}\left(B\right)& = & 0.5 \mathrm{ln}\left({\left(2\pi \right)-0.5}\right) \mathrm{ln}\left(b_0\right) + \Delta \left(a_0\right) + \Delta \left(b_0\right) - \Delta \left(a_0+b_0\right) - u - v \text{;} \end{array}
where
:math:`\Delta \left(a_0\right) = \mathrm{ln}\left({\Gamma \left(a_0\right)}\right)-\left(a_0-0.5\right)\mathrm{ln}\left(a_0\right)+a_0-0.5\mathrm{ln}\left(2\pi \right)`,
:math:`u = -\left(a_0-0.5\right)\mathrm{ln}\left[\frac{a_0}{{a_0+b_0}}\right]` and
:math:`v = b_0\mathrm{ln}\left(1+\frac{a_0}{b_0}\right)`;
for :math:`a_0 < 1`,
for :math:`b_0\geq 8`,
.. math::
\mathrm{ln}\left(B\right) = \mathrm{ln}\left(\Gamma \right)\left(a_0\right)+\mathrm{ln}\left(\frac{{\Gamma \left(b_0\right)}}{{\Gamma \left(a_0+b_0\right)}}\right)\text{;}
for :math:`b_0 < 8`,
.. math::
\mathrm{ln}\left(B\right) = \mathrm{ln}\left(\Gamma \right)\left(a_0\right)+\mathrm{ln}\left(\Gamma \right)\left(b_0\right)-\mathrm{ln}\left(\Gamma \right)\left(a_0+b_0\right)\text{;}
for :math:`2 < a_0 < 8`, :math:`a_0` is reduced to the interval :math:`\left[1, 2\right]` by :math:`B\left(a, b\right) = \frac{{a_0-1}}{{a_0+b_0-1}}B\left({a_0-1}, b_0\right)`;
for :math:`1\leq a_0\leq 2`,
for :math:`b_0\geq 8`,
.. math::
\mathrm{ln}\left(B\right) = \mathrm{ln}\left(\Gamma \right)\left(a_0\right)+\mathrm{ln}\left(\frac{{\Gamma \left(b_0\right)}}{{\Gamma \left(a_0+b_0\right)}}\right)\text{;}
for :math:`2 < b_0 < 8`, :math:`b_0` is reduced to the interval :math:`\left[1, 2\right]`;
for :math:`b_0\leq 2`,
.. math::
\mathrm{ln}\left(B\right) = \mathrm{ln}\left(\Gamma \right)\left(a_0\right)+\mathrm{ln}\left(\Gamma \right)\left(b_0\right)-\mathrm{ln}\left(\Gamma \right)\left(a_0+b_0\right)\text{.}
``beta_log_real_vector`` is derived from BETALN in DiDonato and Morris (1992).
.. _s14cp-py2-py-references:
**References**
DiDonato, A R and Morris, A H, 1992, `Algorithm 708: Significant digit computation of the incomplete beta function ratios`, ACM Trans. Math. Software (18), 360--373
"""
raise NotImplementedError
[docs]def beta_incomplete_vector(a, b, x):
r"""
``beta_incomplete_vector`` computes an array of values for the regularized incomplete beta function :math:`I_x\left(a, b\right)` and its complement :math:`1-I_x\left(a, b\right)`.
.. _s14cq-py2-py-doc:
For full information please refer to the NAG Library document for s14cq
https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s14cqf.html
.. _s14cq-py2-py-parameters:
**Parameters**
**a** : float, array-like, shape :math:`\left(n\right)`
The argument :math:`a_{\textit{i}}` of the function, for :math:`\textit{i} = 1,2,\ldots,n`.
**b** : float, array-like, shape :math:`\left(n\right)`
The argument :math:`b_{\textit{i}}` of the function, for :math:`\textit{i} = 1,2,\ldots,n`.
**x** : float, array-like, shape :math:`\left(n\right)`
:math:`x_{\textit{i}}`, the upper limit of integration, for :math:`\textit{i} = 1,2,\ldots,n`.
**Returns**
**w** : float, ndarray, shape :math:`\left(n\right)`
The values of the incomplete beta function :math:`I_{x_i}\left(a_i, b_i\right)` evaluated from zero to :math:`x_i`.
**w1** : float, ndarray, shape :math:`\left(n\right)`
The values of the complement of the incomplete beta function :math:`1-I_{x_i}\left(a_i, b_i\right)`, i.e., the incomplete beta function evaluated from :math:`x_i` to one.
**ivalid** : int, ndarray, shape :math:`\left(n\right)`
:math:`\mathrm{ivalid}[\textit{i}-1]` contains the error code for the :math:`\textit{i}`\ th evaluation, for :math:`\textit{i} = 1,2,\ldots,n`.
:math:`\mathrm{ivalid}[i-1] = 0`
No error.
:math:`\mathrm{ivalid}[i-1] = 1`
:math:`a_i\text{ or }b_i < 0`.
:math:`\mathrm{ivalid}[i-1] = 2`
Both :math:`a_i\text{ and }b_i = 0`.
:math:`\mathrm{ivalid}[i-1] = 3`
:math:`x_i \notin \left[0, 1\right]`.
:math:`\mathrm{ivalid}[i-1] = 4`
Both :math:`x_i\text{ and }a_i = 0`.
:math:`\mathrm{ivalid}[i-1] = 5`
Both :math:`1-x_i\text{ and }b_i = 0`.
.. _s14cq-py2-py-errors:
**Raises**
**NagValueError**
(`errno` :math:`2`)
On entry, :math:`n = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`n\geq 0`.
**Warns**
**NagAlgorithmicWarning**
(`errno` :math:`1`)
On entry, at least one argument had an invalid value.
Check :math:`\mathrm{ivalid}` for more information.
.. _s14cq-py2-py-notes:
**Notes**
``beta_incomplete_vector`` evaluates the regularized incomplete beta function :math:`I_x\left(a, b\right)` and its complement :math:`1-I_x\left(a, b\right)` in the normalized form, for arrays of arguments :math:`x_i`, :math:`a_i` and :math:`b_i`, for :math:`\textit{i} = 1,2,\ldots,n`.
The incomplete beta function and its complement are given by
.. math::
\begin{array}{ccc} I_x\left(a, b\right) & = & \frac{1}{{B\left(a, b\right)}} \int_0^x t^{{a-1}} \left(1-t\right)^{{b-1}} dt \\ 1-I_x \left(a, b\right) & = & I_y \left(b, a\right) \text{, where } y = 1-x \text{,} \end{array}
with
:math:`0\leq x\leq 1`,
:math:`a\geq 0` and :math:`b\geq 0`,
and the beta function :math:`B\left(a, b\right)` is defined as :math:`B\left(a, b\right) = \int_0^1t^{{a-1}}\left(1-t\right)^{{b-1}}dt = \frac{{\Gamma \left(a\right)\Gamma \left(b\right)}}{{\Gamma \left(a+b\right)}}` where :math:`\Gamma \left(y\right)` is the gamma function.
Several methods are used to evaluate the functions depending on the arguments :math:`a`, :math:`b` and :math:`x`.
The methods include Wise's asymptotic expansion (see Wise (1950)) when :math:`a > b`, continued fraction derived by DiDonato and Morris (1992) when :math:`a`, :math:`b > 1`, and power series when :math:`b\leq 1` or :math:`b\times x\leq 0.7`.
When both :math:`a` and :math:`b` are large, specifically :math:`a`, :math:`b\geq 15`, the DiDonato and Morris (1992) asymptotic expansion is employed for greater efficiency.
Once either :math:`I_x\left(a, b\right)` or :math:`I_y\left(b, a\right)` is computed, the other is obtained by subtraction from :math:`1`.
In order to avoid loss of relative precision in this subtraction, the smaller of :math:`I_x\left(a, b\right)` and :math:`I_y\left(b, a\right)` is computed first.
``beta_incomplete_vector`` is derived from BRATIO in DiDonato and Morris (1992).
.. _s14cq-py2-py-references:
**References**
DiDonato, A R and Morris, A H, 1992, `Algorithm 708: Significant digit computation of the incomplete beta function ratios`, ACM Trans. Math. Software (18), 360--373
Wise, M E, 1950, `The incomplete beta function as a contour integral and a quickly converging series for its inverse`, Biometrika (37), 208--218
"""
raise NotImplementedError
[docs]def cdf_normal(x):
r"""
``cdf_normal`` returns the value of the cumulative Normal distribution function, :math:`P\left(x\right)`.
.. _s15ab-py2-py-doc:
For full information please refer to the NAG Library document for s15ab
https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s15abf.html
.. _s15ab-py2-py-parameters:
**Parameters**
**x** : float
The argument :math:`x` of the function.
**Returns**
**p** : float
The value of the cumulative Normal distribution function, :math:`P\left(x\right)`.
.. _s15ab-py2-py-notes:
**Notes**
``cdf_normal`` evaluates an approximate value for the cumulative Normal distribution function
.. math::
P\left(x\right) = \frac{1}{\sqrt{2\pi }}\int_{{-\infty }}^xe^{{-u^2/2}}{du}\text{.}
The function is based on the fact that
.. math::
P\left(x\right) = \frac{1}{2}\mathrm{erfc}\left(\frac{{-x}}{\sqrt{2}}\right)
and it calls :meth:`erfc_real` to obtain a value of :math:`\textit{erfc}` for the appropriate argument.
.. _s15ab-py2-py-references:
**References**
NIST Digital Library of Mathematical Functions
"""
raise NotImplementedError
[docs]def compcdf_normal(x):
r"""
``compcdf_normal`` returns the value of the complement of the cumulative Normal distribution function, :math:`Q\left(x\right)`.
.. _s15ac-py2-py-doc:
For full information please refer to the NAG Library document for s15ac
https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s15acf.html
.. _s15ac-py2-py-parameters:
**Parameters**
**x** : float
The argument :math:`x` of the function.
**Returns**
**q** : float
The value of the complement of the cumulative Normal distribution function, :math:`Q\left(x\right)`.
.. _s15ac-py2-py-notes:
**Notes**
``compcdf_normal`` evaluates an approximate value for the complement of the cumulative Normal distribution function
.. math::
Q\left(x\right) = \frac{1}{\sqrt{2\pi }}\int_x^{\infty }e^{{-u^2/2}}{du}\text{.}
The function is based on the fact that
.. math::
Q\left(x\right) = \frac{1}{2}\mathrm{erfc}\left(\frac{x}{\sqrt{2}}\right)
and it calls :meth:`erfc_real` to obtain the necessary value of :math:`\textit{erfc}`, the complementary error function.
.. _s15ac-py2-py-references:
**References**
NIST Digital Library of Mathematical Functions
"""
raise NotImplementedError
[docs]def erfc_real(x):
r"""
``erfc_real`` returns the value of the complementary error function, :math:`\mathrm{erfc}\left(x\right)`.
.. _s15ad-py2-py-doc:
For full information please refer to the NAG Library document for s15ad
https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s15adf.html
.. _s15ad-py2-py-parameters:
**Parameters**
**x** : float
The argument :math:`x` of the function.
**Returns**
**res** : float
The value of the complementary error function, :math:`\mathrm{erfc}\left(x\right)`.
.. _s15ad-py2-py-notes:
**Notes**
``erfc_real`` calculates an approximate value for the complement of the error function
.. math::
\mathrm{erfc}\left(x\right) = \frac{2}{\sqrt{\pi }}\int_x^{\infty }e^{{-t^2}}{dt} = 1-\mathrm{erf}\left(x\right)\text{.}
Let :math:`\hat{x}` be the root of the equation :math:`\mathrm{erfc}\left(x\right)-\mathrm{erf}\left(x\right) = 0` (then :math:`\hat{x}≈0.46875`).
For :math:`\left\lvert x\right\rvert \leq \hat{x}` the value of :math:`\mathrm{erfc}\left(x\right)` is based on the following rational Chebyshev expansion for :math:`\mathrm{erf}\left(x\right)`:
.. math::
\mathrm{erf}\left(x\right)≈xR_{{\ell,m}}\left(x^2\right)\text{,}
where :math:`R_{{\ell,m}}` denotes a rational function of degree :math:`\ell` in the numerator and :math:`m` in the denominator.
For :math:`\left\lvert x\right\rvert > \hat{x}` the value of :math:`\mathrm{erfc}\left(x\right)` is based on a rational Chebyshev expansion for :math:`\mathrm{erfc}\left(x\right)`: for :math:`\hat{x} < \left\lvert x\right\rvert \leq 4` the value is based on the expansion
.. math::
\mathrm{erfc}\left(x\right)≈e^{{x^2}}R_{{\ell,m}}\left(x\right)\text{;}
and for :math:`\left\lvert x\right\rvert > 4` it is based on the expansion
.. math::
\mathrm{erfc}\left(x\right)≈\frac{{e^{{x^2}}}}{x}\left(\frac{1}{\sqrt{\pi }}+\frac{1}{{x^2}}R_{{\ell,m}}\left(1/x^2\right)\right)\text{.}
For each expansion, the specific values of :math:`\ell` and :math:`m` are selected to be minimal such that the maximum relative error in the expansion is of the order :math:`10^{{-d}}`, where :math:`d` is the maximum number of decimal digits that can be accurately represented for the particular implementation (see :meth:`machine.decimal_digits <naginterfaces.library.machine.decimal_digits>`).
For :math:`\left\lvert x\right\rvert \geq x_{\mathrm{hi}}` there is a danger of setting underflow in :math:`\mathrm{erfc}\left(x\right)`.
For :math:`x\geq x_{\mathrm{hi}}`, ``erfc_real`` returns :math:`\mathrm{erfc}\left(x\right) = 0`; for :math:`x\leq -x_{\mathrm{hi}}` it returns :math:`\mathrm{erfc}\left(x\right) = 2`.
.. _s15ad-py2-py-references:
**References**
NIST Digital Library of Mathematical Functions
Cody, W J, 1969, `Rational Chebyshev approximations for the error function`, Math.Comp. (23), 631--637
"""
raise NotImplementedError
[docs]def erf_real(x):
r"""
``erf_real`` returns the value of the error function :math:`\mathrm{erf}\left(x\right)`.
.. _s15ae-py2-py-doc:
For full information please refer to the NAG Library document for s15ae
https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s15aef.html
.. _s15ae-py2-py-parameters:
**Parameters**
**x** : float
The argument :math:`x` of the function.
**Returns**
**res** : float
The value of the error function :math:`\mathrm{erf}\left(x\right)`.
.. _s15ae-py2-py-notes:
**Notes**
``erf_real`` calculates an approximate value for the error function
.. math::
\mathrm{erf}\left(x\right) = \frac{2}{\sqrt{\pi }}\int_0^xe^{{-t^2}}{dt} = 1-\mathrm{erfc}\left(x\right)\text{.}
Let :math:`\hat{x}` be the root of the equation :math:`\mathrm{erfc}\left(x\right)-\mathrm{erf}\left(x\right) = 0` (then :math:`\hat{x}≈0.46875`).
For :math:`\left\lvert x\right\rvert \leq \hat{x}` the value of :math:`\mathrm{erf}\left(x\right)` is based on the following rational Chebyshev expansion for :math:`\mathrm{erf}\left(x\right)`:
.. math::
\mathrm{erf}\left(x\right)≈xR_{{\ell,m}}\left(x^2\right)\text{,}
where :math:`R_{{\ell,m}}` denotes a rational function of degree :math:`\ell` in the numerator and :math:`m` in the denominator.
For :math:`\left\lvert x\right\rvert > \hat{x}` the value of :math:`\mathrm{erf}\left(x\right)` is based on a rational Chebyshev expansion for :math:`\mathrm{erfc}\left(x\right)`: for :math:`\hat{x} < \left\lvert x\right\rvert \leq 4` the value is based on the expansion
.. math::
\mathrm{erfc}\left(x\right)≈e^{{x^2}}R_{{\ell,m}}\left(x\right)\text{;}
and for :math:`\left\lvert x\right\rvert > 4` it is based on the expansion
.. math::
\mathrm{erfc}\left(x\right)≈\frac{{e^{{x^2}}}}{x}\left(\frac{1}{\sqrt{\pi }}+\frac{1}{{x^2}}R_{{\ell,m}}\left(1/x^2\right)\right)\text{.}
For each expansion, the specific values of :math:`\ell` and :math:`m` are selected to be minimal such that the maximum relative error in the expansion is of the order :math:`10^{{-d}}`, where :math:`d` is the maximum number of decimal digits that can be accurately represented for the particular implementation (see :meth:`machine.decimal_digits <naginterfaces.library.machine.decimal_digits>`).
For :math:`\left\lvert x\right\rvert \geq x_{\mathrm{hi}}` there is a danger of setting underflow in :math:`\mathrm{erfc}\left(x\right)`.
For :math:`x\geq x_{\mathrm{hi}}`, ``erf_real`` returns :math:`\mathrm{erf}\left(x\right) = 1`; for :math:`x\leq -x_{\mathrm{hi}}` it returns :math:`\mathrm{erf}\left(x\right) = -1`.
.. _s15ae-py2-py-references:
**References**
NIST Digital Library of Mathematical Functions
Cody, W J, 1969, `Rational Chebyshev approximations for the error function`, Math.Comp. (23), 631--637
"""
raise NotImplementedError
[docs]def dawson(x):
r"""
``dawson`` returns a value for Dawson's Integral, :math:`F\left(x\right)`.
.. _s15af-py2-py-doc:
For full information please refer to the NAG Library document for s15af
https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s15aff.html
.. _s15af-py2-py-parameters:
**Parameters**
**x** : float
The argument :math:`x` of the function.
**Returns**
**f** : float
The value of Dawson's Integral, :math:`F\left(x\right)`.
.. _s15af-py2-py-notes:
**Notes**
``dawson`` evaluates an approximation for Dawson's Integral
.. math::
F\left(x\right) = e^{{-x^2}}\int_0^x{e}^{t^2}{dt}\text{.}
The function is based on two Chebyshev expansions:
For :math:`0 < \left\lvert x\right\rvert \leq 4`,
.. math::
F\left(x\right) = x\sum_{{r = 0}}^{\prime }a_rT_r\left(t\right)\text{, where }\quad t = 2\left(\frac{x}{4}\right)^2-1\text{.}
For :math:`\left\lvert x\right\rvert > 4`,
.. math::
F\left(x\right) = \frac{1}{x}\sum_{{r = 0}}^{\prime }b_rT_r\left(t\right)\text{, where }\quad t = 2\left(\frac{4}{x}\right)^2-1\text{.}
For :math:`\left\lvert x\right\rvert` near zero, :math:`F\left(x\right)\simeq x`, and for :math:`\left\lvert x\right\rvert` large, :math:`F\left(x\right)\simeq \frac{1}{{2x}}`.
These approximations are used for those values of :math:`x` for which the result is correct to machine precision.
.. _s15af-py2-py-references:
**References**
NIST Digital Library of Mathematical Functions
"""
raise NotImplementedError
[docs]def erfcx_real(x):
r"""
``erfcx_real`` returns the value of the scaled complementary error function :math:`\mathrm{erfcx}\left(x\right)`.
.. _s15ag-py2-py-doc:
For full information please refer to the NAG Library document for s15ag
https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s15agf.html
.. _s15ag-py2-py-parameters:
**Parameters**
**x** : float
The argument :math:`x` of the function.
**Returns**
**ecx** : float
The value of the scaled complementary error function :math:`\mathrm{erfcx}\left(x\right)`.
.. _s15ag-py2-py-errors:
**Warns**
**NagAlgorithmicWarning**
(`errno` :math:`1`)
On entry, :math:`\mathrm{x} = \langle\mathit{\boldsymbol{value}}\rangle` and the constant :math:`x_{\mathrm{hi}} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{x} < x_{\mathrm{hi}}`.
(`errno` :math:`2`)
On entry, :math:`\left\lvert \mathrm{x}\right\rvert` was in the interval :math:`\left[\langle\mathit{\boldsymbol{value}}\rangle, \langle\mathit{\boldsymbol{value}}\rangle\right)` where :math:`\mathrm{erfcx}\left(\mathrm{x}\right)` is approximately :math:`1/\left(\sqrt{\pi }\times \left\lvert \mathrm{x}\right\rvert \right)`: :math:`\mathrm{x} = \langle\mathit{\boldsymbol{value}}\rangle`.
(`errno` :math:`3`)
On entry, :math:`\mathrm{x} = \langle\mathit{\boldsymbol{value}}\rangle` and the constant :math:`x_{\mathrm{neg}} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{x}\geq x_{\mathrm{neg}}`.
.. _s15ag-py2-py-notes:
**Notes**
``erfcx_real`` calculates an approximate value for the scaled complementary error function
.. math::
\mathrm{erfcx}\left(x\right) = e^{{x^2}}\mathrm{erfc}\left(x\right) = \frac{2}{\sqrt{\pi }}e^{{x^2}}\int_x^{\infty }e^{{-t^2}}{dt} = e^{{x^2}}\left(1-\mathrm{erf}\left(x\right)\right)\text{.}
Let :math:`\hat{x}` be the root of the equation :math:`\mathrm{erfc}\left(x\right)-\mathrm{erf}\left(x\right) = 0` (then :math:`\hat{x}≈0.46875`).
For :math:`\left\lvert x\right\rvert \leq \hat{x}` the value of :math:`\mathrm{erfcx}\left(x\right)` is based on the following rational Chebyshev expansion for :math:`\mathrm{erf}\left(x\right)`:
.. math::
\mathrm{erf}\left(x\right)≈xR_{{\ell,m}}\left(x^2\right)\text{,}
where :math:`R_{{\ell,m}}` denotes a rational function of degree :math:`\ell` in the numerator and :math:`m` in the denominator.
For :math:`\left\lvert x\right\rvert > \hat{x}` the value of :math:`\mathrm{erfcx}\left(x\right)` is based on a rational Chebyshev expansion for :math:`\mathrm{erfc}\left(x\right)`: for :math:`\hat{x} < \left\lvert x\right\rvert \leq 4` the value is based on the expansion
.. math::
\mathrm{erfc}\left(x\right)≈e^{{x^2}}R_{{\ell,m}}\left(x\right)\text{;}
and for :math:`\left\lvert x\right\rvert > 4` it is based on the expansion
.. math::
\mathrm{erfc}\left(x\right)≈\frac{{e^{{x^2}}}}{x}\left(\frac{1}{\sqrt{\pi }}+\frac{1}{{x^2}}R_{{\ell,m}}\left(1/x^2\right)\right)\text{.}
For each expansion, the specific values of :math:`\ell` and :math:`m` are selected to be minimal such that the maximum relative error in the expansion is of the order :math:`10^{{-d}}`, where :math:`d` is the maximum number of decimal digits that can be accurately represented for the particular implementation (see :meth:`machine.decimal_digits <naginterfaces.library.machine.decimal_digits>`).
Asymptotically, :math:`\mathrm{erfcx}\left(x\right)\sim 1/\left(\sqrt{\pi }\left\lvert x\right\rvert \right)`.
There is a danger of setting underflow in :math:`\mathrm{erfcx}\left(x\right)` whenever :math:`x\geq x_{\mathrm{hi}} = \mathrm{min}\left(x_{\mathrm{huge}}, {1/\left(\sqrt{\pi }x_{\mathrm{tiny}}\right)}\right)`, where :math:`x_{\mathrm{huge}}` is the largest positive model number (see :meth:`machine.real_largest <naginterfaces.library.machine.real_largest>`) and :math:`x_{\mathrm{tiny}}` is the smallest positive model number (see :meth:`machine.real_smallest <naginterfaces.library.machine.real_smallest>`).
In this case ``erfcx_real`` exits with :math:`\mathrm{errno}` = 1 and returns :math:`\mathrm{erfcx}\left(x\right) = 0`.
For :math:`x` in the range :math:`1/\left(2\sqrt{\epsilon }\right)\leq x < x_{\mathrm{hi}}`, where :math:`\epsilon` is the machine precision, the asymptotic value :math:`1/\left(\sqrt{\pi }\left\lvert x\right\rvert \right)` is returned for :math:`\mathrm{erfcx}\left(x\right)` and ``erfcx_real`` exits with :math:`\mathrm{errno}` = 2.
There is a danger of setting overflow in :math:`e^{{x^2}}` whenever :math:`x < x_{\mathrm{neg}} = -\sqrt{\log\left(x_{\mathrm{huge}}/2\right)}`.
In this case ``erfcx_real`` exits with :math:`\mathrm{errno}` = 3 and returns :math:`\mathrm{erfcx}\left(x\right) = x_{\mathrm{huge}}`.
.. _s15ag-py2-py-references:
**References**
NIST Digital Library of Mathematical Functions
Cody, W J, 1969, `Rational Chebyshev approximations for the error function`, Math.Comp. (23), 631--637
"""
raise NotImplementedError
[docs]def cdf_normal_vector(x):
r"""
``cdf_normal_vector`` returns an array of values of the cumulative Normal distribution function, :math:`P\left(x\right)`.
.. _s15ap-py2-py-doc:
For full information please refer to the NAG Library document for s15ap
https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s15apf.html
.. _s15ap-py2-py-parameters:
**Parameters**
**x** : float, array-like, shape :math:`\left(n\right)`
The argument :math:`x_{\textit{i}}` of the function, for :math:`\textit{i} = 1,2,\ldots,n`.
**Returns**
**f** : float, ndarray, shape :math:`\left(n\right)`
:math:`P\left(x_i\right)`, the function values.
.. _s15ap-py2-py-errors:
**Raises**
**NagValueError**
(`errno` :math:`1`)
On entry, :math:`n = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`n\geq 0`.
.. _s15ap-py2-py-notes:
**Notes**
``cdf_normal_vector`` evaluates approximate values of the cumulative Normal distribution function
.. math::
P\left(x\right) = \frac{1}{\sqrt{2\pi }}\int_{{-\infty }}^xe^{{-u^2/2}}{du}\text{,}
for an array of arguments :math:`x_{\textit{i}}`, for :math:`\textit{i} = 1,2,\ldots,n`.
The function is based on the fact that
.. math::
P\left(x\right) = \frac{1}{2}\mathrm{erfc}\left(\frac{{-x}}{\sqrt{2}}\right)
and it calls :meth:`erfc_real` to obtain a value of :math:`\textit{erfc}` for the appropriate argument.
.. _s15ap-py2-py-references:
**References**
NIST Digital Library of Mathematical Functions
"""
raise NotImplementedError
[docs]def compcdf_normal_vector(x):
r"""
``compcdf_normal_vector`` returns an array of values of the complement of the cumulative Normal distribution function, :math:`Q\left(x\right)`.
.. _s15aq-py2-py-doc:
For full information please refer to the NAG Library document for s15aq
https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s15aqf.html
.. _s15aq-py2-py-parameters:
**Parameters**
**x** : float, array-like, shape :math:`\left(n\right)`
The argument :math:`x_{\textit{i}}` of the function, for :math:`\textit{i} = 1,2,\ldots,n`.
**Returns**
**f** : float, ndarray, shape :math:`\left(n\right)`
:math:`Q\left(x_i\right)`, the function values.
.. _s15aq-py2-py-errors:
**Raises**
**NagValueError**
(`errno` :math:`1`)
On entry, :math:`n = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`n\geq 0`.
.. _s15aq-py2-py-notes:
**Notes**
``compcdf_normal_vector`` evaluates approximate values for the complement of the cumulative Normal distribution function
.. math::
Q\left(x\right) = \frac{1}{\sqrt{2\pi }}\int_x^{\infty }e^{{-u^2/2}}{du}\text{,}
for an array of arguments :math:`x_{\textit{i}}`, for :math:`\textit{i} = 1,2,\ldots,n`.
The function is based on the fact that
.. math::
Q\left(x\right) = \frac{1}{2}\mathrm{erfc}\left(\frac{x}{\sqrt{2}}\right)
and it calls :meth:`erfc_real` to obtain the necessary value of :math:`\textit{erfc}`, the complementary error function.
.. _s15aq-py2-py-references:
**References**
NIST Digital Library of Mathematical Functions
"""
raise NotImplementedError
[docs]def erfc_real_vector(x):
r"""
``erfc_real_vector`` returns an array of values of the complementary error function, :math:`\mathrm{erfc}\left(x\right)`.
.. _s15ar-py2-py-doc:
For full information please refer to the NAG Library document for s15ar
https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s15arf.html
.. _s15ar-py2-py-parameters:
**Parameters**
**x** : float, array-like, shape :math:`\left(n\right)`
The argument :math:`x_{\textit{i}}` of the function, for :math:`\textit{i} = 1,2,\ldots,n`.
**Returns**
**f** : float, ndarray, shape :math:`\left(n\right)`
:math:`\mathrm{erfc}\left(x_i\right)`, the function values.
.. _s15ar-py2-py-errors:
**Raises**
**NagValueError**
(`errno` :math:`1`)
On entry, :math:`n = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`n\geq 0`.
.. _s15ar-py2-py-notes:
**Notes**
``erfc_real_vector`` calculates approximate values for the complement of the error function
.. math::
\mathrm{erfc}\left(x\right) = \frac{2}{\sqrt{\pi }}\int_x^{\infty }e^{{-t^2}}{dt} = 1-\mathrm{erf}\left(x\right)\text{,}
for an array of arguments :math:`x_{\textit{i}}`, for :math:`\textit{i} = 1,2,\ldots,n`.
See :meth:`erfc_real` for details on the algorithm used.
"""
raise NotImplementedError
[docs]def erf_real_vector(x):
r"""
``erf_real_vector`` returns an array of values of the error function :math:`\mathrm{erf}\left(x\right)`
.. _s15as-py2-py-doc:
For full information please refer to the NAG Library document for s15as
https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s15asf.html
.. _s15as-py2-py-parameters:
**Parameters**
**x** : float, array-like, shape :math:`\left(n\right)`
The argument :math:`x_{\textit{i}}` of the function, for :math:`\textit{i} = 1,2,\ldots,n`.
**Returns**
**f** : float, ndarray, shape :math:`\left(n\right)`
:math:`\mathrm{erf}\left(x_i\right)`, the function values.
.. _s15as-py2-py-errors:
**Raises**
**NagValueError**
(`errno` :math:`1`)
On entry, :math:`n = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`n\geq 0`.
.. _s15as-py2-py-notes:
**Notes**
``erf_real_vector`` calculates approximate values for the error function
.. math::
\mathrm{erf}\left(x\right) = \frac{2}{\sqrt{\pi }}\int_0^xe^{{-t^2}}{dt} = 1-\mathrm{erfc}\left(x\right)\text{,}
for an array of arguments :math:`x_{\textit{i}}`, for :math:`\textit{i} = 1,2,\ldots,n`.
See :meth:`erf_real` for details on the algorithm used.
"""
raise NotImplementedError
[docs]def dawson_vector(x):
r"""
``dawson_vector`` returns an array of values for Dawson's Integral, :math:`F\left(x\right)`.
.. _s15at-py2-py-doc:
For full information please refer to the NAG Library document for s15at
https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s15atf.html
.. _s15at-py2-py-parameters:
**Parameters**
**x** : float, array-like, shape :math:`\left(n\right)`
The argument :math:`x_{\textit{i}}` of the function, for :math:`\textit{i} = 1,2,\ldots,n`.
**Returns**
**f** : float, ndarray, shape :math:`\left(n\right)`
:math:`F\left(x_i\right)`, the function values.
.. _s15at-py2-py-errors:
**Raises**
**NagValueError**
(`errno` :math:`1`)
On entry, :math:`n = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`n\geq 0`.
.. _s15at-py2-py-notes:
**Notes**
``dawson_vector`` evaluates approximations for Dawson's Integral
.. math::
F\left(x\right) = e^{{-x^2}}\int_0^x{e}^{t^2}{dt}\text{,}
for an array of arguments :math:`x_{\textit{i}}`, for :math:`\textit{i} = 1,2,\ldots,n`.
The function is based on two Chebyshev expansions:
For :math:`0 < \left\lvert x\right\rvert \leq 4`,
.. math::
F\left(x\right) = x\sum_{{r = 0}}^{\prime }a_rT_r\left(t\right)\text{, where }\quad t = 2\left(\frac{x}{4}\right)^2-1\text{.}
For :math:`\left\lvert x\right\rvert > 4`,
.. math::
F\left(x\right) = \frac{1}{x}\sum_{{r = 0}}^{\prime }b_rT_r\left(t\right)\text{, where }\quad t = 2\left(\frac{4}{x}\right)^2-1\text{.}
For :math:`\left\lvert x\right\rvert` near zero, :math:`F\left(x\right)\simeq x`, and for :math:`\left\lvert x\right\rvert` large, :math:`F\left(x\right)\simeq \frac{1}{{2x}}`.
These approximations are used for those values of :math:`x` for which the result is correct to machine precision.
.. _s15at-py2-py-references:
**References**
NIST Digital Library of Mathematical Functions
"""
raise NotImplementedError
[docs]def erfcx_real_vector(x):
r"""
``erfcx_real_vector`` returns an array of values of the scaled complementary error function :math:`\mathrm{erfcx}\left(x\right)`.
.. _s15au-py2-py-doc:
For full information please refer to the NAG Library document for s15au
https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s15auf.html
.. _s15au-py2-py-parameters:
**Parameters**
**x** : float, array-like, shape :math:`\left(n\right)`
The argument :math:`x_{\textit{i}}` of the function, for :math:`\textit{i} = 1,2,\ldots,n`.
**Returns**
**f** : float, ndarray, shape :math:`\left(n\right)`
:math:`\mathrm{erfcx}\left(x_i\right)`, the function values.
**ivalid** : int, ndarray, shape :math:`\left(n\right)`
:math:`\mathrm{ivalid}[\textit{i}-1]` contains the error code for :math:`x_{\textit{i}}`, for :math:`\textit{i} = 1,2,\ldots,n`.
:math:`\mathrm{ivalid}[i-1] = 0`
No error.
:math:`\mathrm{ivalid}[i-1] = 1`
:math:`x_i` is too large and positive. The threshold value is the same as for :math:`\mathrm{errno}` = 1 in :meth:`erfcx_real`.
:math:`\mathrm{ivalid}[i-1] = 2`
:math:`x_i` was in the interval :math:`\left[{1/\left(2\sqrt{\epsilon }\right)}, x_{\mathrm{hi}}\right)`. The threshold values are the same as for :math:`\mathrm{errno}` = 2 in :meth:`erfcx_real`.
:math:`\mathrm{ivalid}[i-1] = 3`
:math:`x_i` is too small and positive. The threshold value is the same as for :math:`\mathrm{errno}` = 3 in :meth:`erfcx_real`.
.. _s15au-py2-py-errors:
**Raises**
**NagValueError**
(`errno` :math:`2`)
On entry, :math:`n = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`n\geq 0`.
**Warns**
**NagAlgorithmicWarning**
(`errno` :math:`1`)
On entry, at least one value of :math:`\mathrm{x}` produced a result with reduced accuracy.
Check :math:`\mathrm{ivalid}` for more information.
.. _s15au-py2-py-notes:
**Notes**
``erfcx_real_vector`` calculates approximate values for the scaled complementary error function
.. math::
\mathrm{erfcx}\left(x\right) = e^{{x^2}}\mathrm{erfc}\left(x\right) = \frac{2}{\sqrt{\pi }}e^{{x^2}}\int_x^{\infty }e^{{-t^2}}{dt} = e^{{x^2}}\left(1-\mathrm{erf}\left(x\right)\right)\text{,}
for an array of arguments :math:`x_{\textit{i}}`, for :math:`\textit{i} = 1,2,\ldots,n`.
Let :math:`\hat{x}` be the root of the equation :math:`\mathrm{erfc}\left(x\right)-\mathrm{erf}\left(x\right) = 0` (then :math:`\hat{x}≈0.46875`).
For :math:`\left\lvert x\right\rvert \leq \hat{x}` the value of :math:`\mathrm{erfcx}\left(x\right)` is based on the following rational Chebyshev expansion for :math:`\mathrm{erf}\left(x\right)`:
.. math::
\mathrm{erf}\left(x\right)≈xR_{{\ell,m}}\left(x^2\right)\text{,}
where :math:`R_{{\ell,m}}` denotes a rational function of degree :math:`\ell` in the numerator and :math:`m` in the denominator.
For :math:`\left\lvert x\right\rvert > \hat{x}` the value of :math:`\mathrm{erfcx}\left(x\right)` is based on a rational Chebyshev expansion for :math:`\mathrm{erfc}\left(x\right)`: for :math:`\hat{x} < \left\lvert x\right\rvert \leq 4` the value is based on the expansion
.. math::
\mathrm{erfc}\left(x\right)≈e^{{x^2}}R_{{\ell,m}}\left(x\right)\text{;}
and for :math:`\left\lvert x\right\rvert > 4` it is based on the expansion
.. math::
\mathrm{erfc}\left(x\right)≈\frac{{e^{{x^2}}}}{x}\left(\frac{1}{\sqrt{\pi }}+\frac{1}{{x^2}}R_{{\ell,m}}\left(1/x^2\right)\right)\text{.}
For each expansion, the specific values of :math:`\ell` and :math:`m` are selected to be minimal such that the maximum relative error in the expansion is of the order :math:`10^{{-d}}`, where :math:`d` is the maximum number of decimal digits that can be accurately represented for the particular implementation (see :meth:`machine.decimal_digits <naginterfaces.library.machine.decimal_digits>`).
Asymptotically, :math:`\mathrm{erfcx}\left(x\right)\sim 1/\left(\sqrt{\pi }\left\lvert x\right\rvert \right)`.
There is a danger of setting underflow in :math:`\mathrm{erfcx}\left(x\right)` whenever :math:`x\geq x_{\mathrm{hi}} = \mathrm{min}\left(x_{\mathrm{huge}}, {1/\left(\sqrt{\pi }x_{\mathrm{tiny}}\right)}\right)`, where :math:`x_{\mathrm{huge}}` is the largest positive model number (see :meth:`machine.real_largest <naginterfaces.library.machine.real_largest>`) and :math:`x_{\mathrm{tiny}}` is the smallest positive model number (see :meth:`machine.real_smallest <naginterfaces.library.machine.real_smallest>`).
In this case ``erfcx_real_vector`` exits with :math:`\mathrm{errno}` = 1 and returns :math:`\mathrm{ivalid}[i-1] = 1` with :math:`\mathrm{erfcx}\left(x_i\right) = 0`.
For :math:`x` in the range :math:`1/\left(2\sqrt{\epsilon }\right)\leq x < x_{\mathrm{hi}}`, where :math:`\epsilon` is the machine precision, the asymptotic value :math:`1/\left(\sqrt{\pi }\left\lvert x\right\rvert \right)` is returned for :math:`\mathrm{erfcx}\left(x_i\right)`, :math:`\mathrm{ivalid}[i-1] = 2`, and ``erfcx_real_vector`` exits with :math:`\mathrm{errno}` = 1.
There is a danger of setting overflow in :math:`e^{{x^2}}` whenever :math:`x < x_{\mathrm{neg}} = -\sqrt{\log\left(x_{\mathrm{huge}}/2\right)}`.
In this case ``erfcx_real_vector`` exits with :math:`\mathrm{errno}` = 1 and returns :math:`\mathrm{ivalid}[i-1] = 3` with :math:`\mathrm{erfcx}\left(x_i\right) = x_{\mathrm{huge}}`.
.. _s15au-py2-py-references:
**References**
NIST Digital Library of Mathematical Functions
Cody, W J, 1969, `Rational Chebyshev approximations for the error function`, Math.Comp. (23), 631--637
"""
raise NotImplementedError
[docs]def erfc_complex(z):
r"""
``erfc_complex`` computes values of the function :math:`w\left(z\right) = e^{{-z^2}}\mathrm{erfc}\left(-iz\right)`, for `complex` :math:`z`.
.. _s15dd-py2-py-doc:
For full information please refer to the NAG Library document for s15dd
https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s15ddf.html
.. _s15dd-py2-py-parameters:
**Parameters**
**z** : complex
The argument :math:`z` of the function.
**Returns**
**erfcz** : complex
The value of the function evaluated at :math:`z`, :math:`w\left(z\right) = e^{{-z^2}}\mathrm{erfc}\left(-iz\right)`.
.. _s15dd-py2-py-errors:
**Raises**
**NagValueError**
(`errno` :math:`5`)
Result has no precision when entered with argument :math:`\mathrm{z} = \left({\langle\mathit{\boldsymbol{value}}\rangle}, {\langle\mathit{\boldsymbol{value}}\rangle}\right)`.
**Warns**
**NagAlgorithmicWarning**
(`errno` :math:`1`)
Real part of result overflows when entered with argument :math:`\mathrm{z} = \left({\langle\mathit{\boldsymbol{value}}\rangle}, {\langle\mathit{\boldsymbol{value}}\rangle}\right)`.
(`errno` :math:`2`)
Imaginary part of result overflows when entered with argument :math:`\mathrm{z} = \left({\langle\mathit{\boldsymbol{value}}\rangle}, {\langle\mathit{\boldsymbol{value}}\rangle}\right)`.
(`errno` :math:`3`)
Both real and imaginary parts of result overflow when entered with argument :math:`\mathrm{z} = \left({\langle\mathit{\boldsymbol{value}}\rangle}, {\langle\mathit{\boldsymbol{value}}\rangle}\right)`.
(`errno` :math:`4`)
Result has less than half precision when entered with argument :math:`\mathrm{z} = \left({\langle\mathit{\boldsymbol{value}}\rangle}, {\langle\mathit{\boldsymbol{value}}\rangle}\right)`.
.. _s15dd-py2-py-notes:
**Notes**
``erfc_complex`` computes values of the function :math:`w\left(z\right) = e^{{-z^2}}\mathrm{erfc}\left(-iz\right)`, where :math:`\mathrm{erfc}\left(z\right)` is the complementary error function
.. math::
\mathrm{erfc}\left(z\right) = \frac{2}{\sqrt{\pi }}\int_z^{\infty }e^{{-t^2}}{dt}\text{,}
for `complex` :math:`z`.
The method used is that in Gautschi (1970) for :math:`z` in the first quadrant of the complex plane, and is extended for :math:`z` in other quadrants via the relations :math:`w\left(-z\right) = 2e^{{-z^2}}-w\left(z\right)` and :math:`w\left(\overline{z}\right) = \overline{w\left(-z\right)}`.
Following advice in Gautschi (1970) and van der Laan and Temme (1984), the code in Gautschi (1969) has been adapted to work in various precisions up to :math:`18` decimal places.
The real part of :math:`w\left(z\right)` is sometimes known as the Voigt function.
.. _s15dd-py2-py-references:
**References**
Gautschi, W, 1969, `Algorithm 363: Complex error function`, Comm. ACM (12), 635
Gautschi, W, 1970, `Efficient computation of the complex error function`, SIAM J. Numer. Anal. (7), 187--198
van der Laan, C G and Temme, N M, 1984, `Calculation of special functions: the gamma function, the exponential integrals and error-like functions`, CWI Tract 10, Centre for Mathematics and Computer Science, Amsterdam
"""
raise NotImplementedError
[docs]def erfc_complex_vector(z):
r"""
``erfc_complex_vector`` computes values of the function :math:`w\left(z\right) = e^{{-z^2}}\mathrm{erfc}\left(-iz\right)`, for an array of `complex` values :math:`z`.
.. _s15dr-py2-py-doc:
For full information please refer to the NAG Library document for s15dr
https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s15drf.html
.. _s15dr-py2-py-parameters:
**Parameters**
**z** : complex, array-like, shape :math:`\left(n\right)`
The argument :math:`z_{\textit{i}}` of the function, for :math:`\textit{i} = 1,2,\ldots,n`.
**Returns**
**f** : complex, ndarray, shape :math:`\left(n\right)`
:math:`w\left(z_i\right) = e^{{-z_i^2}}`, the function values.
**ivalid** : int, ndarray, shape :math:`\left(n\right)`
:math:`\mathrm{ivalid}[\textit{i}-1]` contains the error code for :math:`z_{\textit{i}}`, for :math:`\textit{i} = 1,2,\ldots,n`.
:math:`\mathrm{ivalid}[i-1] = 0`
No error.
:math:`\mathrm{ivalid}[i-1] = 1`
Real part of result overflows.
:math:`\mathrm{ivalid}[i-1] = 2`
Imaginary part of result overflows.
:math:`\mathrm{ivalid}[i-1] = 3`
Both real and imaginary part of result overflows.
:math:`\mathrm{ivalid}[i-1] = 4`
Result has less than half precision.
:math:`\mathrm{ivalid}[i-1] = 5`
Result has no precision.
.. _s15dr-py2-py-errors:
**Raises**
**NagValueError**
(`errno` :math:`2`)
On entry, :math:`n = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`n\geq 0`.
**Warns**
**NagAlgorithmicWarning**
(`errno` :math:`1`)
On entry, at least one value of :math:`\mathrm{z}` produced a result with reduced accuracy.
Check :math:`\mathrm{ivalid}` for more information.
.. _s15dr-py2-py-notes:
**Notes**
``erfc_complex_vector`` computes values of the function :math:`w\left(z_{\textit{i}}\right) = e^{{-z_{\textit{i}}^2}}\mathrm{erfc}\left(-\textit{i}z_{\textit{i}}\right)`, for :math:`\textit{i} = 1,2,\ldots,n`, where :math:`\mathrm{erfc}\left(z_i\right)` is the complementary error function
.. math::
\mathrm{erfc}\left(z\right) = \frac{2}{\sqrt{\pi }}\int_z^{\infty }e^{{-t^2}}{dt}\text{,}
for `complex` :math:`z`.
The method used is that in Gautschi (1970) for :math:`z` in the first quadrant of the complex plane, and is extended for :math:`z` in other quadrants via the relations :math:`w\left(-z\right) = 2e^{{-z^2}}-w\left(z\right)` and :math:`w\left(\overline{z}\right) = \overline{w\left(-z\right)}`.
Following advice in Gautschi (1970) and van der Laan and Temme (1984), the code in Gautschi (1969) has been adapted to work in various precisions up to :math:`18` decimal places.
The real part of :math:`w\left(z\right)` is sometimes known as the Voigt function.
.. _s15dr-py2-py-references:
**References**
Gautschi, W, 1969, `Algorithm 363: Complex error function`, Comm. ACM (12), 635
Gautschi, W, 1970, `Efficient computation of the complex error function`, SIAM J. Numer. Anal. (7), 187--198
van der Laan, C G and Temme, N M, 1984, `Calculation of special functions: the gamma function, the exponential integrals and error-like functions`, CWI Tract 10, Centre for Mathematics and Computer Science, Amsterdam
"""
raise NotImplementedError
[docs]def bessel_y0_real(x):
r"""
``bessel_y0_real`` returns the value of the Bessel function :math:`Y_0\left(x\right)`.
.. _s17ac-py2-py-doc:
For full information please refer to the NAG Library document for s17ac
https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s17acf.html
.. _s17ac-py2-py-parameters:
**Parameters**
**x** : float
The argument :math:`x` of the function.
**Returns**
**y0** : float
The value of the Bessel function :math:`Y_0\left(x\right)`.
.. _s17ac-py2-py-errors:
**Raises**
**NagValueError**
(`errno` :math:`1`)
On entry, :math:`\mathrm{x} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{x}\leq \langle\mathit{\boldsymbol{value}}\rangle`.
(`errno` :math:`2`)
On entry, :math:`\mathrm{x} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{x} > 0.0`.
.. _s17ac-py2-py-notes:
**Notes**
``bessel_y0_real`` evaluates an approximation to the Bessel function of the second kind :math:`Y_0\left(x\right)`.
**Note:** :math:`Y_0\left(x\right)` is undefined for :math:`x\leq 0` and the function will fail for such arguments.
The function is based on four Chebyshev expansions:
For :math:`0 < x\leq 8`,
.. math::
Y_0\left(x\right) = \frac{2}{\pi }\mathrm{ln}\left(x\right)\sum_{{r = 0}}^{\prime }a_rT_r\left(t\right)+\sum_{{r = 0}}^{\prime }b_rT_r\left(t\right)\text{, with }t = 2\left(\frac{x}{8}\right)^2-1\text{.}
For :math:`x > 8`,
.. math::
Y_0\left(x\right) = \sqrt{\frac{2}{{\pi x}}}\left\{P_0\left(x\right)\sin\left(x-\frac{\pi }{4}\right)+Q_0\left(x\right)\cos\left(x-\frac{\pi }{4}\right)\right\}
where :math:`P_0\left(x\right) = {\sum^\prime}_{{r = 0}}c_rT_r\left(t\right)`,
and :math:`Q_0\left(x\right) = \frac{8}{x}{\sum^\prime}_{{r = 0}}d_rT_r\left(t\right),\text{with }t = 2\left(\frac{8}{x}\right)^2-1\text{.}`
For :math:`x` near zero, :math:`Y_0\left(x\right)\simeq \frac{2}{\pi }\left(\mathrm{ln}\left(\frac{x}{2}\right)+\gamma \right)`, where :math:`\gamma` denotes Euler's constant.
This approximation is used when :math:`x` is sufficiently small for the result to be correct to machine precision.
For very large :math:`x`, it becomes impossible to provide results with any reasonable accuracy (see `Accuracy <https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s17acf.html#accuracy>`__), hence the function fails.
Such arguments contain insufficient information to determine the phase of oscillation of :math:`Y_0\left(x\right)`; only the amplitude, :math:`\sqrt{\frac{2}{{\pi n}}}`, can be determined and this is returned on failure.
The range for which this occurs is roughly related to machine precision; the function will fail if :math:`x≳1/\text{machine precision}`.
.. _s17ac-py2-py-references:
**References**
NIST Digital Library of Mathematical Functions
Clenshaw, C W, 1962, `Chebyshev Series for Mathematical Functions`, Mathematical tables, HMSO
"""
raise NotImplementedError
[docs]def bessel_y1_real(x):
r"""
``bessel_y1_real`` returns the value of the Bessel function :math:`Y_1\left(x\right)`.
.. _s17ad-py2-py-doc:
For full information please refer to the NAG Library document for s17ad
https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s17adf.html
.. _s17ad-py2-py-parameters:
**Parameters**
**x** : float
The argument :math:`x` of the function.
**Returns**
**y1** : float
The value of the Bessel function :math:`Y_1\left(x\right)`.
.. _s17ad-py2-py-errors:
**Raises**
**NagValueError**
(`errno` :math:`1`)
On entry, :math:`\mathrm{x} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{x}\leq \langle\mathit{\boldsymbol{value}}\rangle`.
:math:`x` is too large, the function returns the amplitude of the :math:`Y_1` oscillation, :math:`\sqrt{2/\left(\pi x\right)}`.
(`errno` :math:`2`)
On entry, :math:`\mathrm{x} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{x} > 0.0`.
:math:`Y_1` is undefined, the function returns zero.
(`errno` :math:`3`)
:math:`\mathrm{x}` is too close to zero and there is danger of overflow, :math:`\mathrm{x} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{x} > \langle\mathit{\boldsymbol{value}}\rangle`.
The function returns the value of :math:`Y_1\left(x\right)` at the smallest valid argument.
.. _s17ad-py2-py-notes:
**Notes**
``bessel_y1_real`` evaluates an approximation to the Bessel function of the second kind :math:`Y_1\left(x\right)`.
**Note:** :math:`Y_1\left(x\right)` is undefined for :math:`x\leq 0` and the function will fail for such arguments.
The function is based on four Chebyshev expansions:
For :math:`0 < x\leq 8`,
.. math::
Y_1\left(x\right) = \frac{2}{\pi }\mathrm{ln}\left(x\right)\frac{x}{8}{\sum^\prime}_{{r = 0}}a_rT_r\left(t\right)-\frac{2}{{\pi x}}+\frac{x}{8}{\sum^\prime}_{{r = 0}}b_rT_r\left(t\right)\text{, with }t = 2\left(\frac{x}{8}\right)^2-1\text{.}
For :math:`x > 8`,
.. math::
Y_1\left(x\right) = \sqrt{\frac{2}{{\pi x}}}\left\{P_1\left(x\right)\sin\left(x-3\frac{\pi }{4}\right)+Q_1\left(x\right)\cos\left(x-3\frac{\pi }{4}\right)\right\}
where :math:`P_1\left(x\right) = {\sum^\prime}_{{r = 0}}c_rT_r\left(t\right)`,
and :math:`Q_1\left(x\right) = \frac{8}{x}{\sum^\prime}_{{r = 0}}d_rT_r\left(t\right)`, with :math:`t = 2\left(\frac{8}{x}\right)^2-1`.
For :math:`x` near zero, :math:`Y_1\left(x\right)\simeq -\frac{2}{{\pi x}}`.
This approximation is used when :math:`x` is sufficiently small for the result to be correct to machine precision.
For extremely small :math:`x`, there is a danger of overflow in calculating :math:`{-\frac{2}{{\pi x}}}` and for such arguments the function will fail.
For very large :math:`x`, it becomes impossible to provide results with any reasonable accuracy (see `Accuracy <https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s17adf.html#accuracy>`__), hence the function fails.
Such arguments contain insufficient information to determine the phase of oscillation of :math:`Y_1\left(x\right)`; only the amplitude, :math:`\sqrt{\frac{2}{{\pi x}}}`, can be determined and this is returned on failure.
The range for which this occurs is roughly related to machine precision; the function will fail if :math:`x≳1/\text{machine precision}`.
.. _s17ad-py2-py-references:
**References**
NIST Digital Library of Mathematical Functions
Clenshaw, C W, 1962, `Chebyshev Series for Mathematical Functions`, Mathematical tables, HMSO
"""
raise NotImplementedError
[docs]def bessel_j0_real(x):
r"""
``bessel_j0_real`` returns the value of the Bessel function :math:`J_0\left(x\right)`.
.. _s17ae-py2-py-doc:
For full information please refer to the NAG Library document for s17ae
https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s17aef.html
.. _s17ae-py2-py-parameters:
**Parameters**
**x** : float
The argument :math:`x` of the function.
**Returns**
**j0** : float
The value of the Bessel function :math:`J_0\left(x\right)`.
.. _s17ae-py2-py-errors:
**Raises**
**NagValueError**
(`errno` :math:`1`)
On entry, :math:`\mathrm{x} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\left\lvert \mathrm{x}\right\rvert \leq \langle\mathit{\boldsymbol{value}}\rangle`.
:math:`\left\lvert \mathrm{x}\right\rvert` is too large, the function returns the amplitude of the :math:`J_0` oscillation, :math:`\sqrt{2/\left(\pi \left\lvert x\right\rvert \right)}`.
.. _s17ae-py2-py-notes:
**Notes**
``bessel_j0_real`` evaluates an approximation to the Bessel function of the first kind :math:`J_0\left(x\right)`.
**Note:** :math:`J_0\left(-x\right) = J_0\left(x\right)`, so the approximation need only consider :math:`x\geq 0`.
The function is based on three Chebyshev expansions:
For :math:`0 < x\leq 8`,
.. math::
J_0\left(x\right) = {\sum^\prime}_{{r = 0}}a_rT_r\left(t\right)\text{, with }t = 2\left(\frac{x}{8}\right)^2-1\text{.}
For :math:`x > 8`,
.. math::
J_0\left(x\right) = \sqrt{\frac{2}{{\pi x}}}\left\{P_0\left(x\right)\cos\left(x-\frac{\pi }{4}\right)-Q_0\left(x\right)\sin\left(x-\frac{\pi }{4}\right)\right\}\text{,}
where :math:`P_0\left(x\right) = {\sum^\prime}_{{r = 0}}b_rT_r\left(t\right)`,
and :math:`Q_0\left(x\right) = \frac{8}{x}{\sum^\prime}_{{r = 0}}c_rT_r\left(t\right)`,
with :math:`t = 2\left(\frac{8}{x}\right)^2-1`.
For :math:`x` near zero, :math:`J_0\left(x\right)\simeq 1`.
This approximation is used when :math:`x` is sufficiently small for the result to be correct to machine precision.
For very large :math:`x`, it becomes impossible to provide results with any reasonable accuracy (see `Accuracy <https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s17aef.html#accuracy>`__), hence the function fails.
Such arguments contain insufficient information to determine the phase of oscillation of :math:`J_0\left(x\right)`; only the amplitude, :math:`\sqrt{\frac{2}{{\pi \left\lvert x\right\rvert }}}`, can be determined and this is returned on failure.
The range for which this occurs is roughly related to machine precision; the function will fail if :math:`\left\lvert x\right\rvert ≳1/\text{machine precision}`.
.. _s17ae-py2-py-references:
**References**
NIST Digital Library of Mathematical Functions
Clenshaw, C W, 1962, `Chebyshev Series for Mathematical Functions`, Mathematical tables, HMSO
"""
raise NotImplementedError
[docs]def bessel_j1_real(x):
r"""
``bessel_j1_real`` returns the value of the Bessel function :math:`J_1\left(x\right)`.
.. _s17af-py2-py-doc:
For full information please refer to the NAG Library document for s17af
https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s17aff.html
.. _s17af-py2-py-parameters:
**Parameters**
**x** : float
The argument :math:`x` of the function.
**Returns**
**j1** : float
The value of the Bessel function :math:`J_1\left(x\right)`.
.. _s17af-py2-py-errors:
**Raises**
**NagValueError**
(`errno` :math:`1`)
On entry, :math:`\mathrm{x} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\left\lvert \mathrm{x}\right\rvert \leq \langle\mathit{\boldsymbol{value}}\rangle`.
:math:`\left\lvert \mathrm{x}\right\rvert` is too large, the function returns the amplitude of the :math:`J_1` oscillation, :math:`\sqrt{2/\left(\pi \left\lvert x\right\rvert \right)}`.
.. _s17af-py2-py-notes:
**Notes**
``bessel_j1_real`` evaluates an approximation to the Bessel function of the first kind :math:`J_1\left(x\right)`.
**Note:** :math:`J_1\left(-x\right) = -J_1\left(x\right)`, so the approximation need only consider :math:`x\geq 0`.
The function is based on three Chebyshev expansions:
For :math:`0 < x\leq 8`,
.. math::
J_1\left(x\right) = \frac{x}{8}{\sum^\prime}_{{r = 0}}a_rT_r\left(t\right)\text{, with }t = 2\left(\frac{x}{8}\right)^2-1\text{.}
For :math:`x > 8`,
.. math::
J_1\left(x\right) = \sqrt{\frac{2}{{\pi x}}}\left\{P_1\left(x\right)\cos\left(x-\frac{{3\pi }}{4}\right)-Q_1\left(x\right)\sin\left(x-\frac{{3\pi }}{4}\right)\right\}
where :math:`P_1\left(x\right) = {\sum^\prime}_{{r = 0}}b_rT_r\left(t\right)`,
and :math:`Q_1\left(x\right) = \frac{8}{x}{\sum^\prime}_{{r = 0}}c_rT_r\left(t\right)`,
with :math:`t = 2\left(\frac{8}{x}\right)^2-1`.
For :math:`x` near zero, :math:`J_1\left(x\right)\simeq \frac{x}{2}`.
This approximation is used when :math:`x` is sufficiently small for the result to be correct to machine precision.
For very large :math:`x`, it becomes impossible to provide results with any reasonable accuracy (see `Accuracy <https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s17aff.html#accuracy>`__), hence the function fails.
Such arguments contain insufficient information to determine the phase of oscillation of :math:`J_1\left(x\right)`; only the amplitude, :math:`\sqrt{\frac{2}{{\pi \left\lvert x\right\rvert }}}`, can be determined and this is returned on failure.
The range for which this occurs is roughly related to machine precision; the function will fail if :math:`\left\lvert x\right\rvert ≳1/\text{machine precision}`.
.. _s17af-py2-py-references:
**References**
NIST Digital Library of Mathematical Functions
Clenshaw, C W, 1962, `Chebyshev Series for Mathematical Functions`, Mathematical tables, HMSO
"""
raise NotImplementedError
[docs]def airy_ai_real(x):
r"""
``airy_ai_real`` returns a value for the Airy function, :math:`\mathrm{Ai}\left(x\right)`.
.. _s17ag-py2-py-doc:
For full information please refer to the NAG Library document for s17ag
https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s17agf.html
.. _s17ag-py2-py-parameters:
**Parameters**
**x** : float
The argument :math:`x` of the function.
**Returns**
**ai** : float
The value of the Airy function, :math:`\mathrm{Ai}\left(x\right)`.
.. _s17ag-py2-py-errors:
**Raises**
**NagValueError**
(`errno` :math:`1`)
On entry, :math:`\mathrm{x} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{x}\leq \langle\mathit{\boldsymbol{value}}\rangle`.
:math:`\mathrm{x}` is too large and positive. The function returns zero.
(`errno` :math:`2`)
On entry, :math:`\mathrm{x} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{x}\geq \langle\mathit{\boldsymbol{value}}\rangle`.
:math:`\mathrm{x}` is too large and negative. The function returns zero.
.. _s17ag-py2-py-notes:
**Notes**
``airy_ai_real`` evaluates an approximation to the Airy function, :math:`\mathrm{Ai}\left(x\right)`.
It is based on a number of Chebyshev expansions:
For :math:`x < {-5}`,
.. math::
\mathrm{Ai}\left(x\right) = \frac{{a\left(t\right)\sin\left(z\right)-b\left(t\right)\cos\left(z\right)}}{\left(-x\right)^{{1/4}}}
where :math:`z = \frac{\pi }{4}+\frac{2}{3}\sqrt{-x^3}`, and :math:`a\left(t\right)` and :math:`b\left(t\right)` are expansions in the variable :math:`t = {-2}\left(\frac{5}{x}\right)^3-1`.
For :math:`{-5}\leq x\leq 0`,
.. math::
\mathrm{Ai}\left(x\right) = f\left(t\right)-xg\left(t\right)\text{,}
where :math:`f` and :math:`g` are expansions in :math:`t = {-2}\left(\frac{x}{5}\right)^3-1\text{.}`
For :math:`0 < x < 4.5`,
.. math::
\mathrm{Ai}\left(x\right) = e^{{-3x/2}}y\left(t\right)\text{,}
where :math:`y` is an expansion in :math:`t = 4x/9-1`.
For :math:`4.5\leq x < 9`,
.. math::
\mathrm{Ai}\left(x\right) = e^{{-5x/2}}u\left(t\right)\text{,}
where :math:`u` is an expansion in :math:`t = 4x/9-3`.
For :math:`x\geq 9`,
.. math::
\mathrm{Ai}\left(x\right) = \frac{{e^{{-z}}v\left(t\right)}}{x^{{1/4}}}\text{,}
where :math:`z = \frac{2}{3}\sqrt{x^3}` and :math:`v` is an expansion in :math:`t = 2\left(\frac{18}{z}\right)-1`.
For :math:`\left\lvert x\right\rvert < \text{machine precision}`, the result is set directly to :math:`\mathrm{Ai}\left(0\right)`.
This both saves time and guards against underflow in intermediate calculations.
For large negative arguments, it becomes impossible to calculate the phase of the oscillatory function with any precision and so the function must fail.
This occurs if :math:`x < -\left(\frac{3}{{2\epsilon }}\right)^{{2/3}}`, where :math:`\epsilon` is the machine precision.
For large positive arguments, where :math:`\textit{Ai}` decays in an essentially exponential manner, there is a danger of underflow so the function must fail.
.. _s17ag-py2-py-references:
**References**
NIST Digital Library of Mathematical Functions
"""
raise NotImplementedError
[docs]def airy_bi_real(x):
r"""
``airy_bi_real`` returns a value of the Airy function, :math:`\mathrm{Bi}\left(x\right)`.
.. _s17ah-py2-py-doc:
For full information please refer to the NAG Library document for s17ah
https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s17ahf.html
.. _s17ah-py2-py-parameters:
**Parameters**
**x** : float
The argument :math:`x` of the function.
**Returns**
**bi** : float
The value of the Airy function, :math:`\mathrm{Bi}\left(x\right)`.
.. _s17ah-py2-py-errors:
**Raises**
**NagValueError**
(`errno` :math:`1`)
On entry, :math:`\mathrm{x} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{x}\leq \langle\mathit{\boldsymbol{value}}\rangle`.
:math:`\mathrm{x}` is too large and positive. The function returns zero.
(`errno` :math:`2`)
On entry, :math:`\mathrm{x} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{x}\geq \langle\mathit{\boldsymbol{value}}\rangle`.
:math:`\mathrm{x}` is too large and negative. The function returns zero.
.. _s17ah-py2-py-notes:
**Notes**
``airy_bi_real`` evaluates an approximation to the Airy function :math:`\mathrm{Bi}\left(x\right)`.
It is based on a number of Chebyshev expansions.
For :math:`x < {-5}`,
.. math::
\mathrm{Bi}\left(x\right) = \frac{{a\left(t\right)\cos\left(z\right)+b\left(t\right)\sin\left(z\right)}}{\left(-x\right)^{{1/4}}}\text{,}
where :math:`z = \frac{\pi }{4}+\frac{2}{3}\sqrt{-x^3}` and :math:`a\left(t\right)` and :math:`b\left(t\right)` are expansions in the variable :math:`t = {-2}\left(\frac{5}{x}\right)^3-1`.
For :math:`{-5}\leq x\leq 0`,
.. math::
\mathrm{Bi}\left(x\right) = \sqrt{3}\left(f\left(t\right)+xg\left(t\right)\right)\text{,}
where :math:`f` and :math:`g` are expansions in :math:`t = {-2}\left(\frac{x}{5}\right)^3-1`.
For :math:`0 < x < 4.5`,
.. math::
\mathrm{Bi}\left(x\right) = e^{{11x/8}}y\left(t\right)\text{,}
where :math:`y` is an expansion in :math:`t = 4x/9-1`.
For :math:`4.5\leq x < 9`,
.. math::
\mathrm{Bi}\left(x\right) = e^{{5x/2}}v\left(t\right)\text{,}
where :math:`v` is an expansion in :math:`t = 4x/9-3`.
For :math:`x\geq 9`,
.. math::
\mathrm{Bi}\left(x\right) = \frac{{e^zu\left(t\right)}}{x^{{1/4}}}\text{,}
where :math:`z = \frac{2}{3}\sqrt{x^3}` and :math:`u` is an expansion in :math:`t = 2\left(\frac{18}{z}\right)-1`.
For :math:`\left\lvert x\right\rvert < \text{machine precision}`, the result is set directly to :math:`\mathrm{Bi}\left(0\right)`.
This both saves time and avoids possible intermediate underflows.
For large negative arguments, it becomes impossible to calculate the phase of the oscillating function with any accuracy so the function must fail.
This occurs if :math:`x < -\left(\frac{3}{{2\epsilon }}\right)^{{2/3}}`, where :math:`\epsilon` is the machine precision.
For large positive arguments, there is a danger of causing overflow since Bi grows in an essentially exponential manner, so the function must fail.
.. _s17ah-py2-py-references:
**References**
NIST Digital Library of Mathematical Functions
"""
raise NotImplementedError
[docs]def airy_ai_deriv(x):
r"""
``airy_ai_deriv`` returns a value of the derivative of the Airy function :math:`\mathrm{Ai}\left(x\right)`.
.. _s17aj-py2-py-doc:
For full information please refer to the NAG Library document for s17aj
https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s17ajf.html
.. _s17aj-py2-py-parameters:
**Parameters**
**x** : float
The argument :math:`x` of the function.
**Returns**
**aid** : float
The value of the derivative of the Airy function :math:`\mathrm{Ai}\left(x\right)`.
.. _s17aj-py2-py-errors:
**Raises**
**NagValueError**
(`errno` :math:`1`)
On entry, :math:`\mathrm{x} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{x}\leq \langle\mathit{\boldsymbol{value}}\rangle`.
:math:`\mathrm{x}` is too large and positive. The function returns zero.
(`errno` :math:`2`)
On entry, :math:`\mathrm{x} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{x}\geq \langle\mathit{\boldsymbol{value}}\rangle`.
:math:`\mathrm{x}` is too large and negative. The function returns zero.
.. _s17aj-py2-py-notes:
**Notes**
``airy_ai_deriv`` evaluates an approximation to the derivative of the Airy function :math:`\mathrm{Ai}\left(x\right)`.
It is based on a number of Chebyshev expansions.
For :math:`x < {-5}`,
.. math::
\textit{Ai}^{\prime }\left(x\right) = \sqrt[4]{{-x}}\left[a\left(t\right)\cos\left(z\right)+\frac{{b\left(t\right)}}{\zeta }\sin\left(z\right)\right]\text{,}
where :math:`z = \frac{\pi }{4}+\zeta`, :math:`\zeta = \frac{2}{3}\sqrt{-x^3}` and :math:`a\left(t\right)` and :math:`b\left(t\right)` are expansions in variable :math:`t = {-2}\left(\frac{5}{x}\right)^3-1`.
For :math:`{-5}\leq x\leq 0`,
.. math::
\textit{Ai}^{\prime }\left(x\right) = x^2f\left(t\right)-g\left(t\right)\text{,}
where :math:`f` and :math:`g` are expansions in :math:`t = {-2}\left(\frac{x}{5}\right)^3-1`.
For :math:`0 < x < 4.5`,
.. math::
\textit{Ai}^{\prime }\left(x\right) = e^{{-11x/8}}y\left(t\right)\text{,}
where :math:`y\left(t\right)` is an expansion in :math:`t = 4\left(\frac{x}{9}\right)-1`.
For :math:`4.5\leq x < 9`,
.. math::
\textit{Ai}^{\prime }\left(x\right) = e^{{-5x/2}}v\left(t\right)\text{,}
where :math:`v\left(t\right)` is an expansion in :math:`t = 4\left(\frac{x}{9}\right)-3`.
For :math:`x\geq 9`,
.. math::
\textit{Ai}^{\prime }\left(x\right) = \sqrt[4]{{x}}e^{{-z}}u\left(t\right)\text{,}
where :math:`z = \frac{2}{3}\sqrt{x^3}` and :math:`u\left(t\right)` is an expansion in :math:`t = 2\left(\frac{18}{z}\right)-1`.
For :math:`\left\lvert x\right\rvert < \text{}` the square of the machine precision, the result is set directly to :math:`\textit{Ai}^{\prime }\left(0\right)`.
This both saves time and avoids possible intermediate underflows.
For large negative arguments, it becomes impossible to calculate a result for the oscillating function with any accuracy and so the function must fail.
This occurs for :math:`x < -\left(\frac{\sqrt{\pi }}{\epsilon }\right)^{{4/7}}`, where :math:`\epsilon` is the machine precision.
For large positive arguments, where :math:`\textit{Ai}^{\prime }` decays in an essentially exponential manner, there is a danger of underflow so the function must fail.
.. _s17aj-py2-py-references:
**References**
NIST Digital Library of Mathematical Functions
"""
raise NotImplementedError
[docs]def airy_bi_deriv(x):
r"""
``airy_bi_deriv`` returns a value for the derivative of the Airy function :math:`\mathrm{Bi}\left(x\right)`.
.. _s17ak-py2-py-doc:
For full information please refer to the NAG Library document for s17ak
https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s17akf.html
.. _s17ak-py2-py-parameters:
**Parameters**
**x** : float
The argument :math:`x` of the function.
**Returns**
**bid** : float
The value of the derivative of the Airy function :math:`\mathrm{Bi}\left(x\right)`.
.. _s17ak-py2-py-errors:
**Raises**
**NagValueError**
(`errno` :math:`1`)
On entry, :math:`\mathrm{x} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{x}\leq \langle\mathit{\boldsymbol{value}}\rangle`.
:math:`\mathrm{x}` is too large and positive. The function returns zero.
(`errno` :math:`2`)
On entry, :math:`\mathrm{x} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{x}\geq \langle\mathit{\boldsymbol{value}}\rangle`.
:math:`\mathrm{x}` is too large and negative. The function returns zero.
.. _s17ak-py2-py-notes:
**Notes**
``airy_bi_deriv`` calculates an approximate value for the derivative of the Airy function :math:`\mathrm{Bi}\left(x\right)`.
It is based on a number of Chebyshev expansions.
For :math:`x < {-5}`,
.. math::
\textit{Bi}^{\prime }\left(x\right) = \sqrt[4]{{-x}}\left[-a\left(t\right)\sin\left(z\right)+\frac{{b\left(t\right)}}{\zeta }\cos\left(z\right)\right]\text{,}
where :math:`z = \frac{\pi }{4}+\zeta`, :math:`\zeta = \frac{2}{3}\sqrt{-x^3}` and :math:`a\left(t\right)` and :math:`b\left(t\right)` are expansions in the variable :math:`t = {-2}\left(\frac{5}{x}\right)^3-1`.
For :math:`{-5}\leq x\leq 0`,
.. math::
\textit{Bi}^{\prime }\left(x\right) = \sqrt{3}\left(x^2f\left(t\right)+g\left(t\right)\right)\text{,}
where :math:`f` and :math:`g` are expansions in :math:`t = {-2}\left(\frac{x}{5}\right)^3-1`.
For :math:`0 < x < 4.5`,
.. math::
\textit{Bi}^{\prime }\left(x\right) = e^{{3x/2}}y\left(t\right)\text{,}
where :math:`y\left(t\right)` is an expansion in :math:`t = 4x/9-1`.
For :math:`4.5\leq x < 9`,
.. math::
\textit{Bi}^{\prime }\left(x\right) = e^{{21x/8}}u\left(t\right)\text{,}
where :math:`u\left(t\right)` is an expansion in :math:`t = 4x/9-3`.
For :math:`x\geq 9`,
.. math::
\textit{Bi}^{\prime }\left(x\right) = \sqrt[4]{x}e^zv\left(t\right)\text{,}
where :math:`z = \frac{2}{3}\sqrt{x^3}` and :math:`v\left(t\right)` is an expansion in :math:`t = 2\left(\frac{18}{z}\right)-1`.
For :math:`\left\lvert x\right\rvert < \text{}` the square of the machine precision, the result is set directly to :math:`\textit{Bi}^{\prime }\left(0\right)`.
This saves time and avoids possible underflows in calculation.
For large negative arguments, it becomes impossible to calculate a result for the oscillating function with any accuracy so the function must fail.
This occurs for :math:`x < -\left(\frac{\sqrt{\pi }}{\epsilon }\right)^{{4/7}}`, where :math:`\epsilon` is the machine precision.
For large positive arguments, where :math:`\textit{Bi}^{\prime }` grows in an essentially exponential manner, there is a danger of overflow so the function must fail.
.. _s17ak-py2-py-references:
**References**
NIST Digital Library of Mathematical Functions
"""
raise NotImplementedError
[docs]def bessel_zeros(a, n, mode, rel=sqrt(machine.precision())):
r"""
``bessel_zeros`` determines the leading :math:`\mathrm{n}` zeros of one of the Bessel functions :math:`J_{\alpha }\left(x\right)`, :math:`Y_{\alpha }\left(x\right)`, :math:`J_{\alpha }^{\prime }\left(x\right)` or :math:`Y_{\alpha }^{\prime }\left(x\right)` for real :math:`x` and non-negative :math:`\alpha`.
.. _s17al-py2-py-doc:
For full information please refer to the NAG Library document for s17al
https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s17alf.html
.. _s17al-py2-py-parameters:
**Parameters**
**a** : float
The order :math:`\alpha` of the function.
**n** : int
The number :math:`N` of zeros required.
**mode** : int
Specifies the form of the function whose zeros are required.
:math:`\mathrm{mode} = 1`
The zeros of :math:`J_{\alpha }\left(x\right)` are required.
:math:`\mathrm{mode} = 2`
The zeros of :math:`Y_{\alpha }\left(x\right)` are required;
:math:`\mathrm{mode} = 3`
The zeros of :math:`J_{\alpha }^{\prime }\left(x\right)` are required;
:math:`\mathrm{mode} = 4`
The zeros of :math:`Y_{\alpha }^{\prime }\left(x\right)` are required.
**rel** : float, optional
The relative accuracy to which the zeros are required.
**Returns**
**x** : float, ndarray, shape :math:`\left(\mathrm{n}\right)`
The :math:`N` required zeros of the function specified by :math:`\mathrm{mode}`.
.. _s17al-py2-py-errors:
**Raises**
**NagValueError**
(`errno` :math:`1`)
On entry, :math:`\mathrm{rel} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{rel} > 0.0`.
(`errno` :math:`1`)
On entry, :math:`\mathrm{mode} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{mode}\leq 4`.
(`errno` :math:`1`)
On entry, :math:`\mathrm{mode} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{mode}\geq 1`.
(`errno` :math:`1`)
On entry, :math:`\mathrm{a} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{a}\leq 100000.0`.
(`errno` :math:`1`)
On entry, :math:`\mathrm{a} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{a}\geq 0.0`.
(`errno` :math:`1`)
On entry, :math:`\mathrm{n} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{n}\geq 1`.
.. _s17al-py2-py-notes:
**Notes**
``bessel_zeros`` attempts to find the leading :math:`N` zeros of one of the Bessel functions :math:`J_{\alpha }\left(x\right)`, :math:`Y_{\alpha }\left(x\right)`, :math:`J_{\alpha }^{\prime }\left(x\right)` or :math:`Y_{\alpha }^{\prime }\left(x\right)`, where :math:`x` is real.
When :math:`\alpha` is real, these functions each have an infinite number of real zeros, all of which are simple with the possible exception of :math:`x = 0`.
If :math:`\alpha \geq 0`, the :math:`\textit{n}`\ th positive zero is denoted by :math:`j_{{\alpha,\textit{n}}},j_{{\alpha,\textit{n}}}^{\prime },y_{{\alpha,\textit{n}}}` and :math:`y_{{\alpha,\textit{n}}}^{\prime }`, respectively, for :math:`\textit{n} = 1,2,\ldots,N`, except that :math:`x = 0` is counted as the first zero of :math:`J_{\alpha }^{\prime }\left(x\right)` when :math:`\alpha = 0`.
Since :math:`J_0^{\prime }\left(x\right) = -J_1\left(x\right)`, it, therefore, follows that :math:`j_{{0,1}}^{\prime } = 0` and :math:`j_{{0,n}}^{\prime } = -j_{{1,n-1}}` for :math:`n = 2,3,\ldots,N-1`.
Further details can be found in Section 9.5 of Abramowitz and Stegun (1972).
``bessel_zeros`` is based on Algol 60 procedures given by Temme (1979).
Initial approximations to the zeros are computed from asymptotic expansions.
These are then improved by higher-order Newton iteration making use of the differential equation for the Bessel functions.
.. _s17al-py2-py-references:
**References**
Abramowitz, M and Stegun, I A, 1972, `Handbook of Mathematical Functions`, (3rd Edition), Dover Publications
Temme, N M, 1976, `On the numerical evaluation of the ordinary Bessel function of the second kind`, J. Comput. Phys. (21), 343--350
Temme, N M, 1979, `An algorithm with Algol 60 program for the computation of the zeros of ordinary Bessel functions and those of their derivatives`, J. Comput. Phys. (32), 270--279
"""
raise NotImplementedError
[docs]def bessel_y0_real_vector(x):
r"""
``bessel_y0_real_vector`` returns an array of values of the Bessel function :math:`Y_0\left(x\right)`.
.. _s17aq-py2-py-doc:
For full information please refer to the NAG Library document for s17aq
https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s17aqf.html
.. _s17aq-py2-py-parameters:
**Parameters**
**x** : float, array-like, shape :math:`\left(n\right)`
The argument :math:`x_{\textit{i}}` of the function, for :math:`\textit{i} = 1,2,\ldots,n`.
**Returns**
**f** : float, ndarray, shape :math:`\left(n\right)`
:math:`Y_0\left(x_i\right)`, the function values.
**ivalid** : int, ndarray, shape :math:`\left(n\right)`
:math:`\mathrm{ivalid}[\textit{i}-1]` contains the error code for :math:`x_{\textit{i}}`, for :math:`\textit{i} = 1,2,\ldots,n`.
:math:`\mathrm{ivalid}[i-1] = 0`
No error.
:math:`\mathrm{ivalid}[i-1] = 1`
On entry, :math:`x_i` is too large. :math:`\mathrm{f}[\textit{i}-1]` contains the amplitude of the :math:`Y_0` oscillation, :math:`\sqrt{\frac{2}{{\pi x_i}}}`.
:math:`\mathrm{ivalid}[i-1] = 2`
On entry, :math:`x_i\leq 0.0`, :math:`Y_0` is undefined. :math:`\mathrm{f}[\textit{i}-1]` contains :math:`0.0`.
.. _s17aq-py2-py-errors:
**Raises**
**NagValueError**
(`errno` :math:`2`)
On entry, :math:`n = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`n\geq 0`.
**Warns**
**NagAlgorithmicWarning**
(`errno` :math:`1`)
On entry, at least one value of :math:`\mathrm{x}` was invalid.
Check :math:`\mathrm{ivalid}` for more information.
.. _s17aq-py2-py-notes:
**Notes**
``bessel_y0_real_vector`` evaluates an approximation to the Bessel function of the second kind :math:`Y_0\left(x_i\right)` for an array of arguments :math:`x_{\textit{i}}`, for :math:`\textit{i} = 1,2,\ldots,n`.
**Note:** :math:`Y_0\left(x\right)` is undefined for :math:`x\leq 0` and the function will fail for such arguments.
The function is based on four Chebyshev expansions:
For :math:`0 < x\leq 8`,
.. math::
Y_0\left(x\right) = \frac{2}{\pi }\mathrm{ln}\left(x\right){\sum^\prime}_{{r = 0}}a_rT_r\left(t\right)+{\sum^\prime}_{{r = 0}}b_rT_r\left(t\right)\text{, with }t = 2\left(\frac{x}{8}\right)^2-1\text{.}
For :math:`x > 8`,
.. math::
Y_0\left(x\right) = \sqrt{\frac{2}{{\pi x}}}\left\{P_0\left(x\right)\sin\left(x-\frac{\pi }{4}\right)+Q_0\left(x\right)\cos\left(x-\frac{\pi }{4}\right)\right\}
where :math:`P_0\left(x\right) = {\sum^\prime}_{{r = 0}}c_rT_r\left(t\right)`,
and :math:`Q_0\left(x\right) = \frac{8}{x}{\sum^\prime}_{{r = 0}}d_rT_r\left(t\right),\text{with }t = 2\left(\frac{8}{x}\right)^2-1\text{.}`
For :math:`x` near zero, :math:`Y_0\left(x\right)\simeq \frac{2}{\pi }\left(\mathrm{ln}\left(\frac{x}{2}\right)+\gamma \right)`, where :math:`\gamma` denotes Euler's constant.
This approximation is used when :math:`x` is sufficiently small for the result to be correct to machine precision.
For very large :math:`x`, it becomes impossible to provide results with any reasonable accuracy (see `Accuracy <https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s17aqf.html#accuracy>`__), hence the function fails.
Such arguments contain insufficient information to determine the phase of oscillation of :math:`Y_0\left(x\right)`; only the amplitude, :math:`\sqrt{\frac{2}{{\pi n}}}`, can be determined and this is returned on failure.
The range for which this occurs is roughly related to machine precision; the function will fail if :math:`x≳1/\text{machine precision}`.
.. _s17aq-py2-py-references:
**References**
NIST Digital Library of Mathematical Functions
Clenshaw, C W, 1962, `Chebyshev Series for Mathematical Functions`, Mathematical tables, HMSO
"""
raise NotImplementedError
[docs]def bessel_y1_real_vector(x):
r"""
``bessel_y1_real_vector`` returns an array of values of the Bessel function :math:`Y_1\left(x\right)`.
.. _s17ar-py2-py-doc:
For full information please refer to the NAG Library document for s17ar
https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s17arf.html
.. _s17ar-py2-py-parameters:
**Parameters**
**x** : float, array-like, shape :math:`\left(n\right)`
The argument :math:`x_{\textit{i}}` of the function, for :math:`\textit{i} = 1,2,\ldots,n`.
**Returns**
**f** : float, ndarray, shape :math:`\left(n\right)`
:math:`Y_1\left(x_i\right)`, the function values.
**ivalid** : int, ndarray, shape :math:`\left(n\right)`
:math:`\mathrm{ivalid}[\textit{i}-1]` contains the error code for :math:`x_{\textit{i}}`, for :math:`\textit{i} = 1,2,\ldots,n`.
:math:`\mathrm{ivalid}[i-1] = 0`
No error.
:math:`\mathrm{ivalid}[i-1] = 1`
On entry, :math:`x_i` is too large. :math:`\mathrm{f}[\textit{i}-1]` contains the amplitude of the :math:`Y_1` oscillation, :math:`\sqrt{\frac{2}{{\pi x_i}}}`.
:math:`\mathrm{ivalid}[i-1] = 2`
On entry, :math:`x_i\leq 0.0`, :math:`Y_1` is undefined. :math:`\mathrm{f}[\textit{i}-1]` contains :math:`0.0`.
:math:`\mathrm{ivalid}[i-1] = 3`
:math:`x_i` is too close to zero, there is a danger of overflow. On failure, :math:`\mathrm{f}[\textit{i}-1]` contains the value of :math:`Y_1\left(x\right)` at the smallest valid argument.
.. _s17ar-py2-py-errors:
**Raises**
**NagValueError**
(`errno` :math:`2`)
On entry, :math:`n = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`n\geq 0`.
**Warns**
**NagAlgorithmicWarning**
(`errno` :math:`1`)
On entry, at least one value of :math:`\mathrm{x}` was invalid.
Check :math:`\mathrm{ivalid}` for more information.
.. _s17ar-py2-py-notes:
**Notes**
``bessel_y1_real_vector`` evaluates an approximation to the Bessel function of the second kind :math:`Y_1\left(x_i\right)` for an array of arguments :math:`x_{\textit{i}}`, for :math:`\textit{i} = 1,2,\ldots,n`.
**Note:** :math:`Y_1\left(x\right)` is undefined for :math:`x\leq 0` and the function will fail for such arguments.
The function is based on four Chebyshev expansions:
For :math:`0 < x\leq 8`,
.. math::
Y_1\left(x\right) = \frac{2}{\pi }\mathrm{ln}\left(x\right)\frac{x}{8}{\sum^\prime}_{{r = 0}}a_rT_r\left(t\right)-\frac{2}{{\pi x}}+\frac{x}{8}{\sum^\prime}_{{r = 0}}b_rT_r\left(t\right)\text{, with }t = 2\left(\frac{x}{8}\right)^2-1\text{.}
For :math:`x > 8`,
.. math::
Y_1\left(x\right) = \sqrt{\frac{2}{{\pi x}}}\left\{P_1\left(x\right)\sin\left(x-3\frac{\pi }{4}\right)+Q_1\left(x\right)\cos\left(x-3\frac{\pi }{4}\right)\right\}
where :math:`P_1\left(x\right) = {\sum^\prime}_{{r = 0}}c_rT_r\left(t\right)`,
and :math:`Q_1\left(x\right) = \frac{8}{x}{\sum^\prime}_{{r = 0}}d_rT_r\left(t\right)`, with :math:`t = 2\left(\frac{8}{x}\right)^2-1`.
For :math:`x` near zero, :math:`Y_1\left(x\right)\simeq -\frac{2}{{\pi x}}`.
This approximation is used when :math:`x` is sufficiently small for the result to be correct to machine precision.
For extremely small :math:`x`, there is a danger of overflow in calculating :math:`{-\frac{2}{{\pi x}}}` and for such arguments the function will fail.
For very large :math:`x`, it becomes impossible to provide results with any reasonable accuracy (see `Accuracy <https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s17arf.html#accuracy>`__), hence the function fails.
Such arguments contain insufficient information to determine the phase of oscillation of :math:`Y_1\left(x\right)`; only the amplitude, :math:`\sqrt{\frac{2}{{\pi x}}}`, can be determined and this is returned on failure.
The range for which this occurs is roughly related to machine precision; the function will fail if :math:`x≳1/\text{machine precision}`.
.. _s17ar-py2-py-references:
**References**
NIST Digital Library of Mathematical Functions
Clenshaw, C W, 1962, `Chebyshev Series for Mathematical Functions`, Mathematical tables, HMSO
"""
raise NotImplementedError
[docs]def bessel_j0_real_vector(x):
r"""
``bessel_j0_real_vector`` returns an array of values of the Bessel function :math:`J_0\left(x\right)`.
.. _s17as-py2-py-doc:
For full information please refer to the NAG Library document for s17as
https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s17asf.html
.. _s17as-py2-py-parameters:
**Parameters**
**x** : float, array-like, shape :math:`\left(n\right)`
The argument :math:`x_{\textit{i}}` of the function, for :math:`\textit{i} = 1,2,\ldots,n`.
**Returns**
**f** : float, ndarray, shape :math:`\left(n\right)`
:math:`J_0\left(x_i\right)`, the function values.
**ivalid** : int, ndarray, shape :math:`\left(n\right)`
:math:`\mathrm{ivalid}[\textit{i}-1]` contains the error code for :math:`x_{\textit{i}}`, for :math:`\textit{i} = 1,2,\ldots,n`.
:math:`\mathrm{ivalid}[i-1] = 0`
No error.
:math:`\mathrm{ivalid}[i-1] = 1`
On entry, :math:`x_i` is too large. :math:`\mathrm{f}[\textit{i}-1]` contains the amplitude of the :math:`J_0` oscillation, :math:`\sqrt{\frac{2}{{\pi \left\lvert x_i\right\rvert }}}`.
.. _s17as-py2-py-errors:
**Raises**
**NagValueError**
(`errno` :math:`2`)
On entry, :math:`n = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`n\geq 0`.
**Warns**
**NagAlgorithmicWarning**
(`errno` :math:`1`)
On entry, at least one value of :math:`\mathrm{x}` was invalid.
Check :math:`\mathrm{ivalid}` for more information.
.. _s17as-py2-py-notes:
**Notes**
``bessel_j0_real_vector`` evaluates an approximation to the Bessel function of the first kind :math:`J_0\left(x_i\right)` for an array of arguments :math:`x_{\textit{i}}`, for :math:`\textit{i} = 1,2,\ldots,n`.
**Note:** :math:`J_0\left(-x\right) = J_0\left(x\right)`, so the approximation need only consider :math:`x\geq 0`.
The function is based on three Chebyshev expansions:
For :math:`0 < x\leq 8`,
.. math::
J_0\left(x\right) = {\sum^\prime}_{{r = 0}}a_rT_r\left(t\right)\text{, with }t = 2\left(\frac{x}{8}\right)^2-1\text{.}
For :math:`x > 8`,
.. math::
J_0\left(x\right) = \sqrt{\frac{2}{{\pi x}}}\left\{P_0\left(x\right)\cos\left(x-\frac{\pi }{4}\right)-Q_0\left(x\right)\sin\left(x-\frac{\pi }{4}\right)\right\}\text{,}
where :math:`P_0\left(x\right) = {\sum^\prime}_{{r = 0}}b_rT_r\left(t\right)`,
and :math:`Q_0\left(x\right) = \frac{8}{x}{\sum^\prime}_{{r = 0}}c_rT_r\left(t\right)`,
with :math:`t = 2\left(\frac{8}{x}\right)^2-1`.
For :math:`x` near zero, :math:`J_0\left(x\right)\simeq 1`.
This approximation is used when :math:`x` is sufficiently small for the result to be correct to machine precision.
For very large :math:`x`, it becomes impossible to provide results with any reasonable accuracy (see `Accuracy <https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s17asf.html#accuracy>`__), hence the function fails.
Such arguments contain insufficient information to determine the phase of oscillation of :math:`J_0\left(x\right)`; only the amplitude, :math:`\sqrt{\frac{2}{{\pi \left\lvert x\right\rvert }}}`, can be determined and this is returned on failure.
The range for which this occurs is roughly related to machine precision; the function will fail if :math:`\left\lvert x\right\rvert ≳1/\text{machine precision}`.
.. _s17as-py2-py-references:
**References**
NIST Digital Library of Mathematical Functions
Clenshaw, C W, 1962, `Chebyshev Series for Mathematical Functions`, Mathematical tables, HMSO
"""
raise NotImplementedError
[docs]def bessel_j1_real_vector(x):
r"""
``bessel_j1_real_vector`` returns an array of values of the Bessel function :math:`J_1\left(x\right)`.
.. _s17at-py2-py-doc:
For full information please refer to the NAG Library document for s17at
https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s17atf.html
.. _s17at-py2-py-parameters:
**Parameters**
**x** : float, array-like, shape :math:`\left(n\right)`
The argument :math:`x_{\textit{i}}` of the function, for :math:`\textit{i} = 1,2,\ldots,n`.
**Returns**
**f** : float, ndarray, shape :math:`\left(n\right)`
:math:`J_1\left(x_i\right)`, the function values.
**ivalid** : int, ndarray, shape :math:`\left(n\right)`
:math:`\mathrm{ivalid}[\textit{i}-1]` contains the error code for :math:`x_{\textit{i}}`, for :math:`\textit{i} = 1,2,\ldots,n`.
:math:`\mathrm{ivalid}[i-1] = 0`
No error.
:math:`\mathrm{ivalid}[i-1] = 1`
On entry, :math:`x_i` is too large. :math:`\mathrm{f}[\textit{i}-1]` contains the amplitude of the :math:`J_1` oscillation, :math:`\sqrt{\frac{2}{{\pi \left\lvert x_i\right\rvert }}}`.
.. _s17at-py2-py-errors:
**Raises**
**NagValueError**
(`errno` :math:`2`)
On entry, :math:`n = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`n\geq 0`.
**Warns**
**NagAlgorithmicWarning**
(`errno` :math:`1`)
On entry, at least one value of :math:`\mathrm{x}` was invalid.
Check :math:`\mathrm{ivalid}` for more information.
.. _s17at-py2-py-notes:
**Notes**
``bessel_j1_real_vector`` evaluates an approximation to the Bessel function of the first kind :math:`J_1\left(x_i\right)` for an array of arguments :math:`x_{\textit{i}}`, for :math:`\textit{i} = 1,2,\ldots,n`.
**Note:** :math:`J_1\left(-x\right) = -J_1\left(x\right)`, so the approximation need only consider :math:`x\geq 0`.
The function is based on three Chebyshev expansions:
For :math:`0 < x\leq 8`,
.. math::
J_1\left(x\right) = \frac{x}{8}{\sum^\prime}_{{r = 0}}a_rT_r\left(t\right)\text{, with }t = 2\left(\frac{x}{8}\right)^2-1\text{.}
For :math:`x > 8`,
.. math::
J_1\left(x\right) = \sqrt{\frac{2}{{\pi x}}}\left\{P_1\left(x\right)\cos\left(x-\frac{{3\pi }}{4}\right)-Q_1\left(x\right)\sin\left(x-\frac{{3\pi }}{4}\right)\right\}
where :math:`P_1\left(x\right) = {\sum^\prime}_{{r = 0}}b_rT_r\left(t\right)`,
and :math:`Q_1\left(x\right) = \frac{8}{x}{\sum^\prime}_{{r = 0}}c_rT_r\left(t\right)`,
with :math:`t = 2\left(\frac{8}{x}\right)^2-1`.
For :math:`x` near zero, :math:`J_1\left(x\right)\simeq \frac{x}{2}`.
This approximation is used when :math:`x` is sufficiently small for the result to be correct to machine precision.
For very large :math:`x`, it becomes impossible to provide results with any reasonable accuracy (see `Accuracy <https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s17atf.html#accuracy>`__), hence the function fails.
Such arguments contain insufficient information to determine the phase of oscillation of :math:`J_1\left(x\right)`; only the amplitude, :math:`\sqrt{\frac{2}{{\pi \left\lvert x\right\rvert }}}`, can be determined and this is returned on failure.
The range for which this occurs is roughly related to machine precision; the function will fail if :math:`\left\lvert x\right\rvert ≳1/\text{machine precision}`.
.. _s17at-py2-py-references:
**References**
NIST Digital Library of Mathematical Functions
Clenshaw, C W, 1962, `Chebyshev Series for Mathematical Functions`, Mathematical tables, HMSO
"""
raise NotImplementedError
[docs]def airy_ai_real_vector(x):
r"""
``airy_ai_real_vector`` returns an array of values for the Airy function, :math:`\mathrm{Ai}\left(x\right)`.
.. _s17au-py2-py-doc:
For full information please refer to the NAG Library document for s17au
https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s17auf.html
.. _s17au-py2-py-parameters:
**Parameters**
**x** : float, array-like, shape :math:`\left(n\right)`
The argument :math:`x_{\textit{i}}` of the function, for :math:`\textit{i} = 1,2,\ldots,n`.
**Returns**
**f** : float, ndarray, shape :math:`\left(n\right)`
:math:`\mathrm{Ai}\left(x_i\right)`, the function values.
**ivalid** : int, ndarray, shape :math:`\left(n\right)`
:math:`\mathrm{ivalid}[\textit{i}-1]` contains the error code for :math:`x_{\textit{i}}`, for :math:`\textit{i} = 1,2,\ldots,n`.
:math:`\mathrm{ivalid}[i-1] = 0`
No error.
:math:`\mathrm{ivalid}[i-1] = 1`
:math:`x_i` is too large and positive. :math:`\mathrm{f}[\textit{i}-1]` contains zero. The threshold value is the same as for :math:`\mathrm{errno}` = 1 in :meth:`airy_ai_real`.
:math:`\mathrm{ivalid}[i-1] = 2`
:math:`x_i` is too large and negative. :math:`\mathrm{f}[\textit{i}-1]` contains zero. The threshold value is the same as for :math:`\mathrm{errno}` = 2 in :meth:`airy_ai_real`.
.. _s17au-py2-py-errors:
**Raises**
**NagValueError**
(`errno` :math:`2`)
On entry, :math:`n = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`n\geq 0`.
**Warns**
**NagAlgorithmicWarning**
(`errno` :math:`1`)
On entry, at least one value of :math:`\mathrm{x}` was invalid.
Check :math:`\mathrm{ivalid}` for more information.
.. _s17au-py2-py-notes:
**Notes**
``airy_ai_real_vector`` evaluates an approximation to the Airy function, :math:`\mathrm{Ai}\left(x_i\right)` for an array of arguments :math:`x_{\textit{i}}`, for :math:`\textit{i} = 1,2,\ldots,n`.
It is based on a number of Chebyshev expansions:
For :math:`x < {-5}`,
.. math::
\mathrm{Ai}\left(x\right) = \frac{{a\left(t\right)\sin\left(z\right)-b\left(t\right)\cos\left(z\right)}}{\left(-x\right)^{{1/4}}}
where :math:`z = \frac{\pi }{4}+\frac{2}{3}\sqrt{-x^3}`, and :math:`a\left(t\right)` and :math:`b\left(t\right)` are expansions in the variable :math:`t = {-2}\left(\frac{5}{x}\right)^3-1`.
For :math:`{-5}\leq x\leq 0`,
.. math::
\mathrm{Ai}\left(x\right) = f\left(t\right)-xg\left(t\right)\text{,}
where :math:`f` and :math:`g` are expansions in :math:`t = {-2}\left(\frac{x}{5}\right)^3-1\text{.}`
For :math:`0 < x < 4.5`,
.. math::
\mathrm{Ai}\left(x\right) = e^{{-3x/2}}y\left(t\right)\text{,}
where :math:`y` is an expansion in :math:`t = 4x/9-1`.
For :math:`4.5\leq x < 9`,
.. math::
\mathrm{Ai}\left(x\right) = e^{{-5x/2}}u\left(t\right)\text{,}
where :math:`u` is an expansion in :math:`t = 4x/9-3`.
For :math:`x\geq 9`,
.. math::
\mathrm{Ai}\left(x\right) = \frac{{e^{{-z}}v\left(t\right)}}{x^{{1/4}}}\text{,}
where :math:`z = \frac{2}{3}\sqrt{x^3}` and :math:`v` is an expansion in :math:`t = 2\left(\frac{18}{z}\right)-1`.
For :math:`\left\lvert x\right\rvert < \text{machine precision}`, the result is set directly to :math:`\mathrm{Ai}\left(0\right)`.
This both saves time and guards against underflow in intermediate calculations.
For large negative arguments, it becomes impossible to calculate the phase of the oscillatory function with any precision and so the function must fail.
This occurs if :math:`x < -\left(\frac{3}{{2\epsilon }}\right)^{{2/3}}`, where :math:`\epsilon` is the machine precision.
For large positive arguments, where :math:`\textit{Ai}` decays in an essentially exponential manner, there is a danger of underflow so the function must fail.
.. _s17au-py2-py-references:
**References**
NIST Digital Library of Mathematical Functions
"""
raise NotImplementedError
[docs]def airy_bi_real_vector(x):
r"""
``airy_bi_real_vector`` returns an array of values of the Airy function, :math:`\mathrm{Bi}\left(x\right)`.
.. _s17av-py2-py-doc:
For full information please refer to the NAG Library document for s17av
https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s17avf.html
.. _s17av-py2-py-parameters:
**Parameters**
**x** : float, array-like, shape :math:`\left(n\right)`
The argument :math:`x_{\textit{i}}` of the function, for :math:`\textit{i} = 1,2,\ldots,n`.
**Returns**
**f** : float, ndarray, shape :math:`\left(n\right)`
:math:`\mathrm{Bi}\left(x_i\right)`, the function values.
**ivalid** : int, ndarray, shape :math:`\left(n\right)`
:math:`\mathrm{ivalid}[\textit{i}-1]` contains the error code for :math:`x_{\textit{i}}`, for :math:`\textit{i} = 1,2,\ldots,n`.
:math:`\mathrm{ivalid}[i-1] = 0`
No error.
:math:`\mathrm{ivalid}[i-1] = 1`
:math:`x_i` is too large and positive. :math:`\mathrm{f}[\textit{i}-1]` contains zero. The threshold value is the same as for :math:`\mathrm{errno}` = 1 in :meth:`airy_bi_real`.
:math:`\mathrm{ivalid}[i-1] = 2`
:math:`x_i` is too large and negative. :math:`\mathrm{f}[\textit{i}-1]` contains zero. The threshold value is the same as for :math:`\mathrm{errno}` = 2 in :meth:`airy_bi_real`.
.. _s17av-py2-py-errors:
**Raises**
**NagValueError**
(`errno` :math:`2`)
On entry, :math:`n = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`n\geq 0`.
**Warns**
**NagAlgorithmicWarning**
(`errno` :math:`1`)
On entry, at least one value of :math:`\mathrm{x}` was invalid.
Check :math:`\mathrm{ivalid}` for more information.
.. _s17av-py2-py-notes:
**Notes**
``airy_bi_real_vector`` evaluates an approximation to the Airy function :math:`\mathrm{Bi}\left(x_i\right)` for an array of arguments :math:`x_{\textit{i}}`, for :math:`\textit{i} = 1,2,\ldots,n`.
It is based on a number of Chebyshev expansions.
For :math:`x < {-5}`,
.. math::
\mathrm{Bi}\left(x\right) = \frac{{a\left(t\right)\cos\left(z\right)+b\left(t\right)\sin\left(z\right)}}{\left(-x\right)^{{1/4}}}\text{,}
where :math:`z = \frac{\pi }{4}+\frac{2}{3}\sqrt{-x^3}` and :math:`a\left(t\right)` and :math:`b\left(t\right)` are expansions in the variable :math:`t = {-2}\left(\frac{5}{x}\right)^3-1`.
For :math:`{-5}\leq x\leq 0`,
.. math::
\mathrm{Bi}\left(x\right) = \sqrt{3}\left(f\left(t\right)+xg\left(t\right)\right)\text{,}
where :math:`f` and :math:`g` are expansions in :math:`t = {-2}\left(\frac{x}{5}\right)^3-1`.
For :math:`0 < x < 4.5`,
.. math::
\mathrm{Bi}\left(x\right) = e^{{11x/8}}y\left(t\right)\text{,}
where :math:`y` is an expansion in :math:`t = 4x/9-1`.
For :math:`4.5\leq x < 9`,
.. math::
\mathrm{Bi}\left(x\right) = e^{{5x/2}}v\left(t\right)\text{,}
where :math:`v` is an expansion in :math:`t = 4x/9-3`.
For :math:`x\geq 9`,
.. math::
\mathrm{Bi}\left(x\right) = \frac{{e^zu\left(t\right)}}{x^{{1/4}}}\text{,}
where :math:`z = \frac{2}{3}\sqrt{x^3}` and :math:`u` is an expansion in :math:`t = 2\left(\frac{18}{z}\right)-1`.
For :math:`\left\lvert x\right\rvert < \text{machine precision}`, the result is set directly to :math:`\mathrm{Bi}\left(0\right)`.
This both saves time and avoids possible intermediate underflows.
For large negative arguments, it becomes impossible to calculate the phase of the oscillating function with any accuracy so the function must fail.
This occurs if :math:`x < -\left(\frac{3}{{2\epsilon }}\right)^{{2/3}}`, where :math:`\epsilon` is the machine precision.
For large positive arguments, there is a danger of causing overflow since Bi grows in an essentially exponential manner, so the function must fail.
.. _s17av-py2-py-references:
**References**
NIST Digital Library of Mathematical Functions
"""
raise NotImplementedError
[docs]def airy_ai_deriv_vector(x):
r"""
``airy_ai_deriv_vector`` returns an array of values of the derivative of the Airy function :math:`\mathrm{Ai}\left(x\right)`.
.. _s17aw-py2-py-doc:
For full information please refer to the NAG Library document for s17aw
https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s17awf.html
.. _s17aw-py2-py-parameters:
**Parameters**
**x** : float, array-like, shape :math:`\left(n\right)`
The argument :math:`x_{\textit{i}}` of the function, for :math:`\textit{i} = 1,2,\ldots,n`.
**Returns**
**f** : float, ndarray, shape :math:`\left(n\right)`
:math:`\textit{Ai}^{\prime }\left(x_i\right)`, the function values.
**ivalid** : int, ndarray, shape :math:`\left(n\right)`
:math:`\mathrm{ivalid}[\textit{i}-1]` contains the error code for :math:`x_{\textit{i}}`, for :math:`\textit{i} = 1,2,\ldots,n`.
:math:`\mathrm{ivalid}[i-1] = 0`
No error.
:math:`\mathrm{ivalid}[i-1] = 1`
:math:`x_i` is too large and positive. :math:`\mathrm{f}[\textit{i}-1]` contains zero. The threshold value is the same as for :math:`\mathrm{errno}` = 1 in :meth:`airy_ai_deriv`.
:math:`\mathrm{ivalid}[i-1] = 2`
:math:`x_i` is too large and negative. :math:`\mathrm{f}[\textit{i}-1]` contains zero. The threshold value is the same as for :math:`\mathrm{errno}` = 2 in :meth:`airy_ai_deriv`.
.. _s17aw-py2-py-errors:
**Raises**
**NagValueError**
(`errno` :math:`2`)
On entry, :math:`n = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`n\geq 0`.
**Warns**
**NagAlgorithmicWarning**
(`errno` :math:`1`)
On entry, at least one value of :math:`\mathrm{x}` was invalid.
Check :math:`\mathrm{ivalid}` for more information.
.. _s17aw-py2-py-notes:
**Notes**
``airy_ai_deriv_vector`` evaluates an approximation to the derivative of the Airy function :math:`\mathrm{Ai}\left(x_i\right)` for an array of arguments :math:`x_{\textit{i}}`, for :math:`\textit{i} = 1,2,\ldots,n`.
It is based on a number of Chebyshev expansions.
For :math:`x < {-5}`,
.. math::
\textit{Ai}^{\prime }\left(x\right) = \sqrt[4]{{-x}}\left[a\left(t\right)\cos\left(z\right)+\frac{{b\left(t\right)}}{\zeta }\sin\left(z\right)\right]\text{,}
where :math:`z = \frac{\pi }{4}+\zeta`, :math:`\zeta = \frac{2}{3}\sqrt{-x^3}` and :math:`a\left(t\right)` and :math:`b\left(t\right)` are expansions in variable :math:`t = {-2}\left(\frac{5}{x}\right)^3-1`.
For :math:`{-5}\leq x\leq 0`,
.. math::
\textit{Ai}^{\prime }\left(x\right) = x^2f\left(t\right)-g\left(t\right)\text{,}
where :math:`f` and :math:`g` are expansions in :math:`t = {-2}\left(\frac{x}{5}\right)^3-1`.
For :math:`0 < x < 4.5`,
.. math::
\textit{Ai}^{\prime }\left(x\right) = e^{{-11x/8}}y\left(t\right)\text{,}
where :math:`y\left(t\right)` is an expansion in :math:`t = 4\left(\frac{x}{9}\right)-1`.
For :math:`4.5\leq x < 9`,
.. math::
\textit{Ai}^{\prime }\left(x\right) = e^{{-5x/2}}v\left(t\right)\text{,}
where :math:`v\left(t\right)` is an expansion in :math:`t = 4\left(\frac{x}{9}\right)-3`.
For :math:`x\geq 9`,
.. math::
\textit{Ai}^{\prime }\left(x\right) = \sqrt[4]{{x}}e^{{-z}}u\left(t\right)\text{,}
where :math:`z = \frac{2}{3}\sqrt{x^3}` and :math:`u\left(t\right)` is an expansion in :math:`t = 2\left(\frac{18}{z}\right)-1`.
For :math:`\left\lvert x\right\rvert < \text{}` the square of the machine precision, the result is set directly to :math:`\textit{Ai}^{\prime }\left(0\right)`.
This both saves time and avoids possible intermediate underflows.
For large negative arguments, it becomes impossible to calculate a result for the oscillating function with any accuracy and so the function must fail.
This occurs for :math:`x < -\left(\frac{\sqrt{\pi }}{\epsilon }\right)^{{4/7}}`, where :math:`\epsilon` is the machine precision.
For large positive arguments, where :math:`\textit{Ai}^{\prime }` decays in an essentially exponential manner, there is a danger of underflow so the function must fail.
.. _s17aw-py2-py-references:
**References**
NIST Digital Library of Mathematical Functions
"""
raise NotImplementedError
[docs]def airy_bi_deriv_vector(x):
r"""
``airy_bi_deriv_vector`` returns an array of values for the derivative of the Airy function :math:`\mathrm{Bi}\left(x\right)`.
.. _s17ax-py2-py-doc:
For full information please refer to the NAG Library document for s17ax
https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s17axf.html
.. _s17ax-py2-py-parameters:
**Parameters**
**x** : float, array-like, shape :math:`\left(n\right)`
The argument :math:`x_{\textit{i}}` of the function, for :math:`\textit{i} = 1,2,\ldots,n`.
**Returns**
**f** : float, ndarray, shape :math:`\left(n\right)`
:math:`\textit{Bi}^{\prime }\left(x_i\right)`, the function values.
**ivalid** : int, ndarray, shape :math:`\left(n\right)`
:math:`\mathrm{ivalid}[\textit{i}-1]` contains the error code for :math:`x_{\textit{i}}`, for :math:`\textit{i} = 1,2,\ldots,n`.
:math:`\mathrm{ivalid}[i-1] = 0`
No error.
:math:`\mathrm{ivalid}[i-1] = 1`
:math:`x_i` is too large and positive. :math:`\mathrm{f}[\textit{i}-1]` contains zero. The threshold value is the same as for :math:`\mathrm{errno}` = 1 in :meth:`airy_bi_deriv`.
:math:`\mathrm{ivalid}[i-1] = 2`
:math:`x_i` is too large and negative. :math:`\mathrm{f}[\textit{i}-1]` contains zero. The threshold value is the same as for :math:`\mathrm{errno}` = 2 in :meth:`airy_bi_deriv`.
.. _s17ax-py2-py-errors:
**Raises**
**NagValueError**
(`errno` :math:`2`)
On entry, :math:`n = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`n\geq 0`.
**Warns**
**NagAlgorithmicWarning**
(`errno` :math:`1`)
On entry, at least one value of :math:`\mathrm{x}` was invalid.
Check :math:`\mathrm{ivalid}` for more information.
.. _s17ax-py2-py-notes:
**Notes**
``airy_bi_deriv_vector`` calculates an approximate value for the derivative of the Airy function :math:`\mathrm{Bi}\left(x_i\right)` for an array of arguments :math:`x_{\textit{i}}`, for :math:`\textit{i} = 1,2,\ldots,n`.
It is based on a number of Chebyshev expansions.
For :math:`x < {-5}`,
.. math::
\textit{Bi}^{\prime }\left(x\right) = \sqrt[4]{{-x}}\left[-a\left(t\right)\sin\left(z\right)+\frac{{b\left(t\right)}}{\zeta }\cos\left(z\right)\right]\text{,}
where :math:`z = \frac{\pi }{4}+\zeta`, :math:`\zeta = \frac{2}{3}\sqrt{-x^3}` and :math:`a\left(t\right)` and :math:`b\left(t\right)` are expansions in the variable :math:`t = {-2}\left(\frac{5}{x}\right)^3-1`.
For :math:`{-5}\leq x\leq 0`,
.. math::
\textit{Bi}^{\prime }\left(x\right) = \sqrt{3}\left(x^2f\left(t\right)+g\left(t\right)\right)\text{,}
where :math:`f` and :math:`g` are expansions in :math:`t = {-2}\left(\frac{x}{5}\right)^3-1`.
For :math:`0 < x < 4.5`,
.. math::
\textit{Bi}^{\prime }\left(x\right) = e^{{3x/2}}y\left(t\right)\text{,}
where :math:`y\left(t\right)` is an expansion in :math:`t = 4x/9-1`.
For :math:`4.5\leq x < 9`,
.. math::
\textit{Bi}^{\prime }\left(x\right) = e^{{21x/8}}u\left(t\right)\text{,}
where :math:`u\left(t\right)` is an expansion in :math:`t = 4x/9-3`.
For :math:`x\geq 9`,
.. math::
\textit{Bi}^{\prime }\left(x\right) = \sqrt[4]{x}e^zv\left(t\right)\text{,}
where :math:`z = \frac{2}{3}\sqrt{x^3}` and :math:`v\left(t\right)` is an expansion in :math:`t = 2\left(\frac{18}{z}\right)-1`.
For :math:`\left\lvert x\right\rvert < \text{}` the square of the machine precision, the result is set directly to :math:`\textit{Bi}^{\prime }\left(0\right)`.
This saves time and avoids possible underflows in calculation.
For large negative arguments, it becomes impossible to calculate a result for the oscillating function with any accuracy so the function must fail.
This occurs for :math:`x < -\left(\frac{\sqrt{\pi }}{\epsilon }\right)^{{4/7}}`, where :math:`\epsilon` is the machine precision.
For large positive arguments, where :math:`\textit{Bi}^{\prime }` grows in an essentially exponential manner, there is a danger of overflow so the function must fail.
.. _s17ax-py2-py-references:
**References**
NIST Digital Library of Mathematical Functions
"""
raise NotImplementedError
[docs]def bessel_y_complex(fnu, z, n, scal):
r"""
``bessel_y_complex`` returns a sequence of values for the Bessel functions :math:`Y_{{\nu +n}}\left(z\right)` for complex :math:`z`, non-negative :math:`\nu` and :math:`n = 0,1,\ldots,N-1`, with an option for exponential scaling.
.. _s17dc-py2-py-doc:
For full information please refer to the NAG Library document for s17dc
https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s17dcf.html
.. _s17dc-py2-py-parameters:
**Parameters**
**fnu** : float
:math:`\nu`, the order of the first member of the sequence of functions.
**z** : complex
:math:`z`, the argument of the functions.
**n** : int
:math:`N`, the number of members required in the sequence :math:`Y_{\nu }\left(z\right),Y_{{\nu +1}}\left(z\right),\ldots,Y_{{\nu +N-1}}\left(z\right)`.
**scal** : str, length 1
The scaling option.
:math:`\mathrm{scal} = \texttt{'U'}`
The results are returned unscaled.
:math:`\mathrm{scal} = \texttt{'S'}`
The results are returned scaled by the factor :math:`e^{{-\left\lvert \mathrm{Im}\left(z\right)\right\rvert }}`.
**Returns**
**cy** : complex, ndarray, shape :math:`\left(\mathrm{n}\right)`
The :math:`N` required function values: :math:`\mathrm{cy}[i-1]` contains :math:`Y_{{\nu +i-1}}\left(z\right)`, for :math:`\textit{i} = 1,2,\ldots,N`.
**nz** : int
The number of components of :math:`\mathrm{cy}` that are set to zero due to underflow. The positions of such components in the array :math:`\mathrm{cy}` are arbitrary.
.. _s17dc-py2-py-errors:
**Raises**
**NagValueError**
(`errno` :math:`1`)
On entry, :math:`\mathrm{z} = \left(0.0, 0.0\right)`.
(`errno` :math:`1`)
On entry, :math:`\mathrm{fnu} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{fnu}\geq 0.0`.
(`errno` :math:`1`)
On entry, :math:`\mathrm{scal}` has an illegal value: :math:`\mathrm{scal} = \langle\mathit{\boldsymbol{value}}\rangle`.
(`errno` :math:`1`)
On entry, :math:`\mathrm{n} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{n}\geq 1`.
(`errno` :math:`2`)
No computation because :math:`\left\lvert \mathrm{z}\right\rvert = \langle\mathit{\boldsymbol{value}}\rangle < \langle\mathit{\boldsymbol{value}}\rangle`.
(`errno` :math:`2`)
No computation because :math:`\mathrm{Re}\left(\mathrm{z}\right) = \langle\mathit{\boldsymbol{value}}\rangle > \langle\mathit{\boldsymbol{value}}\rangle`, :math:`\mathrm{scal} = \texttt{'U'}`.
(`errno` :math:`3`)
No computation because :math:`\mathrm{fnu}+\mathrm{n}-1 = \langle\mathit{\boldsymbol{value}}\rangle` is too large.
(`errno` :math:`5`)
No computation because :math:`\left\lvert \mathrm{z}\right\rvert = \langle\mathit{\boldsymbol{value}}\rangle > \langle\mathit{\boldsymbol{value}}\rangle`.
(`errno` :math:`5`)
No computation because :math:`\mathrm{fnu}+\mathrm{n}-1 = \langle\mathit{\boldsymbol{value}}\rangle > \langle\mathit{\boldsymbol{value}}\rangle`.
(`errno` :math:`6`)
No computation -- algorithm termination condition not met.
**Warns**
**NagAlgorithmicWarning**
(`errno` :math:`4`)
Results lack precision because :math:`\left\lvert \mathrm{z}\right\rvert = \langle\mathit{\boldsymbol{value}}\rangle > \langle\mathit{\boldsymbol{value}}\rangle`.
(`errno` :math:`4`)
Results lack precision because :math:`\mathrm{fnu}+\mathrm{n}-1 = \langle\mathit{\boldsymbol{value}}\rangle > \langle\mathit{\boldsymbol{value}}\rangle`.
.. _s17dc-py2-py-notes:
**Notes**
``bessel_y_complex`` evaluates a sequence of values for the Bessel function :math:`Y_{\nu }\left(z\right)`, where :math:`z` is complex, :math:`{-\pi } < {\mathrm{arg}z}\leq \pi`, and :math:`\nu` is the real, non-negative order.
The :math:`N`-member sequence is generated for orders :math:`\nu`, :math:`\nu +1,\ldots,\nu +N-1`.
Optionally, the sequence is scaled by the factor :math:`e^{{-\left\lvert \mathrm{Im}\left(z\right)\right\rvert }}`.
**Note:** although the function may not be called with :math:`\nu` less than zero, for negative orders the formula :math:`Y_{{-\nu }}\left(z\right) = Y_{\nu }\left(z\right)\cos\left(\pi \nu \right)+J_{\nu }\left(z\right)\sin\left(\pi \nu \right)` may be used (for the Bessel function :math:`J_{\nu }\left(z\right)`, see :meth:`bessel_j_complex`).
The function is derived from the function CBESY in Amos (1986).
It is based on the relation :math:`Y_{\nu }\left(z\right) = \frac{{H_{\nu }^{\left(1\right)}\left(z\right)-H_{\nu }^{\left(2\right)}\left(z\right)}}{{2i}}`, where :math:`H_{\nu }^{\left(1\right)}\left(z\right)` and :math:`H_{\nu }^{\left(2\right)}\left(z\right)` are the Hankel functions of the first and second kinds respectively (see :meth:`hankel_complex`).
When :math:`N` is greater than :math:`1`, extra values of :math:`Y_{\nu }\left(z\right)` are computed using recurrence relations.
For very large :math:`\left\lvert z\right\rvert` or :math:`\left(\nu +N-1\right)`, argument reduction will cause total loss of accuracy, and so no computation is performed.
For slightly smaller :math:`\left\lvert z\right\rvert` or :math:`\left(\nu +N-1\right)`, the computation is performed but results are accurate to less than half of machine precision.
If :math:`\left\lvert z\right\rvert` is very small, near the machine underflow threshold, or :math:`\left(\nu +N-1\right)` is too large, there is a risk of overflow and so no computation is performed.
In all the above cases, a warning is given by the function.
.. _s17dc-py2-py-references:
**References**
NIST Digital Library of Mathematical Functions
Amos, D E, 1986, `Algorithm 644: A portable package for Bessel functions of a complex argument and non-negative order`, ACM Trans. Math. Software (12), 265--273
"""
raise NotImplementedError
[docs]def bessel_j_complex(fnu, z, n, scal):
r"""
``bessel_j_complex`` returns a sequence of values for the Bessel functions :math:`J_{{\nu +n}}\left(z\right)` for complex :math:`z`, non-negative :math:`\nu` and :math:`n = 0,1,\ldots,N-1`, with an option for exponential scaling.
.. _s17de-py2-py-doc:
For full information please refer to the NAG Library document for s17de
https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s17def.html
.. _s17de-py2-py-parameters:
**Parameters**
**fnu** : float
:math:`\nu`, the order of the first member of the sequence of functions.
**z** : complex
The argument :math:`z` of the functions.
**n** : int
:math:`N`, the number of members required in the sequence :math:`J_{\nu }\left(z\right),J_{{\nu +1}}\left(z\right),\ldots,J_{{\nu +N-1}}\left(z\right)`.
**scal** : str, length 1
The scaling option.
:math:`\mathrm{scal} = \texttt{'U'}`
The results are returned unscaled.
:math:`\mathrm{scal} = \texttt{'S'}`
The results are returned scaled by the factor :math:`e^{{-\left\lvert \mathrm{Im}\left(z\right)\right\rvert }}`.
**Returns**
**cy** : complex, ndarray, shape :math:`\left(\mathrm{n}\right)`
The :math:`N` required function values: :math:`\mathrm{cy}[i-1]` contains :math:`J_{{\nu +i-1}}\left(z\right)`, for :math:`\textit{i} = 1,2,\ldots,N`.
**nz** : int
The number of components of :math:`\mathrm{cy}` that are set to zero due to underflow. If :math:`\mathrm{nz} > 0`, then elements :math:`\mathrm{cy}[\mathrm{n}-\mathrm{nz}]`, :math:`\mathrm{cy}[\mathrm{n}-\mathrm{nz}+1],\ldots,\mathrm{cy}[\mathrm{n}-1]` are set to zero.
.. _s17de-py2-py-errors:
**Raises**
**NagValueError**
(`errno` :math:`1`)
On entry, :math:`\mathrm{fnu} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{fnu}\geq 0.0`.
(`errno` :math:`1`)
On entry, :math:`\mathrm{scal}` has an illegal value: :math:`\mathrm{scal} = \langle\mathit{\boldsymbol{value}}\rangle`.
(`errno` :math:`1`)
On entry, :math:`\mathrm{n} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{n}\geq 1`.
(`errno` :math:`2`)
No computation because :math:`\mathrm{Im}\left(\mathrm{z}\right) = \langle\mathit{\boldsymbol{value}}\rangle > \langle\mathit{\boldsymbol{value}}\rangle`, :math:`\mathrm{scal} = \texttt{'U'}`.
(`errno` :math:`4`)
No computation because :math:`\left\lvert \mathrm{z}\right\rvert = \langle\mathit{\boldsymbol{value}}\rangle > \langle\mathit{\boldsymbol{value}}\rangle`.
(`errno` :math:`4`)
No computation because :math:`\mathrm{fnu}+\mathrm{n}-1 = \langle\mathit{\boldsymbol{value}}\rangle > \langle\mathit{\boldsymbol{value}}\rangle`.
(`errno` :math:`5`)
No computation -- algorithm termination condition not met.
**Warns**
**NagAlgorithmicWarning**
(`errno` :math:`3`)
Results lack precision because :math:`\left\lvert \mathrm{z}\right\rvert = \langle\mathit{\boldsymbol{value}}\rangle > \langle\mathit{\boldsymbol{value}}\rangle`.
(`errno` :math:`3`)
Results lack precision because :math:`\mathrm{fnu}+\mathrm{n}-1 = \langle\mathit{\boldsymbol{value}}\rangle > \langle\mathit{\boldsymbol{value}}\rangle`.
.. _s17de-py2-py-notes:
**Notes**
``bessel_j_complex`` evaluates a sequence of values for the Bessel function :math:`J_{\nu }\left(z\right)`, where :math:`z` is complex, :math:`{-\pi } < {\mathrm{arg}z}\leq \pi`, and :math:`\nu` is the real, non-negative order.
The :math:`N`-member sequence is generated for orders :math:`\nu`, :math:`\nu +1,\ldots,\nu +N-1`.
Optionally, the sequence is scaled by the factor :math:`e^{{-\left\lvert \mathrm{Im}\left(z\right)\right\rvert }}`.
**Note:** although the function may not be called with :math:`\nu` less than zero, for negative orders the formula :math:`J_{{-\nu }}\left(z\right) = J_{\nu }\left(z\right)\cos\left(\pi \nu \right)-Y_{\nu }\left(z\right)\sin\left(\pi \nu \right)` may be used (for the Bessel function :math:`Y_{\nu }\left(z\right)`, see :meth:`bessel_y_complex`).
The function is derived from the function CBESJ in Amos (1986).
It is based on the relations :math:`J_{\nu }\left(z\right) = e^{{\nu \pi i/2}}I_{\nu }\left(-iz\right)`, :math:`\mathrm{Im}\left(z\right)\geq 0.0`, and :math:`J_{\nu }\left(z\right) = e^{{-\nu \pi i/2}}I_{\nu }\left(iz\right)`, :math:`\mathrm{Im}\left(z\right) < 0.0`.
The Bessel function :math:`I_{\nu }\left(z\right)` is computed using a variety of techniques depending on the region under consideration.
When :math:`N` is greater than :math:`1`, extra values of :math:`J_{\nu }\left(z\right)` are computed using recurrence relations.
For very large :math:`\left\lvert z\right\rvert` or :math:`\left(\nu +N-1\right)`, argument reduction will cause total loss of accuracy, and so no computation is performed.
For slightly smaller :math:`\left\lvert z\right\rvert` or :math:`\left(\nu +N-1\right)`, the computation is performed but results are accurate to less than half of machine precision.
If :math:`\mathrm{Im}\left(z\right)` is large, there is a risk of overflow and so no computation is performed.
In all the above cases, a warning is given by the function.
.. _s17de-py2-py-references:
**References**
NIST Digital Library of Mathematical Functions
Amos, D E, 1986, `Algorithm 644: A portable package for Bessel functions of a complex argument and non-negative order`, ACM Trans. Math. Software (12), 265--273
"""
raise NotImplementedError
[docs]def airy_ai_complex(deriv, z, scal):
r"""
``airy_ai_complex`` returns the value of the Airy function :math:`\mathrm{Ai}\left(z\right)` or its derivative :math:`\textit{Ai}^{\prime }\left(z\right)` for complex :math:`z`, with an option for exponential scaling.
.. _s17dg-py2-py-doc:
For full information please refer to the NAG Library document for s17dg
https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s17dgf.html
.. _s17dg-py2-py-parameters:
**Parameters**
**deriv** : str, length 1
Specifies whether the function or its derivative is required.
:math:`\mathrm{deriv} = \texttt{'F'}`
:math:`\mathrm{Ai}\left(z\right)` is returned.
:math:`\mathrm{deriv} = \texttt{'D'}`
:math:`\textit{Ai}^{\prime }\left(z\right)` is returned.
**z** : complex
The argument :math:`z` of the function.
**scal** : str, length 1
The scaling option.
:math:`\mathrm{scal} = \texttt{'U'}`
The result is returned unscaled.
:math:`\mathrm{scal} = \texttt{'S'}`
The result is returned scaled by the factor :math:`e^{{2z\sqrt{z}/3}}`.
**Returns**
**ai** : complex
The required function or derivative value.
**nz** : int
Indicates whether or not :math:`\mathrm{ai}` is set to zero due to underflow. This can only occur when :math:`\mathrm{scal} = \texttt{'U'}`.
:math:`\mathrm{nz} = 0`
:math:`\mathrm{ai}` is not set to zero.
:math:`\mathrm{nz} = 1`
:math:`\mathrm{ai}` is set to zero.
.. _s17dg-py2-py-errors:
**Raises**
**NagValueError**
(`errno` :math:`1`)
On entry, :math:`\mathrm{deriv}` has an illegal value: :math:`\mathrm{deriv} = \langle\mathit{\boldsymbol{value}}\rangle`.
(`errno` :math:`1`)
On entry, :math:`\mathrm{scal}` has an illegal value: :math:`\mathrm{scal} = \langle\mathit{\boldsymbol{value}}\rangle`.
(`errno` :math:`2`)
No computation because :math:`\mathrm{Re}\left(\omega \right)` too large, where :math:`\omega = \left(2/3\right)\times \mathrm{z}^{\left(3/2\right)}`.
(`errno` :math:`4`)
No computation because :math:`\left\lvert \mathrm{z}\right\rvert = \langle\mathit{\boldsymbol{value}}\rangle > \langle\mathit{\boldsymbol{value}}\rangle`.
(`errno` :math:`5`)
No computation -- algorithm termination condition not met.
**Warns**
**NagAlgorithmicWarning**
(`errno` :math:`3`)
Results lack precision because :math:`\left\lvert \mathrm{z}\right\rvert = \langle\mathit{\boldsymbol{value}}\rangle > \langle\mathit{\boldsymbol{value}}\rangle`.
.. _s17dg-py2-py-notes:
**Notes**
``airy_ai_complex`` returns a value for the Airy function :math:`\mathrm{Ai}\left(z\right)` or its derivative :math:`\textit{Ai}^{\prime }\left(z\right)`, where :math:`z` is complex, :math:`{-\pi } < {\mathrm{arg}z}\leq \pi`.
Optionally, the value is scaled by the factor :math:`e^{{2z\sqrt{z}/3}}`.
The function is derived from the function CAIRY in Amos (1986).
It is based on the relations :math:`\mathrm{Ai}\left(z\right) = \frac{{\sqrt{z}K_{{1/3}}\left(w\right)}}{{\pi \sqrt{3}}}`, and :math:`\textit{Ai}^{\prime }\left(z\right) = \frac{{-zK_{{2/3}}\left(w\right)}}{{\pi \sqrt{3}}}`, where :math:`K_{\nu }` is the modified Bessel function and :math:`w = 2z\sqrt{z}/3`.
For very large :math:`\left\lvert z\right\rvert`, argument reduction will cause total loss of accuracy, and so no computation is performed.
For slightly smaller :math:`\left\lvert z\right\rvert`, the computation is performed but results are accurate to less than half of machine precision.
If :math:`\mathrm{Re}\left(w\right)` is too large, and the unscaled function is required, there is a risk of overflow and so no computation is performed.
In all the above cases, a warning is given by the function.
.. _s17dg-py2-py-references:
**References**
NIST Digital Library of Mathematical Functions
Amos, D E, 1986, `Algorithm 644: A portable package for Bessel functions of a complex argument and non-negative order`, ACM Trans. Math. Software (12), 265--273
"""
raise NotImplementedError
[docs]def airy_bi_complex(deriv, z, scal):
r"""
``airy_bi_complex`` returns the value of the Airy function :math:`\mathrm{Bi}\left(z\right)` or its derivative :math:`\textit{Bi}^{\prime }\left(z\right)` for complex :math:`z`, with an option for exponential scaling.
.. _s17dh-py2-py-doc:
For full information please refer to the NAG Library document for s17dh
https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s17dhf.html
.. _s17dh-py2-py-parameters:
**Parameters**
**deriv** : str, length 1
Specifies whether the function or its derivative is required.
:math:`\mathrm{deriv} = \texttt{'F'}`
:math:`\mathrm{Bi}\left(z\right)` is returned.
:math:`\mathrm{deriv} = \texttt{'D'}`
:math:`\textit{Bi}^{\prime }\left(z\right)` is returned.
**z** : complex
The argument :math:`z` of the function.
**scal** : str, length 1
The scaling option.
:math:`\mathrm{scal} = \texttt{'U'}`
The result is returned unscaled.
:math:`\mathrm{scal} = \texttt{'S'}`
The result is returned scaled by the factor :math:`e^{{\left\lvert \mathrm{Re}\left(2z\sqrt{z}/3\right)\right\rvert }}`.
**Returns**
**bi** : complex
The required function or derivative value.
.. _s17dh-py2-py-errors:
**Raises**
**NagValueError**
(`errno` :math:`1`)
On entry, :math:`\mathrm{deriv}` has an illegal value: :math:`\mathrm{deriv} = \langle\mathit{\boldsymbol{value}}\rangle`.
(`errno` :math:`1`)
On entry, :math:`\mathrm{scal}` has an illegal value: :math:`\mathrm{scal} = \langle\mathit{\boldsymbol{value}}\rangle`.
(`errno` :math:`2`)
No computation because :math:`\mathrm{Re}\left(\mathrm{z}\right) = \langle\mathit{\boldsymbol{value}}\rangle` is too large when :math:`\mathrm{scal} = \texttt{'U'}`.
(`errno` :math:`4`)
No computation because :math:`\left\lvert \mathrm{z}\right\rvert = \langle\mathit{\boldsymbol{value}}\rangle > \langle\mathit{\boldsymbol{value}}\rangle`.
(`errno` :math:`5`)
No computation -- algorithm termination condition not met.
**Warns**
**NagAlgorithmicWarning**
(`errno` :math:`3`)
Results lack precision because :math:`\left\lvert \mathrm{z}\right\rvert = \langle\mathit{\boldsymbol{value}}\rangle > \langle\mathit{\boldsymbol{value}}\rangle`.
.. _s17dh-py2-py-notes:
**Notes**
``airy_bi_complex`` returns a value for the Airy function :math:`\mathrm{Bi}\left(z\right)` or its derivative :math:`\textit{Bi}^{\prime }\left(z\right)`, where :math:`z` is complex, :math:`{-\pi } < {\mathrm{arg}z}\leq \pi`.
Optionally, the value is scaled by the factor :math:`e^{{\left\lvert \mathrm{Re}\left(2z\sqrt{z}/3\right)\right\rvert }}`.
The function is derived from the function CBIRY in Amos (1986).
It is based on the relations :math:`\mathrm{Bi}\left(z\right) = \frac{{\sqrt{z}}}{\sqrt{3}}\left(I_{{-1/3}}\left(w\right)+I_{{1/3}}\left(w\right)\right)`, and :math:`\textit{Bi}^{\prime }\left(z\right) = \frac{z}{\sqrt{3}}\left(I_{{-2/3}}\left(w\right)+I_{{2/3}}\left(w\right)\right)`, where :math:`I_{\nu }` is the modified Bessel function and :math:`w = 2z\sqrt{z}/3`.
For very large :math:`\left\lvert z\right\rvert`, argument reduction will cause total loss of accuracy, and so no computation is performed.
For slightly smaller :math:`\left\lvert z\right\rvert`, the computation is performed but results are accurate to less than half of machine precision.
If :math:`\mathrm{Re}\left(z\right)` is too large, and the unscaled function is required, there is a risk of overflow and so no computation is performed.
In all the above cases, a warning is given by the function.
.. _s17dh-py2-py-references:
**References**
NIST Digital Library of Mathematical Functions
Amos, D E, 1986, `Algorithm 644: A portable package for Bessel functions of a complex argument and non-negative order`, ACM Trans. Math. Software (12), 265--273
"""
raise NotImplementedError
[docs]def hankel_complex(m, fnu, z, n, scal):
r"""
``hankel_complex`` returns a sequence of values for the Hankel functions :math:`H_{{\nu +n}}^{\left(1\right)}\left(z\right)` or :math:`H_{{\nu +n}}^{\left(2\right)}\left(z\right)` for complex :math:`z`, non-negative :math:`\nu` and :math:`n = 0,1,\ldots,N-1`, with an option for exponential scaling.
.. _s17dl-py2-py-doc:
For full information please refer to the NAG Library document for s17dl
https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s17dlf.html
.. _s17dl-py2-py-parameters:
**Parameters**
**m** : int
The kind of functions required.
:math:`\mathrm{m} = 1`
The functions are :math:`H_{\nu }^{\left(1\right)}\left(z\right)`.
:math:`\mathrm{m} = 2`
The functions are :math:`H_{\nu }^{\left(2\right)}\left(z\right)`.
**fnu** : float
:math:`\nu`, the order of the first member of the sequence of functions.
**z** : complex
The argument :math:`z` of the functions.
**n** : int
:math:`N`, the number of members required in the sequence :math:`H_{\nu }^{\left(\mathrm{m}\right)}\left(z\right),H_{{\nu +1}}^{\left(\mathrm{m}\right)}\left(z\right),\ldots,H_{{\nu +N-1}}^{\left(\mathrm{m}\right)}\left(z\right)`.
**scal** : str, length 1
The scaling option.
:math:`\mathrm{scal} = \texttt{'U'}`
The results are returned unscaled.
:math:`\mathrm{scal} = \texttt{'S'}`
The results are returned scaled by the factor :math:`e^{{-iz}}` when :math:`\mathrm{m} = 1`, or by the factor :math:`e^{{iz}}` when :math:`\mathrm{m} = 2`.
**Returns**
**cy** : complex, ndarray, shape :math:`\left(\mathrm{n}\right)`
The :math:`N` required function values: :math:`\mathrm{cy}[i-1]` contains :math:`H_{{\nu +i-1}}^{\left(\mathrm{m}\right)}\left(z\right)`, for :math:`\textit{i} = 1,2,\ldots,N`.
**nz** : int
The number of components of :math:`\mathrm{cy}` that are set to zero due to underflow. If :math:`\mathrm{nz} > 0`, then if :math:`\mathrm{Im}\left(z\right) > 0.0` and :math:`\mathrm{m} = 1`, or :math:`\mathrm{Im}\left(z\right) < 0.0` and :math:`\mathrm{m} = 2`, elements :math:`\mathrm{cy}[0],\mathrm{cy}[1],\ldots,\mathrm{cy}[\mathrm{nz}-1]` are set to zero. In the complementary half-planes, :math:`\mathrm{nz}` simply states the number of underflows, and not which elements they are.
.. _s17dl-py2-py-errors:
**Raises**
**NagValueError**
(`errno` :math:`1`)
On entry, :math:`\mathrm{z} = \left(0.0, 0.0\right)`.
(`errno` :math:`1`)
On entry, :math:`\mathrm{fnu} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{fnu}\geq 0.0`.
(`errno` :math:`1`)
On entry, :math:`\mathrm{scal}` has an illegal value: :math:`\mathrm{scal} = \langle\mathit{\boldsymbol{value}}\rangle`.
(`errno` :math:`1`)
On entry, :math:`\mathrm{n} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{n}\geq 1`.
(`errno` :math:`1`)
On entry, :math:`\mathrm{m}` has illegal value: :math:`\mathrm{m} = \langle\mathit{\boldsymbol{value}}\rangle`.
(`errno` :math:`2`)
No computation because :math:`\left\lvert \mathrm{z}\right\rvert = \langle\mathit{\boldsymbol{value}}\rangle < \langle\mathit{\boldsymbol{value}}\rangle`.
(`errno` :math:`3`)
No computation because :math:`\mathrm{fnu}+\mathrm{n}-1 = \langle\mathit{\boldsymbol{value}}\rangle` is too large.
(`errno` :math:`5`)
No computation because :math:`\left\lvert \mathrm{z}\right\rvert = \langle\mathit{\boldsymbol{value}}\rangle > \langle\mathit{\boldsymbol{value}}\rangle`.
(`errno` :math:`5`)
No computation because :math:`\mathrm{fnu}+\mathrm{n}-1 = \langle\mathit{\boldsymbol{value}}\rangle > \langle\mathit{\boldsymbol{value}}\rangle`.
(`errno` :math:`6`)
No computation -- algorithm termination condition not met.
**Warns**
**NagAlgorithmicWarning**
(`errno` :math:`4`)
Results lack precision because :math:`\left\lvert \mathrm{z}\right\rvert = \langle\mathit{\boldsymbol{value}}\rangle > \langle\mathit{\boldsymbol{value}}\rangle`.
(`errno` :math:`4`)
Results lack precision, :math:`\mathrm{fnu}+\mathrm{n}-1 = \langle\mathit{\boldsymbol{value}}\rangle > \langle\mathit{\boldsymbol{value}}\rangle`.
.. _s17dl-py2-py-notes:
**Notes**
``hankel_complex`` evaluates a sequence of values for the Hankel function :math:`H_{\nu }^{\left(1\right)}\left(z\right)` or :math:`H_{\nu }^{\left(2\right)}\left(z\right)`, where :math:`z` is complex, :math:`{-\pi } < {\mathrm{arg}z}\leq \pi`, and :math:`\nu` is the real, non-negative order.
The :math:`N`-member sequence is generated for orders :math:`\nu`, :math:`\nu +1,\ldots,\nu +N-1`.
Optionally, the sequence is scaled by the factor :math:`e^{{-iz}}` if the function is :math:`H_{\nu }^{\left(1\right)}\left(z\right)` or by the factor :math:`e^{{iz}}` if the function is :math:`H_{\nu }^{\left(2\right)}\left(z\right)`.
**Note:** although the function may not be called with :math:`\nu` less than zero, for negative orders the formulae :math:`H_{{-\nu }}^{\left(1\right)}\left(z\right) = e^{{\nu \pi i}}H_{\nu }^{\left(1\right)}\left(z\right)`, and :math:`H_{{-\nu }}^{\left(2\right)}\left(z\right) = e^{{-\nu \pi i}}H_{\nu }^{\left(2\right)}\left(z\right)` may be used.
The function is derived from the function CBESH in Amos (1986).
It is based on the relation
.. math::
H_{\nu }^{\left(m\right)}\left(z\right) = \frac{1}{p}e^{{-p\nu }}K_{\nu }\left(ze^{{-p}}\right)\text{,}
where :math:`p = \frac{{i\pi }}{2}` if :math:`m = 1` and :math:`p = -\frac{{i\pi }}{2}` if :math:`m = 2`, and the Bessel function :math:`K_{\nu }\left(z\right)` is computed in the right half-plane only.
Continuation of :math:`K_{\nu }\left(z\right)` to the left half-plane is computed in terms of the Bessel function :math:`I_{\nu }\left(z\right)`.
These functions are evaluated using a variety of different techniques, depending on the region under consideration.
When :math:`N` is greater than :math:`1`, extra values of :math:`H_{\nu }^{\left(m\right)}\left(z\right)` are computed using recurrence relations.
For very large :math:`\left\lvert z\right\rvert` or :math:`\left(\nu +N-1\right)`, argument reduction will cause total loss of accuracy, and so no computation is performed.
For slightly smaller :math:`\left\lvert z\right\rvert` or :math:`\left(\nu +N-1\right)`, the computation is performed but results are accurate to less than half of machine precision.
If :math:`\left\lvert z\right\rvert` is very small, near the machine underflow threshold, or :math:`\left(\nu +N-1\right)` is too large, there is a risk of overflow and so no computation is performed.
In all the above cases, a warning is given by the function.
.. _s17dl-py2-py-references:
**References**
NIST Digital Library of Mathematical Functions
Amos, D E, 1986, `Algorithm 644: A portable package for Bessel functions of a complex argument and non-negative order`, ACM Trans. Math. Software (12), 265--273
"""
raise NotImplementedError
[docs]def struve_h0(x):
r"""
``struve_h0`` returns the value of the Struve function of order :math:`0`, :math:`H_0\left(x\right)`.
.. _s17ga-py2-py-doc:
For full information please refer to the NAG Library document for s17ga
https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s17gaf.html
.. _s17ga-py2-py-parameters:
**Parameters**
**x** : float
The argument :math:`x` of the function.
**Returns**
**h0** : float
The value of the function at :math:`x`.
.. _s17ga-py2-py-errors:
**Raises**
**NagValueError**
(`errno` :math:`1`)
:math:`\mathrm{x}` is too large and the function returns zero.
.. _s17ga-py2-py-notes:
**Notes**
``struve_h0`` evaluates an approximation to the Struve function of order zero, :math:`H_0\left(x\right)`.
Please consult the NIST Digital Library of Mathematical Functions for a detailed discussion of the Struve function including special cases, transformations, relations and asymptotic approximations.
The approximation method used by this function is based on Chebyshev expansions.
.. _s17ga-py2-py-references:
**References**
NIST Digital Library of Mathematical Functions
MacLeod, A J, 1996, `MISCFUN, a software package to compute uncommon special functions`, ACM Trans. Math. Software (TOMS) (22(3)), 288--301
"""
raise NotImplementedError
[docs]def struve_h1(x):
r"""
``struve_h1`` returns the value of the Struve function of order :math:`1`, :math:`H_1\left(x\right)`.
.. _s17gb-py2-py-doc:
For full information please refer to the NAG Library document for s17gb
https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s17gbf.html
.. _s17gb-py2-py-parameters:
**Parameters**
**x** : float
The argument :math:`x` of the function.
**Returns**
**h1** : float
The value of the function at :math:`x`.
.. _s17gb-py2-py-errors:
**Raises**
**NagValueError**
(`errno` :math:`1`)
:math:`\mathrm{x}` is too large and the function returns zero.
.. _s17gb-py2-py-notes:
**Notes**
``struve_h1`` evaluates an approximation to the Struve function of order :math:`1`, :math:`H_1\left(x\right)`.
Please consult the NIST Digital Library of Mathematical Functions for a detailed discussion of the Struve function including special cases, transformations, relations and asymptotic approximations.
The approximation method used by this function is based on Chebyshev expansions.
.. _s17gb-py2-py-references:
**References**
NIST Digital Library of Mathematical Functions
MacLeod, A J, 1996, `MISCFUN, a software package to compute uncommon special functions`, ACM Trans. Math. Software (TOMS) (22(3)), 288--301
"""
raise NotImplementedError
[docs]def bessel_k0_real(x):
r"""
``bessel_k0_real`` returns the value of the modified Bessel function :math:`K_0\left(x\right)`.
.. _s18ac-py2-py-doc:
For full information please refer to the NAG Library document for s18ac
https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s18acf.html
.. _s18ac-py2-py-parameters:
**Parameters**
**x** : float
The argument :math:`x` of the function.
**Returns**
**k0** : float
The value of the function at :math:`x`.
.. _s18ac-py2-py-errors:
**Raises**
**NagValueError**
(`errno` :math:`1`)
On entry, :math:`\mathrm{x} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{x} > 0.0`.
:math:`K_0` is undefined and the function returns zero.
.. _s18ac-py2-py-notes:
**Notes**
``bessel_k0_real`` evaluates an approximation to the modified Bessel function of the second kind :math:`K_0\left(x\right)`.
**Note:** :math:`K_0\left(x\right)` is undefined for :math:`x\leq 0` and the function will fail for such arguments.
The function is based on five Chebyshev expansions:
For :math:`0 < x\leq 1`,
.. math::
K_0\left(x\right) = -\mathrm{ln}\left(x\right){\sum^\prime}_{{r = 0}}a_rT_r\left(t\right)+{\sum^\prime}_{{r = 0}}b_rT_r\left(t\right)\text{, where }t = 2x^2-1\text{.}
For :math:`1 < x\leq 2`,
.. math::
K_0\left(x\right) = e^{{-x}}{\sum^\prime}_{{r = 0}}c_rT_r\left(t\right)\text{, where }t = 2x-3\text{.}
For :math:`2 < x\leq 4`,
.. math::
K_0\left(x\right) = e^{{-x}}{\sum^\prime}_{{r = 0}}d_rT_r\left(t\right)\text{, where }t = x-3\text{.}
For :math:`x > 4`,
.. math::
K_0\left(x\right) = \frac{e^{{-x}}}{{\sqrt{x}}}{\sum^\prime}_{{r = 0}}e_rT_r\left(t\right),\text{where }t = \frac{{9-x}}{{1+x}}\text{.}
For :math:`x` near zero, :math:`K_0\left(x\right)\simeq -\gamma -\mathrm{ln}\left(\frac{x}{2}\right)`, where :math:`\gamma` denotes Euler's constant.
This approximation is used when :math:`x` is sufficiently small for the result to be correct to machine precision.
For large :math:`x`, where there is a danger of underflow due to the smallness of :math:`K_0`, the result is set exactly to zero.
.. _s18ac-py2-py-references:
**References**
NIST Digital Library of Mathematical Functions
"""
raise NotImplementedError
[docs]def bessel_k1_real(x):
r"""
``bessel_k1_real`` returns the value of the modified Bessel function :math:`K_1\left(x\right)`.
.. _s18ad-py2-py-doc:
For full information please refer to the NAG Library document for s18ad
https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s18adf.html
.. _s18ad-py2-py-parameters:
**Parameters**
**x** : float
The argument :math:`x` of the function.
**Returns**
**k1** : float
The value of the function at :math:`x`.
.. _s18ad-py2-py-errors:
**Raises**
**NagValueError**
(`errno` :math:`1`)
On entry, :math:`\mathrm{x} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{x} > 0.0`.
:math:`K_0` is undefined and the function returns zero.
**Warns**
**NagAlgorithmicWarning**
(`errno` :math:`2`)
On entry, :math:`\mathrm{x} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{x} > \langle\mathit{\boldsymbol{value}}\rangle`.
:math:`\mathrm{x}` is too small, there is a danger of overflow and the function returns approximately the largest representable value.
.. _s18ad-py2-py-notes:
**Notes**
``bessel_k1_real`` evaluates an approximation to the modified Bessel function of the second kind :math:`K_1\left(x\right)`.
**Note:** :math:`K_1\left(x\right)` is undefined for :math:`x\leq 0` and the function will fail for such arguments.
The function is based on five Chebyshev expansions:
For :math:`0 < x\leq 1`,
.. math::
K_1\left(x\right) = \frac{1}{x}+x\mathrm{ln}\left(x\right){\sum^\prime}_{{r = 0}}a_rT_r\left(t\right)-x{\sum^\prime}_{{r = 0}}b_rT_r\left(t\right)\text{, where }t = 2x^2-1\text{.}
For :math:`1 < x\leq 2`,
.. math::
K_1\left(x\right) = e^{{-x}}{\sum^\prime}_{{r = 0}}c_rT_r\left(t\right)\text{, where }t = 2x-3\text{.}
For :math:`2 < x\leq 4`,
.. math::
K_1\left(x\right) = e^{{-x}}{\sum^\prime}_{{r = 0}}d_rT_r\left(t\right)\text{, where }t = x-3\text{.}
For :math:`x > 4`,
.. math::
K_1\left(x\right) = \frac{e^{{-x}}}{{\sqrt{x}}}{\sum^\prime}_{{r = 0}}e_rT_r\left(t\right)\text{, where }t = \frac{{9-x}}{{1+x}}\text{.}
For :math:`x` near zero, :math:`K_1\left(x\right)\simeq \frac{1}{x}`.
This approximation is used when :math:`x` is sufficiently small for the result to be correct to machine precision.
For very small :math:`x` on some machines, it is impossible to calculate :math:`\frac{1}{x}` without overflow and the function must fail.
For large :math:`x`, where there is a danger of underflow due to the smallness of :math:`K_1`, the result is set exactly to zero.
.. _s18ad-py2-py-references:
**References**
NIST Digital Library of Mathematical Functions
"""
raise NotImplementedError
[docs]def bessel_i0_real(x):
r"""
``bessel_i0_real`` returns the value of the modified Bessel function :math:`I_0\left(x\right)`.
.. _s18ae-py2-py-doc:
For full information please refer to the NAG Library document for s18ae
https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s18aef.html
.. _s18ae-py2-py-parameters:
**Parameters**
**x** : float
The argument :math:`x` of the function.
**Returns**
**i0** : float
The value of the function at :math:`x`.
.. _s18ae-py2-py-errors:
**Raises**
**NagValueError**
(`errno` :math:`1`)
On entry, :math:`\mathrm{x} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\left\lvert \mathrm{x}\right\rvert \leq \langle\mathit{\boldsymbol{value}}\rangle`.
:math:`\left\lvert \mathrm{x}\right\rvert` is too large and the function returns the approximate value of :math:`I_0\left(x\right)` at the nearest valid argument.
.. _s18ae-py2-py-notes:
**Notes**
``bessel_i0_real`` evaluates an approximation to the modified Bessel function of the first kind :math:`I_0\left(x\right)`.
**Note:** :math:`I_0\left(-x\right) = I_0\left(x\right)`, so the approximation need only consider :math:`x\geq 0`.
The function is based on three Chebyshev expansions:
For :math:`0 < x\leq 4`,
.. math::
I_0\left(x\right) = e^x{\sum^\prime}_{{r = 0}}a_rT_r\left(t\right)\text{, where }t = 2\left(\frac{x}{4}\right)-1\text{.}
For :math:`4 < x\leq 12`,
.. math::
I_0\left(x\right) = e^x{\sum^\prime}_{{r = 0}}b_rT_r\left(t\right)\text{, where }t = \frac{{x-8}}{4}\text{.}
For :math:`x > 12`,
.. math::
I_0\left(x\right) = \frac{e^x}{{\sqrt{x}}}{\sum^\prime}_{{r = 0}}c_rT_r\left(t\right)\text{, where }t = 2\left(\frac{12}{x}\right)-1\text{.}
For small :math:`x`, :math:`I_0\left(x\right)\simeq 1`.
This approximation is used when :math:`x` is sufficiently small for the result to be correct to machine precision.
For large :math:`x`, the function must fail because of the danger of overflow in calculating :math:`e^x`.
.. _s18ae-py2-py-references:
**References**
NIST Digital Library of Mathematical Functions
"""
raise NotImplementedError
[docs]def bessel_i1_real(x):
r"""
``bessel_i1_real`` returns a value for the modified Bessel function :math:`I_1\left(x\right)`.
.. _s18af-py2-py-doc:
For full information please refer to the NAG Library document for s18af
https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s18aff.html
.. _s18af-py2-py-parameters:
**Parameters**
**x** : float
The argument :math:`x` of the function.
**Returns**
**i1** : float
The value of the function at :math:`x`.
.. _s18af-py2-py-errors:
**Raises**
**NagValueError**
(`errno` :math:`1`)
On entry, :math:`\mathrm{x} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\left\lvert \mathrm{x}\right\rvert \leq \langle\mathit{\boldsymbol{value}}\rangle`.
:math:`\left\lvert \mathrm{x}\right\rvert` is too large and the function returns the approximate value of :math:`I_1\left(x\right)` at the nearest valid argument.
.. _s18af-py2-py-notes:
**Notes**
``bessel_i1_real`` evaluates an approximation to the modified Bessel function of the first kind :math:`I_1\left(x\right)`.
**Note:** :math:`I_1\left(-x\right) = -I_1\left(x\right)`, so the approximation need only consider :math:`x\geq 0`.
The function is based on three Chebyshev expansions:
For :math:`0 < x\leq 4`,
.. math::
I_1\left(x\right) = x{\sum^\prime}_{{r = 0}}a_rT_r\left(t\right)\text{, where }t = 2\left(\frac{x}{4}\right)^2-1\text{;}
For :math:`4 < x\leq 12`,
.. math::
I_1\left(x\right) = e^x{\sum^\prime}_{{r = 0}}b_rT_r\left(t\right)\text{, where }t = \frac{{x-8}}{4}\text{;}
For :math:`x > 12`,
.. math::
I_1\left(x\right) = \frac{e^x}{{\sqrt{x}}}{\sum^\prime}_{{r = 0}}c_rT_r\left(t\right)\text{, where }t = 2\left(\frac{12}{x}\right)-1\text{.}
For small :math:`x`, :math:`I_1\left(x\right)\simeq x`.
This approximation is used when :math:`x` is sufficiently small for the result to be correct to machine precision.
For large :math:`x`, the function must fail because :math:`I_1\left(x\right)` cannot be represented without overflow.
.. _s18af-py2-py-references:
**References**
NIST Digital Library of Mathematical Functions
"""
raise NotImplementedError
[docs]def bessel_k0_real_vector(x):
r"""
``bessel_k0_real_vector`` returns an array of values of the modified Bessel function :math:`K_0\left(x\right)`.
.. _s18aq-py2-py-doc:
For full information please refer to the NAG Library document for s18aq
https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s18aqf.html
.. _s18aq-py2-py-parameters:
**Parameters**
**x** : float, array-like, shape :math:`\left(n\right)`
The argument :math:`x_{\textit{i}}` of the function, for :math:`\textit{i} = 1,2,\ldots,n`.
**Returns**
**f** : float, ndarray, shape :math:`\left(n\right)`
:math:`K_0\left(x_i\right)`, the function values.
**ivalid** : int, ndarray, shape :math:`\left(n\right)`
:math:`\mathrm{ivalid}[\textit{i}-1]` contains the error code for :math:`x_{\textit{i}}`, for :math:`\textit{i} = 1,2,\ldots,n`.
:math:`\mathrm{ivalid}[i-1] = 0`
No error.
:math:`\mathrm{ivalid}[i-1] = 1`
:math:`x_i\leq 0.0`, :math:`K_0\left(x_i\right)` is undefined. :math:`\mathrm{f}[\textit{i}-1]` contains :math:`0.0`.
.. _s18aq-py2-py-errors:
**Raises**
**NagValueError**
(`errno` :math:`2`)
On entry, :math:`n = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`n\geq 0`.
**Warns**
**NagAlgorithmicWarning**
(`errno` :math:`1`)
On entry, at least one value of :math:`\mathrm{x}` was invalid.
Check :math:`\mathrm{ivalid}` for more information.
.. _s18aq-py2-py-notes:
**Notes**
``bessel_k0_real_vector`` evaluates an approximation to the modified Bessel function of the second kind :math:`K_0\left(x_i\right)` for an array of arguments :math:`x_{\textit{i}}`, for :math:`\textit{i} = 1,2,\ldots,n`.
**Note:** :math:`K_0\left(x\right)` is undefined for :math:`x\leq 0` and the function will fail for such arguments.
The function is based on five Chebyshev expansions:
For :math:`0 < x\leq 1`,
.. math::
K_0\left(x\right) = -\mathrm{ln}\left(x\right){\sum^\prime}_{{r = 0}}a_rT_r\left(t\right)+{\sum^\prime}_{{r = 0}}b_rT_r\left(t\right)\text{, where }t = 2x^2-1\text{.}
For :math:`1 < x\leq 2`,
.. math::
K_0\left(x\right) = e^{{-x}}{\sum^\prime}_{{r = 0}}c_rT_r\left(t\right)\text{, where }t = 2x-3\text{.}
For :math:`2 < x\leq 4`,
.. math::
K_0\left(x\right) = e^{{-x}}{\sum^\prime}_{{r = 0}}d_rT_r\left(t\right)\text{, where }t = x-3\text{.}
For :math:`x > 4`,
.. math::
K_0\left(x\right) = \frac{e^{{-x}}}{{\sqrt{x}}}{\sum^\prime}_{{r = 0}}e_rT_r\left(t\right),\text{where }t = \frac{{9-x}}{{1+x}}\text{.}
For :math:`x` near zero, :math:`K_0\left(x\right)\simeq -\gamma -\mathrm{ln}\left(\frac{x}{2}\right)`, where :math:`\gamma` denotes Euler's constant.
This approximation is used when :math:`x` is sufficiently small for the result to be correct to machine precision.
For large :math:`x`, where there is a danger of underflow due to the smallness of :math:`K_0`, the result is set exactly to zero.
.. _s18aq-py2-py-references:
**References**
NIST Digital Library of Mathematical Functions
"""
raise NotImplementedError
[docs]def bessel_k1_real_vector(x):
r"""
``bessel_k1_real_vector`` returns an array of values of the modified Bessel function :math:`K_1\left(x\right)`.
.. _s18ar-py2-py-doc:
For full information please refer to the NAG Library document for s18ar
https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s18arf.html
.. _s18ar-py2-py-parameters:
**Parameters**
**x** : float, array-like, shape :math:`\left(n\right)`
The argument :math:`x_{\textit{i}}` of the function, for :math:`\textit{i} = 1,2,\ldots,n`.
**Returns**
**f** : float, ndarray, shape :math:`\left(n\right)`
:math:`K_1\left(x_i\right)`, the function values.
**ivalid** : int, ndarray, shape :math:`\left(n\right)`
:math:`\mathrm{ivalid}[\textit{i}-1]` contains the error code for :math:`x_{\textit{i}}`, for :math:`\textit{i} = 1,2,\ldots,n`.
:math:`\mathrm{ivalid}[i-1] = 0`
No error.
:math:`\mathrm{ivalid}[i-1] = 1`
:math:`x_i\leq 0.0`, :math:`K_1\left(x_i\right)` is undefined. :math:`\mathrm{f}[\textit{i}-1]` contains :math:`0.0`.
:math:`\mathrm{ivalid}[i-1] = 2`
:math:`x_i` is too small, there is a danger of overflow. :math:`\mathrm{f}[\textit{i}-1]` contains zero. The threshold value is the same as for :math:`\mathrm{errno}` = 2 in :meth:`bessel_k1_real`.
.. _s18ar-py2-py-errors:
**Raises**
**NagValueError**
(`errno` :math:`2`)
On entry, :math:`n = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`n\geq 0`.
**Warns**
**NagAlgorithmicWarning**
(`errno` :math:`1`)
On entry, at least one value of :math:`\mathrm{x}` was invalid.
Check :math:`\mathrm{ivalid}` for more information.
.. _s18ar-py2-py-notes:
**Notes**
``bessel_k1_real_vector`` evaluates an approximation to the modified Bessel function of the second kind :math:`K_1\left(x_i\right)` for an array of arguments :math:`x_{\textit{i}}`, for :math:`\textit{i} = 1,2,\ldots,n`.
**Note:** :math:`K_1\left(x\right)` is undefined for :math:`x\leq 0` and the function will fail for such arguments.
The function is based on five Chebyshev expansions:
For :math:`0 < x\leq 1`,
.. math::
K_1\left(x\right) = \frac{1}{x}+x\mathrm{ln}\left(x\right){\sum^\prime}_{{r = 0}}a_rT_r\left(t\right)-x{\sum^\prime}_{{r = 0}}b_rT_r\left(t\right)\text{, where }t = 2x^2-1\text{.}
For :math:`1 < x\leq 2`,
.. math::
K_1\left(x\right) = e^{{-x}}{\sum^\prime}_{{r = 0}}c_rT_r\left(t\right)\text{, where }t = 2x-3\text{.}
For :math:`2 < x\leq 4`,
.. math::
K_1\left(x\right) = e^{{-x}}{\sum^\prime}_{{r = 0}}d_rT_r\left(t\right)\text{, where }t = x-3\text{.}
For :math:`x > 4`,
.. math::
K_1\left(x\right) = \frac{e^{{-x}}}{{\sqrt{x}}}{\sum^\prime}_{{r = 0}}e_rT_r\left(t\right)\text{, where }t = \frac{{9-x}}{{1+x}}\text{.}
For :math:`x` near zero, :math:`K_1\left(x\right)\simeq \frac{1}{x}`.
This approximation is used when :math:`x` is sufficiently small for the result to be correct to machine precision.
For very small :math:`x` it is impossible to calculate :math:`\frac{1}{x}` without overflow and the function must fail.
For large :math:`x`, where there is a danger of underflow due to the smallness of :math:`K_1`, the result is set exactly to zero.
.. _s18ar-py2-py-references:
**References**
NIST Digital Library of Mathematical Functions
"""
raise NotImplementedError
[docs]def bessel_i0_real_vector(x):
r"""
``bessel_i0_real_vector`` returns an array of values of the modified Bessel function :math:`I_0\left(x\right)`.
.. _s18as-py2-py-doc:
For full information please refer to the NAG Library document for s18as
https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s18asf.html
.. _s18as-py2-py-parameters:
**Parameters**
**x** : float, array-like, shape :math:`\left(n\right)`
The argument :math:`x_{\textit{i}}` of the function, for :math:`\textit{i} = 1,2,\ldots,n`.
**Returns**
**f** : float, ndarray, shape :math:`\left(n\right)`
:math:`I_0\left(x_i\right)`, the function values.
**ivalid** : int, ndarray, shape :math:`\left(n\right)`
:math:`\mathrm{ivalid}[\textit{i}-1]` contains the error code for :math:`x_{\textit{i}}`, for :math:`\textit{i} = 1,2,\ldots,n`.
:math:`\mathrm{ivalid}[i-1] = 0`
No error.
:math:`\mathrm{ivalid}[i-1] = 1`
:math:`x_i` is too large. :math:`\mathrm{f}[\textit{i}-1]` contains the approximate value of :math:`I_0\left(x_i\right)` at the nearest valid argument. The threshold value is the same as for :math:`\mathrm{errno}` = 1 in :meth:`bessel_i0_real`.
.. _s18as-py2-py-errors:
**Raises**
**NagValueError**
(`errno` :math:`2`)
On entry, :math:`n = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`n\geq 0`.
**Warns**
**NagAlgorithmicWarning**
(`errno` :math:`1`)
On entry, at least one value of :math:`\mathrm{x}` was invalid.
Check :math:`\mathrm{ivalid}` for more information.
.. _s18as-py2-py-notes:
**Notes**
``bessel_i0_real_vector`` evaluates an approximation to the modified Bessel function of the first kind :math:`I_0\left(x_i\right)` for an array of arguments :math:`x_{\textit{i}}`, for :math:`\textit{i} = 1,2,\ldots,n`.
**Note:** :math:`I_0\left(-x\right) = I_0\left(x\right)`, so the approximation need only consider :math:`x\geq 0`.
The function is based on three Chebyshev expansions:
For :math:`0 < x\leq 4`,
.. math::
I_0\left(x\right) = e^x{\sum^\prime}_{{r = 0}}a_rT_r\left(t\right)\text{, where }t = 2\left(\frac{x}{4}\right)-1\text{.}
For :math:`4 < x\leq 12`,
.. math::
I_0\left(x\right) = e^x{\sum^\prime}_{{r = 0}}b_rT_r\left(t\right)\text{, where }t = \frac{{x-8}}{4}\text{.}
For :math:`x > 12`,
.. math::
I_0\left(x\right) = \frac{e^x}{{\sqrt{x}}}{\sum^\prime}_{{r = 0}}c_rT_r\left(t\right)\text{, where }t = 2\left(\frac{12}{x}\right)-1\text{.}
For small :math:`x`, :math:`I_0\left(x\right)\simeq 1`.
This approximation is used when :math:`x` is sufficiently small for the result to be correct to machine precision.
For large :math:`x`, the function must fail because of the danger of overflow in calculating :math:`e^x`.
.. _s18as-py2-py-references:
**References**
NIST Digital Library of Mathematical Functions
"""
raise NotImplementedError
[docs]def bessel_i1_real_vector(x):
r"""
``bessel_i1_real_vector`` returns an array of values for the modified Bessel function :math:`I_1\left(x\right)`.
.. _s18at-py2-py-doc:
For full information please refer to the NAG Library document for s18at
https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s18atf.html
.. _s18at-py2-py-parameters:
**Parameters**
**x** : float, array-like, shape :math:`\left(n\right)`
The argument :math:`x_{\textit{i}}` of the function, for :math:`\textit{i} = 1,2,\ldots,n`.
**Returns**
**f** : float, ndarray, shape :math:`\left(n\right)`
:math:`I_1\left(x_i\right)`, the function values.
**ivalid** : int, ndarray, shape :math:`\left(n\right)`
:math:`\mathrm{ivalid}[\textit{i}-1]` contains the error code for :math:`x_{\textit{i}}`, for :math:`\textit{i} = 1,2,\ldots,n`.
:math:`\mathrm{ivalid}[i-1] = 0`
No error.
:math:`\mathrm{ivalid}[i-1] = 1`
:math:`x_i` is too large. :math:`\mathrm{f}[\textit{i}-1]` contains the approximate value of :math:`I_1\left(x_i\right)` at the nearest valid argument. The threshold value is the same as for :math:`\mathrm{errno}` = 1 in :meth:`bessel_i1_real`.
.. _s18at-py2-py-errors:
**Raises**
**NagValueError**
(`errno` :math:`2`)
On entry, :math:`n = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`n\geq 0`.
**Warns**
**NagAlgorithmicWarning**
(`errno` :math:`1`)
On entry, at least one value of :math:`\mathrm{x}` was invalid.
Check :math:`\mathrm{ivalid}` for more information.
.. _s18at-py2-py-notes:
**Notes**
``bessel_i1_real_vector`` evaluates an approximation to the modified Bessel function of the first kind :math:`I_1\left(x_i\right)` for an array of arguments :math:`x_{\textit{i}}`, for :math:`\textit{i} = 1,2,\ldots,n`.
**Note:** :math:`I_1\left(-x\right) = -I_1\left(x\right)`, so the approximation need only consider :math:`x\geq 0`.
The function is based on three Chebyshev expansions:
For :math:`0 < x\leq 4`,
.. math::
I_1\left(x\right) = x{\sum^\prime}_{{r = 0}}a_rT_r\left(t\right)\text{, where }t = 2\left(\frac{x}{4}\right)^2-1\text{;}
For :math:`4 < x\leq 12`,
.. math::
I_1\left(x\right) = e^x{\sum^\prime}_{{r = 0}}b_rT_r\left(t\right)\text{, where }t = \frac{{x-8}}{4}\text{;}
For :math:`x > 12`,
.. math::
I_1\left(x\right) = \frac{e^x}{{\sqrt{x}}}{\sum^\prime}_{{r = 0}}c_rT_r\left(t\right)\text{, where }t = 2\left(\frac{12}{x}\right)-1\text{.}
For small :math:`x`, :math:`I_1\left(x\right)\simeq x`.
This approximation is used when :math:`x` is sufficiently small for the result to be correct to machine precision.
For large :math:`x`, the function must fail because :math:`I_1\left(x\right)` cannot be represented without overflow.
.. _s18at-py2-py-references:
**References**
NIST Digital Library of Mathematical Functions
"""
raise NotImplementedError
[docs]def bessel_k0_scaled(x):
r"""
``bessel_k0_scaled`` returns a value of the scaled modified Bessel function :math:`e^xK_0\left(x\right)`.
.. _s18cc-py2-py-doc:
For full information please refer to the NAG Library document for s18cc
https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s18ccf.html
.. _s18cc-py2-py-parameters:
**Parameters**
**x** : float
The argument :math:`x` of the function.
**Returns**
**sk0** : float
The value of the function at :math:`x`.
.. _s18cc-py2-py-errors:
**Raises**
**NagValueError**
(`errno` :math:`1`)
On entry, :math:`\mathrm{x} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{x} > 0.0`.
.. _s18cc-py2-py-notes:
**Notes**
``bessel_k0_scaled`` evaluates an approximation to :math:`e^xK_0\left(x\right)`, where :math:`K_0` is a modified Bessel function of the second kind.
The scaling factor :math:`e^x` removes most of the variation in :math:`K_0\left(x\right)`.
The function uses the same Chebyshev expansions as :meth:`bessel_k0_real`, which returns the unscaled value of :math:`K_0\left(x\right)`.
.. _s18cc-py2-py-references:
**References**
NIST Digital Library of Mathematical Functions
"""
raise NotImplementedError
[docs]def bessel_k1_scaled(x):
r"""
``bessel_k1_scaled`` returns a value of the scaled modified Bessel function :math:`e^xK_1\left(x\right)`.
.. _s18cd-py2-py-doc:
For full information please refer to the NAG Library document for s18cd
https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s18cdf.html
.. _s18cd-py2-py-parameters:
**Parameters**
**x** : float
The argument :math:`x` of the function.
**Returns**
**sk1** : float
The value of the function at :math:`x`.
.. _s18cd-py2-py-errors:
**Raises**
**NagValueError**
(`errno` :math:`1`)
On entry, :math:`\mathrm{x} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{x} > 0.0`.
:math:`K_1` is undefined and the function returns zero.
(`errno` :math:`2`)
On entry, :math:`\mathrm{x} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{x} > \langle\mathit{\boldsymbol{value}}\rangle`.
The function returns the value of the function at the smallest permitted value of the argument.
.. _s18cd-py2-py-notes:
**Notes**
``bessel_k1_scaled`` evaluates an approximation to :math:`e^xK_1\left(x\right)`, where :math:`K_1` is a modified Bessel function of the second kind.
The scaling factor :math:`e^x` removes most of the variation in :math:`K_1\left(x\right)`.
The function uses the same Chebyshev expansions as :meth:`bessel_k1_real`, which returns the unscaled value of :math:`K_1\left(x\right)`.
.. _s18cd-py2-py-references:
**References**
NIST Digital Library of Mathematical Functions
"""
raise NotImplementedError
[docs]def bessel_i0_scaled(x):
r"""
``bessel_i0_scaled`` returns a value of the scaled modified Bessel function :math:`e^{{-\left\lvert x\right\rvert }}I_0\left(x\right)`.
.. _s18ce-py2-py-doc:
For full information please refer to the NAG Library document for s18ce
https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s18cef.html
.. _s18ce-py2-py-parameters:
**Parameters**
**x** : float
The argument :math:`x` of the function.
**Returns**
**si0** : float
The value of the function at :math:`x`.
.. _s18ce-py2-py-notes:
**Notes**
``bessel_i0_scaled`` evaluates an approximation to :math:`e^{{-\left\lvert x\right\rvert }}I_0\left(x\right)`, where :math:`I_0` is a modified Bessel function of the first kind.
The scaling factor :math:`e^{{-\left\lvert x\right\rvert }}` removes most of the variation in :math:`I_0\left(x\right)`.
The function uses the same Chebyshev expansions as :meth:`bessel_i0_real`, which returns the unscaled value of :math:`I_0\left(x\right)`.
.. _s18ce-py2-py-references:
**References**
NIST Digital Library of Mathematical Functions
"""
raise NotImplementedError
[docs]def bessel_i1_scaled(x):
r"""
``bessel_i1_scaled`` returns a value of the scaled modified Bessel function :math:`e^{{-\left\lvert x\right\rvert }}I_1\left(x\right)`.
.. _s18cf-py2-py-doc:
For full information please refer to the NAG Library document for s18cf
https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s18cff.html
.. _s18cf-py2-py-parameters:
**Parameters**
**x** : float
The argument :math:`x` of the function.
**Returns**
**si1** : float
The value of the function at :math:`x`.
.. _s18cf-py2-py-notes:
**Notes**
``bessel_i1_scaled`` evaluates an approximation to :math:`e^{{-\left\lvert x\right\rvert }}I_1\left(x\right)`, where :math:`I_1` is a modified Bessel function of the first kind.
The scaling factor :math:`e^{{-\left\lvert x\right\rvert }}` removes most of the variation in :math:`I_1\left(x\right)`.
The function uses the same Chebyshev expansions as :meth:`bessel_i1_real`, which returns the unscaled value of :math:`I_1\left(x\right)`.
.. _s18cf-py2-py-references:
**References**
NIST Digital Library of Mathematical Functions
"""
raise NotImplementedError
[docs]def bessel_k0_scaled_vector(x):
r"""
``bessel_k0_scaled_vector`` returns an array of values of the scaled modified Bessel function :math:`e^xK_0\left(x\right)`.
.. _s18cq-py2-py-doc:
For full information please refer to the NAG Library document for s18cq
https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s18cqf.html
.. _s18cq-py2-py-parameters:
**Parameters**
**x** : float, array-like, shape :math:`\left(n\right)`
The argument :math:`x_{\textit{i}}` of the function, for :math:`\textit{i} = 1,2,\ldots,n`.
**Returns**
**f** : float, ndarray, shape :math:`\left(n\right)`
:math:`e^{x_i}K_0\left(x_i\right)`, the function values.
**ivalid** : int, ndarray, shape :math:`\left(n\right)`
:math:`\mathrm{ivalid}[\textit{i}-1]` contains the error code for :math:`x_{\textit{i}}`, for :math:`\textit{i} = 1,2,\ldots,n`.
:math:`\mathrm{ivalid}[i-1] = 0`
No error.
:math:`\mathrm{ivalid}[i-1] = 1`
On entry, :math:`x_i\leq 0.0`, :math:`K_0\left(x_i\right)` is undefined. :math:`\mathrm{f}[\textit{i}-1]` contains :math:`0.0`.
.. _s18cq-py2-py-errors:
**Raises**
**NagValueError**
(`errno` :math:`2`)
On entry, :math:`n = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`n\geq 0`.
**Warns**
**NagAlgorithmicWarning**
(`errno` :math:`1`)
On entry, at least one value of :math:`\mathrm{x}` was invalid.
Check :math:`\mathrm{ivalid}` for more information.
.. _s18cq-py2-py-notes:
**Notes**
``bessel_k0_scaled_vector`` evaluates an approximation to :math:`e^{x_i}K_0\left(x_i\right)`, where :math:`K_0` is a modified Bessel function of the second kind for an array of arguments :math:`x_{\textit{i}}`, for :math:`\textit{i} = 1,2,\ldots,n`.
The scaling factor :math:`e^x` removes most of the variation in :math:`K_0\left(x\right)`.
The function uses the same Chebyshev expansions as :meth:`bessel_k0_real_vector`, which returns an array of the unscaled values of :math:`K_0\left(x\right)`.
.. _s18cq-py2-py-references:
**References**
NIST Digital Library of Mathematical Functions
"""
raise NotImplementedError
[docs]def bessel_k1_scaled_vector(x):
r"""
``bessel_k1_scaled_vector`` returns an array of values of the scaled modified Bessel function :math:`e^xK_1\left(x\right)`.
.. _s18cr-py2-py-doc:
For full information please refer to the NAG Library document for s18cr
https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s18crf.html
.. _s18cr-py2-py-parameters:
**Parameters**
**x** : float, array-like, shape :math:`\left(n\right)`
The argument :math:`x_{\textit{i}}` of the function, for :math:`\textit{i} = 1,2,\ldots,n`.
**Returns**
**f** : float, ndarray, shape :math:`\left(n\right)`
:math:`e^{x_i}K_1\left(x_i\right)`, the function values.
**ivalid** : int, ndarray, shape :math:`\left(n\right)`
:math:`\mathrm{ivalid}[\textit{i}-1]` contains the error code for :math:`x_{\textit{i}}`, for :math:`\textit{i} = 1,2,\ldots,n`.
:math:`\mathrm{ivalid}[i-1] = 0`
No error.
:math:`\mathrm{ivalid}[i-1] = 1`
On entry, :math:`x_i\leq 0.0`, :math:`K_1\left(x_i\right)` is undefined. :math:`\mathrm{f}[\textit{i}-1]` contains :math:`0.0`.
:math:`\mathrm{ivalid}[i-1] = 2`
:math:`x_i` is too close to zero, as determined by the value of the safe-range parameter :meth:`machine.real_safe <naginterfaces.library.machine.real_safe>`: there is a danger of causing overflow. :math:`\mathrm{f}[\textit{i}-1]` contains the reciprocal of the safe-range parameter.
.. _s18cr-py2-py-errors:
**Raises**
**NagValueError**
(`errno` :math:`2`)
On entry, :math:`n = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`n\geq 0`.
**Warns**
**NagAlgorithmicWarning**
(`errno` :math:`1`)
On entry, at least one value of :math:`\mathrm{x}` was invalid.
Check :math:`\mathrm{ivalid}` for more information.
.. _s18cr-py2-py-notes:
**Notes**
``bessel_k1_scaled_vector`` evaluates an approximation to :math:`e^{x_i}K_1\left(x_i\right)`, where :math:`K_1` is a modified Bessel function of the second kind for an array of arguments :math:`x_{\textit{i}}`, for :math:`\textit{i} = 1,2,\ldots,n`.
The scaling factor :math:`e^x` removes most of the variation in :math:`K_1\left(x\right)`.
The function uses the same Chebyshev expansions as :meth:`bessel_k1_real_vector`, which returns an array of the unscaled values of :math:`K_1\left(x\right)`.
.. _s18cr-py2-py-references:
**References**
NIST Digital Library of Mathematical Functions
"""
raise NotImplementedError
[docs]def bessel_i0_scaled_vector(x):
r"""
``bessel_i0_scaled_vector`` returns an array of values of the scaled modified Bessel function :math:`e^{{-\left\lvert x\right\rvert }}I_0\left(x\right)`.
.. _s18cs-py2-py-doc:
For full information please refer to the NAG Library document for s18cs
https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s18csf.html
.. _s18cs-py2-py-parameters:
**Parameters**
**x** : float, array-like, shape :math:`\left(n\right)`
The argument :math:`x_{\textit{i}}` of the function, for :math:`\textit{i} = 1,2,\ldots,n`.
**Returns**
**f** : float, ndarray, shape :math:`\left(n\right)`
:math:`e^{{-\left\lvert x_i\right\rvert }}I_0\left(x_i\right)`, the function values.
.. _s18cs-py2-py-errors:
**Warns**
**NagAlgorithmicWarning**
(`errno` :math:`1`)
On entry, :math:`n = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`n\geq 0`.
.. _s18cs-py2-py-notes:
**Notes**
``bessel_i0_scaled_vector`` evaluates an approximation to :math:`e^{{-\left\lvert x_i\right\rvert }}I_0\left(x_i\right)`, where :math:`I_0` is a modified Bessel function of the first kind for an array of arguments :math:`x_{\textit{i}}`, for :math:`\textit{i} = 1,2,\ldots,n`.
The scaling factor :math:`e^{{-\left\lvert x\right\rvert }}` removes most of the variation in :math:`I_0\left(x\right)`.
The function uses the same Chebyshev expansions as :meth:`bessel_i0_real_vector`, which returns an array of the unscaled values of :math:`I_0\left(x\right)`.
.. _s18cs-py2-py-references:
**References**
NIST Digital Library of Mathematical Functions
"""
raise NotImplementedError
[docs]def bessel_i1_scaled_vector(x):
r"""
``bessel_i1_scaled_vector`` returns an array of values of the scaled modified Bessel function :math:`e^{{-\left\lvert x\right\rvert }}I_1\left(x\right)`.
.. _s18ct-py2-py-doc:
For full information please refer to the NAG Library document for s18ct
https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s18ctf.html
.. _s18ct-py2-py-parameters:
**Parameters**
**x** : float, array-like, shape :math:`\left(n\right)`
The argument :math:`x_{\textit{i}}` of the function, for :math:`\textit{i} = 1,2,\ldots,n`.
**Returns**
**f** : float, ndarray, shape :math:`\left(n\right)`
:math:`e^{{-\left\lvert x_i\right\rvert }}I_1\left(x_i\right)`, the function values.
.. _s18ct-py2-py-errors:
**Warns**
**NagAlgorithmicWarning**
(`errno` :math:`1`)
On entry, :math:`n = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`n\geq 0`.
.. _s18ct-py2-py-notes:
**Notes**
``bessel_i1_scaled_vector`` evaluates an approximation to :math:`e^{{-\left\lvert x_i\right\rvert }}I_1\left(x_i\right)`, where :math:`I_1` is a modified Bessel function of the first kind for an array of arguments :math:`x_{\textit{i}}`, for :math:`\textit{i} = 1,2,\ldots,n`.
The scaling factor :math:`e^{{-\left\lvert x\right\rvert }}` removes most of the variation in :math:`I_1\left(x\right)`.
The function uses the same Chebyshev expansions as :meth:`bessel_i1_real_vector`, which returns an array of the unscaled values of :math:`I_1\left(x\right)`.
.. _s18ct-py2-py-references:
**References**
NIST Digital Library of Mathematical Functions
"""
raise NotImplementedError
[docs]def bessel_k_complex(fnu, z, n, scal):
r"""
``bessel_k_complex`` returns a sequence of values for the modified Bessel functions :math:`K_{{\nu +n}}\left(z\right)` for complex :math:`z`, non-negative :math:`\nu` and :math:`n = 0,1,\ldots,N-1`, with an option for exponential scaling.
.. _s18dc-py2-py-doc:
For full information please refer to the NAG Library document for s18dc
https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s18dcf.html
.. _s18dc-py2-py-parameters:
**Parameters**
**fnu** : float
:math:`\nu`, the order of the first member of the sequence of functions.
**z** : complex
The argument :math:`z` of the functions.
**n** : int
:math:`N`, the number of members required in the sequence :math:`K_{\nu }\left(z\right),K_{{\nu +1}}\left(z\right),\ldots,K_{{\nu +N-1}}\left(z\right)`.
**scal** : str, length 1
The scaling option.
:math:`\mathrm{scal} = \texttt{'U'}`
The results are returned unscaled.
:math:`\mathrm{scal} = \texttt{'S'}`
The results are returned scaled by the factor :math:`e^z`.
**Returns**
**cy** : complex, ndarray, shape :math:`\left(\mathrm{n}\right)`
The :math:`N` required function values: :math:`\mathrm{cy}[i-1]` contains :math:`K_{{\nu +i-1}}\left(z\right)`, for :math:`\textit{i} = 1,2,\ldots,N`.
**nz** : int
The number of components of :math:`\mathrm{cy}` that are set to zero due to underflow. If :math:`\mathrm{nz} > 0` and :math:`\mathrm{Re}\left(z\right)\geq 0.0`, elements :math:`\mathrm{cy}[0],\mathrm{cy}[1],\ldots,\mathrm{cy}[\mathrm{nz}-1]` are set to zero. If :math:`\mathrm{Re}\left(z\right) < 0.0`, :math:`\mathrm{nz}` simply states the number of underflows, and not which elements they are.
.. _s18dc-py2-py-errors:
**Raises**
**NagValueError**
(`errno` :math:`1`)
On entry, :math:`\mathrm{z} = \left(0.0, 0.0\right)`.
(`errno` :math:`1`)
On entry, :math:`\mathrm{fnu} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{fnu}\geq 0.0`.
(`errno` :math:`1`)
On entry, :math:`\mathrm{scal}` has an illegal value: :math:`\mathrm{scal} = \langle\mathit{\boldsymbol{value}}\rangle`.
(`errno` :math:`1`)
On entry, :math:`\mathrm{n} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{n}\geq 1`.
(`errno` :math:`2`)
No computation because :math:`\left\lvert \mathrm{z}\right\rvert = \langle\mathit{\boldsymbol{value}}\rangle < \langle\mathit{\boldsymbol{value}}\rangle`.
(`errno` :math:`3`)
No computation because :math:`\mathrm{fnu}+\mathrm{n}-1 = \langle\mathit{\boldsymbol{value}}\rangle` is too large.
(`errno` :math:`5`)
No computation because :math:`\left\lvert \mathrm{z}\right\rvert = \langle\mathit{\boldsymbol{value}}\rangle > \langle\mathit{\boldsymbol{value}}\rangle`.
(`errno` :math:`5`)
No computation because :math:`\mathrm{fnu}+\mathrm{n}-1 = \langle\mathit{\boldsymbol{value}}\rangle > \langle\mathit{\boldsymbol{value}}\rangle`.
(`errno` :math:`6`)
No computation -- algorithm termination condition not met.
**Warns**
**NagAlgorithmicWarning**
(`errno` :math:`4`)
Results lack precision because :math:`\left\lvert \mathrm{z}\right\rvert = \langle\mathit{\boldsymbol{value}}\rangle > \langle\mathit{\boldsymbol{value}}\rangle`.
(`errno` :math:`4`)
Results lack precision because :math:`\mathrm{fnu}+\mathrm{n}-1 = \langle\mathit{\boldsymbol{value}}\rangle > \langle\mathit{\boldsymbol{value}}\rangle`.
.. _s18dc-py2-py-notes:
**Notes**
``bessel_k_complex`` evaluates a sequence of values for the modified Bessel function :math:`K_{\nu }\left(z\right)`, where :math:`z` is complex, :math:`{-\pi } < {\mathrm{arg}z}\leq \pi`, and :math:`\nu` is the real, non-negative order.
The :math:`N`-member sequence is generated for orders :math:`\nu`, :math:`\nu +1,\ldots,\nu +N-1`.
Optionally, the sequence is scaled by the factor :math:`e^z`.
The function is derived from the function CBESK in Amos (1986).
**Note:** although the function may not be called with :math:`\nu` less than zero, for negative orders the formula :math:`K_{{-\nu }}\left(z\right) = K_{\nu }\left(z\right)` may be used.
When :math:`N` is greater than :math:`1`, extra values of :math:`K_{\nu }\left(z\right)` are computed using recurrence relations.
For very large :math:`\left\lvert z\right\rvert` or :math:`\left(\nu +N-1\right)`, argument reduction will cause total loss of accuracy, and so no computation is performed.
For slightly smaller :math:`\left\lvert z\right\rvert` or :math:`\left(\nu +N-1\right)`, the computation is performed but results are accurate to less than half of machine precision.
If :math:`\left\lvert z\right\rvert` is very small, near the machine underflow threshold, or :math:`\left(\nu +N-1\right)` is too large, there is a risk of overflow and so no computation is performed.
In all the above cases, a warning is given by the function.
.. _s18dc-py2-py-references:
**References**
NIST Digital Library of Mathematical Functions
Amos, D E, 1986, `Algorithm 644: A portable package for Bessel functions of a complex argument and non-negative order`, ACM Trans. Math. Software (12), 265--273
"""
raise NotImplementedError
[docs]def bessel_i_complex(fnu, z, n, scal):
r"""
``bessel_i_complex`` returns a sequence of values for the modified Bessel functions :math:`I_{{\nu +n}}\left(z\right)` for complex :math:`z`, non-negative :math:`\nu` and :math:`n = 0,1,\ldots,N-1`, with an option for exponential scaling.
.. _s18de-py2-py-doc:
For full information please refer to the NAG Library document for s18de
https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s18def.html
.. _s18de-py2-py-parameters:
**Parameters**
**fnu** : float
:math:`\nu`, the order of the first member of the sequence of functions.
**z** : complex
The argument :math:`z` of the functions.
**n** : int
:math:`N`, the number of members required in the sequence :math:`I_{\nu }\left(z\right),I_{{\nu +1}}\left(z\right),\ldots,I_{{\nu +N-1}}\left(z\right)`.
**scal** : str, length 1
The scaling option.
:math:`\mathrm{scal} = \texttt{'U'}`
The results are returned unscaled.
:math:`\mathrm{scal} = \texttt{'S'}`
The results are returned scaled by the factor :math:`e^{{-\left\lvert \mathrm{Re}\left(z\right)\right\rvert }}`.
**Returns**
**cy** : complex, ndarray, shape :math:`\left(\mathrm{n}\right)`
The :math:`N` required function values: :math:`\mathrm{cy}[i-1]` contains :math:`I_{{\nu +i-1}}\left(z\right)`, for :math:`\textit{i} = 1,2,\ldots,N`.
**nz** : int
The number of components of :math:`\mathrm{cy}` that are set to zero due to underflow.
If :math:`\mathrm{nz} > 0`, then elements :math:`\mathrm{cy}[\mathrm{n}-\mathrm{nz}],\mathrm{cy}[\mathrm{n}-\mathrm{nz}+1],\ldots,\mathrm{cy}[\mathrm{n}-1]` are set to zero.
.. _s18de-py2-py-errors:
**Raises**
**NagValueError**
(`errno` :math:`1`)
On entry, :math:`\mathrm{fnu} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{fnu}\geq 0.0`.
(`errno` :math:`1`)
On entry, :math:`\mathrm{scal}` has an illegal value: :math:`\mathrm{scal} = \langle\mathit{\boldsymbol{value}}\rangle`.
(`errno` :math:`1`)
On entry, :math:`\mathrm{n} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{n}\geq 1`.
(`errno` :math:`2`)
No computation because :math:`\mathrm{Re}\left(\mathrm{z}\right) = \langle\mathit{\boldsymbol{value}}\rangle > \langle\mathit{\boldsymbol{value}}\rangle`, :math:`\mathrm{scal} = \texttt{'U'}`.
(`errno` :math:`4`)
No computation because :math:`\left\lvert \mathrm{z}\right\rvert = \langle\mathit{\boldsymbol{value}}\rangle > \langle\mathit{\boldsymbol{value}}\rangle`.
(`errno` :math:`4`)
No computation because :math:`\mathrm{fnu}+\mathrm{n}-1 = \langle\mathit{\boldsymbol{value}}\rangle > \langle\mathit{\boldsymbol{value}}\rangle`.
(`errno` :math:`5`)
No computation -- algorithm termination condition not met.
**Warns**
**NagAlgorithmicWarning**
(`errno` :math:`3`)
Results lack precision because :math:`\left\lvert \mathrm{z}\right\rvert = \langle\mathit{\boldsymbol{value}}\rangle > \langle\mathit{\boldsymbol{value}}\rangle`.
(`errno` :math:`3`)
Results lack precision because :math:`\mathrm{fnu}+\mathrm{n}-1 = \langle\mathit{\boldsymbol{value}}\rangle > \langle\mathit{\boldsymbol{value}}\rangle`.
.. _s18de-py2-py-notes:
**Notes**
``bessel_i_complex`` evaluates a sequence of values for the modified Bessel function :math:`I_{\nu }\left(z\right)`, where :math:`z` is complex, :math:`{-\pi } < {\mathrm{arg}z}\leq \pi`, and :math:`\nu` is the real, non-negative order.
The :math:`N`-member sequence is generated for orders :math:`\nu,\nu +1,\ldots,\nu +N-1`.
Optionally, the sequence is scaled by the factor :math:`e^{{-\left\lvert \mathrm{Re}\left(z\right)\right\rvert }}`.
The function is derived from the function CBESI in Amos (1986).
**Note:** although the function may not be called with :math:`\nu` less than zero, for negative orders the formula :math:`I_{{-\nu }}\left(z\right) = I_{\nu }\left(z\right)+\frac{2}{\pi }\sin\left(\pi \nu \right)K_{\nu }\left(z\right)` may be used (for the Bessel function :math:`K_{\nu }\left(z\right)`, see :meth:`bessel_k_complex`).
When :math:`N` is greater than :math:`1`, extra values of :math:`I_{\nu }\left(z\right)` are computed using recurrence relations.
For very large :math:`\left\lvert z\right\rvert` or :math:`\left(\nu +N-1\right)`, argument reduction will cause total loss of accuracy, and so no computation is performed.
For slightly smaller :math:`\left\lvert z\right\rvert` or :math:`\left(\nu +N-1\right)`, the computation is performed but results are accurate to less than half of machine precision.
If :math:`\mathrm{Re}\left(z\right)` is too large and the unscaled function is required, there is a risk of overflow and so no computation is performed.
In all the above cases, a warning is given by the function.
.. _s18de-py2-py-references:
**References**
NIST Digital Library of Mathematical Functions
Amos, D E, 1986, `Algorithm 644: A portable package for Bessel functions of a complex argument and non-negative order`, ACM Trans. Math. Software (12), 265--273
"""
raise NotImplementedError
[docs]def struve_l0(x):
r"""
``struve_l0`` returns the value of the modified Struve function of order :math:`0`, :math:`L_0\left(x\right)`.
.. _s18ga-py2-py-doc:
For full information please refer to the NAG Library document for s18ga
https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s18gaf.html
.. _s18ga-py2-py-parameters:
**Parameters**
**x** : float
The argument :math:`x` of the function.
**Returns**
**l0** : float
The value of the function at :math:`x`.
.. _s18ga-py2-py-errors:
**Raises**
**NagValueError**
(`errno` :math:`1`)
The value of :math:`L_0\left(x\right)` is larger than the largest positive floating-point number, which is returned.
.. _s18ga-py2-py-notes:
**Notes**
``struve_l0`` evaluates an approximation to the modified Struve function of order zero, :math:`L_0\left(x\right)`.
Please consult the NIST Digital Library of Mathematical Functions for a detailed discussion of the Struve function including special cases, transformations, relations and asymptotic approximations.
The approximation method used by this function is based on Chebyshev expansions.
.. _s18ga-py2-py-references:
**References**
NIST Digital Library of Mathematical Functions
MacLeod, A J, 1996, `MISCFUN, a software package to compute uncommon special functions`, ACM Trans. Math. Software (TOMS) (22(3)), 288--301
"""
raise NotImplementedError
[docs]def struve_l1(x):
r"""
``struve_l1`` returns the value of the modified Struve function of order :math:`1`, :math:`L_1\left(x\right)`.
.. _s18gb-py2-py-doc:
For full information please refer to the NAG Library document for s18gb
https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s18gbf.html
.. _s18gb-py2-py-parameters:
**Parameters**
**x** : float
The argument :math:`x` of the function.
**Returns**
**l1** : float
The value of the function at :math:`x`.
.. _s18gb-py2-py-errors:
**Raises**
**NagValueError**
(`errno` :math:`1`)
The value of :math:`L_1\left(x\right)` is larger than the largest positive floating-point number, which is returned.
.. _s18gb-py2-py-notes:
**Notes**
``struve_l1`` evaluates an approximation to the modified Struve function of order :math:`1`, :math:`L_1\left(x\right)`.
Please consult the NIST Digital Library of Mathematical Functions for a detailed discussion of the Struve function including special cases, transformations, relations and asymptotic approximations.
The approximation method used by this function is based on Chebyshev expansions.
.. _s18gb-py2-py-references:
**References**
NIST Digital Library of Mathematical Functions
MacLeod, A J, 1996, `MISCFUN, a software package to compute uncommon special functions`, ACM Trans. Math. Software (TOMS) (22(3)), 288--301
"""
raise NotImplementedError
[docs]def struve_i0ml0(x):
r"""
``struve_i0ml0`` returns the value of :math:`I_0\left(x\right)-L_0\left(x\right)` where :math:`I_0\left(x\right)` is the modified Bessel function of the first kind of order zero, and :math:`L_0\left(x\right)` is the modified Struve function of order :math:`0`.
.. _s18gc-py2-py-doc:
For full information please refer to the NAG Library document for s18gc
https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s18gcf.html
.. _s18gc-py2-py-parameters:
**Parameters**
**x** : float
The argument :math:`x` of the function.
**Returns**
**iml0** : float
The value of the function at :math:`x`.
.. _s18gc-py2-py-errors:
**Raises**
**NagValueError**
(`errno` :math:`1`)
On entry, :math:`\mathrm{x} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{x}\geq 0.0`.
.. _s18gc-py2-py-notes:
**Notes**
``struve_i0ml0`` evaluates an approximation to :math:`I_0\left(x\right)-L_0\left(x\right)`.
Please consult the NIST Digital Library of Mathematical Functions for a detailed discussion of the Struve function including special cases, transformations, relations and asymptotic approximations.
The approximation method used by this function is based on Chebyshev expansions.
.. _s18gc-py2-py-references:
**References**
NIST Digital Library of Mathematical Functions
MacLeod, A J, 1996, `MISCFUN, a software package to compute uncommon special functions`, ACM Trans. Math. Software (TOMS) (22(3)), 288--301
"""
raise NotImplementedError
[docs]def struve_i1ml1(x):
r"""
``struve_i1ml1`` returns the value of :math:`I_1\left(x\right)-L_1\left(x\right)` where :math:`I_1\left(x\right)` is the modified Bessel function of the first kind of order :math:`1`, and :math:`L_1\left(x\right)` is the modified Struve function of order :math:`1`.
.. _s18gd-py2-py-doc:
For full information please refer to the NAG Library document for s18gd
https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s18gdf.html
.. _s18gd-py2-py-parameters:
**Parameters**
**x** : float
The argument :math:`x` of the function.
**Returns**
**iml1** : float
The value of the function at :math:`x`.
.. _s18gd-py2-py-errors:
**Raises**
**NagValueError**
(`errno` :math:`1`)
On entry, :math:`\mathrm{x} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{x}\geq 0.0`.
.. _s18gd-py2-py-notes:
**Notes**
``struve_i1ml1`` evaluates an approximation to :math:`I_1\left(x\right)-L_1\left(x\right)`.
Please consult the NIST Digital Library of Mathematical Functions for a detailed discussion of the Struve function including special cases, transformations, relations and asymptotic approximations.
The approximation method used by this function is based on Chebyshev expansions.
.. _s18gd-py2-py-references:
**References**
NIST Digital Library of Mathematical Functions
MacLeod, A J, 1996, `MISCFUN, a software package to compute uncommon special functions`, ACM Trans. Math. Software (TOMS) (22(3)), 288--301
"""
raise NotImplementedError
[docs]def bessel_j_seq_complex(z, a, nl):
r"""
``bessel_j_seq_complex`` returns a sequence of values for the Bessel functions :math:`J_{{\alpha +n-1}}\left(z\right)` or :math:`J_{{\alpha -n+1}}\left(z\right)` for complex :math:`z`, non-negative :math:`\alpha < 1` and :math:`n = 1,2,\ldots,\left\lvert N\right\rvert +1`.
.. _s18gk-py2-py-doc:
For full information please refer to the NAG Library document for s18gk
https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s18gkf.html
.. _s18gk-py2-py-parameters:
**Parameters**
**z** : complex
The argument :math:`z` of the function.
**a** : float
The order :math:`\alpha` of the first member in the required sequence of function values.
**nl** : int
The value of :math:`N`.
**Returns**
**b** : complex, ndarray, shape :math:`\left(\left\lvert \mathrm{nl}\right\rvert +1\right)`
With the function exits successfully or :math:`\mathrm{errno}` = 3, the required sequence of function values: :math:`\mathrm{b}[\textit{n}-1]` contains :math:`J_{{\alpha +\textit{n}-1}}\left(z\right)` if :math:`\mathrm{nl}\geq 0` and :math:`J_{{\alpha -\textit{n}+1}}\left(z\right)` otherwise, for :math:`\textit{n} = 1,2,\ldots,\mathrm{abs}\left(\mathrm{nl}\right)+1`.
.. _s18gk-py2-py-errors:
**Raises**
**NagValueError**
(`errno` :math:`1`)
On entry, :math:`\left\lvert \mathrm{nl}\right\rvert = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\left\lvert \mathrm{nl}\right\rvert \leq 101`.
(`errno` :math:`1`)
On entry, :math:`\mathrm{a} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{a} < 1.0`.
(`errno` :math:`1`)
On entry, :math:`\mathrm{a} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{a}\geq 0.0`.
(`errno` :math:`1`)
On entry, :math:`\mathrm{nl} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: when :math:`\mathrm{nl} < 0`, :math:`\mathrm{z}\neq \left(0.0, 0.0\right)`.
(`errno` :math:`2`)
Computation abandoned due to the likelihood of overflow.
(`errno` :math:`4`)
Computation abandoned due to total loss of precision.
(`errno` :math:`5`)
Computation abandoned due to failure to satisfy the termination condition.
**Warns**
**NagAlgorithmicWarning**
(`errno` :math:`3`)
Computation completed but some precision has been lost.
.. _s18gk-py2-py-notes:
**Notes**
``bessel_j_seq_complex`` evaluates a sequence of values for the Bessel function of the first kind :math:`J_{\alpha }\left(z\right)`, where :math:`z` is complex and nonzero and :math:`\alpha` is the order with :math:`0\leq \alpha < 1`.
The :math:`\left(\left\lvert N\right\rvert +1\right)`-member sequence is generated for orders :math:`\alpha,\alpha +1,\ldots,\alpha +\left\lvert N\right\rvert` when :math:`N\geq 0`.
Note that :math:`+` is replaced by :math:`-` when :math:`N < 0`.
For positive orders the function may also be called with :math:`z = 0`, since :math:`J_q\left(0\right) = 0` when :math:`q > 0`.
For negative orders the formula
.. math::
J_{{-q}}\left(z\right) = \cos\left(\pi q\right)J_q\left(z\right)-\sin\left(\pi q\right)Y_q\left(z\right)
is used to generate the required sequence.
The appropriate values of :math:`J_q\left(z\right)` and :math:`Y_q\left(z\right)` are obtained by calls to :meth:`bessel_j_complex` and :meth:`bessel_y_complex`.
.. _s18gk-py2-py-references:
**References**
NIST Digital Library of Mathematical Functions
"""
raise NotImplementedError
[docs]def kelvin_ber(x):
r"""
``kelvin_ber`` returns a value for the Kelvin function :math:`\mathrm{ber}\left(x\right)`.
.. _s19aa-py2-py-doc:
For full information please refer to the NAG Library document for s19aa
https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s19aaf.html
.. _s19aa-py2-py-parameters:
**Parameters**
**x** : float
The argument :math:`x` of the function.
**Returns**
**ber** : float
The value of the function at :math:`x`.
.. _s19aa-py2-py-errors:
**Raises**
**NagValueError**
(`errno` :math:`1`)
On entry, :math:`\mathrm{x} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\left\lvert \mathrm{x}\right\rvert \leq \langle\mathit{\boldsymbol{value}}\rangle`.
:math:`\left\lvert \mathrm{x}\right\rvert` is too large for an accurate result to be returned and the function returns zero.
.. _s19aa-py2-py-notes:
**Notes**
``kelvin_ber`` evaluates an approximation to the Kelvin function :math:`\mathrm{ber}\left(x\right)`.
**Note:** :math:`\mathrm{ber}\left(-x\right) = \mathrm{ber}\left(x\right)`, so the approximation need only consider :math:`x\geq 0.0`.
The function is based on several Chebyshev expansions:
For :math:`0\leq x\leq 5`,
.. math::
\mathrm{ber}\left(x\right) = {\sum^\prime}_{{r = 0}}a_rT_r\left(t\right)\text{, with }t = 2\left(\frac{x}{5}\right)^4-1\text{.}
For :math:`x > 5`,
.. math::
\begin{array}{ll}\mathrm{ber}\left(x\right) = &\frac{e^{{x/\sqrt{2}}}}{{\sqrt{2\pi x}}} \left[\left(1+\frac{1}{x}a\left(t\right)\right)\cos\left(\alpha \right)+\frac{1}{x}b\left(t\right)\sin\left(\alpha \right)\right] \\&\\&+\frac{e^{{-x/\sqrt{2}}}}{{\sqrt{2\pi x}}} \left[\left(1+\frac{1}{x}c\left(t\right)\right)\sin\left(\beta \right)+\frac{1}{x}d\left(t\right)\cos\left(\beta \right)\right] \text{,}\end{array}
where :math:`\alpha = \frac{x}{\sqrt{2}}-\frac{\pi }{8}`, :math:`\beta = \frac{x}{\sqrt{2}}+\frac{\pi }{8}`,
and :math:`a\left(t\right)`, :math:`b\left(t\right)`, :math:`c\left(t\right)`, and :math:`d\left(t\right)` are expansions in the variable :math:`t = \frac{10}{x}-1`.
When :math:`x` is sufficiently close to zero, the result is set directly to :math:`\mathrm{ber}\left(0\right) = 1.0`.
For large :math:`x`, there is a danger of the result being totally inaccurate, as the error amplification factor grows in an essentially exponential manner;, therefore, the function must fail.
.. _s19aa-py2-py-references:
**References**
NIST Digital Library of Mathematical Functions
"""
raise NotImplementedError
[docs]def kelvin_bei(x):
r"""
``kelvin_bei`` returns a value for the Kelvin function :math:`\mathrm{bei}\left(x\right)`.
.. _s19ab-py2-py-doc:
For full information please refer to the NAG Library document for s19ab
https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s19abf.html
.. _s19ab-py2-py-parameters:
**Parameters**
**x** : float
The argument :math:`x` of the function.
**Returns**
**bei** : float
The value of the function at :math:`x`.
.. _s19ab-py2-py-errors:
**Raises**
**NagValueError**
(`errno` :math:`1`)
On entry, :math:`\mathrm{x} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\left\lvert \mathrm{x}\right\rvert \leq \langle\mathit{\boldsymbol{value}}\rangle`.
:math:`\left\lvert \mathrm{x}\right\rvert` is too large for an accurate result to be returned and the function returns zero.
.. _s19ab-py2-py-notes:
**Notes**
``kelvin_bei`` evaluates an approximation to the Kelvin function :math:`\mathrm{bei}\left(x\right)`.
**Note:** :math:`\mathrm{bei}\left(-x\right) = \mathrm{bei}\left(x\right)`, so the approximation need only consider :math:`x\geq 0.0`.
The function is based on several Chebyshev expansions:
For :math:`0\leq x\leq 5`,
.. math::
\mathrm{bei}\left(x\right) = \frac{x^2}{4}\sum_{{r = 0}}^{\prime }a_rT_r\left(t\right)\text{, with }t = 2\left(\frac{x}{5}\right)^4-1\text{;}
For :math:`x > 5`,
.. math::
\mathrm{bei}\left(x\right) = \frac{e^{{x/\sqrt{2}}}}{{\sqrt{2\pi x}}}\left[\left(1+\frac{1}{x}a\left(t\right)\right)\sin\left(\alpha \right)-\frac{1}{x}b\left(t\right)\cos\left(\alpha \right)\right]
.. math::
+\frac{e^{{x/\sqrt{2}}}}{{\sqrt{2\pi x}}}\left[\left(1+\frac{1}{x}c\left(t\right)\right)\cos\left(\beta \right)-\frac{1}{x}d\left(t\right)\sin\left(\beta \right)\right]
where :math:`\alpha = \frac{x}{\sqrt{2}}-\frac{\pi }{8}`, :math:`\beta = \frac{x}{\sqrt{2}}+\frac{\pi }{8}`,
and :math:`a\left(t\right)`, :math:`b\left(t\right)`, :math:`c\left(t\right)`, and :math:`d\left(t\right)` are expansions in the variable :math:`t = \frac{10}{x}-1`.
When :math:`x` is sufficiently close to zero, the result is computed as :math:`\mathrm{bei}\left(x\right) = \frac{x^2}{4}`.
If this result would underflow, the result returned is :math:`\mathrm{bei}\left(x\right) = 0.0`.
For large :math:`x`, there is a danger of the result being totally inaccurate, as the error amplification factor grows in an essentially exponential manner;, therefore, the function must fail.
.. _s19ab-py2-py-references:
**References**
NIST Digital Library of Mathematical Functions
"""
raise NotImplementedError
[docs]def kelvin_ker(x):
r"""
``kelvin_ker`` returns a value for the Kelvin function :math:`\mathrm{ker}\left(x\right)`.
.. _s19ac-py2-py-doc:
For full information please refer to the NAG Library document for s19ac
https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s19acf.html
.. _s19ac-py2-py-parameters:
**Parameters**
**x** : float
The argument :math:`x` of the function.
**Returns**
**ker** : float
The value of the function at :math:`x`.
.. _s19ac-py2-py-errors:
**Raises**
**NagValueError**
(`errno` :math:`1`)
On entry, :math:`\mathrm{x} = \langle\mathit{\boldsymbol{value}}\rangle`. The function returns zero.
Constraint: :math:`\mathrm{x}\leq \langle\mathit{\boldsymbol{value}}\rangle`.
:math:`\mathrm{x}` is too large, the result underflows and the function returns zero.
(`errno` :math:`2`)
On entry, :math:`\mathrm{x} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{x} > 0.0`.
The function is undefined and returns zero.
.. _s19ac-py2-py-notes:
**Notes**
``kelvin_ker`` evaluates an approximation to the Kelvin function :math:`\mathrm{ker}\left(x\right)`.
**Note:** for :math:`x < 0` the function is undefined and at :math:`x = 0` it is infinite so we need only consider :math:`x > 0`.
The function is based on several Chebyshev expansions:
For :math:`0 < x\leq 1`,
.. math::
\mathrm{ker}\left(x\right) = -f\left(t\right)\log\left(x\right)+\frac{\pi }{16}x^2g\left(t\right)+y\left(t\right)
where :math:`f\left(t\right)`, :math:`g\left(t\right)` and :math:`y\left(t\right)` are expansions in the variable :math:`t = 2x^4-1`.
For :math:`1 < x\leq 3`,
.. math::
\mathrm{ker}\left(x\right) = \mathrm{exp}\left(-\frac{11}{16}x\right)q\left(t\right)
where :math:`q\left(t\right)` is an expansion in the variable :math:`t = x-2`.
For :math:`x > 3`,
.. math::
\mathrm{ker}\left(x\right) = \sqrt{\frac{\pi }{{2x}}}e^{{-x/\sqrt{2}}}\left[\left(1+\frac{1}{x}c\left(t\right)\right)\cos\left(\beta \right)-\frac{1}{x}d\left(t\right)\sin\left(\beta \right)\right]
where :math:`\beta = \frac{x}{\sqrt{2}}+\frac{\pi }{8}`, and :math:`c\left(t\right)` and :math:`d\left(t\right)` are expansions in the variable :math:`t = \frac{6}{x}-1`.
When :math:`x` is sufficiently close to zero, the result is computed as
.. math::
\mathrm{ker}\left(x\right) = -\gamma -\log\left(\frac{x}{2}\right)+\left(\pi -\frac{3}{8}x^2\right)\frac{x^2}{16}
and when :math:`x` is even closer to zero, simply as :math:`\mathrm{ker}\left(x\right) = -\gamma -\log\left(\frac{x}{2}\right)`.
For large :math:`x`, :math:`\mathrm{ker}\left(x\right)` is asymptotically given by :math:`\sqrt{\frac{\pi }{{2x}}}e^{{-x/\sqrt{2}}}` and this becomes so small that it cannot be computed without underflow and the function fails.
.. _s19ac-py2-py-references:
**References**
NIST Digital Library of Mathematical Functions
"""
raise NotImplementedError
[docs]def kelvin_kei(x):
r"""
``kelvin_kei`` returns a value for the Kelvin function :math:`\mathrm{kei}\left(x\right)`.
.. _s19ad-py2-py-doc:
For full information please refer to the NAG Library document for s19ad
https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s19adf.html
.. _s19ad-py2-py-parameters:
**Parameters**
**x** : float
The argument :math:`x` of the function.
**Returns**
**kei** : float
The value of the function at :math:`x`.
.. _s19ad-py2-py-errors:
**Raises**
**NagValueError**
(`errno` :math:`1`)
On entry, :math:`\mathrm{x} = \langle\mathit{\boldsymbol{value}}\rangle`. The function returns zero.
Constraint: :math:`\mathrm{x}\leq \langle\mathit{\boldsymbol{value}}\rangle`.
:math:`\mathrm{x}` is too large, the result underflows and the function returns zero.
(`errno` :math:`2`)
On entry, :math:`\mathrm{x} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{x}\geq 0.0`.
The function is undefined and returns zero.
.. _s19ad-py2-py-notes:
**Notes**
``kelvin_kei`` evaluates an approximation to the Kelvin function :math:`\mathrm{kei}\left(x\right)`.
**Note:** for :math:`x < 0` the function is undefined, so we need only consider :math:`x\geq 0`.
The function is based on several Chebyshev expansions:
For :math:`0\leq x\leq 1`,
.. math::
\mathrm{kei}\left(x\right) = -\frac{\pi }{4}f\left(t\right)+\frac{x^2}{4}\left[-g\left(t\right)\log\left(x\right)+v\left(t\right)\right]
where :math:`f\left(t\right)`, :math:`g\left(t\right)` and :math:`v\left(t\right)` are expansions in the variable :math:`t = 2x^4-1`;
For :math:`1 < x\leq 3`,
.. math::
\mathrm{kei}\left(x\right) = \mathrm{exp}\left(-\frac{9}{8}x\right)u\left(t\right)
where :math:`u\left(t\right)` is an expansion in the variable :math:`t = x-2`;
For :math:`x > 3`,
.. math::
\mathrm{kei}\left(x\right) = \sqrt{\frac{\pi }{{2x}}}e^{{-x/\sqrt{2}}}\left[\left(1+\frac{1}{x}\right)c\left(t\right)\sin\left(\beta \right)+\frac{1}{x}d\left(t\right)\cos\left(\beta \right)\right]
where :math:`\beta = \frac{x}{\sqrt{2}}+\frac{\pi }{8}`, and :math:`c\left(t\right)` and :math:`d\left(t\right)` are expansions in the variable :math:`t = \frac{6}{x}-1`.
For :math:`x < 0`, the function is undefined, and hence the function fails and returns zero.
When :math:`x` is sufficiently close to zero, the result is computed as
.. math::
\mathrm{kei}\left(x\right) = -\frac{\pi }{4}+\left(1-\gamma -\log\left(\frac{x}{2}\right)\right)\frac{x^2}{4}
and when :math:`x` is even closer to zero simply as
.. math::
\mathrm{kei}\left(x\right) = -\frac{\pi }{4}\text{.}
For large :math:`x`, :math:`\mathrm{kei}\left(x\right)` is asymptotically given by :math:`\sqrt{\frac{\pi }{{2x}}}e^{{-x/\sqrt{2}}}` and this becomes so small that it cannot be computed without underflow and the function fails.
.. _s19ad-py2-py-references:
**References**
NIST Digital Library of Mathematical Functions
"""
raise NotImplementedError
[docs]def kelvin_ber_vector(x):
r"""
``kelvin_ber_vector`` returns an array of values for the Kelvin function :math:`\mathrm{ber}\left(x\right)`.
.. _s19an-py2-py-doc:
For full information please refer to the NAG Library document for s19an
https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s19anf.html
.. _s19an-py2-py-parameters:
**Parameters**
**x** : float, array-like, shape :math:`\left(n\right)`
The argument :math:`x_{\textit{i}}` of the function, for :math:`\textit{i} = 1,2,\ldots,n`.
**Returns**
**f** : float, ndarray, shape :math:`\left(n\right)`
:math:`\mathrm{ber}\left(x_i\right)`, the function values.
**ivalid** : int, ndarray, shape :math:`\left(n\right)`
:math:`\mathrm{ivalid}[\textit{i}-1]` contains the error code for :math:`x_{\textit{i}}`, for :math:`\textit{i} = 1,2,\ldots,n`.
:math:`\mathrm{ivalid}[i-1] = 0`
No error.
:math:`\mathrm{ivalid}[i-1] = 1`
:math:`\mathrm{abs}\left(x_i\right)` is too large for an accurate result to be returned. :math:`\mathrm{f}[\textit{i}-1]` contains zero. The threshold value is the same as for :math:`\mathrm{errno}` = 1 in :meth:`kelvin_ber`.
.. _s19an-py2-py-errors:
**Raises**
**NagValueError**
(`errno` :math:`2`)
On entry, :math:`n = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`n\geq 0`.
**Warns**
**NagAlgorithmicWarning**
(`errno` :math:`1`)
On entry, at least one value of :math:`\mathrm{x}` was invalid.
Check :math:`\mathrm{ivalid}` for more information.
.. _s19an-py2-py-notes:
**Notes**
``kelvin_ber_vector`` evaluates an approximation to the Kelvin function :math:`\mathrm{ber}\left(x_i\right)` for an array of arguments :math:`x_{\textit{i}}`, for :math:`\textit{i} = 1,2,\ldots,n`.
**Note:** :math:`\mathrm{ber}\left(-x\right) = \mathrm{ber}\left(x\right)`, so the approximation need only consider :math:`x\geq 0.0`.
The function is based on several Chebyshev expansions:
For :math:`0\leq x\leq 5`,
.. math::
\mathrm{ber}\left(x\right) = {\sum^\prime}_{{r = 0}}a_rT_r\left(t\right)\text{, with }t = 2\left(\frac{x}{5}\right)^4-1\text{.}
For :math:`x > 5`,
.. math::
\begin{array}{ll}\mathrm{ber}\left(x\right) = & \frac{e^{{x/\sqrt{2}}}}{{\sqrt{2\pi x}}} \left[\left(1+\frac{1}{x}a\left(t\right)\right)\cos\left(\alpha \right)+\frac{1}{x}b\left(t\right)\sin\left(\alpha \right)\right] \\&\\&+\frac{e^{{-x/\sqrt{2}}}}{{\sqrt{2\pi x}}} \left[\left(1+\frac{1}{x}c\left(t\right)\right)\sin\left(\beta \right)+\frac{1}{x}d\left(t\right)\cos\left(\beta \right)\right] \text{,}\end{array}
where :math:`\alpha = \frac{x}{\sqrt{2}}-\frac{\pi }{8}`, :math:`\beta = \frac{x}{\sqrt{2}}+\frac{\pi }{8}`,
and :math:`a\left(t\right)`, :math:`b\left(t\right)`, :math:`c\left(t\right)`, and :math:`d\left(t\right)` are expansions in the variable :math:`t = \frac{10}{x}-1`.
When :math:`x` is sufficiently close to zero, the result is set directly to :math:`\mathrm{ber}\left(0\right) = 1.0`.
For large :math:`x`, there is a danger of the result being totally inaccurate, as the error amplification factor grows in an essentially exponential manner;, therefore, the function must fail.
.. _s19an-py2-py-references:
**References**
NIST Digital Library of Mathematical Functions
"""
raise NotImplementedError
[docs]def kelvin_bei_vector(x):
r"""
``kelvin_bei_vector`` returns an array of values for the Kelvin function :math:`\mathrm{bei}\left(x\right)`.
.. _s19ap-py2-py-doc:
For full information please refer to the NAG Library document for s19ap
https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s19apf.html
.. _s19ap-py2-py-parameters:
**Parameters**
**x** : float, array-like, shape :math:`\left(n\right)`
The argument :math:`x_{\textit{i}}` of the function, for :math:`\textit{i} = 1,2,\ldots,n`.
**Returns**
**f** : float, ndarray, shape :math:`\left(n\right)`
:math:`\mathrm{bei}\left(x_i\right)`, the function values.
**ivalid** : int, ndarray, shape :math:`\left(n\right)`
:math:`\mathrm{ivalid}[\textit{i}-1]` contains the error code for :math:`x_{\textit{i}}`, for :math:`\textit{i} = 1,2,\ldots,n`.
:math:`\mathrm{ivalid}[i-1] = 0`
No error.
:math:`\mathrm{ivalid}[i-1] = 1`
:math:`\mathrm{abs}\left(x_i\right)` is too large for an accurate result to be returned. :math:`\mathrm{f}[\textit{i}-1]` contains zero. The threshold value is the same as for :math:`\mathrm{errno}` = 1 in :meth:`kelvin_bei`.
.. _s19ap-py2-py-errors:
**Raises**
**NagValueError**
(`errno` :math:`2`)
On entry, :math:`n = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`n\geq 0`.
**Warns**
**NagAlgorithmicWarning**
(`errno` :math:`1`)
On entry, at least one value of :math:`\mathrm{x}` was invalid.
Check :math:`\mathrm{ivalid}` for more information.
.. _s19ap-py2-py-notes:
**Notes**
``kelvin_bei_vector`` evaluates an approximation to the Kelvin function :math:`\mathrm{bei}\left(x_i\right)` for an array of arguments :math:`x_{\textit{i}}`, for :math:`\textit{i} = 1,2,\ldots,n`.
**Note:** :math:`\mathrm{bei}\left(-x\right) = \mathrm{bei}\left(x\right)`, so the approximation need only consider :math:`x\geq 0.0`.
The function is based on several Chebyshev expansions:
For :math:`0\leq x\leq 5`,
.. math::
\mathrm{bei}\left(x\right) = \frac{x^2}{4}{\sum^\prime}_{{r = 0}}a_rT_r\left(t\right)\text{, with }t = 2\left(\frac{x}{5}\right)^4-1\text{;}
For :math:`x > 5`,
.. math::
\mathrm{bei}\left(x\right) = \frac{e^{{x/\sqrt{2}}}}{{\sqrt{2\pi x}}}\left[\left(1+\frac{1}{x}a\left(t\right)\right)\sin\left(\alpha \right)-\frac{1}{x}b\left(t\right)\cos\left(\alpha \right)\right]
.. math::
+\frac{e^{{x/\sqrt{2}}}}{{\sqrt{2\pi x}}}\left[\left(1+\frac{1}{x}c\left(t\right)\right)\cos\left(\beta \right)-\frac{1}{x}d\left(t\right)\sin\left(\beta \right)\right]
where :math:`\alpha = \frac{x}{\sqrt{2}}-\frac{\pi }{8}`, :math:`\beta = \frac{x}{\sqrt{2}}+\frac{\pi }{8}`,
and :math:`a\left(t\right)`, :math:`b\left(t\right)`, :math:`c\left(t\right)`, and :math:`d\left(t\right)` are expansions in the variable :math:`t = \frac{10}{x}-1`.
When :math:`x` is sufficiently close to zero, the result is computed as :math:`\mathrm{bei}\left(x\right) = \frac{x^2}{4}`.
If this result would underflow, the result returned is :math:`\mathrm{bei}\left(x\right) = 0.0`.
For large :math:`x`, there is a danger of the result being totally inaccurate, as the error amplification factor grows in an essentially exponential manner;, therefore, the function must fail.
.. _s19ap-py2-py-references:
**References**
NIST Digital Library of Mathematical Functions
"""
raise NotImplementedError
[docs]def kelvin_ker_vector(x):
r"""
``kelvin_ker_vector`` returns an array of values for the Kelvin function :math:`\mathrm{ker}\left(x\right)`.
.. _s19aq-py2-py-doc:
For full information please refer to the NAG Library document for s19aq
https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s19aqf.html
.. _s19aq-py2-py-parameters:
**Parameters**
**x** : float, array-like, shape :math:`\left(n\right)`
The argument :math:`x_{\textit{i}}` of the function, for :math:`\textit{i} = 1,2,\ldots,n`.
**Returns**
**f** : float, ndarray, shape :math:`\left(n\right)`
:math:`\mathrm{ker}\left(x_i\right)`, the function values.
**ivalid** : int, ndarray, shape :math:`\left(n\right)`
:math:`\mathrm{ivalid}[\textit{i}-1]` contains the error code for :math:`x_{\textit{i}}`, for :math:`\textit{i} = 1,2,\ldots,n`.
:math:`\mathrm{ivalid}[i-1] = 0`
No error.
:math:`\mathrm{ivalid}[i-1] = 1`
:math:`x_i` is too large, the result underflows. :math:`\mathrm{f}[\textit{i}-1]` contains zero. The threshold value is the same as for :math:`\mathrm{errno}` = 1 in :meth:`kelvin_ker`.
:math:`\mathrm{ivalid}[i-1] = 2`
:math:`x_i\leq 0.0`, the function is undefined. :math:`\mathrm{f}[\textit{i}-1]` contains :math:`0.0`.
.. _s19aq-py2-py-errors:
**Raises**
**NagValueError**
(`errno` :math:`2`)
On entry, :math:`n = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`n\geq 0`.
**Warns**
**NagAlgorithmicWarning**
(`errno` :math:`1`)
On entry, at least one value of :math:`\mathrm{x}` was invalid.
Check :math:`\mathrm{ivalid}` for more information.
.. _s19aq-py2-py-notes:
**Notes**
``kelvin_ker_vector`` evaluates an approximation to the Kelvin function :math:`\mathrm{ker}\left(x_i\right)` for an array of arguments :math:`x_{\textit{i}}`, for :math:`\textit{i} = 1,2,\ldots,n`.
**Note:** for :math:`x < 0` the function is undefined and at :math:`x = 0` it is infinite so we need only consider :math:`x > 0`.
The function is based on several Chebyshev expansions:
For :math:`0 < x\leq 1`,
.. math::
\mathrm{ker}\left(x\right) = -f\left(t\right)\log\left(x\right)+\frac{\pi }{16}x^2g\left(t\right)+y\left(t\right)
where :math:`f\left(t\right)`, :math:`g\left(t\right)` and :math:`y\left(t\right)` are expansions in the variable :math:`t = 2x^4-1`.
For :math:`1 < x\leq 3`,
.. math::
\mathrm{ker}\left(x\right) = \mathrm{exp}\left(-\frac{11}{16}x\right)q\left(t\right)
where :math:`q\left(t\right)` is an expansion in the variable :math:`t = x-2`.
For :math:`x > 3`,
.. math::
\mathrm{ker}\left(x\right) = \sqrt{\frac{\pi }{{2x}}}e^{{-x/\sqrt{2}}}\left[\left(1+\frac{1}{x}c\left(t\right)\right)\cos\left(\beta \right)-\frac{1}{x}d\left(t\right)\sin\left(\beta \right)\right]
where :math:`\beta = \frac{x}{\sqrt{2}}+\frac{\pi }{8}`, and :math:`c\left(t\right)` and :math:`d\left(t\right)` are expansions in the variable :math:`t = \frac{6}{x}-1`.
When :math:`x` is sufficiently close to zero, the result is computed as
.. math::
\mathrm{ker}\left(x\right) = -\gamma -\log\left(\frac{x}{2}\right)+\left(\pi -\frac{3}{8}x^2\right)\frac{x^2}{16}
and when :math:`x` is even closer to zero, simply as :math:`\mathrm{ker}\left(x\right) = -\gamma -\log\left(\frac{x}{2}\right)`.
For large :math:`x`, :math:`\mathrm{ker}\left(x\right)` is asymptotically given by :math:`\sqrt{\frac{\pi }{{2x}}}e^{{-x/\sqrt{2}}}` and this becomes so small that it cannot be computed without underflow and the function fails.
.. _s19aq-py2-py-references:
**References**
NIST Digital Library of Mathematical Functions
"""
raise NotImplementedError
[docs]def kelvin_kei_vector(x):
r"""
``kelvin_kei_vector`` returns an array of values for the Kelvin function :math:`\mathrm{kei}\left(x\right)`.
.. _s19ar-py2-py-doc:
For full information please refer to the NAG Library document for s19ar
https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s19arf.html
.. _s19ar-py2-py-parameters:
**Parameters**
**x** : float, array-like, shape :math:`\left(n\right)`
The argument :math:`x_{\textit{i}}` of the function, for :math:`\textit{i} = 1,2,\ldots,n`.
**Returns**
**f** : float, ndarray, shape :math:`\left(n\right)`
:math:`\mathrm{kei}\left(x_i\right)`, the function values.
**ivalid** : int, ndarray, shape :math:`\left(n\right)`
:math:`\mathrm{ivalid}[\textit{i}-1]` contains the error code for :math:`x_{\textit{i}}`, for :math:`\textit{i} = 1,2,\ldots,n`.
:math:`\mathrm{ivalid}[i-1] = 0`
No error.
:math:`\mathrm{ivalid}[i-1] = 1`
:math:`x_i` is too large, the result underflows. :math:`\mathrm{f}[\textit{i}-1]` contains zero. The threshold value is the same as for :math:`\mathrm{errno}` = 1 in :meth:`kelvin_kei`.
:math:`\mathrm{ivalid}[i-1] = 2`
:math:`x_i < 0.0`, the function is undefined. :math:`\mathrm{f}[\textit{i}-1]` contains :math:`0.0`.
.. _s19ar-py2-py-errors:
**Raises**
**NagValueError**
(`errno` :math:`2`)
On entry, :math:`n = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`n\geq 0`.
**Warns**
**NagAlgorithmicWarning**
(`errno` :math:`1`)
On entry, at least one value of :math:`\mathrm{x}` was invalid.
Check :math:`\mathrm{ivalid}` for more information.
.. _s19ar-py2-py-notes:
**Notes**
``kelvin_kei_vector`` evaluates an approximation to the Kelvin function :math:`\mathrm{kei}\left(x_i\right)` for an array of arguments :math:`x_{\textit{i}}`, for :math:`\textit{i} = 1,2,\ldots,n`.
**Note:** for :math:`x < 0` the function is undefined, so we need only consider :math:`x\geq 0`.
The function is based on several Chebyshev expansions:
For :math:`0\leq x\leq 1`,
.. math::
\mathrm{kei}\left(x\right) = -\frac{\pi }{4}f\left(t\right)+\frac{x^2}{4}\left[-g\left(t\right)\log\left(x\right)+v\left(t\right)\right]
where :math:`f\left(t\right)`, :math:`g\left(t\right)` and :math:`v\left(t\right)` are expansions in the variable :math:`t = 2x^4-1`;
For :math:`1 < x\leq 3`,
.. math::
\mathrm{kei}\left(x\right) = \mathrm{exp}\left(-\frac{9}{8}x\right)u\left(t\right)
where :math:`u\left(t\right)` is an expansion in the variable :math:`t = x-2`;
For :math:`x > 3`,
.. math::
\mathrm{kei}\left(x\right) = \sqrt{\frac{\pi }{{2x}}}e^{{-x/\sqrt{2}}}\left[\left(1+\frac{1}{x}\right)c\left(t\right)\sin\left(\beta \right)+\frac{1}{x}d\left(t\right)\cos\left(\beta \right)\right]
where :math:`\beta = \frac{x}{\sqrt{2}}+\frac{\pi }{8}`, and :math:`c\left(t\right)` and :math:`d\left(t\right)` are expansions in the variable :math:`t = \frac{6}{x}-1`.
For :math:`x < 0`, the function is undefined, and hence the function fails and returns zero.
When :math:`x` is sufficiently close to zero, the result is computed as
.. math::
\mathrm{kei}\left(x\right) = -\frac{\pi }{4}+\left(1-\gamma -\log\left(\frac{x}{2}\right)\right)\frac{x^2}{4}
and when :math:`x` is even closer to zero simply as
.. math::
\mathrm{kei}\left(x\right) = -\frac{\pi }{4}\text{.}
For large :math:`x`, :math:`\mathrm{kei}\left(x\right)` is asymptotically given by :math:`\sqrt{\frac{\pi }{{2x}}}e^{{-x/\sqrt{2}}}` and this becomes so small that it cannot be computed without underflow and the function fails.
.. _s19ar-py2-py-references:
**References**
NIST Digital Library of Mathematical Functions
"""
raise NotImplementedError
[docs]def fresnel_s(x):
r"""
``fresnel_s`` returns a value for the Fresnel integral :math:`S\left(x\right)`.
.. _s20ac-py2-py-doc:
For full information please refer to the NAG Library document for s20ac
https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s20acf.html
.. _s20ac-py2-py-parameters:
**Parameters**
**x** : float
The argument :math:`x` of the function.
**Returns**
**sx** : float
The value of the function at :math:`x`.
.. _s20ac-py2-py-notes:
**Notes**
``fresnel_s`` evaluates an approximation to the Fresnel integral
.. math::
S\left(x\right) = \int_0^x\sin\left(\frac{\pi }{2}t^2\right){dt}\text{.}
**Note:** :math:`S\left(x\right) = -S\left(-x\right)`, so the approximation need only consider :math:`x\geq 0.0`.
The function is based on three Chebyshev expansions:
For :math:`0 < x\leq 3`,
.. math::
S\left(x\right) = x^3{\sum^\prime}_{{r = 0}}a_rT_r\left(t\right)\text{, with }t = 2\left(\frac{x}{3}\right)^4-1\text{.}
For :math:`x > 3`,
.. math::
S\left(x\right) = \frac{1}{2}-\frac{{f\left(x\right)}}{x}\cos\left(\frac{\pi }{2}x^2\right)-\frac{{g\left(x\right)}}{x^3}\sin\left(\frac{\pi }{2}x^2\right)\text{,}
where :math:`f\left(x\right) = {\sum^\prime}_{{r = 0}}b_rT_r\left(t\right)`,
and :math:`g\left(x\right) = {\sum^\prime}_{{r = 0}}c_rT_r\left(t\right)`,
with :math:`t = 2\left(\frac{3}{x}\right)^4-1`.
For small :math:`x`, :math:`S\left(x\right)\simeq \frac{\pi }{6}x^3`.
This approximation is used when :math:`x` is sufficiently small for the result to be correct to machine precision.
For very small :math:`x`, this approximation would underflow; the result is then set exactly to zero.
For large :math:`x`, :math:`f\left(x\right)\simeq \frac{1}{\pi }` and :math:`g\left(x\right)\simeq \frac{1}{{\pi^2}}`.
Therefore, for moderately large :math:`x`, when :math:`\frac{1}{{\pi^2x^3}}` is negligible compared with :math:`\frac{1}{2}`, the second term in the approximation for :math:`x > 3` may be dropped.
For very large :math:`x`, when :math:`\frac{1}{{\pi x}}` becomes negligible, :math:`S\left(x\right)\simeq \frac{1}{2}`.
However, there will be considerable difficulties in calculating :math:`\cos\left(\frac{\pi }{2}x^2\right)` accurately before this final limiting value can be used.
Since :math:`\cos\left(\frac{\pi }{2}x^2\right)` is periodic, its value is essentially determined by the fractional part of :math:`x^2`.
If :math:`x^2 = N+\theta` where :math:`N` is an integer and :math:`0\leq \theta < 1`, then :math:`\cos\left(\frac{\pi }{2}x^2\right)` depends on :math:`\theta` and on :math:`N` modulo :math:`4`.
By exploiting this fact, it is possible to retain significance in the calculation of :math:`\cos\left(\frac{\pi }{2}x^2\right)` either all the way to the very large :math:`x` limit, or at least until the integer part of :math:`\frac{x}{2}` is equal to the maximum integer allowed on the machine.
.. _s20ac-py2-py-references:
**References**
NIST Digital Library of Mathematical Functions
"""
raise NotImplementedError
[docs]def fresnel_c(x):
r"""
``fresnel_c`` returns a value for the Fresnel integral :math:`C\left(x\right)`.
.. _s20ad-py2-py-doc:
For full information please refer to the NAG Library document for s20ad
https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s20adf.html
.. _s20ad-py2-py-parameters:
**Parameters**
**x** : float
The argument :math:`x` of the function.
**Returns**
**cx** : float
The value of the function at :math:`x`.
.. _s20ad-py2-py-notes:
**Notes**
``fresnel_c`` evaluates an approximation to the Fresnel integral
.. math::
C\left(x\right) = \int_0^x\cos\left(\frac{\pi }{2}t^2\right){dt}\text{.}
**Note:** :math:`C\left(x\right) = -C\left(-x\right)`, so the approximation need only consider :math:`x\geq 0.0`.
The function is based on three Chebyshev expansions:
For :math:`0 < x\leq 3`,
.. math::
C\left(x\right) = x{\sum^\prime}_{{r = 0}}a_rT_r\left(t\right)\text{, with }t = 2\left(\frac{x}{3}\right)^4-1\text{.}
For :math:`x > 3`,
.. math::
C\left(x\right) = \frac{1}{2}+\frac{{f\left(x\right)}}{x}\sin\left(\frac{\pi }{2}x^2\right)-\frac{{g\left(x\right)}}{x^3}\cos\left(\frac{\pi }{2}x^2\right)\text{,}
where :math:`f\left(x\right) = {\sum^\prime}_{{r = 0}}b_rT_r\left(t\right)`,
and :math:`g\left(x\right) = {\sum^\prime}_{{r = 0}}c_rT_r\left(t\right)`,
with :math:`t = 2\left(\frac{3}{x}\right)^4-1`.
For small :math:`x`, :math:`C\left(x\right)\simeq x`.
This approximation is used when :math:`x` is sufficiently small for the result to be correct to machine precision.
For large :math:`x`, :math:`f\left(x\right)\simeq \frac{1}{\pi }` and :math:`g\left(x\right)\simeq \frac{1}{{\pi^2}}`.
Therefore, for moderately large :math:`x`, when :math:`\frac{1}{{\pi^2x^3}}` is negligible compared with :math:`\frac{1}{2}`, the second term in the approximation for :math:`x > 3` may be dropped.
For very large :math:`x`, when :math:`\frac{1}{{\pi x}}` becomes negligible, :math:`C\left(x\right)\simeq \frac{1}{2}`.
However, there will be considerable difficulties in calculating :math:`\sin\left(\frac{\pi }{2}x^2\right)` accurately before this final limiting value can be used.
Since :math:`\sin\left(\frac{\pi }{2}x^2\right)` is periodic, its value is essentially determined by the fractional part of :math:`x^2`.
If :math:`x^2 = N+\theta`, where :math:`N` is an integer and :math:`0\leq \theta < 1`, then :math:`\sin\left(\frac{\pi }{2}x^2\right)` depends on :math:`\theta` and on :math:`N` modulo :math:`4`.
By exploiting this fact, it is possible to retain some significance in the calculation of :math:`\sin\left(\frac{\pi }{2}x^2\right)` either all the way to the very large :math:`x` limit, or at least until the integer part of :math:`\frac{x}{2}` is equal to the maximum integer allowed on the machine.
.. _s20ad-py2-py-references:
**References**
NIST Digital Library of Mathematical Functions
"""
raise NotImplementedError
[docs]def fresnel_s_vector(x):
r"""
``fresnel_s_vector`` returns an array of values for the Fresnel integral :math:`S\left(x\right)`.
.. _s20aq-py2-py-doc:
For full information please refer to the NAG Library document for s20aq
https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s20aqf.html
.. _s20aq-py2-py-parameters:
**Parameters**
**x** : float, array-like, shape :math:`\left(n\right)`
The argument :math:`x_{\textit{i}}` of the function, for :math:`\textit{i} = 1,2,\ldots,n`.
**Returns**
**f** : float, ndarray, shape :math:`\left(n\right)`
:math:`S\left(x_i\right)`, the function values.
.. _s20aq-py2-py-errors:
**Warns**
**NagAlgorithmicWarning**
(`errno` :math:`1`)
On entry, :math:`n = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`n\geq 0`.
.. _s20aq-py2-py-notes:
**Notes**
``fresnel_s_vector`` evaluates an approximation to the Fresnel integral
.. math::
S\left(x_i\right) = \int_0^{x_i}\sin\left(\frac{\pi }{2}t^2\right){dt}
for an array of arguments :math:`x_{\textit{i}}`, for :math:`\textit{i} = 1,2,\ldots,n`.
**Note:** :math:`S\left(x\right) = -S\left(-x\right)`, so the approximation need only consider :math:`x\geq 0.0`.
The function is based on three Chebyshev expansions:
For :math:`0 < x\leq 3`,
.. math::
S\left(x\right) = x^3{\sum^\prime}_{{r = 0}}a_rT_r\left(t\right)\text{, with }t = 2\left(\frac{x}{3}\right)^4-1\text{.}
For :math:`x > 3`,
.. math::
S\left(x\right) = \frac{1}{2}-\frac{{f\left(x\right)}}{x}\cos\left(\frac{\pi }{2}x^2\right)-\frac{{g\left(x\right)}}{x^3}\sin\left(\frac{\pi }{2}x^2\right)\text{,}
where :math:`f\left(x\right) = {\sum^\prime}_{{r = 0}}b_rT_r\left(t\right)`,
and :math:`g\left(x\right) = {\sum^\prime}_{{r = 0}}c_rT_r\left(t\right)`,
with :math:`t = 2\left(\frac{3}{x}\right)^4-1`.
For small :math:`x`, :math:`S\left(x\right)\simeq \frac{\pi }{6}x^3`.
This approximation is used when :math:`x` is sufficiently small for the result to be correct to machine precision.
For very small :math:`x`, this approximation would underflow; the result is then set exactly to zero.
For large :math:`x`, :math:`f\left(x\right)\simeq \frac{1}{\pi }` and :math:`g\left(x\right)\simeq \frac{1}{{\pi^2}}`.
Therefore, for moderately large :math:`x`, when :math:`\frac{1}{{\pi^2x^3}}` is negligible compared with :math:`\frac{1}{2}`, the second term in the approximation for :math:`x > 3` may be dropped.
For very large :math:`x`, when :math:`\frac{1}{{\pi x}}` becomes negligible, :math:`S\left(x\right)\simeq \frac{1}{2}`.
However, there will be considerable difficulties in calculating :math:`\cos\left(\frac{\pi }{2}x^2\right)` accurately before this final limiting value can be used.
Since :math:`\cos\left(\frac{\pi }{2}x^2\right)` is periodic, its value is essentially determined by the fractional part of :math:`x^2`.
If :math:`x^2 = N+\theta` where :math:`N` is an integer and :math:`0\leq \theta < 1`, then :math:`\cos\left(\frac{\pi }{2}x^2\right)` depends on :math:`\theta` and on :math:`N` modulo :math:`4`.
By exploiting this fact, it is possible to retain significance in the calculation of :math:`\cos\left(\frac{\pi }{2}x^2\right)` either all the way to the very large :math:`x` limit, or at least until the integer part of :math:`\frac{x}{2}` is equal to the maximum integer allowed on the machine.
.. _s20aq-py2-py-references:
**References**
NIST Digital Library of Mathematical Functions
"""
raise NotImplementedError
[docs]def fresnel_c_vector(x):
r"""
``fresnel_c_vector`` returns an array of values for the Fresnel integral :math:`C\left(x\right)`.
.. _s20ar-py2-py-doc:
For full information please refer to the NAG Library document for s20ar
https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s20arf.html
.. _s20ar-py2-py-parameters:
**Parameters**
**x** : float, array-like, shape :math:`\left(n\right)`
The argument :math:`x_{\textit{i}}` of the function, for :math:`\textit{i} = 1,2,\ldots,n`.
**Returns**
**f** : float, ndarray, shape :math:`\left(n\right)`
:math:`C\left(x_i\right)`, the function values.
.. _s20ar-py2-py-errors:
**Warns**
**NagAlgorithmicWarning**
(`errno` :math:`1`)
On entry, :math:`n = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`n\geq 0`.
.. _s20ar-py2-py-notes:
**Notes**
``fresnel_c_vector`` evaluates an approximation to the Fresnel integral
.. math::
C\left(x_i\right) = \int_0^{x_i}\cos\left(\frac{\pi }{2}t^2\right){dt}
for an array of arguments :math:`x_{\textit{i}}`, for :math:`\textit{i} = 1,2,\ldots,n`.
**Note:** :math:`C\left(x\right) = -C\left(-x\right)`, so the approximation need only consider :math:`x\geq 0.0`.
The function is based on three Chebyshev expansions:
For :math:`0 < x\leq 3`,
.. math::
C\left(x\right) = x{\sum^\prime}_{{r = 0}}a_rT_r\left(t\right)\text{, with }t = 2\left(\frac{x}{3}\right)^4-1\text{.}
For :math:`x > 3`,
.. math::
C\left(x\right) = \frac{1}{2}+\frac{{f\left(x\right)}}{x}\sin\left(\frac{\pi }{2}x^2\right)-\frac{{g\left(x\right)}}{x^3}\cos\left(\frac{\pi }{2}x^2\right)\text{,}
where :math:`f\left(x\right) = {\sum^\prime}_{{r = 0}}b_rT_r\left(t\right)`,
and :math:`g\left(x\right) = {\sum^\prime}_{{r = 0}}c_rT_r\left(t\right)`,
with :math:`t = 2\left(\frac{3}{x}\right)^4-1`.
For small :math:`x`, :math:`C\left(x\right)\simeq x`.
This approximation is used when :math:`x` is sufficiently small for the result to be correct to machine precision.
For large :math:`x`, :math:`f\left(x\right)\simeq \frac{1}{\pi }` and :math:`g\left(x\right)\simeq \frac{1}{{\pi^2}}`.
Therefore, for moderately large :math:`x`, when :math:`\frac{1}{{\pi^2x^3}}` is negligible compared with :math:`\frac{1}{2}`, the second term in the approximation for :math:`x > 3` may be dropped.
For very large :math:`x`, when :math:`\frac{1}{{\pi x}}` becomes negligible, :math:`C\left(x\right)\simeq \frac{1}{2}`.
However, there will be considerable difficulties in calculating :math:`\sin\left(\frac{\pi }{2}x^2\right)` accurately before this final limiting value can be used.
Since :math:`\sin\left(\frac{\pi }{2}x^2\right)` is periodic, its value is essentially determined by the fractional part of :math:`x^2`.
If :math:`x^2 = N+\theta`, where :math:`N` is an integer and :math:`0\leq \theta < 1`, then :math:`\sin\left(\frac{\pi }{2}x^2\right)` depends on :math:`\theta` and on :math:`N` modulo :math:`4`.
By exploiting this fact, it is possible to retain some significance in the calculation of :math:`\sin\left(\frac{\pi }{2}x^2\right)` either all the way to the very large :math:`x` limit, or at least until the integer part of :math:`\frac{x}{2}` is equal to the maximum integer allowed on the machine.
.. _s20ar-py2-py-references:
**References**
NIST Digital Library of Mathematical Functions
"""
raise NotImplementedError
[docs]def ellipint_symm_1_degen(x, y):
r"""
``ellipint_symm_1_degen`` returns a value of an elementary integral, which occurs as a degenerate case of an elliptic integral of the first kind.
.. _s21ba-py2-py-doc:
For full information please refer to the NAG Library document for s21ba
https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s21baf.html
.. _s21ba-py2-py-parameters:
**Parameters**
**x** : float
The argument :math:`x` of the function.
**y** : float
The argument :math:`y` of the function.
**Returns**
**rc** : float
The value of an elementary integral, which occurs as a degenerate case of an elliptic integral of the first kind.
.. _s21ba-py2-py-errors:
**Raises**
**NagValueError**
(`errno` :math:`1`)
On entry, :math:`\mathrm{x} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{x}\geq 0.0`.
The function is undefined.
(`errno` :math:`2`)
On entry, :math:`\mathrm{y} = 0.0`.
Constraint: :math:`\mathrm{y}\neq 0.0`.
The function is undefined and returns zero.
.. _s21ba-py2-py-notes:
**Notes**
``ellipint_symm_1_degen`` calculates an approximate value for the integral
.. math::
R_C\left(x, y\right) = \frac{1}{2}\int_0^{\infty }\frac{{dt}}{{\left(t+y\right).\sqrt{t+x}}}
where :math:`x\geq 0` and :math:`y\neq 0`.
This function, which is related to the logarithm or inverse hyperbolic functions for :math:`y < x` and to inverse circular functions if :math:`x < y`, arises as a degenerate form of the elliptic integral of the first kind.
If :math:`y < 0`, the result computed is the Cauchy principal value of the integral.
The basic algorithm, which is due to Carlson (1979) and Carlson (1988), is to reduce the arguments recursively towards their mean by the system:
.. math::
\begin{array}{cc}x_0 = x&y_0 = y\\\mu_n = \left(x_n+2y_n\right)/3\text{,}&S_n = \left(y_n-x_n\right)/3\mu_n\\&\lambda_n = y_n+2\sqrt{x_ny_n}\\x_{{n+1}} = \left(x_n+\lambda_n\right)/4\text{,}&y_{{n+1}} = \left(y_n+\lambda_n\right)/4\text{.}\end{array}
The quantity :math:`\left\lvert S_n\right\rvert` for :math:`n = 0,1,2,3,\ldots \text{}` decreases with increasing :math:`n`, eventually :math:`\left\lvert S_n\right\rvert \sim 1/4^n`.
For small enough :math:`S_n` the required function value can be approximated by the first few terms of the Taylor series about the mean.
That is
.. math::
R_C\left(x, y\right) = \left(1+\frac{{3S_n^2}}{10}+\frac{S_n^3}{7}+\frac{{3S_n^4}}{8}+\frac{{9S_n^5}}{22}\right)/\sqrt{\mu_n}\text{.}
The truncation error involved in using this approximation is bounded by :math:`16\left\lvert S_n\right\rvert^6/\left(1-2\left\lvert S_n\right\rvert \right)` and the recursive process is stopped when :math:`S_n` is small enough for this truncation error to be negligible compared to the machine precision.
Within the domain of definition, the function value is itself representable for all representable values of its arguments.
However, for values of the arguments near the extremes the above algorithm must be modified so as to avoid causing underflows or overflows in intermediate steps.
In extreme regions arguments are prescaled away from the extremes and compensating scaling of the result is done before returning to the calling program.
.. _s21ba-py2-py-references:
**References**
NIST Digital Library of Mathematical Functions
Carlson, B C, 1979, `Computing elliptic integrals by duplication`, Numerische Mathematik (33), 1--16
Carlson, B C, 1988, `A table of elliptic integrals of the third kind`, Math. Comput. (51), 267--280
"""
raise NotImplementedError
[docs]def ellipint_symm_1(x, y, z):
r"""
``ellipint_symm_1`` returns a value of the symmetrised elliptic integral of the first kind.
.. _s21bb-py2-py-doc:
For full information please refer to the NAG Library document for s21bb
https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s21bbf.html
.. _s21bb-py2-py-parameters:
**Parameters**
**x** : float
The arguments :math:`x`, :math:`y` and :math:`z` of the function.
**y** : float
The arguments :math:`x`, :math:`y` and :math:`z` of the function.
**z** : float
The arguments :math:`x`, :math:`y` and :math:`z` of the function.
**Returns**
**rf** : float
The value of the symmetrised elliptic integral of the first kind.
.. _s21bb-py2-py-errors:
**Raises**
**NagValueError**
(`errno` :math:`1`)
On entry, :math:`\mathrm{x} = \langle\mathit{\boldsymbol{value}}\rangle`, :math:`\mathrm{y} = \langle\mathit{\boldsymbol{value}}\rangle` and :math:`\mathrm{z} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{x}\geq 0.0` and :math:`\mathrm{y}\geq 0.0` and :math:`\mathrm{z}\geq 0.0`.
The function is undefined.
(`errno` :math:`2`)
On entry, :math:`\mathrm{x} = \langle\mathit{\boldsymbol{value}}\rangle`, :math:`\mathrm{y} = \langle\mathit{\boldsymbol{value}}\rangle` and :math:`\mathrm{z} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: at most one of :math:`\mathrm{x}`, :math:`\mathrm{y}` and :math:`\mathrm{z}` is :math:`0.0`.
The function is undefined and returns zero.
.. _s21bb-py2-py-notes:
**Notes**
``ellipint_symm_1`` calculates an approximation to the integral
.. math::
R_F\left(x, y, z\right) = \frac{1}{2}\int_0^{\infty }\frac{{dt}}{{\sqrt{\left(t+x\right)\left(t+y\right)\left(t+z\right)}}}
where :math:`x`, :math:`y`, :math:`z\geq 0` and at most one is zero.
The basic algorithm, which is due to Carlson (1979) and Carlson (1988), is to reduce the arguments recursively towards their mean by the rule:
:math:`x_0 = \mathrm{min}\left(x, y, z\right)`, :math:`\quad \text{ }\quad z_0 = \mathrm{max}\left({x,y}, z\right)`,
:math:`y_0 = \text{}` remaining third intermediate value argument.
(This ordering, which is possible because of the symmetry of the function, is done for technical reasons related to the avoidance of overflow and underflow.)
.. math::
\begin{array}{lcl}\mu_n& = &\left(x_n+y_n+z_n\right)/3\\X_n& = &\left(1-x_n\right)/\mu_n\\Y_n& = &\left(1-y_n\right)/\mu_n\\Z_n& = &\left(1-z_n\right)/\mu_n\\\lambda_n& = &\sqrt{x_ny_n}+\sqrt{y_nz_n}+\sqrt{z_nx_n}\\x_{{n+1}}& = &\left(x_n+\lambda_n\right)/4\\y_{{n+1}}& = &\left(y_n+\lambda_n\right)/4\\z_{{n+1}}& = &\left(z_n+\lambda_n\right)/4\end{array}
:math:`\epsilon_n = \mathrm{max}\left({\left\lvert X_n\right\rvert,\left\lvert Y_n\right\rvert }, {\left\lvert Z_n\right\rvert }\right)` and the function may be approximated adequately by a fifth order power series:
.. math::
R_F\left(x, y, z\right) = \frac{1}{{\sqrt{\mu_n}}}\left(1-\frac{E_2}{10}+\frac{E_2^2}{24}-\frac{{3E_2E_3}}{44}+\frac{E_3}{14}\right)
where :math:`E_2 = X_nY_n+Y_nZ_n+Z_nX_n`, :math:`E_3 = X_nY_nZ_n`.
The truncation error involved in using this approximation is bounded by :math:`\epsilon_n^6/4\left(1-\epsilon_n\right)` and the recursive process is stopped when this truncation error is negligible compared with the machine precision.
Within the domain of definition, the function value is itself representable for all representable values of its arguments.
However, for values of the arguments near the extremes the above algorithm must be modified so as to avoid causing underflows or overflows in intermediate steps.
In extreme regions arguments are prescaled away from the extremes and compensating scaling of the result is done before returning to the calling program.
.. _s21bb-py2-py-references:
**References**
NIST Digital Library of Mathematical Functions
Carlson, B C, 1979, `Computing elliptic integrals by duplication`, Numerische Mathematik (33), 1--16
Carlson, B C, 1988, `A table of elliptic integrals of the third kind`, Math. Comput. (51), 267--280
"""
raise NotImplementedError
[docs]def ellipint_symm_2(x, y, z):
r"""
``ellipint_symm_2`` returns a value of the symmetrised elliptic integral of the second kind.
.. _s21bc-py2-py-doc:
For full information please refer to the NAG Library document for s21bc
https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s21bcf.html
.. _s21bc-py2-py-parameters:
**Parameters**
**x** : float
The arguments :math:`x`, :math:`y` and :math:`z` of the function.
**y** : float
The arguments :math:`x`, :math:`y` and :math:`z` of the function.
**z** : float
The arguments :math:`x`, :math:`y` and :math:`z` of the function.
**Returns**
**rd** : float
The value of the symmetrised elliptic integral of the second kind.
.. _s21bc-py2-py-errors:
**Raises**
**NagValueError**
(`errno` :math:`1`)
On entry, :math:`\mathrm{x}` and :math:`\mathrm{y}` are both :math:`0.0`.
Constraint: at most one of :math:`\mathrm{x}` and :math:`\mathrm{y}` is :math:`0.0`.
The function is undefined.
(`errno` :math:`1`)
On entry, :math:`\mathrm{x} = \langle\mathit{\boldsymbol{value}}\rangle` and :math:`\mathrm{y} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{x}\geq 0.0` and :math:`\mathrm{y}\geq 0.0`.
The function is undefined.
(`errno` :math:`2`)
On entry, :math:`\mathrm{z} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{z} > 0.0`.
The function is undefined.
(`errno` :math:`3`)
On entry, :math:`L = \langle\mathit{\boldsymbol{value}}\rangle`, :math:`\mathrm{x} = \langle\mathit{\boldsymbol{value}}\rangle`, :math:`\mathrm{y} = \langle\mathit{\boldsymbol{value}}\rangle` and :math:`\mathrm{z} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{z}\geq L` and (:math:`\mathrm{x}\geq L` or :math:`\mathrm{y}\geq L`).
The function is undefined.
(`errno` :math:`4`)
On entry, :math:`U = \langle\mathit{\boldsymbol{value}}\rangle`, :math:`\mathrm{x} = \langle\mathit{\boldsymbol{value}}\rangle`, :math:`\mathrm{y} = \langle\mathit{\boldsymbol{value}}\rangle` and :math:`\mathrm{z} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{x} < U` and :math:`\mathrm{y} < U` and :math:`\mathrm{z} < U`.
There is a danger of setting underflow and the function returns zero.
.. _s21bc-py2-py-notes:
**Notes**
``ellipint_symm_2`` calculates an approximate value for the integral
.. math::
R_D\left(x, y, z\right) = \frac{3}{2}\int_0^{\infty }\frac{{dt}}{{\sqrt{\left(t+x\right)\left(t+y\right)\left(t+z\right)^3}}}
where :math:`x`, :math:`y\geq 0`, at most one of :math:`x` and :math:`y` is zero, and :math:`z > 0`.
The basic algorithm, which is due to Carlson (1979) and Carlson (1988), is to reduce the arguments recursively towards their mean by the rule:
.. math::
\begin{array}{lcl}x_0& = &x,y_0 = y,z_0 = z\\\mu_n& = &\left(x_n+y_n+3z_n\right)/5\\X_n& = &\left(1-x_n\right)/\mu_n\\Y_n& = &\left(1-y_n\right)/\mu_n\\Z_n& = &\left(1-z_n\right)/\mu_n\\\lambda_n& = &\sqrt{x_ny_n}+\sqrt{y_nz_n}+\sqrt{z_nx_n}\\x_{{n+1}}& = &\left(x_n+\lambda_n\right)/4\\y_{{n+1}}& = &\left(y_n+\lambda_n\right)/4\\z_{{n+1}}& = &\left(z_n+\lambda_n\right)/4\end{array}
For :math:`n` sufficiently large,
.. math::
\epsilon_n = \mathrm{max}\left({\left\lvert X_n\right\rvert,\left\lvert Y_n\right\rvert }, {\left\lvert Z_n\right\rvert }\right)\sim \left(\frac{1}{4}\right)^n
and the function may be approximated adequately by a fifth order power series
.. math::
\begin{array}{ll}R_D\left(x, y, z\right) = &3\sum_{{m = 0}}^{{n-1}} \frac{4^{{-m}}}{{\left(z_m+\lambda_n\right)\sqrt{z_m}}}\\&\\&\\&+\frac{4^{{-n}}}{{\sqrt{\mu_n^3}}} \left[1+\frac{3}{7}S_n^{\left(2\right)}+\frac{1}{3}S_n^{\left(3\right)}+\frac{3}{22}{\left(S_n^{\left(2\right)}\right)}^2+\frac{3}{11}S_n^{\left(4\right)}+\frac{3}{13}S_n^{\left(2\right)}S_n^{\left(3\right)}+\frac{3}{13}S_n^{\left(5\right)}\right] \end{array}
where :math:`S_n^{\left(m\right)} = \left(X_n^m+Y_n^m+3Z_n^m\right)/2m\text{.}` The truncation error in this expansion is bounded by :math:`\frac{{3\epsilon_n^6}}{{\sqrt{\left(1-\epsilon_n\right)^3}}}` and the recursive process is terminated when this quantity is negligible compared with the machine precision.
The function may fail either because it has been called with arguments outside the domain of definition, or with arguments so extreme that there is an unavoidable danger of setting underflow or overflow.
**Note:** :math:`R_D\left(x, x, x\right) = x^{{-3/2}}`, so there exists a region of extreme arguments for which the function value is not representable.
.. _s21bc-py2-py-references:
**References**
NIST Digital Library of Mathematical Functions
Carlson, B C, 1979, `Computing elliptic integrals by duplication`, Numerische Mathematik (33), 1--16
Carlson, B C, 1988, `A table of elliptic integrals of the third kind`, Math. Comput. (51), 267--280
"""
raise NotImplementedError
[docs]def ellipint_symm_3(x, y, z, r):
r"""
``ellipint_symm_3`` returns a value of the symmetrised elliptic integral of the third kind.
.. _s21bd-py2-py-doc:
For full information please refer to the NAG Library document for s21bd
https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s21bdf.html
.. _s21bd-py2-py-parameters:
**Parameters**
**x** : float
The arguments :math:`x`, :math:`y`, :math:`z` and :math:`\rho` of the function.
**y** : float
The arguments :math:`x`, :math:`y`, :math:`z` and :math:`\rho` of the function.
**z** : float
The arguments :math:`x`, :math:`y`, :math:`z` and :math:`\rho` of the function.
**r** : float
The arguments :math:`x`, :math:`y`, :math:`z` and :math:`\rho` of the function.
**Returns**
**rj** : float
The value of the symmetrised elliptic integral of the third kind.
.. _s21bd-py2-py-errors:
**Raises**
**NagValueError**
(`errno` :math:`1`)
On entry, :math:`\mathrm{x} = \langle\mathit{\boldsymbol{value}}\rangle`, :math:`\mathrm{y} = \langle\mathit{\boldsymbol{value}}\rangle` and :math:`\mathrm{z} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: at most one of :math:`\mathrm{x}`, :math:`\mathrm{y}` and :math:`\mathrm{z}` is :math:`0.0`.
The function is undefined.
(`errno` :math:`1`)
On entry, :math:`\mathrm{x} = \langle\mathit{\boldsymbol{value}}\rangle`, :math:`\mathrm{y} = \langle\mathit{\boldsymbol{value}}\rangle` and :math:`\mathrm{z} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{x}\geq 0.0` and :math:`\mathrm{y}\geq 0.0` and :math:`\mathrm{z}\geq 0.0`.
(`errno` :math:`2`)
On entry, :math:`\mathrm{r} = 0.0`.
Constraint: :math:`\mathrm{r}\neq 0.0`.
(`errno` :math:`3`)
On entry, :math:`L = \langle\mathit{\boldsymbol{value}}\rangle`, :math:`\mathrm{r} = \langle\mathit{\boldsymbol{value}}\rangle`, :math:`\mathrm{x} = \langle\mathit{\boldsymbol{value}}\rangle`, :math:`\mathrm{y} = \langle\mathit{\boldsymbol{value}}\rangle` and :math:`\mathrm{z} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\left\lvert \mathrm{r}\right\rvert \geq L` and at most one of :math:`\mathrm{x}`, :math:`\mathrm{y}` and :math:`\mathrm{z}` is less than :math:`L`.
(`errno` :math:`4`)
On entry, :math:`U = \langle\mathit{\boldsymbol{value}}\rangle`, :math:`\mathrm{r} = \langle\mathit{\boldsymbol{value}}\rangle`, :math:`\mathrm{x} = \langle\mathit{\boldsymbol{value}}\rangle`, :math:`\mathrm{y} = \langle\mathit{\boldsymbol{value}}\rangle` and :math:`\mathrm{z} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\left\lvert \mathrm{r}\right\rvert \leq U` and :math:`\mathrm{x}\leq U` and :math:`\mathrm{y}\leq U` and :math:`\mathrm{z}\leq U`.
.. _s21bd-py2-py-notes:
**Notes**
``ellipint_symm_3`` calculates an approximation to the integral
.. math::
R_J\left(x, y, z, \rho \right) = \frac{3}{2}\int_0^{\infty }\frac{{dt}}{{\left(t+\rho \right)\sqrt{\left(t+x\right)\left(t+y\right)\left(t+z\right)}}}
where :math:`x`, :math:`y`, :math:`z\geq 0`, :math:`\rho \neq 0` and at most one of :math:`x`, :math:`y` and :math:`z` is zero.
If :math:`\rho < 0`, the result computed is the Cauchy principal value of the integral.
The basic algorithm, which is due to Carlson (1979) and Carlson (1988), is to reduce the arguments recursively towards their mean by the rule:
.. math::
\begin{array}{lcl}x_0& = &x,y_0 = y,z_0 = z,\rho_0 = \rho \\\mu_n& = &\left(x_n+y_n+z_n+2\rho_n\right)/5\\X_n& = &1-x_n/\mu_n\\Y_n& = &1-y_n/\mu_n\\Z_n& = &1-z_n/\mu_n\\P_n& = &1-\rho_n/\mu_n\\\lambda_n& = &\sqrt{x_ny_n}+\sqrt{y_nz_n}+\sqrt{z_nx_n}\\x_{{n+1}}& = &\left(x_n+\lambda_n\right)/4\\y_{{n+1}}& = &\left(y_n+\lambda_n\right)/4\\z_{{n+1}}& = &\left(z_n+\lambda_n\right)/4\\\rho_{{n+1}}& = &\left(\rho_n+\lambda_n\right)/4\\\alpha_n& = &\left[\rho_n\left({\sqrt{x_n}}, {+\sqrt{y_n}}, {+\sqrt{z_n}}\right)+\sqrt{x_ny_nz_n}\right]^2\\\beta_n& = &\rho_n\left(\rho_n+\lambda_n\right)^2\end{array}
For :math:`n` sufficiently large,
.. math::
\epsilon_n = \mathrm{max}\left({\left\lvert X_n\right\rvert,\left\lvert Y_n\right\rvert,\left\lvert Z_n\right\rvert }, {\left\lvert P_n\right\rvert }\right)\sim \frac{1}{4^n}
and the function may be approximated by a fifth order power series
.. math::
\begin{array}{ll}R_J\left(x, y, z, \rho \right) = &3\sum_{{m = 0}}^{{n-1}}4^{{-m}} R_C\left(\alpha_m, {\beta_m}\right)\\&\\&\\&+\frac{4^{{-n}}}{{\sqrt{\mu_n^3}}} \left[1+\frac{3}{7}S_n^{\left(2\right)}+\frac{1}{3}S_n^{\left(3\right)}+\frac{3}{22}{\left(S_n^{\left(2\right)}\right)}^2+\frac{3}{11}S_n^{\left(4\right)}+\frac{3}{13}S_n^{\left(2\right)}S_n^{\left(3\right)}+\frac{3}{13}S_n^{\left(5\right)}\right] \end{array}
where :math:`S_n^{\left(m\right)} = \left(X_n^m+Y_n^m+Z_n^m+2P_n^m\right)/2m`.
The truncation error in this expansion is bounded by :math:`3\epsilon_n^6/\sqrt{\left(1-\epsilon_n\right)^3}` and the recursion process is terminated when this quantity is negligible compared with the machine precision.
The function may fail either because it has been called with arguments outside the domain of definition or with arguments so extreme that there is an unavoidable danger of setting underflow or overflow.
**Note:** :math:`R_J\left(x, x, x, x\right) = x^{{-\frac{3}{2}}}`, so there exists a region of extreme arguments for which the function value is not representable.
.. _s21bd-py2-py-references:
**References**
NIST Digital Library of Mathematical Functions
Carlson, B C, 1979, `Computing elliptic integrals by duplication`, Numerische Mathematik (33), 1--16
Carlson, B C, 1988, `A table of elliptic integrals of the third kind`, Math. Comput. (51), 267--280
"""
raise NotImplementedError
[docs]def ellipint_legendre_1(phi, dm):
r"""
``ellipint_legendre_1`` returns a value of the classical (Legendre) form of the incomplete elliptic integral of the first kind.
.. _s21be-py2-py-doc:
For full information please refer to the NAG Library document for s21be
https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s21bef.html
.. _s21be-py2-py-parameters:
**Parameters**
**phi** : float
The arguments :math:`\phi` and :math:`m` of the function.
**dm** : float
The arguments :math:`\phi` and :math:`m` of the function.
**Returns**
**f** : float
The value of the classical (Legendre) form of the incomplete elliptic integral of the first kind.
.. _s21be-py2-py-errors:
**Raises**
**NagValueError**
(`errno` :math:`1`)
On entry, :math:`\mathrm{phi} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`0\leq \mathrm{phi}\leq \frac{\pi }{2}`.
On failure, the function returns zero.
(`errno` :math:`2`)
On entry, :math:`\mathrm{phi} = \langle\mathit{\boldsymbol{value}}\rangle` and :math:`\mathrm{dm} = \langle\mathit{\boldsymbol{value}}\rangle`; the integral is undefined.
Constraint: :math:`\mathrm{dm}\times \mathrm{sin}^2\left(\mathrm{phi}\right)\leq 1.0`.
On failure, the function returns zero.
**Warns**
**NagAlgorithmicWarning**
(`errno` :math:`3`)
On entry, :math:`\sin\left(\mathrm{phi}\right) = 1` and :math:`\mathrm{dm} = 1.0`; the integral is infinite.
On failure, the function returns the largest machine number (see :meth:`machine.real_largest <naginterfaces.library.machine.real_largest>`).
.. _s21be-py2-py-notes:
**Notes**
``ellipint_legendre_1`` calculates an approximation to the integral
.. math::
F\left(\phi | m\right) = \int_0^{\phi }\left(1-m\sin^2\left(\theta \right)\right)^{{-\frac{1}{2}}}d\theta \text{,}
where :math:`0\leq \phi \leq \frac{\pi }{2}`, :math:`m\sin^2\left(\phi \right)\leq 1` and :math:`m` and :math:`\sin\left(\phi \right)` may not both equal one.
The integral is computed using the symmetrised elliptic integrals of Carlson (Carlson (1979) and Carlson (1988)).
The relevant identity is
.. math::
F\left(\phi | m\right) = R_F\left(q, r, 1\right)\sin\left(\phi \right)\text{,}
where :math:`q = \cos^2\left(\phi \right)`, :math:`r = 1-m\sin^2\left(\phi \right)` and :math:`R_F` is the Carlson symmetrised incomplete elliptic integral of the first kind (see :meth:`ellipint_symm_1`).
.. _s21be-py2-py-references:
**References**
Abramowitz, M and Stegun, I A, 1972, `Handbook of Mathematical Functions`, (3rd Edition), Dover Publications
Carlson, B C, 1979, `Computing elliptic integrals by duplication`, Numerische Mathematik (33), 1--16
Carlson, B C, 1988, `A table of elliptic integrals of the third kind`, Math. Comput. (51), 267--280
"""
raise NotImplementedError
[docs]def ellipint_legendre_2(phi, dm):
r"""
``ellipint_legendre_2`` returns a value of the classical (Legendre) form of the incomplete elliptic integral of the second kind.
.. _s21bf-py2-py-doc:
For full information please refer to the NAG Library document for s21bf
https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s21bff.html
.. _s21bf-py2-py-parameters:
**Parameters**
**phi** : float
The arguments :math:`\phi` and :math:`m` of the function.
**dm** : float
The arguments :math:`\phi` and :math:`m` of the function.
**Returns**
**e** : float
The value of the classical (Legendre) form of the incomplete elliptic integral of the second kind.
.. _s21bf-py2-py-errors:
**Raises**
**NagValueError**
(`errno` :math:`1`)
On entry, :math:`\mathrm{phi} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`0\leq \mathrm{phi}\leq \frac{\pi }{2}`.
(`errno` :math:`2`)
On entry, :math:`\mathrm{phi} = \langle\mathit{\boldsymbol{value}}\rangle` and :math:`\mathrm{dm} = \langle\mathit{\boldsymbol{value}}\rangle`; the integral is undefined.
Constraint: :math:`\mathrm{dm}\times \mathrm{sin}^2\left(\mathrm{phi}\right)\leq 1.0`.
.. _s21bf-py2-py-notes:
**Notes**
``ellipint_legendre_2`` calculates an approximation to the integral
.. math::
E\left(\phi | m\right) = \int_0^{\phi }\left(1-m\sin^2\left(\theta \right)\right)^{\frac{1}{2}}d\theta \text{,}
where :math:`0\leq \phi \leq \frac{\pi }{2}` and :math:`m\sin^2\left(\phi \right)\leq 1`.
The integral is computed using the symmetrised elliptic integrals of Carlson (Carlson (1979) and Carlson (1988)).
The relevant identity is
.. math::
E\left(\phi | m\right) = \sin\left(\phi \right)R_F\left(q, r, 1\right)-\frac{1}{3}m\sin\left(\phi \right)R_D\left(q, r, 1\right)\text{,}
where :math:`q = \cos^2\left(\phi \right)`, :math:`r = 1-m\sin^2\left(\phi \right)`, :math:`R_F` is the Carlson symmetrised incomplete elliptic integral of the first kind (see :meth:`ellipint_symm_1`) and :math:`R_D` is the Carlson symmetrised incomplete elliptic integral of the second kind (see :meth:`ellipint_symm_2`).
.. _s21bf-py2-py-references:
**References**
Abramowitz, M and Stegun, I A, 1972, `Handbook of Mathematical Functions`, (3rd Edition), Dover Publications
Carlson, B C, 1979, `Computing elliptic integrals by duplication`, Numerische Mathematik (33), 1--16
Carlson, B C, 1988, `A table of elliptic integrals of the third kind`, Math. Comput. (51), 267--280
"""
raise NotImplementedError
[docs]def ellipint_legendre_3(dn, phi, dm):
r"""
``ellipint_legendre_3`` returns a value of the classical (Legendre) form of the incomplete elliptic integral of the third kind.
.. _s21bg-py2-py-doc:
For full information please refer to the NAG Library document for s21bg
https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s21bgf.html
.. _s21bg-py2-py-parameters:
**Parameters**
**dn** : float
The arguments :math:`n`, :math:`\phi` and :math:`m` of the function.
**phi** : float
The arguments :math:`n`, :math:`\phi` and :math:`m` of the function.
**dm** : float
The arguments :math:`n`, :math:`\phi` and :math:`m` of the function.
**Returns**
**p** : float
The value of the classical (Legendre) form of the incomplete elliptic integral of the third kind.
.. _s21bg-py2-py-errors:
**Raises**
**NagValueError**
(`errno` :math:`1`)
On entry, :math:`\mathrm{phi} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`0\leq \mathrm{phi}\leq \left(\pi /2\right)`.
(`errno` :math:`2`)
On entry, :math:`\mathrm{phi} = \langle\mathit{\boldsymbol{value}}\rangle` and :math:`\mathrm{dm} = \langle\mathit{\boldsymbol{value}}\rangle`; the integral is undefined.
Constraint: :math:`\mathrm{dm}\times \sin^2\left(\mathrm{phi}\right)\leq 1.0`.
**Warns**
**NagAlgorithmicWarning**
(`errno` :math:`3`)
On entry, :math:`\sin\left(\mathrm{phi}\right) = 1` and :math:`\mathrm{dm} = 1.0`; the integral is infinite.
(`errno` :math:`4`)
On entry, :math:`\mathrm{phi} = \langle\mathit{\boldsymbol{value}}\rangle` and :math:`\mathrm{dn} = \langle\mathit{\boldsymbol{value}}\rangle`; the integral is infinite.
Constraint: :math:`\mathrm{dn}\times \sin^2\left(\mathrm{phi}\right)\neq 1.0`.
.. _s21bg-py2-py-notes:
**Notes**
``ellipint_legendre_3`` calculates an approximation to the integral
.. math::
\Pi \left(n; {\phi | m}\right) = \int_0^{\phi }\left(1-n\sin^2\left(\theta \right)\right)^{{-1}}\left(1-m\sin^2\left(\theta \right)\right)^{{-\frac{1}{2}}}d\theta \text{,}
where :math:`0\leq \phi \leq \frac{\pi }{2}`, :math:`m\sin^2\left(\phi \right)\leq 1`, :math:`m` and :math:`\sin\left(\phi \right)` may not both equal one, and :math:`n\sin^2\left(\phi \right)\neq 1`.
The integral is computed using the symmetrised elliptic integrals of Carlson (Carlson (1979) and Carlson (1988)).
The relevant identity is
.. math::
\Pi \left(n; {\phi | m}\right) = \sin\left(\phi \right)R_F\left(q, r, 1\right)+\frac{1}{3}n\sin\left(\phi \right)R_J\left(q, r, 1, s\right)\text{,}
where :math:`q = \cos^2\left(\phi \right)`, :math:`r = 1-m\sin^2\left(\phi \right)`, :math:`s = 1-n\sin^2\left(\phi \right)`, :math:`R_F` is the Carlson symmetrised incomplete elliptic integral of the first kind (see :meth:`ellipint_symm_1`) and :math:`R_J` is the Carlson symmetrised incomplete elliptic integral of the third kind (see :meth:`ellipint_symm_3`).
.. _s21bg-py2-py-references:
**References**
Abramowitz, M and Stegun, I A, 1972, `Handbook of Mathematical Functions`, (3rd Edition), Dover Publications
Carlson, B C, 1979, `Computing elliptic integrals by duplication`, Numerische Mathematik (33), 1--16
Carlson, B C, 1988, `A table of elliptic integrals of the third kind`, Math. Comput. (51), 267--280
"""
raise NotImplementedError
[docs]def ellipint_complete_1(dm):
r"""
``ellipint_complete_1`` returns a value of the classical (Legendre) form of the complete elliptic integral of the first kind.
.. _s21bh-py2-py-doc:
For full information please refer to the NAG Library document for s21bh
https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s21bhf.html
.. _s21bh-py2-py-parameters:
**Parameters**
**dm** : float
The argument :math:`m` of the function.
**Returns**
**k** : float
The value of the classical (Legendre) form of the complete elliptic integral of the first kind.
.. _s21bh-py2-py-errors:
**Raises**
**NagValueError**
(`errno` :math:`1`)
On entry, :math:`\mathrm{dm} = \langle\mathit{\boldsymbol{value}}\rangle`; the integral is undefined.
Constraint: :math:`\mathrm{dm} < 1.0`.
On failure, the function returns zero.
**Warns**
**NagAlgorithmicWarning**
(`errno` :math:`2`)
On entry, :math:`\mathrm{dm} = 1.0`; the integral is infinite.
On failure, the function returns the largest machine number (see :meth:`machine.real_largest <naginterfaces.library.machine.real_largest>`).
.. _s21bh-py2-py-notes:
**Notes**
``ellipint_complete_1`` calculates an approximation to the integral
.. math::
K\left(m\right) = \int_0^{\frac{\pi }{2}}\left(1-m\sin^2\left(\theta \right)\right)^{{-\frac{1}{2}}}d\theta \text{,}
where :math:`m < 1`.
The integral is computed using the symmetrised elliptic integrals of Carlson (Carlson (1979) and Carlson (1988)).
The relevant identity is
.. math::
K\left(m\right) = R_F\left(0, {1-m}, 1\right)\text{,}
where :math:`R_F` is the Carlson symmetrised incomplete elliptic integral of the first kind (see :meth:`ellipint_symm_1`).
.. _s21bh-py2-py-references:
**References**
NIST Digital Library of Mathematical Functions
Carlson, B C, 1979, `Computing elliptic integrals by duplication`, Numerische Mathematik (33), 1--16
Carlson, B C, 1988, `A table of elliptic integrals of the third kind`, Math. Comput. (51), 267--280
"""
raise NotImplementedError
[docs]def ellipint_complete_2(dm):
r"""
``ellipint_complete_2`` returns a value of the classical (Legendre) form of the complete elliptic integral of the second kind.
.. _s21bj-py2-py-doc:
For full information please refer to the NAG Library document for s21bj
https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s21bjf.html
.. _s21bj-py2-py-parameters:
**Parameters**
**dm** : float
The argument :math:`m` of the function.
**Returns**
**e** : float
The value of the classical (Legendre) form of the complete elliptic integral of the second kind.
.. _s21bj-py2-py-errors:
**Raises**
**NagValueError**
(`errno` :math:`1`)
On entry, :math:`\mathrm{dm} = \langle\mathit{\boldsymbol{value}}\rangle`; the integral is undefined.
Constraint: :math:`\mathrm{dm}\leq 1.0`.
.. _s21bj-py2-py-notes:
**Notes**
``ellipint_complete_2`` calculates an approximation to the integral
.. math::
E\left(m\right) = \int_0^{\frac{\pi }{2}}\left(1-m\sin^2\left(\theta \right)\right)^{{\frac{1}{2}}}d\theta \text{,}
where :math:`m\leq 1`.
The integral is computed using the symmetrised elliptic integrals of Carlson (Carlson (1979) and Carlson (1988)).
The relevant identity is
.. math::
E\left(m\right) = R_F\left(0, {1-m}, 1\right)-\frac{1}{3}mR_D\left(0, {1-m}, 1\right)\text{,}
where :math:`R_F` is the Carlson symmetrised incomplete elliptic integral of the first kind (see :meth:`ellipint_symm_1`) and :math:`R_D` is the Carlson symmetrised incomplete elliptic integral of the second kind (see :meth:`ellipint_symm_2`).
.. _s21bj-py2-py-references:
**References**
NIST Digital Library of Mathematical Functions
Carlson, B C, 1979, `Computing elliptic integrals by duplication`, Numerische Mathematik (33), 1--16
Carlson, B C, 1988, `A table of elliptic integrals of the third kind`, Math. Comput. (51), 267--280
"""
raise NotImplementedError
[docs]def jacellip_real(u, m):
r"""
``jacellip_real`` evaluates the Jacobian elliptic functions sn, cn and dn.
.. _s21ca-py2-py-doc:
For full information please refer to the NAG Library document for s21ca
https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s21caf.html
.. _s21ca-py2-py-parameters:
**Parameters**
**u** : float
The argument :math:`u`.
**m** : float
The argument :math:`m`.
**Returns**
**sn** : float
The value of :math:`\mathrm{sn}\left(u\right)`.
**cn** : float
The value of :math:`\mathrm{cn}\left(u\right)`.
**dn** : float
The value of :math:`\mathrm{dn}\left(u\right)`.
.. _s21ca-py2-py-errors:
**Raises**
**NagValueError**
(`errno` :math:`1`)
On entry, :math:`\left\lvert \mathrm{u}\right\rvert` is too large: :math:`\left\lvert \mathrm{u}\right\rvert = \langle\mathit{\boldsymbol{value}}\rangle` it must be less than :math:`\langle\mathit{\boldsymbol{value}}\rangle`.
(`errno` :math:`2`)
On entry, :math:`\left\lvert \mathrm{m}\right\rvert` is too large when used in conjunction with the supplied argument :math:`\mathrm{u}`: :math:`\left\lvert \mathrm{m}\right\rvert = \langle\mathit{\boldsymbol{value}}\rangle` it must be less than :math:`\langle\mathit{\boldsymbol{value}}\rangle`.
.. _s21ca-py2-py-notes:
**Notes**
``jacellip_real`` evaluates the Jacobian elliptic functions of argument :math:`u` and argument :math:`m`,
.. math::
\begin{array}{lcl}\mathrm{sn}\left(u | m\right)& = &\sin\left(\phi \right)\text{,}\\\mathrm{cn}\left(u | m\right)& = &\cos\left(\phi \right)\text{,}\\\mathrm{dn}\left(u | m\right)& = &\sqrt{1-m\sin^2\left(\phi \right)}\text{,}\end{array}
where :math:`\phi`, called the `amplitude` of :math:`u`, is defined by the integral
.. math::
u = \int_0^{\phi }\frac{{d\theta }}{{\sqrt{1-m\sin^2\left(\theta \right)}}}\text{.}
The elliptic functions are sometimes written simply as :math:`\mathrm{sn}\left(u\right)`, :math:`\mathrm{cn}\left(u\right)` and :math:`\mathrm{dn}\left(u\right)`, avoiding explicit reference to the argument :math:`m`.
Another nine elliptic functions may be computed via the formulae
.. math::
\begin{array}{lcl}\mathrm{cd}\left(u\right)& = &\mathrm{cn}\left(u\right)/\mathrm{dn}\left(u\right)\\\mathrm{sd}\left(u\right)& = &\mathrm{sn}\left(u\right)/\mathrm{dn}\left(u\right)\\\mathrm{nd}\left(u\right)& = &1/\mathrm{dn}\left(u\right)\\\mathrm{dc}\left(u\right)& = &\mathrm{dn}\left(u\right)/\mathrm{cn}\left(u\right)\\\mathrm{nc}\left(u\right)& = &1/\mathrm{cn}\left(u\right)\\\mathrm{sc}\left(u\right)& = &\mathrm{sn}\left(u\right)/\mathrm{cn}\left(u\right)\\\mathrm{ns}\left(u\right)& = &1/\mathrm{sn}\left(u\right)\\\mathrm{ds}\left(u\right)& = &\mathrm{dn}\left(u\right)/\mathrm{sn}\left(u\right)\\\mathrm{cs}\left(u\right)& = &\mathrm{cn}\left(u\right)/\mathrm{sn}\left(u\right)\end{array}
(see Abramowitz and Stegun (1972)).
``jacellip_real`` is based on a procedure given by Bulirsch (1960), and uses the process of the arithmetic-geometric mean (:math:`16.9` in Abramowitz and Stegun (1972)).
Constraints are placed on the values of :math:`u` and :math:`m` in order to avoid the possibility of machine overflow.
.. _s21ca-py2-py-references:
**References**
Abramowitz, M and Stegun, I A, 1972, `Handbook of Mathematical Functions`, (3rd Edition), Dover Publications
Bulirsch, R, 1960, `Numerical calculation of elliptic integrals and elliptic functions`, Numer. Math. (7), 76--90
"""
raise NotImplementedError
[docs]def jacellip_complex(z, ak2):
r"""
``jacellip_complex`` evaluates the Jacobian elliptic functions :math:`\mathrm{sn}\left(z\right)`, :math:`\mathrm{cn}\left(z\right)` and :math:`\mathrm{dn}\left(z\right)` for a complex argument :math:`z`.
.. _s21cb-py2-py-doc:
For full information please refer to the NAG Library document for s21cb
https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s21cbf.html
.. _s21cb-py2-py-parameters:
**Parameters**
**z** : complex
The argument :math:`z` of the functions.
**ak2** : float
The value of :math:`k^2`.
**Returns**
**sn** : complex
The value of the function :math:`\mathrm{sn}\left(z\right)`.
**cn** : complex
The value of the function :math:`\mathrm{cn}\left(z\right)`.
**dn** : complex
The value of the function :math:`\mathrm{dn}\left(z\right)`.
.. _s21cb-py2-py-errors:
**Raises**
**NagValueError**
(`errno` :math:`1`)
On entry, :math:`\left\lvert \mathrm{Im}\left(\mathrm{z}\right)\right\rvert` is too large: :math:`\left\lvert \mathrm{Im}\left(\mathrm{z}\right)\right\rvert = \langle\mathit{\boldsymbol{value}}\rangle`. It must be less than :math:`\langle\mathit{\boldsymbol{value}}\rangle`.
(`errno` :math:`1`)
On entry, :math:`\left\lvert \mathrm{Re}\left(\mathrm{z}\right)\right\rvert` is too large: :math:`\left\lvert \mathrm{Re}\left(\mathrm{z}\right)\right\rvert = \langle\mathit{\boldsymbol{value}}\rangle`. It must be less than :math:`\langle\mathit{\boldsymbol{value}}\rangle`.
(`errno` :math:`1`)
On entry, :math:`\mathrm{ak2} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{ak2}\leq 1.0`.
(`errno` :math:`1`)
On entry, :math:`\mathrm{ak2} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{ak2}\geq 0.0`.
.. _s21cb-py2-py-notes:
**Notes**
``jacellip_complex`` evaluates the Jacobian elliptic functions :math:`\mathrm{sn}\left(z | k\right)`, :math:`\mathrm{cn}\left(z | k\right)` and :math:`\mathrm{dn}\left(z | k\right)` given by
.. math::
\begin{array}{lcl}\mathrm{sn}\left(z | k\right)& = &\sin\left(\phi \right)\\\mathrm{cn}\left(z | k\right)& = &\cos\left(\phi \right)\\\mathrm{dn}\left(z | k\right)& = &\sqrt{1-k^2\sin^2\left(\phi \right)}\text{,}\end{array}
where :math:`z` is a complex argument, :math:`k` is a real argument (the `modulus`) with :math:`k^2\leq 1` and :math:`\phi` (the `amplitude` of :math:`z`) is defined by the integral
.. math::
z = \int_0^{\phi }\frac{{d\theta }}{{\sqrt{1-k^2\sin^2\left(\theta \right)}}}\text{.}
The above definitions can be extended for values of :math:`k^2 > 1` (see Salzer (1962)) by means of the formulae
.. math::
\begin{array}{lcl}\mathrm{sn}\left(z | k\right)& = &k_1\mathrm{sn}\left(kz | k_1\right)\\\mathrm{cn}\left(z | k\right)& = &\mathrm{dn}\left(kz | k_1\right)\\\mathrm{dn}\left(z | k\right)& = &\mathrm{cn}\left(kz | k_1\right)\text{,}\end{array}
where :math:`k_1 = 1/k`.
Special values include
.. math::
\begin{array}{lcl}\mathrm{sn}\left(z | 0\right)& = &\sin\left(z\right)\\\mathrm{cn}\left(z | 0\right)& = &\cos\left(z\right)\\\mathrm{dn}\left(z | 0\right)& = &1\\\mathrm{sn}\left(z | 1\right)& = &\tanh\left(z\right)\\\mathrm{cn}\left(z | 1\right)& = &\mathrm{sech}\left(z\right)\\\mathrm{dn}\left(z | 1\right)& = &\mathrm{sech}\left(z\right)\text{.}\end{array}
These functions are often simply written as :math:`\mathrm{sn}\left(z\right)`, :math:`\mathrm{cn}\left(z\right)` and :math:`\mathrm{dn}\left(z\right)`, thereby avoiding explicit reference to the argument :math:`k`.
They can also be expressed in terms of Jacobian theta functions (see :meth:`jactheta_real`).
Another nine elliptic functions may be computed via the formulae
.. math::
\begin{array}{lcl}\mathrm{cd}\left(z\right)& = &\mathrm{cn}\left(z\right)/\mathrm{dn}\left(z\right)\\\mathrm{sd}\left(z\right)& = &\mathrm{sn}\left(z\right)/\mathrm{dn}\left(z\right)\\\mathrm{nd}\left(z\right)& = &1/\mathrm{dn}\left(z\right)\\\mathrm{dc}\left(z\right)& = &\mathrm{dn}\left(z\right)/\mathrm{cn}\left(z\right)\\\mathrm{nc}\left(z\right)& = &1/\mathrm{cn}\left(z\right)\\\mathrm{sc}\left(z\right)& = &\mathrm{sn}\left(z\right)/\mathrm{cn}\left(z\right)\\\mathrm{ns}\left(z\right)& = &1/\mathrm{sn}\left(z\right)\\\mathrm{ds}\left(z\right)& = &\mathrm{dn}\left(z\right)/\mathrm{sn}\left(z\right)\\\mathrm{cs}\left(z\right)& = &\mathrm{cn}\left(z\right)/\mathrm{sn}\left(z\right)\end{array}
(see Abramowitz and Stegun (1972)).
The values of :math:`\mathrm{sn}\left(z\right)`, :math:`\mathrm{cn}\left(z\right)` and :math:`\mathrm{dn}\left(z\right)` are obtained by calls to :meth:`jacellip_real`.
Further details can be found in `Further Comments <https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s21cbf.html#fcomments>`__.
.. _s21cb-py2-py-references:
**References**
Abramowitz, M and Stegun, I A, 1972, `Handbook of Mathematical Functions`, (3rd Edition), Dover Publications
Salzer, H E, 1962, `Quick calculation of Jacobian elliptic functions`, Comm. ACM (5), 399
"""
raise NotImplementedError
[docs]def jactheta_real(k, x, q):
r"""
``jactheta_real`` returns the value of one of the Jacobian theta functions :math:`\theta_0\left(x, q\right)`, :math:`\theta_1\left(x, q\right)`, :math:`\theta_2\left(x, q\right)`, :math:`\theta_3\left(x, q\right)` or :math:`\theta_4\left(x, q\right)` for a real argument :math:`x` and non-negative :math:`q < 1`.
.. _s21cc-py2-py-doc:
For full information please refer to the NAG Library document for s21cc
https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s21ccf.html
.. _s21cc-py2-py-parameters:
**Parameters**
**k** : int
Denotes the function :math:`\theta_k\left(x, q\right)` to be evaluated. Note that :math:`\mathrm{k} = 4` is equivalent to :math:`\mathrm{k} = 0`.
**x** : float
The argument :math:`x` of the function.
**q** : float
The argument :math:`q` of the function.
**Returns**
**jt** : float
The value of one of the Jacobian theta functions :math:`\theta_0\left(x, q\right)`, :math:`\theta_1\left(x, q\right)`, :math:`\theta_2\left(x, q\right)`, :math:`\theta_3\left(x, q\right)` or :math:`\theta_4\left(x, q\right)` for a real argument :math:`x` and non-negative :math:`q < 1`.
.. _s21cc-py2-py-errors:
**Raises**
**NagValueError**
(`errno` :math:`1`)
On entry, :math:`\mathrm{q} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{q} < 1.0`.
(`errno` :math:`1`)
On entry, :math:`\mathrm{q} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{q}\geq 0.0`.
(`errno` :math:`1`)
On entry, :math:`\mathrm{k} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{k}\leq 4`.
(`errno` :math:`1`)
On entry, :math:`\mathrm{k} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{k}\geq 0`.
.. _s21cc-py2-py-notes:
**Notes**
``jactheta_real`` evaluates an approximation to the Jacobian theta functions :math:`\theta_0\left(x, q\right)`, :math:`\theta_1\left(x, q\right)`, :math:`\theta_2\left(x, q\right)`, :math:`\theta_3\left(x, q\right)` and :math:`\theta_4\left(x, q\right)` given by
.. math::
\begin{array}{lcl}\theta_0\left(x, q\right)& = &1+2\sum_{{n = 1}}^{\infty }\left(-1\right)^n{q}^{n^2}\cos\left(2n\pi x\right)\text{,}\\&&\\\theta_1\left(x, q\right)& = &2\sum_{{n = 0}}^{\infty }\left(-1\right)^n{q}^{\left(n+\frac{1}{2}\right)^2}\sin\left\{\left(2n+1\right)\pi x\right\}\text{,}\\&&\\\theta_2\left(x, q\right)& = &2\sum_{{n = 0}}^{\infty }{q}^{\left(n+\frac{1}{2}\right)^2}\cos\left\{\left(2n+1\right)\pi x\right\}\text{,}\\&&\\\theta_3\left(x, q\right)& = &1+2\sum_{{n = 1}}^{\infty }{q}^{n^2}\cos\left(2n\pi x\right)\text{,}\\&&\\\theta_4\left(x, q\right)& = &\theta_0\left(x, q\right)\text{,}\end{array}
where :math:`x` and :math:`q` (the `nome`) are real with :math:`0\leq q < 1`.
These functions are important in practice because every one of the Jacobian elliptic functions (see :meth:`jacellip_complex`) can be expressed as the ratio of two Jacobian theta functions (see Whittaker and Watson (1990)).
There is also a bewildering variety of notations used in the literature to define them.
Some authors (e.g., Section 16.27 of Abramowitz and Stegun (1972)) define the argument in the trigonometric terms to be :math:`x` instead of :math:`\pi x`.
This can often lead to confusion, so great care must, therefore, be exercised when consulting the literature.
Further details (including various relations and identities) can be found in the references.
``jactheta_real`` is based on a truncated series approach.
If :math:`t` differs from :math:`x` or :math:`{-x}` by an integer when :math:`0\leq t\leq \frac{1}{2}`, it follows from the periodicity and symmetry properties of the functions that :math:`\theta_1\left(x, q\right) = \pm \theta_1\left(t, q\right)` and :math:`\theta_3\left(x, q\right) = \pm \theta_3\left(t, q\right)`.
In a region for which the approximation is sufficiently accurate, :math:`\theta_1` is set equal to the first term (:math:`n = 0`) of the transformed series
.. math::
\theta_1\left(t, q\right) = 2\sqrt{\frac{\lambda }{\pi }}e^{{-\lambda t^2}}\sum_{{n = 0}}^{\infty }\left(-1\right)^ne^{{-\lambda \left(n+\frac{1}{2}\right)^2}}\sinh\left\{\left(2n+1\right)\lambda t\right\}
and :math:`\theta_3` is set equal to the first two terms (i.e., :math:`n\leq 1`) of
.. math::
\theta_3\left(t, q\right) = \sqrt{\frac{\lambda }{\pi }}e^{{-\lambda t^2}}\left\{1+2\sum_{{n = 1}}^{\infty }e^{{-\lambda n^2}}\cosh\left(2n\lambda t\right)\right\}\text{,}
where :math:`\lambda = \pi^2/\left\lvert \mathrm{loge}\left(q\right)\right\rvert`.
Otherwise, the trigonometric series for :math:`\theta_1\left(t, q\right)` and :math:`\theta_3\left(t, q\right)` are used.
For all values of :math:`x`, :math:`\theta_0` and :math:`\theta_2` are computed from the relations :math:`\theta_0\left(x, q\right) = \theta_3\left({\frac{1}{2}-\left\lvert x\right\rvert }, q\right)` and :math:`\theta_2\left(x, q\right) = \theta_1\left({\frac{1}{2}-\left\lvert x\right\rvert }, q\right)`.
.. _s21cc-py2-py-references:
**References**
Abramowitz, M and Stegun, I A, 1972, `Handbook of Mathematical Functions`, (3rd Edition), Dover Publications
Byrd, P F and Friedman, M D, 1971, `Handbook of Elliptic Integrals for Engineers and Scientists`, pp. 315--320, (2nd Edition), Springer--Verlag
Magnus, W, Oberhettinger, F and Soni, R P, 1966, `Formulas and Theorems for the Special Functions of Mathematical Physics`, 371--377, Springer--Verlag
Tølke, F, 1966, `Praktische Funktionenlehre (Bd. II)`, 1--38, Springer--Verlag
Whittaker, E T and Watson, G N, 1990, `A Course in Modern Analysis`, (4th Edition), Cambridge University Press
"""
raise NotImplementedError
[docs]def ellipint_general_2(z, akp, a, b):
r"""
``ellipint_general_2`` returns the value of the general elliptic integral of the second kind :math:`F\left(z, {k^{\prime }}, a, b\right)` for a complex argument :math:`z`.
.. _s21da-py2-py-doc:
For full information please refer to the NAG Library document for s21da
https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s21daf.html
.. _s21da-py2-py-parameters:
**Parameters**
**z** : complex
The argument :math:`z` of the function.
**akp** : float
The argument :math:`k^{\prime }` of the function.
**a** : float
The argument :math:`a` of the function.
**b** : float
The argument :math:`b` of the function.
**Returns**
**f** : complex
The value of the general elliptic integral of the second kind :math:`F\left(z, {k^{\prime }}, a, b\right)` for a complex argument :math:`z`.
.. _s21da-py2-py-errors:
**Raises**
**NagValueError**
(`errno` :math:`1`)
On entry, :math:`\left\lvert \mathrm{Im}\left(\mathrm{z}\right)\right\rvert` is too large: :math:`\left\lvert \mathrm{Im}\left(\mathrm{z}\right)\right\rvert = \langle\mathit{\boldsymbol{value}}\rangle`. It must not exceed :math:`\langle\mathit{\boldsymbol{value}}\rangle`.
(`errno` :math:`1`)
On entry, :math:`\mathrm{Re}\left(\mathrm{z}\right)` is too large: :math:`\mathrm{Re}\left(\mathrm{z}\right) = \langle\mathit{\boldsymbol{value}}\rangle`. It must not exceed :math:`\langle\mathit{\boldsymbol{value}}\rangle`.
(`errno` :math:`1`)
On entry, :math:`\mathrm{Re}\left(\mathrm{z}\right) < 0.0`: :math:`\mathrm{Re}\left(\mathrm{z}\right) = \langle\mathit{\boldsymbol{value}}\rangle`.
(`errno` :math:`1`)
On entry, :math:`\left\lvert \mathrm{akp}\right\rvert` is too large: :math:`\left\lvert \mathrm{akp}\right\rvert = \langle\mathit{\boldsymbol{value}}\rangle`. It must not exceed :math:`\langle\mathit{\boldsymbol{value}}\rangle`.
(`errno` :math:`2`)
The iterative procedure used to evaluate the integral has failed to converge.
.. _s21da-py2-py-notes:
**Notes**
``ellipint_general_2`` evaluates an approximation to the general elliptic integral of the second kind :math:`F\left(z, {k^{\prime }}, a, b\right)` given by
.. math::
F\left(z, {k^{\prime }}, a, b\right) = \int_0^z\frac{{a+b\zeta^2}}{{\left(1+\zeta^2\right)\sqrt{\left(1+\zeta^2\right)\left(1+{k^{\prime }}^2\zeta^2\right)}}}{d\zeta }\text{,}
where :math:`a` and :math:`b` are real arguments, :math:`z` is a complex argument whose real part is non-negative and :math:`k^{\prime }` is a real argument (the `complementary modulus`).
The evaluation of :math:`F` is based on the Gauss transformation.
Further details, in particular for the conformal mapping provided by :math:`F`, can be found in Bulirsch (1960).
Special values include
.. math::
F\left(z, k^{\prime }, 1, 1\right) = \int_0^z\frac{{d\zeta }}{\sqrt{\left(1+\zeta^2\right)\left(1+k^{\prime }2\zeta^2\right)}}\text{,}
or :math:`F_1\left(z, {k^{\prime }}\right)` (the `elliptic integral of the first kind`) and
.. math::
F\left(z, {k^{\prime }}, 1, {{k^{\prime }}^2}\right) = \int_0^z\frac{{\sqrt{1+{k^{\prime }}^2\zeta^2}}}{{\left(1+\zeta^2\right)\sqrt{1+\zeta^2}}}{d\zeta }\text{,}
or :math:`F_2\left(z, {k^{\prime }}\right)` (the `elliptic integral of the second kind`).
Note that the values of :math:`F_1\left(z, {k^{\prime }}\right)` and :math:`F_2\left(z, {k^{\prime }}\right)` are equal to :math:`\mathrm{tan}^{{-1}}\left(z\right)` in the trivial case :math:`k^{\prime } = 1`.
``ellipint_general_2`` is derived from an Algol 60 procedure given by Bulirsch (1960).
Constraints are placed on the values of :math:`z` and :math:`k^{\prime }` in order to avoid the possibility of machine overflow.
.. _s21da-py2-py-references:
**References**
Bulirsch, R, 1960, `Numerical calculation of elliptic integrals and elliptic functions`, Numer. Math. (7), 76--90
"""
raise NotImplementedError
[docs]def legendre_p(mode, x, m, nl):
r"""
``legendre_p`` returns a sequence of values for either the unnormalized or normalized Legendre functions of the first kind :math:`P_n^m\left(x\right)` or :math:`\overline{P_n^m}\left(x\right)` for real :math:`x` of a given order :math:`m` and degree :math:`n = 0,1,\ldots,N`.
.. _s22aa-py2-py-doc:
For full information please refer to the NAG Library document for s22aa
https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s22aaf.html
.. _s22aa-py2-py-parameters:
**Parameters**
**mode** : int
Indicates whether the sequence of function values is to be returned unnormalized or normalized.
:math:`\mathrm{mode} = 1`
The sequence of function values is returned unnormalized.
:math:`\mathrm{mode} = 2`
The sequence of function values is returned normalized.
**x** : float
The argument :math:`x` of the function.
**m** : int
The order :math:`m` of the function.
**nl** : int
The degree :math:`N` of the last function required in the sequence.
**Returns**
**p** : float, ndarray, shape :math:`\left(\mathrm{nl}+1\right)`
The required sequence of function values as follows:
if :math:`\mathrm{mode} = 1`, :math:`\mathrm{p}[n]` contains :math:`P_n^m\left(x\right)`, for :math:`\textit{n} = 0,1,\ldots,N`;
if :math:`\mathrm{mode} = 2`, :math:`\mathrm{p}[n]` contains :math:`\overline{ P_n^m }\left(x\right)`, for :math:`\textit{n} = 0,1,\ldots,N`.
.. _s22aa-py2-py-errors:
**Raises**
**NagValueError**
(`errno` :math:`1`)
On entry, :math:`\mathrm{nl} = \langle\mathit{\boldsymbol{value}}\rangle` and :math:`\left\lvert \mathrm{m}\right\rvert = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{nl}+\left\lvert \mathrm{m}\right\rvert \leq 55`.
(`errno` :math:`1`)
On entry, :math:`\left\lvert \mathrm{m}\right\rvert = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\left\lvert \mathrm{m}\right\rvert \leq 27`.
(`errno` :math:`1`)
On entry, :math:`\mathrm{nl} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: when :math:`\left\lvert \mathrm{m}\right\rvert \neq 0`, :math:`\mathrm{nl}\geq 0`.
(`errno` :math:`1`)
On entry, :math:`\mathrm{nl} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{nl}\leq 100` when :math:`\mathrm{m} = 0`.
(`errno` :math:`1`)
On entry, :math:`\mathrm{nl} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{nl}\geq 0`.
(`errno` :math:`1`)
On entry, :math:`\left\lvert \mathrm{x}\right\rvert = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\left\lvert \mathrm{x}\right\rvert \leq 1.0`.
(`errno` :math:`1`)
On entry, :math:`\mathrm{mode} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{mode}\leq 2`.
(`errno` :math:`1`)
On entry, :math:`\mathrm{mode} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{mode}\geq 1`.
.. _s22aa-py2-py-notes:
**Notes**
``legendre_p`` evaluates a sequence of values for either the unnormalized or normalized Legendre (:math:`m = 0`) or associated Legendre (:math:`m\neq 0`) functions of the first kind :math:`P_n^m\left(x\right)` or :math:`\overline{P_n^m}\left(x\right)`, where :math:`x` is real with :math:`{-1}\leq x\leq 1`, of order :math:`m` and degree :math:`n = 0,1,\ldots,N` defined by
.. math::
\begin{array}{lcll}P_n^m\left(x\right)& = &\left(1-x^2\right)^{{m/2}}\frac{d^m}{{dx^m}}P_n\left(x\right)&\quad \text{ if }m\geq 0\text{,}\\&&&\\P_n^m\left(x\right)& = &\frac{{\left(n+m\right)!}}{{\left(n-m\right)!}}P_n^{{-m}}\left(x\right)&\quad \text{ if }m < 0\quad \text{ and}\\&&&\\\overline{P_n^m}\left(x\right)& = &\sqrt{\frac{\left(2n+1\right)}{2}\frac{{\left(n-m\right)!}}{{\left(n+m\right)!}}}P_n^m\left(x\right)&\end{array}
respectively; :math:`P_n\left(x\right)` is the (unassociated) Legendre polynomial of degree :math:`n` given by
.. math::
P_n\left(x\right)\equiv P_n^0\left(x\right) = \frac{1}{{2^nn!}}\frac{d^n}{{dx^n}}\left(x^2-1\right)^n
(the `Rodrigues formula`).
Note that some authors (e.g., Abramowitz and Stegun (1972)) include an additional factor of :math:`\left(-1\right)^m` (the `Condon--Shortley Phase`) in the definitions of :math:`P_n^m\left(x\right)` and :math:`\overline{P_n^m}\left(x\right)`.
They use the notation :math:`P_{{mn}}\left(x\right)\equiv \left(-1\right)^mP_n^m\left(x\right)` in order to distinguish between the two cases.
``legendre_p`` is based on a standard recurrence relation described in Section 8.5.3 of Abramowitz and Stegun (1972).
Constraints are placed on the values of :math:`m` and :math:`n` in order to avoid the possibility of machine overflow.
It also sets the appropriate elements of the array :math:`\mathrm{p}` (see :ref:`Parameters <s22aa-py2-py-parameters>`) to zero whenever the required function is not defined for certain values of :math:`m` and :math:`n` (e.g., :math:`m = {-5}` and :math:`n = 3`).
.. _s22aa-py2-py-references:
**References**
Abramowitz, M and Stegun, I A, 1972, `Handbook of Mathematical Functions`, (3rd Edition), Dover Publications
"""
raise NotImplementedError
[docs]def hyperg_confl_real(a, b, x):
r"""
``hyperg_confl_real`` returns a value for the confluent hypergeometric function :math:`{}_1 F_1 \left(a; b; x\right)` with real parameters :math:`a` and :math:`b`, and real argument :math:`x`.
This function is sometimes also known as Kummer's function :math:`M\left(a, b, x\right)`.
.. _s22ba-py2-py-doc:
For full information please refer to the NAG Library document for s22ba
https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s22baf.html
.. _s22ba-py2-py-parameters:
**Parameters**
**a** : float
The parameter :math:`a` of the function.
**b** : float
The parameter :math:`b` of the function.
**x** : float
The argument :math:`x` of the function.
**Returns**
**m** : float
The solution :math:`M\left(a, b, x\right)`.
Note: if overflow occurs upon completion, as indicated by :math:`\mathrm{errno}` = 2, :math:`\left\lvert M\left(a, b, x\right)\right\rvert` may be assumed to be too large to be representable. :math:`\mathrm{m}` will be returned as :math:`\pm R_{\mathrm{max}}`, where :math:`R_{\mathrm{max}}` is the largest representable real number (see :meth:`machine.real_largest <naginterfaces.library.machine.real_largest>`). The sign of :math:`\mathrm{m}` should match the sign of :math:`M\left(a, b, x\right)`. If overflow occurs during a subcalculation, as indicated by :math:`\mathrm{errno}` = 5, the sign may be incorrect, and the true value of :math:`M\left(a, b, x\right)` may or may not be greater than :math:`R_{\mathrm{max}}`. In either case it is advisable to subsequently use :meth:`hyperg_confl_real_scaled`.
.. _s22ba-py2-py-errors:
**Raises**
**NagValueError**
(`errno` :math:`4`)
All approximations have completed, and the final residual estimate indicates no accuracy can be guaranteed.
Relative residual :math:`\text{} = \langle\mathit{\boldsymbol{value}}\rangle`.
(`errno` :math:`5`)
Overflow occurred in a subcalculation of :math:`M\left(a, b, x\right)`.
The answer may be completely incorrect.
(`errno` :math:`11`)
On entry, :math:`\mathrm{a} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\left\lvert \mathrm{a}\right\rvert \leq \textit{arbnd} = \langle\mathit{\boldsymbol{value}}\rangle`.
(`errno` :math:`31`)
On entry, :math:`\mathrm{b} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\left\lvert \mathrm{b}\right\rvert \leq \textit{arbnd} = \langle\mathit{\boldsymbol{value}}\rangle`.
(`errno` :math:`32`)
On entry, :math:`\mathrm{b} = \langle\mathit{\boldsymbol{value}}\rangle`.
:math:`M\left(a, b, x\right)` is undefined when :math:`b` is zero or a negative integer.
(`errno` :math:`51`)
On entry, :math:`\mathrm{x} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\left\lvert \mathrm{x}\right\rvert \leq \textit{arbnd} = \langle\mathit{\boldsymbol{value}}\rangle`.
**Warns**
**NagAlgorithmicWarning**
(`errno` :math:`1`)
Underflow occurred during the evaluation of :math:`M\left(a, b, x\right)`.
The returned value may be inaccurate.
(`errno` :math:`2`)
On completion, overflow occurred in the evaluation of :math:`M\left(a, b, x\right)`.
(`errno` :math:`3`)
All approximations have completed, and the final residual estimate indicates some precision may have been lost.
Relative residual :math:`\text{} = \langle\mathit{\boldsymbol{value}}\rangle`.
.. _s22ba-py2-py-notes:
**Notes**
``hyperg_confl_real`` returns a value for the confluent hypergeometric function :math:`{}_1 F_1 \left(a; b; x\right)` with real parameters :math:`a` and :math:`b`, and real argument :math:`x`.
This function is unbounded or not uniquely defined for :math:`b` equal to zero or a negative integer.
The associated function :meth:`hyperg_confl_real_scaled` performs the same operations, but returns :math:`M` in the scaled form :math:`M = m_f\times 2^{m_s}` to allow calculations to be performed when :math:`M` is not representable as a single working precision number.
It also accepts the parameters :math:`a` and :math:`b` as summations of an integer and a decimal fraction, giving higher accuracy when :math:`a` or :math:`b` are close to an integer.
In such cases, :meth:`hyperg_confl_real_scaled` should be used when high accuracy is required.
The confluent hypergeometric function is defined by the confluent series
.. math::
{}_1 F_1 \left(a; b; x\right) = M\left(a, b, x\right) = \sum_{0}^{\infty }{\frac{{\left(a\right)_sx^s}}{{\left(b\right)_s{s!}}}} = {1+\frac{{a}}{b}x}+\frac{{a\left(a+1\right)}}{{{b\left(b+1\right)}{2!}}}x^2+⋯
where :math:`\left(a\right)_s = 1\left(a\right)\left(a+1\right)\left(a+2\right)\ldots \left(a+s-1\right)` is the rising factorial of :math:`a`. :math:`M\left(a, b, x\right)` is a solution to the second order ODE (Kummer's Equation):
.. math::
x\frac{{d^2M}}{{dx^2}}+\left(b-x\right)\frac{{dM}}{{dx}}-aM = 0\text{.}
Given the parameters and argument :math:`\left(a, b, x\right)`, this function determines a set of safe values :math:`\left\{\left(\alpha_i, \beta_i, \zeta_i\right) | i\leq 2\right\}` and selects an appropriate algorithm to accurately evaluate the functions :math:`M_i\left(\alpha_i, \beta_i, \zeta_i\right)`.
The result is then used to construct the solution to the original problem :math:`M\left(a, b, x\right)` using, where necessary, recurrence relations and/or continuation.
Additionally, an artificial bound, :math:`\textit{arbnd}` is placed on the magnitudes of :math:`a`, :math:`b` and :math:`x` to minimize the occurrence of overflow in internal calculations. :math:`\textit{arbnd} = 0.0001\times I_{\mathrm{max}}`, where :math:`I_{\mathrm{max}} = \texttt{machine.integer_max}`.
It should, however, not be assumed that this function will produce an accurate result for all values of :math:`a`, :math:`b` and :math:`x` satisfying this criterion.
Please consult the NIST Digital Library of Mathematical Functions for a detailed discussion of the confluent hypergeometric function including special cases, transformations, relations and asymptotic approximations.
.. _s22ba-py2-py-references:
**References**
NIST Digital Library of Mathematical Functions
Pearson, J, 2009, `Computation of hypergeometric functions`, MSc Dissertation, Mathematical Institute, University of Oxford
"""
raise NotImplementedError
[docs]def hyperg_confl_real_scaled(ani, adr, bni, bdr, x):
r"""
``hyperg_confl_real_scaled`` returns a value for the confluent hypergeometric function :math:`{}_1 F_1 \left(a; b; x\right)`, with real parameters :math:`a` and :math:`b` and real argument :math:`x`.
The solution is returned in the scaled form :math:`{}_1 F_1 \left(a; b; x\right) = m_f\times 2^{m_s}`.
This function is sometimes also known as Kummer's function :math:`M\left(a, b, x\right)`.
.. _s22bb-py2-py-doc:
For full information please refer to the NAG Library document for s22bb
https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s22bbf.html
.. _s22bb-py2-py-parameters:
**Parameters**
**ani** : float
:math:`a_i`, the nearest integer to :math:`a`, satisfying :math:`a_i = a-a_r`.
**adr** : float
:math:`a_r`, the signed decimal remainder satisfying :math:`a_r = a-a_i` and :math:`\left\lvert a_r\right\rvert \leq 0.5`.
Note: if :math:`\left\lvert \mathrm{adr}\right\rvert < 100.0\epsilon`, :math:`a_r = 0.0` will be used, where :math:`\epsilon` is the machine precision as returned by :meth:`machine.precision <naginterfaces.library.machine.precision>`.
**bni** : float
:math:`b_i`, the nearest integer to :math:`b`, satisfying :math:`b_i = b-b_r`.
**bdr** : float
:math:`b_r`, the signed decimal remainder satisfying :math:`b_r = b-b_i` and :math:`\left\lvert b_r\right\rvert \leq 0.5`.
Note: if :math:`\left\lvert \mathrm{bdr}-\mathrm{adr}\right\rvert < 100.0\epsilon`, :math:`a_r = b_r` will be used, where :math:`\epsilon` is the machine precision as returned by :meth:`machine.precision <naginterfaces.library.machine.precision>`.
**x** : float
The argument :math:`x` of the function.
**Returns**
**frm** : float
:math:`m_f`, the scaled real component of the solution satisfying :math:`m_f = M\left(a, b, x\right)\times 2^{{-m_s}}`.
Note: if overflow occurs upon completion, as indicated by :math:`\mathrm{errno}` = 2, the value of :math:`m_f` returned may still be correct. If overflow occurs in a subcalculation, as indicated by :math:`\mathrm{errno}` = 5, this should not be assumed.
**scm** : int
:math:`m_s`, the scaling power of two, satisfying :math:`m_s = \mathrm{log2}\left(\frac{{M\left(a, b, x\right)}}{m_f}\right)`.
Note: if overflow occurs upon completion, as indicated by :math:`\mathrm{errno}` = 2, then :math:`m_s\geq I_{\mathrm{max}}`, where :math:`I_{\mathrm{max}}` is the largest representable integer (see :meth:`machine.integer_max <naginterfaces.library.machine.integer_max>`). If overflow occurs during a subcalculation, as indicated by :math:`\mathrm{errno}` = 5, :math:`m_s` may or may not be greater than :math:`I_{\mathrm{max}}`. In either case, :math:`\mathrm{scm} = \texttt{machine.integer_max}` will have been returned.
.. _s22bb-py2-py-errors:
**Raises**
**NagValueError**
(`errno` :math:`4`)
All approximations have completed, and the final residual estimate indicates no accuracy can be guaranteed.
Relative residual :math:`\text{} = \langle\mathit{\boldsymbol{value}}\rangle`.
(`errno` :math:`5`)
Overflow occurred in a subcalculation of :math:`M\left(a, b, x\right)`.
The answer may be completely incorrect.
(`errno` :math:`11`)
On entry, :math:`\mathrm{ani} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\left\lvert \mathrm{ani}\right\rvert \leq \textit{arbnd} = \langle\mathit{\boldsymbol{value}}\rangle`.
(`errno` :math:`13`)
:math:`\mathrm{ani}` is non-integral.
On entry, :math:`\mathrm{ani} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{ani} = \left\lfloor \mathrm{ani}\right\rfloor`.
(`errno` :math:`21`)
On entry, :math:`\mathrm{adr} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\left\lvert \mathrm{adr}\right\rvert \leq 0.5`.
(`errno` :math:`31`)
On entry, :math:`\mathrm{bni} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\left\lvert \mathrm{bni}\right\rvert \leq \textit{arbnd} = \langle\mathit{\boldsymbol{value}}\rangle`.
(`errno` :math:`32`)
On entry, :math:`b = \mathrm{bni}+\mathrm{bdr} = \langle\mathit{\boldsymbol{value}}\rangle`.
:math:`M\left(a, b, x\right)` is undefined when :math:`b` is zero or a negative integer.
(`errno` :math:`33`)
:math:`\mathrm{bni}` is non-integral.
On entry, :math:`\mathrm{bni} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{bni} = \left\lfloor \mathrm{bni}\right\rfloor`.
(`errno` :math:`41`)
On entry, :math:`\mathrm{bdr} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\left\lvert \mathrm{bdr}\right\rvert \leq 0.5`.
(`errno` :math:`51`)
On entry, :math:`\mathrm{x} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\left\lvert \mathrm{x}\right\rvert \leq \textit{arbnd} = \langle\mathit{\boldsymbol{value}}\rangle`.
**Warns**
**NagAlgorithmicWarning**
(`errno` :math:`1`)
Underflow occurred during the evaluation of :math:`M\left(a, b, x\right)`.
The returned value may be inaccurate.
(`errno` :math:`2`)
On completion, overflow occurred in the evaluation of :math:`M\left(a, b, x\right)`.
(`errno` :math:`3`)
All approximations have completed, and the final residual estimate indicates some precision may have been lost.
Relative residual :math:`\text{} = \langle\mathit{\boldsymbol{value}}\rangle`.
.. _s22bb-py2-py-notes:
**Notes**
``hyperg_confl_real_scaled`` returns a value for the confluent hypergeometric function :math:`{}_1 F_1 \left(a; b; x\right)`, with real parameters :math:`a` and :math:`b` and real argument :math:`x`, in the scaled form :math:`{}_1 F_1 \left(a; b; x\right) = m_f\times 2^{m_s}`, where :math:`m_f` is the real scaled component and :math:`m_s` is the integer power of two scaling.
This function is unbounded or not uniquely defined for :math:`b` equal to zero or a negative integer.
The confluent hypergeometric function is defined by the confluent series,
.. math::
{}_1 F_1 \left(a; b; x\right) = M\left(a, b, x\right) = \sum_{0}^{\infty }{\frac{{\left(a\right)_sx^s}}{{\left(b\right)_s{s!}}}} = {1+\frac{a}{b}x}+\frac{{a\left(a+1\right)}}{{{b\left(b+1\right)}{2!}}}x^2+⋯
where :math:`\left(a\right)_s = 1\left(a\right)\left(a+1\right)\left(a+2\right)\ldots \left(a+s-1\right)` is the rising factorial of :math:`a`. :math:`M\left(a, b, x\right)` is a solution to the second order ODE (Kummer's Equation):
.. math::
x\frac{{d^2M}}{{dx^2}}+\left(b-x\right)\frac{{dM}}{{dx}}-aM = 0\text{.}
Given the parameters and argument :math:`\left(a, b, x\right)`, this function determines a set of safe values :math:`\left\{\left(\alpha_i, \beta_i, \zeta_i\right) | i\leq 2\right\}` and selects an appropriate algorithm to accurately evaluate the functions :math:`M_i\left(\alpha_i, \beta_i, \zeta_i\right)`.
The result is then used to construct the solution to the original problem :math:`M\left(a, b, x\right)` using, where necessary, recurrence relations and/or continuation.
For improved precision in the final result, this function accepts :math:`a` and :math:`b` split into an integral and a decimal fractional component.
Specifically :math:`a = a_i+a_r`, where :math:`\left\lvert a_r\right\rvert \leq 0.5` and :math:`a_i = a-a_r` is integral. :math:`b` is similarly deconstructed.
Additionally, an artificial bound, :math:`\textit{arbnd}` is placed on the magnitudes of :math:`a_i`, :math:`b_i` and :math:`x` to minimize the occurrence of overflow in internal calculations. :math:`\textit{arbnd} = 0.0001\times I_{\mathrm{max}}`, where :math:`I_{\mathrm{max}} = \texttt{machine.integer_max}`.
It should, however, not be assumed that this function will produce an accurate result for all values of :math:`a_i`, :math:`b_i` and :math:`x` satisfying this criterion.
Please consult the NIST Digital Library of Mathematical Functions for a detailed discussion of the confluent hypergeometric function including special cases, transformations, relations and asymptotic approximations.
.. _s22bb-py2-py-references:
**References**
NIST Digital Library of Mathematical Functions
Pearson, J, 2009, `Computation of hypergeometric functions`, MSc Dissertation, Mathematical Institute, University of Oxford
"""
raise NotImplementedError
[docs]def hyperg_gauss_real(a, b, c, x):
r"""
``hyperg_gauss_real`` returns a value for the Gauss hypergeometric function :math:`{}_2 F_1 \left({a,b}; c; x\right)` for real parameters :math:`a,b` and :math:`c`, and real argument :math:`x`.
.. _s22be-py2-py-doc:
For full information please refer to the NAG Library document for s22be
https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s22bef.html
.. _s22be-py2-py-parameters:
**Parameters**
**a** : float
The parameter :math:`a`.
**b** : float
The parameter :math:`b`.
**c** : float
The parameter :math:`c`.
**x** : float
The argument :math:`x`.
**Returns**
**f21** : float
The value returned for the Gauss hypergeometric function :math:`{}_2 F_1 \left({a,b}; c; x\right)` for real parameters :math:`a,b` and :math:`c`, and real argument :math:`x`.
.. _s22be-py2-py-errors:
**Raises**
**NagValueError**
(`errno` :math:`3`)
All approximations have completed, and the final residual estimate indicates no accuracy can be guaranteed.
:math:`\text{Relative residual} = \langle\mathit{\boldsymbol{value}}\rangle`.
(`errno` :math:`4`)
On entry, :math:`\mathrm{x} = \langle\mathit{\boldsymbol{value}}\rangle`, :math:`c = \langle\mathit{\boldsymbol{value}}\rangle`, :math:`a+b = \langle\mathit{\boldsymbol{value}}\rangle`.
:math:`{}_2 F_1 \left(a,b;c;1\right)` is infinite in the case :math:`c\leq a+b`.
(`errno` :math:`6`)
Overflow occurred in a subcalculation of :math:`{}_2 F_1 \left(a,b;c;x\right)`. The result may or may not be infinite.
(`errno` :math:`9`)
An internal calculation has resulted in an undefined result.
(`errno` :math:`11`)
On entry, :math:`\mathrm{a}` does not satisfy :math:`\left\lvert \mathrm{a}\right\rvert \leq \textit{arbnd} = \langle\mathit{\boldsymbol{value}}\rangle`.
(`errno` :math:`21`)
On entry, :math:`\mathrm{b}` does not satisfy :math:`\left\lvert \mathrm{b}\right\rvert \leq \textit{arbnd} = \langle\mathit{\boldsymbol{value}}\rangle`.
(`errno` :math:`31`)
On entry, :math:`\mathrm{c}` does not satisfy :math:`\left\lvert \mathrm{c}\right\rvert \leq \textit{arbnd} = \langle\mathit{\boldsymbol{value}}\rangle`.
(`errno` :math:`32`)
On entry, :math:`\mathrm{c} = \langle\mathit{\boldsymbol{value}}\rangle`.
:math:`{}_2 F_1 \left(a,b;c;x\right)` is undefined when :math:`c` is zero or a negative integer.
(`errno` :math:`41`)
On entry, :math:`\mathrm{x}` does not satisfy :math:`\left\lvert \mathrm{x}\right\rvert \leq \textit{arbnd} = \langle\mathit{\boldsymbol{value}}\rangle`.
(`errno` :math:`42`)
On entry, :math:`\mathrm{x} = \langle\mathit{\boldsymbol{value}}\rangle`.
In general, :math:`{}_2 F_1 \left(a,b;c;x\right)` is not real valued when :math:`x > 1`.
**Warns**
**NagAlgorithmicWarning**
(`errno` :math:`1`)
Underflow occurred during the evaluation of :math:`{}_2 F_1 \left(a,b;c;x\right)`. The returned value may be inaccurate.
(`errno` :math:`2`)
All approximations have completed, and the final residual estimate indicates some precision may have been lost.
:math:`\text{Relative residual} = \langle\mathit{\boldsymbol{value}}\rangle`.
(`errno` :math:`5`)
On completion, overflow occurred in the evaluation of :math:`{}_2 F_1 \left(a,b;c;x\right)`.
.. _s22be-py2-py-notes:
**Notes**
``hyperg_gauss_real`` returns a value for the Gauss hypergeometric function :math:`{}_2 F_1 \left({a,b}; c; x\right)` for real parameters :math:`a`, :math:`b` and :math:`c`, and for real argument :math:`x`.
The associated function :meth:`hyperg_gauss_real_scaled` performs the same operations, but returns :math:`{}_2 F_1 \left({a,b}; c; x\right)` in the scaled form :math:`{}_2 F_1 \left({a,b}; c; x\right) = f_{\mathrm{fr}}\times 2^{f_{\mathrm{sc}}}` to allow calculations to be performed when :math:`{}_2 F_1 \left({a,b}; c; x\right)` is not representable as a single working precision number.
It also accepts the parameters :math:`a`, :math:`b` and :math:`c` as summations of an integer and a decimal fraction, giving higher accuracy when any are close to an integer.
The Gauss hypergeometric function is a solution to the hypergeometric differential equation,
.. math::
x\left(1-x\right)\frac{{d^2f}}{{dx^2}}+\left(c-\left(a+b+1\right)x\right)\frac{{df}}{{dx}}-abf = 0\text{.}
For :math:`\left\lvert x\right\rvert < 1`, it may be defined by the Gauss series,
.. math::
{}_2 F_1 \left({a,b}; c; x\right) = \sum_{0}^{\infty }{\frac{{\left(a\right)_s\left(b\right)_s}}{{\left(c\right)_s{s!}}}x^s} = {1+\frac{{ab}}{c}x}+\frac{{a\left(a+1\right)b\left(b+1\right)}}{{{c\left(c+1\right)}{2!}}}x^2+⋯\text{,}
where :math:`\left(a\right)_s = 1\left(a\right)\left(a+1\right)\left(a+2\right)\ldots \left(a+s-1\right)` is the rising factorial of :math:`a`. :math:`{}_2 F_1 \left({a,b}; c; x\right)` is undefined for :math:`c = 0` or :math:`c` a negative integer.
For :math:`\left\lvert x\right\rvert < 1`, the series is absolutely convergent and :math:`{}_2 F_1 \left({a,b}; c; x\right)` is finite.
For :math:`x < 1`, linear transformations of the form,
.. math::
{}_2 F_1 \left({a,b}; c; x\right) = C_1\left(a_1, b_1, c_1, x_1\right){}_2 F_1 \left({a_1,b_1}; c_1; x_1\right)+C_2\left(a_2, b_2, c_2, x_2\right){}_2 F_1 \left({a_2,b_2}; c_2; x_2\right)
exist, where :math:`x_1`, :math:`x_2 \in \left(0, 1\right]`. :math:`C_1` and :math:`C_2` are real valued functions of the parameters and argument, typically involving products of gamma functions.
When these are degenerate, finite limiting cases exist.
Hence for :math:`x < 0`, :math:`{}_2 F_1 \left({a,b}; c; x\right)` is defined by analytic continuation, and for :math:`x < 1`, :math:`{}_2 F_1 \left({a,b}; c; x\right)` is real and finite.
For :math:`x = 1`, the following apply:
If :math:`c > a+b`, :math:`{}_2 F_1 \left({a,b}; c; 1\right) = \frac{{\Gamma \left(c\right)\Gamma \left(c-a-b\right)}}{{\Gamma \left(c-a\right)\Gamma \left(c-b\right)}}`, and hence is finite. Solutions also exist for the degenerate cases where :math:`c-a` or :math:`c-b` are negative integers or zero.
If :math:`c\leq a+b`, :math:`{}_2 F_1 \left({a,b}; c; 1\right)` is infinite, and the sign of :math:`{}_2 F_1 \left({a,b}; c; 1\right)` is determinable as :math:`x` approaches :math:`1` from below.
In the complex plane, the principal branch of :math:`{}_2 F_1 \left({a,b}; c; z\right)` is taken along the real axis from :math:`x = 1.0` increasing. :math:`{}_2 F_1 \left({a,b}; c; z\right)` is multivalued along this branch, and for real parameters :math:`a,b` and :math:`c` is typically not real valued.
As such, this function will not compute a solution when :math:`x > 1`.
The solution strategy used by this function is primarily dependent upon the value of the argument :math:`x`.
Once trivial cases and the case :math:`x = 1.0` are eliminated, this proceeds as follows.
For :math:`0 < x\leq 0.5`, sets of safe parameters :math:`\left\{\alpha_{{i,j}}; \beta_{{i,j}}; \zeta_{{i,j}}; {\chi_j\left\lvert 1\leq j\leq 2\right\rvert }; {1\leq i\leq 4}\right\}` are determined, such that the values of :math:`{}_2 F_1 \left({a_j,b_j}; c_j; x_j\right)` required for an appropriate transformation of the type `(3) <https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s22bef.html#eqn3>`__ may be calculated either directly or using recurrence relations from the solutions of :math:`{}_2 F_1 \left({\alpha_{{i,j}},\beta_{{i,j}}}; \zeta_{{i,j}}; \chi_j\right)`.
If :math:`c` is positive, then only transformations with :math:`C_2 = 0.0` will be used, implying only :math:`{}_2 F_1 \left({a_1,b_1}; c_1; x_1\right)` will be required, with the transformed argument :math:`x_1 = x`.
If :math:`c` is negative, in some cases a transformation with :math:`C_2\neq 0.0` will be used, with the argument :math:`x_2 = 1.0-x`.
The function then cycles through these sets until acceptable solutions are generated.
If no computation produces an accurate answer, the least inaccurate answer is selected to complete the computation.
See `Accuracy <https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s22bef.html#accuracy>`__.
For :math:`0.5 < x < 1.0`, an identical approach is first used with the argument :math:`x`.
Should this fail, a linear transformation resulting in both transformed arguments satisfying :math:`x_j = 1.0-x` is employed, and the above strategy for :math:`0 < x\leq 0.5` is utilized on both components.
Further transformations in these sub-computations are however, limited to single terms with no argument transformation.
For :math:`x < 0`, a linear transformation mapping the argument :math:`x` to the interval :math:`\left(0, 0.5\right]` is first employed.
The strategy for :math:`0 < x\leq 0.5` is then used on each component, including possible further two term transforms.
To avoid some degenerate cases, a transform mapping the argument :math:`x` to :math:`\left[0.5, 1\right)` may also be used.
In addition to the above restrictions on :math:`c` and :math:`x`, an artificial bound, arbnd, is placed on the magnitudes of :math:`a,b,c` and :math:`x` to minimize the occurrence of overflow in internal calculations, particularly those involving real to integer conversions. :math:`\textit{arbnd} = 0.0001\times I_{\mathrm{max}}`, where :math:`I_{\mathrm{max}}` is the largest machine integer (see :meth:`machine.integer_max <naginterfaces.library.machine.integer_max>`).
It should however, not be assumed that this function will produce accurate answers for all values of :math:`a,b,c` and :math:`x` satisfying this criterion.
This function also tests for non-finite values of the parameters and argument on entry, and assigns non-finite values upon completion if appropriate.
See `Further Comments <https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s22bef.html#fcomments>`__ and submodule :mod:`~naginterfaces.library.ieee`.
Please consult the NIST Digital Library of Mathematical Functions for a detailed discussion of the Gauss hypergeometric function including special cases, transformations, relations and asymptotic approximations.
.. _s22be-py2-py-references:
**References**
NIST Digital Library of Mathematical Functions
Pearson, J, 2009, `Computation of hypergeometric functions`, MSc Dissertation, Mathematical Institute, University of Oxford
"""
raise NotImplementedError
[docs]def hyperg_gauss_real_scaled(ani, adr, bni, bdr, cni, cdr, x):
r"""
``hyperg_gauss_real_scaled`` returns a value for the Gauss hypergeometric function :math:`{}_2 F_1 \left({a,b}; c; x\right)` for real parameters :math:`a,b` and :math:`c`, and real argument :math:`x`.
The result is returned in the scaled form :math:`{}_2 F_1 \left({a,b}; c; x\right) = f_{\mathrm{fr}}\times 2^{f_{\mathrm{sc}}}`.
.. _s22bf-py2-py-doc:
For full information please refer to the NAG Library document for s22bf
https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s22bff.html
.. _s22bf-py2-py-parameters:
**Parameters**
**ani** : float
:math:`a_i`, the nearest integer to :math:`a`, satisfying :math:`a_i = a-a_r`.
**adr** : float
:math:`a_r`, the signed decimal remainder satisfying :math:`a_r = a-a_i` and :math:`\left\lvert a_r\right\rvert \leq 0.5`.
**bni** : float
:math:`b_i`, the nearest integer to :math:`b`, satisfying :math:`b_i = b-b_r`.
**bdr** : float
:math:`b_r`, the signed decimal remainder satisfying :math:`b_r = b-b_i` and :math:`\left\lvert b_r\right\rvert \leq 0.5`.
**cni** : float
:math:`c_i`, the nearest integer to :math:`c`, satisfying :math:`c_i = c-c_r`.
**cdr** : float
:math:`c_r`, the signed decimal remainder satisfying :math:`c_r = c-c_i` and :math:`\left\lvert c_r\right\rvert \leq 0.5`.
**x** : float
The argument :math:`x`.
**Returns**
**frf** : float
:math:`f_{\mathrm{fr}}`, the scaled real component of the solution satisfying :math:`f_{\mathrm{fr}} = {}_2 F_1 \left({a,b}; c; x\right)\times 2^{{-f_{\mathrm{sc}}}}`, i.e., :math:`{}_2 F_1 \left({a,b}; c; x\right) = f_{\mathrm{fr}}\times 2^{f_{\mathrm{sc}}}`. See `Further Comments <https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s22bff.html#fcomments>`__ for the behaviour of :math:`f_{\mathrm{fr}}` when a finite or non-finite answer is returned.
**scf** : int
:math:`f_{\mathrm{sc}}`, the scaling power of two, satisfying :math:`f_{\mathrm{sc}} = \mathrm{log2}\left(\frac{{{}_2 F_1 \left({a,b}; c; x\right)}}{{f_{\mathrm{fr}}}}\right)`, i.e., :math:`{}_2 F_1 \left({a,b}; c; x\right) = f_{\mathrm{fr}}\times 2^{f_{\mathrm{sc}}}`. See `Further Comments <https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s22bff.html#fcomments>`__ for the behaviour of :math:`f_{\mathrm{sc}}` when a non-finite answer is returned.
.. _s22bf-py2-py-errors:
**Raises**
**NagValueError**
(`errno` :math:`3`)
All approximations have completed, and the final residual estimate indicates no accuracy can be guaranteed.
:math:`\text{Relative residual} = \langle\mathit{\boldsymbol{value}}\rangle`.
(`errno` :math:`4`)
On entry, :math:`\mathrm{x} = \langle\mathit{\boldsymbol{value}}\rangle`, :math:`c = \langle\mathit{\boldsymbol{value}}\rangle`, :math:`a+b = \langle\mathit{\boldsymbol{value}}\rangle`.
:math:`{}_2 F_1 \left({a,b}; c; 1\right)` is infinite in the case :math:`c\leq a+b`.
(`errno` :math:`6`)
Overflow occurred in a subcalculation of :math:`{}_2 F_1 \left({a,b}; c; x\right)`. The answer may be completely incorrect.
(`errno` :math:`9`)
An internal calculation has resulted in an undefined result.
(`errno` :math:`11`)
On entry, :math:`\mathrm{ani}` does not satisfy :math:`\left\lvert \mathrm{ani}\right\rvert \leq \textit{arbnd} = \langle\mathit{\boldsymbol{value}}\rangle`.
(`errno` :math:`13`)
:math:`\mathrm{ani}` is non-integral.
On entry, :math:`\mathrm{ani} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{ani} = \left\lfloor \mathrm{ani}\right\rfloor`.
(`errno` :math:`21`)
On entry, :math:`\mathrm{adr}` does not satisfy :math:`\left\lvert \mathrm{adr}\right\rvert \leq 0.5`.
(`errno` :math:`31`)
On entry, :math:`\mathrm{bni}` does not satisfy :math:`\left\lvert \mathrm{bni}\right\rvert \leq \textit{arbnd} = \langle\mathit{\boldsymbol{value}}\rangle`.
(`errno` :math:`33`)
:math:`\mathrm{bni}` is non-integral.
On entry, :math:`\mathrm{bni} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{bni} = \left\lfloor \mathrm{bni}\right\rfloor`.
(`errno` :math:`41`)
On entry, :math:`\mathrm{bdr}` does not satisfy :math:`\left\lvert \mathrm{bdr}\right\rvert \leq 0.5`.
(`errno` :math:`51`)
On entry, :math:`\mathrm{cni}` does not satisfy :math:`\left\lvert \mathrm{cni}\right\rvert \leq \textit{arbnd} = \langle\mathit{\boldsymbol{value}}\rangle`.
(`errno` :math:`52`)
On entry, :math:`c = \mathrm{cni}+\mathrm{cdr} = \langle\mathit{\boldsymbol{value}}\rangle`.
:math:`{}_2 F_1 \left({a,b}; c; x\right)` is undefined when :math:`c` is zero or a negative integer.
(`errno` :math:`53`)
:math:`\mathrm{cni}` is non-integral.
On entry, :math:`\mathrm{cni} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{cni} = \left\lfloor \mathrm{cni}\right\rfloor`.
(`errno` :math:`61`)
On entry, :math:`\mathrm{cdr}` does not satisfy :math:`\left\lvert \mathrm{cdr}\right\rvert \leq 0.5`.
(`errno` :math:`71`)
On entry, :math:`\mathrm{x}` does not satisfy :math:`\left\lvert \mathrm{x}\right\rvert \leq \textit{arbnd} = \langle\mathit{\boldsymbol{value}}\rangle`.
(`errno` :math:`72`)
On entry, :math:`\mathrm{x} = \langle\mathit{\boldsymbol{value}}\rangle`.
In general, :math:`{}_2 F_1 \left({a,b}; c; x\right)` is not real valued when :math:`x > 1`.
**Warns**
**NagAlgorithmicWarning**
(`errno` :math:`1`)
Underflow occurred during the evaluation of :math:`{}_2 F_1 \left({a,b}; c; x\right)`. The returned value may be inaccurate.
(`errno` :math:`2`)
All approximations have completed, and the final residual estimate indicates some precision may have been lost.
:math:`\text{Relative residual} = \langle\mathit{\boldsymbol{value}}\rangle`.
(`errno` :math:`5`)
On completion, overflow occurred in the evaluation of :math:`{}_2 F_1 \left({a,b}; c; x\right)`.
.. _s22bf-py2-py-notes:
**Notes**
``hyperg_gauss_real_scaled`` returns a value for the Gauss hypergeometric function :math:`{}_2 F_1 \left({a,b}; c; x\right)` for real parameters :math:`a`, :math:`b` and :math:`c`, and for real argument :math:`x`.
The Gauss hypergeometric function is a solution to the hypergeometric differential equation,
.. math::
x\left(1-x\right)\frac{{d^2f}}{{dx^2}}+\left(c-\left(a+b+1\right)x\right)\frac{{df}}{{dx}}-abf = 0\text{.}
For :math:`\left\lvert x\right\rvert < 1`, it may be defined by the Gauss series,
.. math::
{}_2 F_1 \left({a,b}; c; x\right) = \sum_{0}^{\infty }{\frac{{\left(a\right)_s\left(b\right)_s}}{{\left(c\right)_s{s!}}}x^s} = {1+\frac{{ab}}{c}x}+\frac{{a\left(a+1\right)b\left(b+1\right)}}{{{c\left(c+1\right)}{2!}}}x^2+⋯\text{,}
where :math:`\left(a\right)_s = 1\left(a\right)\left(a+1\right)\left(a+2\right)\ldots \left(a+s-1\right)` is the rising factorial of :math:`a`. :math:`{}_2 F_1 \left({a,b}; c; x\right)` is undefined for :math:`c = 0` or :math:`c` a negative integer.
For :math:`\left\lvert x\right\rvert < 1`, the series is absolutely convergent and :math:`{}_2 F_1 \left({a,b}; c; x\right)` is finite.
For :math:`x < 1`, linear transformations of the form,
.. math::
{}_2 F_1 \left({a,b}; c; x\right) = C_1\left(a_1, b_1, c_1, x_1\right){}_2 F_1 \left({a_1,b_1}; c_1; x_1\right)+C_2\left(a_2, b_2, c_2, x_2\right){}_2 F_1 \left({a_2,b_2}; c_2; x_2\right)
exist, where :math:`x_1`, :math:`x_2 \in \left(0, 1\right]`. :math:`C_1` and :math:`C_2` are real valued functions of the parameters and argument, typically involving products of gamma functions.
When these are degenerate, finite limiting cases exist.
Hence for :math:`x < 0`, :math:`{}_2 F_1 \left({a,b}; c; x\right)` is defined by analytic continuation, and for :math:`x < 1`, :math:`{}_2 F_1 \left({a,b}; c; x\right)` is real and finite.
For :math:`x = 1`, the following apply:
If :math:`c > a+b`, :math:`{}_2 F_1 \left({a,b}; c; 1\right) = \frac{{\Gamma \left(c\right)\Gamma \left(c-a-b\right)}}{{\Gamma \left(c-a\right)\Gamma \left(c-b\right)}}`, and hence is finite. Solutions also exist for the degenerate cases where :math:`c-a` or :math:`c-b` are negative integers or zero.
If :math:`c\leq a+b`, :math:`{}_2 F_1 \left({a,b}; c; 1\right)` is infinite, and the sign of :math:`{}_2 F_1 \left({a,b}; c; 1\right)` is determinable as :math:`x` approaches :math:`1` from below.
In the complex plane, the principal branch of :math:`{}_2 F_1 \left({a,b}; c; z\right)` is taken along the real axis from :math:`x = 1.0` increasing. :math:`{}_2 F_1 \left({a,b}; c; z\right)` is multivalued along this branch, and for real parameters :math:`a,b` and :math:`c` is typically not real valued.
As such, this function will not compute a solution when :math:`x > 1`.
The solution strategy used by this function is primarily dependent upon the value of the argument :math:`x`.
Once trivial cases and the case :math:`x = 1.0` are eliminated, this proceeds as follows.
For :math:`0 < x\leq 0.5`, sets of safe parameters :math:`\left\{\alpha_{{i,j}}, \beta_{{i,j}}, \zeta_{{i,j}}, {\chi_j\left\lvert 1\leq j\leq 2\right\rvert }, {1\leq i\leq 4}\right\}` are determined, such that the values of :math:`{}_2 F_1 \left({a_j,b_j}; c_j; x_j\right)` required for an appropriate transformation of the type `(3) <https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s22bff.html#eqn3>`__ may be calculated either directly or using recurrence relations from the solutions of :math:`{}_2 F_1 \left({\alpha_{{i,j}},\beta_{{i,j}}}; \zeta_{{i,j}}; \chi_j\right)`.
If :math:`c` is positive, then only transformations with :math:`C_2 = 0.0` will be used, implying only :math:`{}_2 F_1 \left({a_1,b_1}; c_1; x_1\right)` will be required, with the transformed argument :math:`x_1 = x`.
If :math:`c` is negative, in some cases a transformation with :math:`C_2\neq 0.0` will be used, with the argument :math:`x_2 = 1.0-x`.
The function then cycles through these sets until acceptable solutions are generated.
If no computation produces an accurate answer, the least inaccurate answer is selected to complete the computation.
See `Accuracy <https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s22bff.html#accuracy>`__.
For :math:`0.5 < x < 1.0`, an identical approach is first used with the argument :math:`x`.
Should this fail, a linear transformation resulting in both transformed arguments satisfying :math:`x_j = 1.0-x` is employed, and the above strategy for :math:`0 < x\leq 0.5` is utilized on both components.
Further transformations in these sub-computations are however, limited to single terms with no argument transformation.
For :math:`x < 0`, a linear transformation mapping the argument :math:`x` to the interval :math:`\left(0, 0.5\right]` is first employed.
The strategy for :math:`0 < x\leq 0.5` is then used on each component, including possible further two term transforms.
To avoid some degenerate cases, a transform mapping the argument :math:`x` to :math:`\left[0.5, 1\right)` may also be used.
For improved precision in the final result, this function accepts :math:`a,b` and :math:`c` split into an integral and a decimal fractional component.
Specifically, :math:`a = a_i+a_r`, where :math:`\left\lvert a_r\right\rvert \leq 0.5` and :math:`a_i = a-a_r` is integral.
The other parameters :math:`b` and :math:`c` are similarly deconstructed.
In addition to the above restrictions on :math:`c` and :math:`x`, an artificial bound, arbnd, is placed on the magnitudes of :math:`a,b,c` and :math:`x` to minimize the occurrence of overflow in internal calculations, particularly those involving real to integer conversions. :math:`\textit{arbnd} = 0.0001\times I_{\mathrm{max}}`, where :math:`I_{\mathrm{max}}` is the largest machine integer (see :meth:`machine.integer_max <naginterfaces.library.machine.integer_max>`).
It should however, not be assumed that this function will produce accurate answers for all values of :math:`a,b,c` and :math:`x` satisfying this criterion.
This function also tests for non-finite values of the parameters and argument on entry, and assigns non-finite values upon completion if appropriate.
See `Further Comments <https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s22bff.html#fcomments>`__ and submodule :mod:`~naginterfaces.library.ieee`.
Please consult the NIST Digital Library of Mathematical Functions for a detailed discussion of the Gauss hypergeometric function including special cases, transformations, relations and asymptotic approximations.
.. _s22bf-py2-py-references:
**References**
NIST Digital Library of Mathematical Functions
Pearson, J, 2009, `Computation of hypergeometric functions`, MSc Dissertation, Mathematical Institute, University of Oxford
"""
raise NotImplementedError
[docs]def mathieu_ang_periodic_real(ordval, q, parity, mode, x=None):
r"""
``mathieu_ang_periodic_real`` calculates real-valued periodic angular Mathieu functions (:math:`ce_m\left(x, q\right)` or :math:`se_m\left(x, q\right)`) and/or their first derivatives, where :math:`ce_m\left(x, q\right)` and :math:`se_m\left(x, q\right)` are solutions to the Mathieu differential equation :math:`\frac{{d^2y}}{{dx^2}}+\left[a-2q\cos\left(2x\right)\right]y = 0`.
.. _s22ca-py2-py-doc:
For full information please refer to the NAG Library document for s22ca
https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s22caf.html
.. _s22ca-py2-py-parameters:
**Parameters**
**ordval** : int
:math:`m`, the order number of the Mathieu function to be computed.
**q** : float
:math:`q`, the Mathieu function parameter.
**parity** : int
Specifies whether to compute even or odd Mathieu function.
:math:`\mathrm{parity} = 0`
Compute even Mathieu function, :math:`ce_m\left(x, q\right)`.
:math:`\mathrm{parity} = 1`
Compute odd Mathieu function, :math:`se_m\left(x, q\right)`.
**mode** : int
Specifies whether the Mathieu function or its derivative is required.
:math:`\mathrm{mode} = 0`
Compute Mathieu function values.
:math:`\mathrm{mode} = 1`
Compute derivative values of Mathieu function.
:math:`\mathrm{mode} = 2`
Compute both Mathieu function and derivative values.
:math:`\mathrm{mode} = 3`
Compute neither Mathieu functions nor derivative values, returns only :math:`\mathrm{a}` (the characteristic value).
**x** : None or float, array-like, shape :math:`\left(:\right)`, optional
Note: the required length for this argument is determined as follows: if :math:`\mathrm{mode}\neq 3`: :math:`n`; otherwise: :math:`0`.
The values of :math:`x` at which to compute Mathieu function or derivative values.
**Returns**
**f** : None or float, ndarray, shape :math:`\left(:\right)`
If :math:`\mathrm{mode} = 0` or :math:`2`, the Mathieu function values :math:`ce_m\left(x, q\right)` or :math:`se_m\left(x, q\right)`. If :math:`\mathrm{mode} = 1` or :math:`3`, :math:`\mathrm{f}` is not used.
**f_deriv** : None or float, ndarray, shape :math:`\left(:\right)`
If :math:`\mathrm{mode} = 1` or :math:`2`, the Mathieu function derivative values :math:`ce_m^{\prime }\left(x, q\right)` or :math:`se_m^{\prime }\left(x, q\right)`. If :math:`\mathrm{mode} = 0` or :math:`3`, :math:`\mathrm{f\_deriv}` is not used.
**a** : float
:math:`a`, the characteristic value for the Mathieu function.
.. _s22ca-py2-py-errors:
**Raises**
**NagValueError**
(`errno` :math:`1`)
On entry, :math:`\mathrm{ordval} = \langle\mathit{\boldsymbol{value}}\rangle` and :math:`\mathrm{parity} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: if :math:`\mathrm{parity} = 0`, :math:`\mathrm{ordval}\geq 0` or if :math:`\mathrm{parity} = 1`, :math:`\mathrm{ordval}\geq 1`.
(`errno` :math:`2`)
On entry, :math:`\mathrm{parity} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{parity} = 0` or :math:`1`.
(`errno` :math:`3`)
On entry, :math:`\mathrm{mode} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{mode} = 0`, :math:`1`, :math:`2` or :math:`3`.
(`errno` :math:`4`)
On entry, :math:`n = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`n\geq 0`.
.. _s22ca-py2-py-notes:
**Notes**
``mathieu_ang_periodic_real`` calculates an approximation to :math:`ce_m\left(x, q\right)` and/or :math:`{ce}_m^{\prime }\left(x, q\right)`, or :math:`se_m\left(x, q\right)` and/or :math:`{se}_m^{\prime }\left(x, q\right)`, where :math:`ce_m\left(x, q\right)` and :math:`se_m\left(x, q\right)` are respectively the even and odd parity real-valued periodic angular Mathieu functions, for an array of values of :math:`x`, and for integer order value :math:`m`, where :math:`m\geq 0` for even parity, and :math:`m\geq 1` for odd parity.
The function also returns values of :math:`a` for these periodic Mathieu functions, this is known as the characteristic value or eigenvalue.
The solutions are computed by approximating Mathieu functions as Fourier series, where expansion coefficients are obtained by solving the eigenvalue problem generated from the relevant recurrence relation, see Module 28 in NIST Digital Library of Mathematical Functions.
.. _s22ca-py2-py-references:
**References**
NIST Digital Library of Mathematical Functions
"""
raise NotImplementedError
[docs]def opt_bsm_price(calput, x, s, t, sigma, r, q):
r"""
``opt_bsm_price`` computes the European option price given by the Black--Scholes--Merton formula.
.. _s30aa-py2-py-doc:
For full information please refer to the NAG Library document for s30aa
https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s30aaf.html
.. _s30aa-py2-py-parameters:
**Parameters**
**calput** : str, length 1
Determines whether the option is a call or a put.
:math:`\mathrm{calput} = \text{‘C'}`
A call; the holder has a right to buy.
:math:`\mathrm{calput} = \text{‘P'}`
A put; the holder has a right to sell.
**x** : float, array-like, shape :math:`\left(m\right)`
:math:`\mathrm{x}[i-1]` must contain :math:`X_{\textit{i}}`, the :math:`\textit{i}`\ th strike price, for :math:`\textit{i} = 1,2,\ldots,m`.
**s** : float
:math:`S`, the price of the underlying asset.
**t** : float, array-like, shape :math:`\left(n\right)`
:math:`\mathrm{t}[i-1]` must contain :math:`T_{\textit{i}}`, the :math:`\textit{i}`\ th time, in years, to expiry, for :math:`\textit{i} = 1,2,\ldots,n`.
**sigma** : float
:math:`\sigma`, the volatility of the underlying asset. Note that a rate of 15% should be entered as :math:`0.15`.
**r** : float
:math:`r`, the annual risk-free interest rate, continuously compounded. Note that a rate of 5% should be entered as :math:`0.05`.
**q** : float
:math:`q`, the annual continuous yield rate. Note that a rate of 8% should be entered as :math:`0.08`.
**Returns**
**p** : float, ndarray, shape :math:`\left(m, n\right)`
:math:`\mathrm{p}[i-1,j-1]` contains :math:`P_{{ij}}`, the option price evaluated for the strike price :math:`\mathrm{x}_i` at expiry :math:`\mathrm{t}_j` for :math:`i = 1,2,\ldots,m` and :math:`j = 1,2,\ldots,n`.
.. _s30aa-py2-py-errors:
**Raises**
**NagValueError**
(`errno` :math:`1`)
On entry, :math:`\mathrm{calput} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{calput} = \text{‘C'} \text{ or } \text{‘P'}`.
(`errno` :math:`2`)
On entry, :math:`m = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`m\geq 1`.
(`errno` :math:`3`)
On entry, :math:`n = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`n\geq 1`.
(`errno` :math:`4`)
On entry, :math:`\mathrm{x}[\langle\mathit{\boldsymbol{value}}\rangle] = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{x}[i]\geq \langle\mathit{\boldsymbol{value}}\rangle` and :math:`\mathrm{x}[i]\leq \langle\mathit{\boldsymbol{value}}\rangle`.
(`errno` :math:`5`)
On entry, :math:`\mathrm{s} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{s}\geq \langle\mathit{\boldsymbol{value}}\rangle` and :math:`\mathrm{s}\leq \langle\mathit{\boldsymbol{value}}\rangle`.
(`errno` :math:`6`)
On entry, :math:`\mathrm{t}[\langle\mathit{\boldsymbol{value}}\rangle] = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{t}[i]\geq \langle\mathit{\boldsymbol{value}}\rangle`.
(`errno` :math:`7`)
On entry, :math:`\mathrm{sigma} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{sigma} > 0.0`.
(`errno` :math:`8`)
On entry, :math:`\mathrm{r} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{r}\geq 0.0`.
(`errno` :math:`9`)
On entry, :math:`\mathrm{q} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{q}\geq 0.0`.
.. _s30aa-py2-py-notes:
**Notes**
``opt_bsm_price`` computes the price of a European call (or put) option for constant volatility, :math:`\sigma`, and risk-free interest rate, :math:`r`, with possible dividend yield, :math:`q`, using the Black--Scholes--Merton formula (see Black and Scholes (1973) and Merton (1973)).
For a given strike price, :math:`X`, the price of a European call with underlying price, :math:`S`, and time to expiry, :math:`T`, is
.. math::
P_{\mathrm{call}} = Se^{{-qT}}\Phi \left(d_1\right)-Xe^{{-rT}}\Phi \left(d_2\right)
and the corresponding European put price is
.. math::
P_{\mathrm{put}} = Xe^{{-rT}}\Phi \left({-d_2}\right)-Se^{{-qT}}\Phi \left({-d_1}\right)
and where :math:`\Phi` denotes the cumulative Normal distribution function,
.. math::
\Phi \left(x\right) = \frac{1}{\sqrt{2\pi }}\int_{{-\infty }}^x\mathrm{exp}\left(-y^2/2\right)dy
and
.. math::
\begin{array}{l} d_1 = \frac{{\mathrm{ln}\left(S/X\right)+\left(r-q+\sigma^2/2\right)T}}{{\sigma \sqrt{T}}} \text{,} \\\\ d_2 = d_1 - \sigma \sqrt{T} \text{.} \end{array}
The option price :math:`P_{{ij}} = P\left({X = X_i}, {T = T_j}\right)` is computed for each strike price in a set :math:`X_i`, :math:`i = 1,2,\ldots,m`, and for each expiry time in a set :math:`T_j`, :math:`j = 1,2,\ldots,n`.
.. _s30aa-py2-py-references:
**References**
Black, F and Scholes, M, 1973, `The pricing of options and corporate liabilities`, Journal of Political Economy (81), 637--654
Merton, R C, 1973, `Theory of rational option pricing`, Bell Journal of Economics and Management Science (4), 141--183
See Also
--------
:meth:`naginterfaces.library.examples.roots.contfn_brent_interval_ex.main`
:meth:`naginterfaces.library.examples.specfun.opt_bsm_price_ex.main`
"""
raise NotImplementedError
[docs]def opt_bsm_greeks(calput, x, s, t, sigma, r, q):
r"""
``opt_bsm_greeks`` computes the European option price given by the Black--Scholes--Merton formula together with its sensitivities (Greeks).
.. _s30ab-py2-py-doc:
For full information please refer to the NAG Library document for s30ab
https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s30abf.html
.. _s30ab-py2-py-parameters:
**Parameters**
**calput** : str, length 1
Determines whether the option is a call or a put.
:math:`\mathrm{calput} = \text{‘C'}`
A call; the holder has a right to buy.
:math:`\mathrm{calput} = \text{‘P'}`
A put; the holder has a right to sell.
**x** : float, array-like, shape :math:`\left(m\right)`
:math:`\mathrm{x}[i-1]` must contain :math:`X_{\textit{i}}`, the :math:`\textit{i}`\ th strike price, for :math:`\textit{i} = 1,2,\ldots,m`.
**s** : float
:math:`S`, the price of the underlying asset.
**t** : float, array-like, shape :math:`\left(n\right)`
:math:`\mathrm{t}[i-1]` must contain :math:`T_{\textit{i}}`, the :math:`\textit{i}`\ th time, in years, to expiry, for :math:`\textit{i} = 1,2,\ldots,n`.
**sigma** : float
:math:`\sigma`, the volatility of the underlying asset. Note that a rate of 15% should be entered as :math:`0.15`.
**r** : float
:math:`r`, the annual risk-free interest rate, continuously compounded. Note that a rate of 5% should be entered as :math:`0.05`.
**q** : float
:math:`q`, the annual continuous yield rate. Note that a rate of 8% should be entered as :math:`0.08`.
**Returns**
**p** : float, ndarray, shape :math:`\left(m, n\right)`
:math:`\mathrm{p}[i-1,j-1]` contains :math:`P_{{ij}}`, the option price evaluated for the strike price :math:`\mathrm{x}_i` at expiry :math:`\mathrm{t}_j` for :math:`i = 1,2,\ldots,m` and :math:`j = 1,2,\ldots,n`.
**delta** : float, ndarray, shape :math:`\left(m, n\right)`
The leading :math:`m\times n` part of the array :math:`\mathrm{delta}` contains the sensitivity, :math:`\frac{{\partial P}}{{\partial S}}`, of the option price to change in the price of the underlying asset.
**gamma** : float, ndarray, shape :math:`\left(m, n\right)`
The leading :math:`m\times n` part of the array :math:`\mathrm{gamma}` contains the sensitivity, :math:`\frac{{\partial^2P}}{{\partial S^2}}`, of :math:`\mathrm{delta}` to change in the price of the underlying asset.
**vega** : float, ndarray, shape :math:`\left(m, n\right)`
:math:`\mathrm{vega}[i-1,j-1]`, contains the first-order Greek measuring the sensitivity of the option price :math:`P_{{ij}}` to change in the volatility of the underlying asset, i.e., :math:`\frac{{\partial P_{{ij}}}}{{\partial \sigma }}`, for :math:`i = 1,2,\ldots,m` and :math:`j = 1,2,\ldots,n`.
**theta** : float, ndarray, shape :math:`\left(m, n\right)`
:math:`\mathrm{theta}[i-1,j-1]`, contains the first-order Greek measuring the sensitivity of the option price :math:`P_{{ij}}` to change in time, i.e., :math:`-\frac{{\partial P_{{ij}}}}{{\partial T}}`, for :math:`i = 1,2,\ldots,m` and :math:`j = 1,2,\ldots,n`, where :math:`b = r-q`.
**rho** : float, ndarray, shape :math:`\left(m, n\right)`
:math:`\mathrm{rho}[i-1,j-1]`, contains the first-order Greek measuring the sensitivity of the option price :math:`P_{{ij}}` to change in the annual risk-free interest rate, i.e., :math:`-\frac{{\partial P_{{ij}}}}{{\partial r}}`, for :math:`i = 1,2,\ldots,m` and :math:`j = 1,2,\ldots,n`.
**crho** : float, ndarray, shape :math:`\left(m, n\right)`
:math:`\mathrm{crho}[i-1,j-1]`, contains the first-order Greek measuring the sensitivity of the option price :math:`P_{{ij}}` to change in the annual cost of carry rate, i.e., :math:`-\frac{{\partial P_{{ij}}}}{{\partial b}}`, for :math:`i = 1,2,\ldots,m` and :math:`j = 1,2,\ldots,n`, where :math:`b = r-q`.
**vanna** : float, ndarray, shape :math:`\left(m, n\right)`
:math:`\mathrm{vanna}[i-1,j-1]`, contains the second-order Greek measuring the sensitivity of the first-order Greek :math:`\Delta_{{ij}}` to change in the volatility of the asset price, i.e., :math:`-\frac{{\partial \Delta_{{ij}}}}{{\partial T}} = -\frac{{\partial^2P_{{ij}}}}{{\partial S\partial \sigma }}`, for :math:`i = 1,2,\ldots,m` and :math:`j = 1,2,\ldots,n`.
**charm** : float, ndarray, shape :math:`\left(m, n\right)`
:math:`\mathrm{charm}[i-1,j-1]`, contains the second-order Greek measuring the sensitivity of the first-order Greek :math:`\Delta_{{ij}}` to change in the time, i.e., :math:`-\frac{{\partial \Delta_{{ij}}}}{{\partial T}} = -\frac{{\partial^2P_{{ij}}}}{{\partial S\partial T}}`, for :math:`i = 1,2,\ldots,m` and :math:`j = 1,2,\ldots,n`.
**speed** : float, ndarray, shape :math:`\left(m, n\right)`
:math:`\mathrm{speed}[i-1,j-1]`, contains the third-order Greek measuring the sensitivity of the second-order Greek :math:`\Gamma_{{ij}}` to change in the price of the underlying asset, i.e., :math:`-\frac{{\partial \Gamma_{{ij}}}}{{\partial S}} = -\frac{{\partial^3P_{{ij}}}}{{\partial S^3}}`, for :math:`i = 1,2,\ldots,m` and :math:`j = 1,2,\ldots,n`.
**colour** : float, ndarray, shape :math:`\left(m, n\right)`
:math:`\mathrm{colour}[i-1,j-1]`, contains the third-order Greek measuring the sensitivity of the second-order Greek :math:`\Gamma_{{ij}}` to change in the time, i.e., :math:`-\frac{{\partial \Gamma_{{ij}}}}{{\partial T}} = -\frac{{\partial^3P_{{ij}}}}{{\partial S\partial T}}`, for :math:`i = 1,2,\ldots,m` and :math:`j = 1,2,\ldots,n`.
**zomma** : float, ndarray, shape :math:`\left(m, n\right)`
:math:`\mathrm{zomma}[i-1,j-1]`, contains the third-order Greek measuring the sensitivity of the second-order Greek :math:`\Gamma_{{ij}}` to change in the volatility of the underlying asset, i.e., :math:`-\frac{{\partial \Gamma_{{ij}}}}{{\partial \sigma }} = -\frac{{\partial^3P_{{ij}}}}{{\partial S^2\partial \sigma }}`, for :math:`i = 1,2,\ldots,m` and :math:`j = 1,2,\ldots,n`.
**vomma** : float, ndarray, shape :math:`\left(m, n\right)`
:math:`\mathrm{vomma}[i-1,j-1]`, contains the second-order Greek measuring the sensitivity of the first-order Greek :math:`\Delta_{{ij}}` to change in the volatility of the underlying asset, i.e., :math:`-\frac{{\partial \Delta_{{ij}}}}{{\partial \sigma }} = -\frac{{\partial^2P_{{ij}}}}{{\partial \sigma^2}}`, for :math:`i = 1,2,\ldots,m` and :math:`j = 1,2,\ldots,n`.
.. _s30ab-py2-py-errors:
**Raises**
**NagValueError**
(`errno` :math:`1`)
On entry, :math:`\mathrm{calput} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{calput} = \text{‘C'} \text{ or } \text{‘P'}`
(`errno` :math:`2`)
On entry, :math:`m = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`m\geq 1`.
(`errno` :math:`3`)
On entry, :math:`n = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`n\geq 1`.
(`errno` :math:`4`)
On entry, :math:`\mathrm{x}[\langle\mathit{\boldsymbol{value}}\rangle] = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{x}[i]\geq \langle\mathit{\boldsymbol{value}}\rangle` and :math:`\mathrm{x}[i]\leq \langle\mathit{\boldsymbol{value}}\rangle`.
(`errno` :math:`5`)
On entry, :math:`\mathrm{s} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{s}\geq \langle\mathit{\boldsymbol{value}}\rangle` and :math:`\mathrm{s}\leq \langle\mathit{\boldsymbol{value}}\rangle`.
(`errno` :math:`6`)
On entry, :math:`\mathrm{t}[\langle\mathit{\boldsymbol{value}}\rangle] = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{t}[i]\geq \langle\mathit{\boldsymbol{value}}\rangle`.
(`errno` :math:`7`)
On entry, :math:`\mathrm{sigma} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{sigma} > 0.0`.
(`errno` :math:`8`)
On entry, :math:`\mathrm{r} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{r}\geq 0.0`.
(`errno` :math:`9`)
On entry, :math:`\mathrm{q} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{q}\geq 0.0`.
.. _s30ab-py2-py-notes:
**Notes**
``opt_bsm_greeks`` computes the price of a European call (or put) option together with the Greeks or sensitivities, which are the partial derivatives of the option price with respect to certain of the other input parameters, by the Black--Scholes--Merton formula (see Black and Scholes (1973) and Merton (1973)).
The annual volatility, :math:`\sigma`, risk-free interest rate, :math:`r`, and dividend yield, :math:`q`, must be supplied as input.
For a given strike price, :math:`X`, the price of a European call with underlying price, :math:`S`, and time to expiry, :math:`T`, is
.. math::
P_{\mathrm{call}} = Se^{{-qT}}\Phi \left(d_1\right)-Xe^{{-rT}}\Phi \left(d_2\right)
and the corresponding European put price is
.. math::
P_{\mathrm{put}} = Xe^{{-rT}}\Phi \left({-d_2}\right)-Se^{{-qT}}\Phi \left({-d_1}\right)
and where :math:`\Phi` denotes the cumulative Normal distribution function,
.. math::
\Phi \left(x\right) = \frac{1}{\sqrt{2\pi }}\int_{{-\infty }}^x\mathrm{exp}\left(-y^2/2\right)dy
and
.. math::
\begin{array}{l} d_1 = \frac{{\mathrm{ln}\left(S/X\right)+\left(r-q+\sigma^2/2\right)T}}{{\sigma \sqrt{T}}} \text{,} \\\\ d_2 = d_1 - \sigma \sqrt{T} \text{.} \end{array}
The option price :math:`P_{{ij}} = P\left({X = X_i}, {T = T_j}\right)` is computed for each strike price in a set :math:`X_i`, :math:`i = 1,2,\ldots,m`, and for each expiry time in a set :math:`T_j`, :math:`j = 1,2,\ldots,n`.
.. _s30ab-py2-py-references:
**References**
Black, F and Scholes, M, 1973, `The pricing of options and corporate liabilities`, Journal of Political Economy (81), 637--654
Merton, R C, 1973, `Theory of rational option pricing`, Bell Journal of Economics and Management Science (4), 141--183
"""
raise NotImplementedError
[docs]def opt_imp_vol(calput, p, k, s0, t, r, mode=1):
r"""
``opt_imp_vol`` computes the implied volatility of a European option contract based on the Black--Scholes--Merton formula.
.. _s30ac-py2-py-doc:
For full information please refer to the NAG Library document for s30ac
https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s30acf.html
.. _s30ac-py2-py-parameters:
**Parameters**
**calput** : str, length 1
Determines whether the option is a call or a put.
:math:`\mathrm{calput} = \text{‘C'}`
A call; the holder has a right to buy.
:math:`\mathrm{calput} = \text{‘P'}`
A put; the holder has a right to sell.
**p** : float, array-like, shape :math:`\left(n\right)`
:math:`\mathrm{p}[i-1]` must contain :math:`P_i`, the :math:`i`\ th option price, for :math:`i = 1,2,\ldots,n`.
**k** : float, array-like, shape :math:`\left(n\right)`
:math:`\mathrm{k}[i-1]` must contain :math:`K_i`, the :math:`i`\ th strike price, for :math:`i = 1,2,\ldots,n`.
**s0** : float, array-like, shape :math:`\left(n\right)`
:math:`\mathrm{s0}[i-1]` must contain :math:`S_{{0i}}`, the :math:`i`\ th spot price, for :math:`i = 1,2,\ldots,n`.
**t** : float, array-like, shape :math:`\left(n\right)`
:math:`\mathrm{t}[i-1]` must contain :math:`T_i`, the :math:`i`\ th time, in years, to maturity, for :math:`i = 1,2,\ldots,n`.
**r** : float, array-like, shape :math:`\left(n\right)`
:math:`\mathrm{r}[i-1]` must contain :math:`r_i`, the :math:`i`\ th interest rate, for :math:`i = 1,2,\ldots,n`. Note that a rate of 5% should be entered as 0.05.
**mode** : int, optional
Specifies which algorithm will be used to compute the implied volatilities. See `Accuracy <https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s30acf.html#accuracy>`__ and `Parallelism and Performance <https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s30acf.html#accuracy>`__ for further guidance on the choice of mode.
:math:`\mathrm{mode} = 0`
The Glau `et al.` (2018) algorithm will be used. The nodes used in the Chebyshev interpolation will be chosen to achieve relative accuracy to approximately seven decimal places;
:math:`\mathrm{mode} = 1`
The Glau `et al.` (2018) algorithm will be used. The nodes used in the Chebyshev interpolation will be chosen to achieve relative accuracy to approximately :math:`15` decimal places, but limited by the machine precision;
:math:`\mathrm{mode} = 2`
The Jäckel (2015) algorithm will be used, aiming for accuracy to approximately :math:`15`--:math:`16` decimal places, but limited by machine precision.
**Returns**
**sigma** : float, ndarray, shape :math:`\left(n\right)`
:math:`\mathrm{sigma}[i-1]` contains :math:`\sigma_i`, the :math:`i`\ th implied volatility, for :math:`i = 1,2,\ldots,n`.
**ivalid** : int, ndarray, shape :math:`\left(n\right)`
:math:`\mathrm{ivalid}[i-1]` indicates any errors with the input arguments that prevented :math:`\sigma_i` from being computed. If :math:`\mathrm{ivalid}[i-1]\neq 0`, :math:`\mathrm{sigma}[i-1]` contains :math:`0.0`.
:math:`\mathrm{ivalid}[i-1] = 0`
No error.
:math:`\mathrm{ivalid}[i-1] = 1`
:math:`P_i < 0.0`.
:math:`\mathrm{ivalid}[i-1] = 2`
:math:`K_i\leq 0.0`.
:math:`\mathrm{ivalid}[i-1] = 3`
:math:`S_{{0i}}\leq 0.0`.
:math:`\mathrm{ivalid}[i-1] = 4`
:math:`T_i\leq 0.0`.
:math:`\mathrm{ivalid}[i-1] = 5`
The combination of :math:`P_i`, :math:`K_i`, :math:`S_{{0i}}`, :math:`T_i` and :math:`r_i` is out of the domain in which :math:`\sigma_i` can be computed. See `Further Comments <https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s30acf.html#fcomments>`__ for further details.
.. _s30ac-py2-py-errors:
**Raises**
**NagValueError**
(`errno` :math:`2`)
On entry, :math:`n = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`n\geq 0`.
(`errno` :math:`3`)
On entry, :math:`\mathrm{mode} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{mode} = 0`, :math:`1` or :math:`2`.
(`errno` :math:`4`)
On entry, :math:`\mathrm{calput} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{calput} = \text{‘C'} \text{ or } \text{‘P'}`.
**Warns**
**NagAlgorithmicWarning**
(`errno` :math:`1`)
On entry at least one input argument was invalid.
Check :math:`\mathrm{ivalid}` for more information.
.. _s30ac-py2-py-notes:
**Notes**
The Black--Scholes formula for the price of a European option is
.. math::
P_{\mathrm{call}} = S_0\Phi \left(\frac{{\mathrm{ln}\left(\frac{S_0}{K}\right)+\left[r+\frac{\sigma^2}{2}\right]T}}{{\sigma \sqrt{T}}}\right)-Ke^{{-rT}}\Phi \left(\frac{{\mathrm{ln}\left(\frac{S_0}{K}\right)+\left[r-\frac{\sigma^2}{2}\right]T}}{{\sigma \sqrt{T}}}\right)\text{,}
for a call option, and
.. math::
P_{\mathrm{put}} = Ke^{{-rT}}\Phi \left(\frac{{-\mathrm{ln}\left(\frac{S_0}{K}\right)-\left[r-\frac{\sigma^2}{2}\right]T}}{{\sigma \sqrt{T}}}\right)-S_0\Phi \left(\frac{{-\mathrm{ln}\left(\frac{S_0}{K}\right)-\left[r+\frac{\sigma^2}{2}\right]T}}{{\sigma \sqrt{T}}}\right)\text{,}
for a put option, where :math:`\Phi` is the cumulative Normal distribution function, :math:`T` is the time to maturity, :math:`S_0` is the spot price of the underlying asset, :math:`K` is the strike price, :math:`r` is the interest rate and :math:`\sigma` is the volatility.
Given arrays of values :math:`P_i`, :math:`K_i`, :math:`S_{{0i}}`, :math:`T_i` and :math:`r_i`, for :math:`i = 1,2,\ldots n`, ``opt_imp_vol`` computes the implied volatilities :math:`\sigma_i`.
``opt_imp_vol`` offers the choice of two algorithms.
The algorithm of Glau `et al.` (2018) uses Chebyshev interpolation to compute the implied volatilities, and performs best for long arrays of input data.
The algorithm of Jäckel (2015) uses a third order Householder iteration and performs better for short arrays of input data.
.. _s30ac-py2-py-references:
**References**
Glau, K, Herold, P, Madan, D B and Pötz, C, 2018, `The Chebyshev method for the implied volatility`, Accepted for publication in the Journal of Computational Finance
Jäckel, P, 2015, `Let's be Rational`, Wilmott Magazine (2015(75)), 40--53
"""
raise NotImplementedError
[docs]def opt_lookback_fls_price(calput, sm, s, t, sigma, r, q):
r"""
``opt_lookback_fls_price`` computes the price of a floating-strike lookback option.
.. _s30ba-py2-py-doc:
For full information please refer to the NAG Library document for s30ba
https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s30baf.html
.. _s30ba-py2-py-parameters:
**Parameters**
**calput** : str, length 1
Determines whether the option is a call or a put.
:math:`\mathrm{calput} = \text{‘C'}`
A call; the holder has a right to buy.
:math:`\mathrm{calput} = \text{‘P'}`
A put; the holder has a right to sell.
**sm** : float, array-like, shape :math:`\left(m\right)`
:math:`\mathrm{sm}[i-1]` must contain :math:`S_{\mathrm{min}}\left(\textit{i}\right)`, the :math:`\textit{i}`\ th minimum observed price of the underlying asset when :math:`\mathrm{calput} = \text{‘C'}`, or :math:`S_{\mathrm{max}}\left(\textit{i}\right)`, the maximum observed price when :math:`\mathrm{calput} = \text{‘P'}`, for :math:`\textit{i} = 1,2,\ldots,m`.
**s** : float
:math:`S`, the price of the underlying asset.
**t** : float, array-like, shape :math:`\left(n\right)`
:math:`\mathrm{t}[i-1]` must contain :math:`T_{\textit{i}}`, the :math:`\textit{i}`\ th time, in years, to expiry, for :math:`\textit{i} = 1,2,\ldots,n`.
**sigma** : float
:math:`\sigma`, the volatility of the underlying asset. Note that a rate of 15% should be entered as :math:`0.15`.
**r** : float
:math:`r`, the annual risk-free interest rate, continuously compounded. Note that a rate of 5% should be entered as :math:`0.05`.
**q** : float
:math:`q`, the annual continuous yield rate. Note that a rate of 8% should be entered as :math:`0.08`.
**Returns**
**p** : float, ndarray, shape :math:`\left(m, n\right)`
:math:`\mathrm{p}[i-1,j-1]` contains :math:`P_{{ij}}`, the option price evaluated for the minimum or maximum observed price :math:`S_{\mathrm{min}}\left(\textit{i}\right)` or :math:`S_{\mathrm{max}}\left(\textit{i}\right)` at expiry :math:`\mathrm{t}_j` for :math:`i = 1,2,\ldots,m` and :math:`j = 1,2,\ldots,n`.
.. _s30ba-py2-py-errors:
**Raises**
**NagValueError**
(`errno` :math:`1`)
On entry, :math:`\mathrm{calput} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{calput} = \text{‘C'} \text{ or } \text{‘P'}`.
(`errno` :math:`2`)
On entry, :math:`m = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`m\geq 1`.
(`errno` :math:`3`)
On entry, :math:`n = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`n\geq 1`.
(`errno` :math:`4`)
On entry with a put option, :math:`\mathrm{sm}[\langle\mathit{\boldsymbol{value}}\rangle] = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: for put options, :math:`\mathrm{sm}[i]\geq \langle\mathit{\boldsymbol{value}}\rangle` for all :math:`i`.
(`errno` :math:`4`)
On entry with a call option, :math:`\mathrm{sm}[\langle\mathit{\boldsymbol{value}}\rangle] = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: for call options, :math:`\mathrm{sm}[i]\leq \langle\mathit{\boldsymbol{value}}\rangle` for all :math:`i`.
(`errno` :math:`4`)
On entry, :math:`\mathrm{sm}[\langle\mathit{\boldsymbol{value}}\rangle] = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\langle\mathit{\boldsymbol{value}}\rangle\leq \mathrm{sm}[i]\leq \langle\mathit{\boldsymbol{value}}\rangle` for all :math:`i`.
(`errno` :math:`5`)
On entry, :math:`\mathrm{s} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{s}\geq \langle\mathit{\boldsymbol{value}}\rangle` and :math:`\mathrm{s}\leq \langle\mathit{\boldsymbol{value}}\rangle`.
(`errno` :math:`6`)
On entry, :math:`\mathrm{t}[\langle\mathit{\boldsymbol{value}}\rangle] = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{t}[i]\geq \langle\mathit{\boldsymbol{value}}\rangle` for all :math:`i`.
(`errno` :math:`7`)
On entry, :math:`\mathrm{sigma} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{sigma} > 0.0`.
(`errno` :math:`8`)
On entry, :math:`\mathrm{r} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{r}\geq 0.0`.
(`errno` :math:`9`)
On entry, :math:`\mathrm{q} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{q}\geq 0.0`.
.. _s30ba-py2-py-notes:
**Notes**
``opt_lookback_fls_price`` computes the price of a floating-strike lookback call or put option.
A call option of this type confers the right to buy the underlying asset at the lowest price, :math:`S_{\mathrm{min}}`, observed during the lifetime of the contract.
A put option gives the holder the right to sell the underlying asset at the maximum price, :math:`S_{\mathrm{max}}`, observed during the lifetime of the contract.
Thus, at expiry, the payoff for a call option is :math:`S-S_{\mathrm{min}}`, and for a put, :math:`S_{\mathrm{max}}-S`.
For a given minimum value the price of a floating-strike lookback call with underlying asset price, :math:`S`, and time to expiry, :math:`T`, is
.. math::
P_{\mathrm{call}} = Se^{{-qT}}\Phi \left(a_1\right)-S_{\mathrm{min}}e^{{-rT}}\Phi \left(a_2\right)+Se^{{-rT}}\text{ }\frac{\sigma^2}{{2b}}\left[\left(\frac{S}{S_{\mathrm{min}}}\right)^{{-2b/\sigma^2}}\Phi \left({-a}_1+\frac{{2b}}{\sigma }\sqrt{T}\right){-e}^{{bT}}\Phi \left({-a}_1\right)\right]\text{,}
where :math:`b = r-q\neq 0`.
The volatility, :math:`\sigma`, risk-free interest rate, :math:`r`, and annualised dividend yield, :math:`q`, are constants.
When :math:`r = q`, the option price is given by
.. math::
P_{\mathrm{call}} = Se^{{-qT}}\Phi \left(a_1\right)-S_{\mathrm{min}}e^{{-rT}}\Phi \left(a_2\right)+Se^{{-rT}}\sigma \sqrt{T}\left[\phi \left(a_1\right)+a_1\left(\Phi \left(a_1\right)-1\right)\right]\text{.}
The corresponding put price is (for :math:`b\neq 0`),
.. math::
P_{\mathrm{put}} = S_{\mathrm{max}}e^{{-rT}}\Phi \left({-a}_2\right)-Se^{{-qT}}\Phi \left({-a}_1\right)+Se^{{-rT}}\text{ }\frac{\sigma^2}{{2b}}\left[-\left(\frac{S}{S_{\mathrm{max}}}\right)^{{-2b/\sigma^2}}\Phi \left(a_1-\frac{{2b}}{\sigma }\sqrt{T}\right)+e^{{bT}}\Phi \left(a_1\right)\right]\text{.}
When :math:`r = q`,
.. math::
P_{\mathrm{put}} = S_{\mathrm{max}}e^{{-rT}}\Phi \left({-a}_2\right)-Se^{{-qT}}\Phi \left({-a}_1\right)+Se^{{-rT}}\sigma \sqrt{T}\left[\phi \left(a_1\right)+a_1\Phi \left(a_1\right)\right]\text{.}
In the above, :math:`\Phi` denotes the cumulative Normal distribution function,
.. math::
\Phi \left(x\right) = \int_{{-\infty }}^x\phi \left(y\right)dy
where :math:`\phi` denotes the standard Normal probability density function
.. math::
\phi \left(y\right) = \frac{1}{\sqrt{2\pi }}\mathrm{exp}\left(-y^2/2\right)
and
.. math::
\begin{array}{l} a_1 = \frac{{\mathrm{ln}\left(S/S_{\mathrm{m}}\right)+\left(b+\sigma^2/2\right)T}}{{\sigma \sqrt{T}}} \\\\ a_2 = a_1-\sigma \sqrt{T} \end{array}
where :math:`S_m` is taken to be the minimum price attained by the underlying asset, :math:`S_{\mathrm{min}}`, for a call and the maximum price, :math:`S_{\mathrm{max}}`, for a put.
The option price :math:`P_{{ij}} = P\left({X = X_i}, {T = T_j}\right)` is computed for each minimum or maximum observed price in a set :math:`S_{\mathrm{min}}\left(\textit{i}\right)` or :math:`S_{\mathrm{max}}\left(\textit{i}\right)`, :math:`i = 1,2,\ldots,m`, and for each expiry time in a set :math:`T_j`, :math:`j = 1,2,\ldots,n`.
.. _s30ba-py2-py-references:
**References**
Goldman, B M, Sosin, H B and Gatto, M A, 1979, `Path dependent options: buy at the low, sell at the high`, Journal of Finance (34), 1111--1127
"""
raise NotImplementedError
[docs]def opt_lookback_fls_greeks(calput, sm, s, t, sigma, r, q):
r"""
``opt_lookback_fls_greeks`` computes the price of a floating-strike lookback option together with its sensitivities (Greeks).
.. _s30bb-py2-py-doc:
For full information please refer to the NAG Library document for s30bb
https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s30bbf.html
.. _s30bb-py2-py-parameters:
**Parameters**
**calput** : str, length 1
Determines whether the option is a call or a put.
:math:`\mathrm{calput} = \text{‘C'}`
A call; the holder has a right to buy.
:math:`\mathrm{calput} = \text{‘P'}`
A put; the holder has a right to sell.
**sm** : float, array-like, shape :math:`\left(m\right)`
:math:`\mathrm{sm}[i-1]` must contain :math:`S_{\mathrm{min}}\left(\textit{i}\right)`, the :math:`\textit{i}`\ th minimum observed price of the underlying asset when :math:`\mathrm{calput} = \text{‘C'}`, or :math:`S_{\mathrm{max}}\left(\textit{i}\right)`, the maximum observed price when :math:`\mathrm{calput} = \text{‘P'}`, for :math:`\textit{i} = 1,2,\ldots,m`.
**s** : float
:math:`S`, the price of the underlying asset.
**t** : float, array-like, shape :math:`\left(n\right)`
:math:`\mathrm{t}[i-1]` must contain :math:`T_{\textit{i}}`, the :math:`\textit{i}`\ th time, in years, to expiry, for :math:`\textit{i} = 1,2,\ldots,n`.
**sigma** : float
:math:`\sigma`, the volatility of the underlying asset. Note that a rate of 15% should be entered as :math:`0.15`.
**r** : float
The annual risk-free interest rate, :math:`r`, continuously compounded. Note that a rate of 5% should be entered as :math:`0.05`.
**q** : float
The annual continuous yield rate. Note that a rate of 8% should be entered as :math:`0.08`.
**Returns**
**p** : float, ndarray, shape :math:`\left(m, n\right)`
:math:`\mathrm{p}[i-1,j-1]` contains :math:`P_{{ij}}`, the option price evaluated for the minimum or maximum observed price :math:`S_{\mathrm{min}}\left(\textit{i}\right)` or :math:`S_{\mathrm{max}}\left(\textit{i}\right)` at expiry :math:`\mathrm{t}_j` for :math:`i = 1,2,\ldots,m` and :math:`j = 1,2,\ldots,n`.
**delta** : float, ndarray, shape :math:`\left(m, n\right)`
The leading :math:`m\times n` part of the array :math:`\mathrm{delta}` contains the sensitivity, :math:`\frac{{\partial P}}{{\partial S}}`, of the option price to change in the price of the underlying asset.
**gamma** : float, ndarray, shape :math:`\left(m, n\right)`
The leading :math:`m\times n` part of the array :math:`\mathrm{gamma}` contains the sensitivity, :math:`\frac{{\partial^2P}}{{\partial S^2}}`, of :math:`\mathrm{delta}` to change in the price of the underlying asset.
**vega** : float, ndarray, shape :math:`\left(m, n\right)`
:math:`\mathrm{vega}[i-1,j-1]`, contains the first-order Greek measuring the sensitivity of the option price :math:`P_{{ij}}` to change in the volatility of the underlying asset, i.e., :math:`\frac{{\partial P_{{ij}}}}{{\partial \sigma }}`, for :math:`i = 1,2,\ldots,m` and :math:`j = 1,2,\ldots,n`.
**theta** : float, ndarray, shape :math:`\left(m, n\right)`
:math:`\mathrm{theta}[i-1,j-1]`, contains the first-order Greek measuring the sensitivity of the option price :math:`P_{{ij}}` to change in time, i.e., :math:`-\frac{{\partial P_{{ij}}}}{{\partial T}}`, for :math:`i = 1,2,\ldots,m` and :math:`j = 1,2,\ldots,n`, where :math:`b = r-q`.
**rho** : float, ndarray, shape :math:`\left(m, n\right)`
:math:`\mathrm{rho}[i-1,j-1]`, contains the first-order Greek measuring the sensitivity of the option price :math:`P_{{ij}}` to change in the annual risk-free interest rate, i.e., :math:`-\frac{{\partial P_{{ij}}}}{{\partial r}}`, for :math:`i = 1,2,\ldots,m` and :math:`j = 1,2,\ldots,n`.
**crho** : float, ndarray, shape :math:`\left(m, n\right)`
:math:`\mathrm{crho}[i-1,j-1]`, contains the first-order Greek measuring the sensitivity of the option price :math:`P_{{ij}}` to change in the annual cost of carry rate, i.e., :math:`-\frac{{\partial P_{{ij}}}}{{\partial b}}`, for :math:`i = 1,2,\ldots,m` and :math:`j = 1,2,\ldots,n`, where :math:`b = r-q`.
**vanna** : float, ndarray, shape :math:`\left(m, n\right)`
:math:`\mathrm{vanna}[i-1,j-1]`, contains the second-order Greek measuring the sensitivity of the first-order Greek :math:`\Delta_{{ij}}` to change in the volatility of the asset price, i.e., :math:`-\frac{{\partial \Delta_{{ij}}}}{{\partial T}} = -\frac{{\partial^2P_{{ij}}}}{{\partial S\partial \sigma }}`, for :math:`i = 1,2,\ldots,m` and :math:`j = 1,2,\ldots,n`.
**charm** : float, ndarray, shape :math:`\left(m, n\right)`
:math:`\mathrm{charm}[i-1,j-1]`, contains the second-order Greek measuring the sensitivity of the first-order Greek :math:`\Delta_{{ij}}` to change in the time, i.e., :math:`-\frac{{\partial \Delta_{{ij}}}}{{\partial T}} = -\frac{{\partial^2P_{{ij}}}}{{\partial S\partial T}}`, for :math:`i = 1,2,\ldots,m` and :math:`j = 1,2,\ldots,n`.
**speed** : float, ndarray, shape :math:`\left(m, n\right)`
:math:`\mathrm{speed}[i-1,j-1]`, contains the third-order Greek measuring the sensitivity of the second-order Greek :math:`\Gamma_{{ij}}` to change in the price of the underlying asset, i.e., :math:`-\frac{{\partial \Gamma_{{ij}}}}{{\partial S}} = -\frac{{\partial^3P_{{ij}}}}{{\partial S^3}}`, for :math:`i = 1,2,\ldots,m` and :math:`j = 1,2,\ldots,n`.
**colour** : float, ndarray, shape :math:`\left(m, n\right)`
:math:`\mathrm{colour}[i-1,j-1]`, contains the third-order Greek measuring the sensitivity of the second-order Greek :math:`\Gamma_{{ij}}` to change in the time, i.e., :math:`-\frac{{\partial \Gamma_{{ij}}}}{{\partial T}} = -\frac{{\partial^3P_{{ij}}}}{{\partial S\partial T}}`, for :math:`i = 1,2,\ldots,m` and :math:`j = 1,2,\ldots,n`.
**zomma** : float, ndarray, shape :math:`\left(m, n\right)`
:math:`\mathrm{zomma}[i-1,j-1]`, contains the third-order Greek measuring the sensitivity of the second-order Greek :math:`\Gamma_{{ij}}` to change in the volatility of the underlying asset, i.e., :math:`-\frac{{\partial \Gamma_{{ij}}}}{{\partial \sigma }} = -\frac{{\partial^3P_{{ij}}}}{{\partial S^2\partial \sigma }}`, for :math:`i = 1,2,\ldots,m` and :math:`j = 1,2,\ldots,n`.
**vomma** : float, ndarray, shape :math:`\left(m, n\right)`
:math:`\mathrm{vomma}[i-1,j-1]`, contains the second-order Greek measuring the sensitivity of the first-order Greek :math:`\Delta_{{ij}}` to change in the volatility of the underlying asset, i.e., :math:`-\frac{{\partial \Delta_{{ij}}}}{{\partial \sigma }} = -\frac{{\partial^2P_{{ij}}}}{{\partial \sigma^2}}`, for :math:`i = 1,2,\ldots,m` and :math:`j = 1,2,\ldots,n`.
.. _s30bb-py2-py-errors:
**Raises**
**NagValueError**
(`errno` :math:`1`)
On entry, :math:`\mathrm{calput} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{calput} = \text{‘C'} \text{ or } \text{‘P'}`.
(`errno` :math:`2`)
On entry, :math:`m = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`m\geq 1`.
(`errno` :math:`3`)
On entry, :math:`n = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`n\geq 1`.
(`errno` :math:`4`)
On entry with a put option, :math:`\mathrm{sm}[\langle\mathit{\boldsymbol{value}}\rangle] = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: for put options, :math:`\mathrm{sm}[i]\geq \langle\mathit{\boldsymbol{value}}\rangle` for all :math:`i`.
(`errno` :math:`4`)
On entry with a call option, :math:`\mathrm{sm}[\langle\mathit{\boldsymbol{value}}\rangle] = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: for call options, :math:`\mathrm{sm}[i]\leq \langle\mathit{\boldsymbol{value}}\rangle` for all :math:`i`.
(`errno` :math:`4`)
On entry, :math:`\mathrm{sm}[\langle\mathit{\boldsymbol{value}}\rangle] = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\langle\mathit{\boldsymbol{value}}\rangle\leq \mathrm{sm}[i]\leq \langle\mathit{\boldsymbol{value}}\rangle` for all :math:`i`.
(`errno` :math:`5`)
On entry, :math:`\mathrm{s} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{s}\geq \langle\mathit{\boldsymbol{value}}\rangle` and :math:`\mathrm{s}\leq \langle\mathit{\boldsymbol{value}}\rangle`.
(`errno` :math:`6`)
On entry, :math:`\mathrm{t}[\langle\mathit{\boldsymbol{value}}\rangle] = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{t}[i]\geq \langle\mathit{\boldsymbol{value}}\rangle` for all :math:`i`.
(`errno` :math:`7`)
On entry, :math:`\mathrm{sigma} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{sigma} > 0.0`.
(`errno` :math:`8`)
On entry, :math:`\mathrm{r} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{r}\geq 0.0`.
(`errno` :math:`9`)
On entry, :math:`\mathrm{q} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{q}\geq 0.0`.
(`errno` :math:`12`)
On entry, :math:`\mathrm{r} = \langle\mathit{\boldsymbol{value}}\rangle` and :math:`\mathrm{q} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\left\lvert \mathrm{r}-\mathrm{q}\right\rvert > 10\times \textit{eps}\times \mathrm{max}\left(\left\lvert \mathrm{r}\right\rvert, 1\right)`, where :math:`\textit{eps}` is the machine precision.
.. _s30bb-py2-py-notes:
**Notes**
``opt_lookback_fls_greeks`` computes the price of a floating-strike lookback call or put option, together with the Greeks or sensitivities, which are the partial derivatives of the option price with respect to certain of the other input parameters.
A call option of this type confers the right to buy the underlying asset at the lowest price, :math:`S_{\mathrm{min}}`, observed during the lifetime of the contract.
A put option gives the holder the right to sell the underlying asset at the maximum price, :math:`S_{\mathrm{max}}`, observed during the lifetime of the contract.
Thus, at expiry, the payoff for a call option is :math:`S-S_{\mathrm{min}}`, and for a put, :math:`S_{\mathrm{max}}-S`.
For a given minimum value the price of a floating-strike lookback call with underlying asset price, :math:`S`, and time to expiry, :math:`T`, is
.. math::
P_{\mathrm{call}} = Se^{{-qT}}\Phi \left(a_1\right)-S_{\mathrm{min}}e^{{-rT}}\Phi \left(a_2\right)+Se^{{-rT}}\text{ }\frac{\sigma^2}{{2b}}\left[\left(\frac{S}{S_{\mathrm{min}}}\right)^{{-2b/\sigma^2}}\Phi \left({-a}_1+\frac{{2b}}{\sigma }\sqrt{T}\right){-e}^{{bT}}\Phi \left({-a}_1\right)\right]\text{,}
where :math:`b = r-q\neq 0`.
The volatility, :math:`\sigma`, risk-free interest rate, :math:`r`, and annualised dividend yield, :math:`q`, are constants.
The corresponding put price is
.. math::
P_{\mathrm{put}} = S_{\mathrm{max}}e^{{-rT}}\Phi \left({-a}_2\right)-Se^{{-qT}}\Phi \left({-a}_1\right)+Se^{{-rT}}\text{ }\frac{\sigma^2}{{2b}}\left[-\left(\frac{S}{S_{\mathrm{max}}}\right)^{{-2b/\sigma^2}}\Phi \left(a_1-\frac{{2b}}{\sigma }\sqrt{T}\right)+e^{{bT}}\Phi \left(a_1\right)\right]\text{.}
In the above, :math:`\Phi` denotes the cumulative Normal distribution function,
.. math::
\Phi \left(x\right) = \int_{{-\infty }}^x\phi \left(y\right)dy
where :math:`\phi` denotes the standard Normal probability density function
.. math::
\phi \left(y\right) = \frac{1}{\sqrt{2\pi }}\mathrm{exp}\left(-y^2/2\right)
and
.. math::
\begin{array}{l} a_1 = \frac{{\mathrm{ln}\left(S/S_{\mathrm{m}}\right)+\left(b+\sigma^2/2\right)T}}{{\sigma \sqrt{T}}} \\\\ a_2 = a_1-\sigma \sqrt{T} \end{array}
where :math:`S_m` is taken to be the minimum price attained by the underlying asset, :math:`S_{\mathrm{min}}`, for a call and the maximum price, :math:`S_{\mathrm{max}}`, for a put.
The option price :math:`P_{{ij}} = P\left({X = X_i}, {T = T_j}\right)` is computed for each minimum or maximum observed price in a set :math:`S_{\mathrm{min}}\left(\textit{i}\right)` or :math:`S_{\mathrm{max}}\left(\textit{i}\right)`, :math:`i = 1,2,\ldots,m`, and for each expiry time in a set :math:`T_j`, :math:`j = 1,2,\ldots,n`.
.. _s30bb-py2-py-references:
**References**
Goldman, B M, Sosin, H B and Gatto, M A, 1979, `Path dependent options: buy at the low, sell at the high`, Journal of Finance (34), 1111--1127
"""
raise NotImplementedError
[docs]def opt_binary_con_price(calput, x, s, k, t, sigma, r, q):
r"""
``opt_binary_con_price`` computes the price of a binary or digital cash-or-nothing option.
.. _s30ca-py2-py-doc:
For full information please refer to the NAG Library document for s30ca
https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s30caf.html
.. _s30ca-py2-py-parameters:
**Parameters**
**calput** : str, length 1
Determines whether the option is a call or a put.
:math:`\mathrm{calput} = \text{‘C'}`
A call; the holder has a right to buy.
:math:`\mathrm{calput} = \text{‘P'}`
A put; the holder has a right to sell.
**x** : float, array-like, shape :math:`\left(m\right)`
:math:`\mathrm{x}[i-1]` must contain :math:`X_{\textit{i}}`, the :math:`\textit{i}`\ th strike price, for :math:`\textit{i} = 1,2,\ldots,m`.
**s** : float
:math:`S`, the price of the underlying asset.
**k** : float
The amount, :math:`K`, to be paid at expiration if the option is in-the-money, i.e., if :math:`\mathrm{s} > \mathrm{x}[\textit{i}-1]` when :math:`\mathrm{calput} = \text{‘C'}`, or if :math:`\mathrm{s} < \mathrm{x}[\textit{i}-1]` when :math:`\mathrm{calput} = \text{‘P'}`, for :math:`\textit{i} = 1,2,\ldots,m`.
**t** : float, array-like, shape :math:`\left(n\right)`
:math:`\mathrm{t}[i-1]` must contain :math:`T_{\textit{i}}`, the :math:`\textit{i}`\ th time, in years, to expiry, for :math:`\textit{i} = 1,2,\ldots,n`.
**sigma** : float
:math:`\sigma`, the volatility of the underlying asset. Note that a rate of 15% should be entered as :math:`0.15`.
**r** : float
:math:`r`, the annual risk-free interest rate, continuously compounded. Note that a rate of 5% should be entered as :math:`0.05`.
**q** : float
:math:`q`, the annual continuous yield rate. Note that a rate of 8% should be entered as :math:`0.08`.
**Returns**
**p** : float, ndarray, shape :math:`\left(m, n\right)`
:math:`\mathrm{p}[i-1,j-1]` contains :math:`P_{{ij}}`, the option price evaluated for the strike price :math:`\mathrm{x}_i` at expiry :math:`\mathrm{t}_j` for :math:`i = 1,2,\ldots,m` and :math:`j = 1,2,\ldots,n`.
.. _s30ca-py2-py-errors:
**Raises**
**NagValueError**
(`errno` :math:`1`)
On entry, :math:`\mathrm{calput} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{calput} = \text{‘C'} \text{ or } \text{‘P'}`.
(`errno` :math:`2`)
On entry, :math:`m = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`m\geq 1`.
(`errno` :math:`3`)
On entry, :math:`n = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`n\geq 1`.
(`errno` :math:`4`)
On entry, :math:`\mathrm{x}[\langle\mathit{\boldsymbol{value}}\rangle] = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{x}[i]\geq \langle\mathit{\boldsymbol{value}}\rangle` and :math:`\mathrm{x}[i]\leq \langle\mathit{\boldsymbol{value}}\rangle`.
(`errno` :math:`5`)
On entry, :math:`\mathrm{s} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{s}\geq \langle\mathit{\boldsymbol{value}}\rangle` and :math:`\mathrm{s}\leq \langle\mathit{\boldsymbol{value}}\rangle`.
(`errno` :math:`6`)
On entry, :math:`\mathrm{k} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{k}\geq 0.0`.
(`errno` :math:`7`)
On entry, :math:`\mathrm{t}[\langle\mathit{\boldsymbol{value}}\rangle] = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{t}[i]\geq \langle\mathit{\boldsymbol{value}}\rangle`.
(`errno` :math:`8`)
On entry, :math:`\mathrm{sigma} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{sigma} > 0.0`.
(`errno` :math:`9`)
On entry, :math:`\mathrm{r} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{r}\geq 0.0`.
(`errno` :math:`10`)
On entry, :math:`\mathrm{q} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{q}\geq 0.0`.
.. _s30ca-py2-py-notes:
**Notes**
``opt_binary_con_price`` computes the price of a binary or digital cash-or-nothing option which pays a fixed amount, :math:`K`, at expiration if the option is in-the-money (see `the S Introduction <https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/sintro.html#bg_optionpricing>`__).
For a strike price, :math:`X`, underlying asset price, :math:`S`, and time to expiry, :math:`T`, the payoff is, therefore, :math:`K`, if :math:`S > X` for a call or :math:`S < X` for a put.
Nothing is paid out when this condition is not met.
The price of a call with volatility, :math:`\sigma`, risk-free interest rate, :math:`r`, and annualised dividend yield, :math:`q`, is
.. math::
P_{\mathrm{call}} = Ke^{{-rT}}\Phi \left(d_2\right)
and for a put,
.. math::
P_{\mathrm{put}} = Ke^{{-rT}}\Phi \left(-d_2\right)
where :math:`\Phi` is the cumulative Normal distribution function,
.. math::
\Phi \left(x\right) = \frac{1}{{\sqrt{2\pi }}}\int_{{-\infty }}^x\left(-y^2/2\right)dy\text{,}
and
.. math::
d_2 = \frac{{\mathrm{ln}\left(S/X\right)+\left(r-q-\sigma^2/2\right)T}}{{\sigma \sqrt{T}}}\text{.}
The option price :math:`P_{{ij}} = P\left({X = X_i}, {T = T_j}\right)` is computed for each strike price in a set :math:`X_i`, :math:`i = 1,2,\ldots,m`, and for each expiry time in a set :math:`T_j`, :math:`j = 1,2,\ldots,n`.
.. _s30ca-py2-py-references:
**References**
Reiner, E and Rubinstein, M, 1991, `Unscrambling the binary code`, Risk (4)
"""
raise NotImplementedError
[docs]def opt_binary_con_greeks(calput, x, s, k, t, sigma, r, q):
r"""
``opt_binary_con_greeks`` computes the price of a binary or digital cash-or-nothing option together with its sensitivities (Greeks).
.. _s30cb-py2-py-doc:
For full information please refer to the NAG Library document for s30cb
https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s30cbf.html
.. _s30cb-py2-py-parameters:
**Parameters**
**calput** : str, length 1
Determines whether the option is a call or a put.
:math:`\mathrm{calput} = \text{‘C'}`
A call; the holder has a right to buy.
:math:`\mathrm{calput} = \text{‘P'}`
A put; the holder has a right to sell.
**x** : float, array-like, shape :math:`\left(m\right)`
:math:`\mathrm{x}[i-1]` must contain :math:`X_{\textit{i}}`, the :math:`\textit{i}`\ th strike price, for :math:`\textit{i} = 1,2,\ldots,m`.
**s** : float
:math:`S`, the price of the underlying asset.
**k** : float
The amount, :math:`K`, to be paid at expiration if the option is in-the-money, i.e., if :math:`\mathrm{s} > \mathrm{x}[\textit{i}-1]` when :math:`\mathrm{calput} = \text{‘C'}`, or if :math:`\mathrm{s} < \mathrm{x}[\textit{i}-1]` when :math:`\mathrm{calput} = \text{‘P'}`, for :math:`\textit{i} = 1,2,\ldots,m`.
**t** : float, array-like, shape :math:`\left(n\right)`
:math:`\mathrm{t}[i-1]` must contain :math:`T_{\textit{i}}`, the :math:`\textit{i}`\ th time, in years, to expiry, for :math:`\textit{i} = 1,2,\ldots,n`.
**sigma** : float
:math:`\sigma`, the volatility of the underlying asset. Note that a rate of 15% should be entered as :math:`0.15`.
**r** : float
:math:`r`, the annual risk-free interest rate, continuously compounded. Note that a rate of 5% should be entered as :math:`0.05`.
**q** : float
:math:`q`, the annual continuous yield rate. Note that a rate of 8% should be entered as :math:`0.08`.
**Returns**
**p** : float, ndarray, shape :math:`\left(m, n\right)`
:math:`\mathrm{p}[i-1,j-1]` contains :math:`P_{{ij}}`, the option price evaluated for the strike price :math:`\mathrm{x}_i` at expiry :math:`\mathrm{t}_j` for :math:`i = 1,2,\ldots,m` and :math:`j = 1,2,\ldots,n`.
**delta** : float, ndarray, shape :math:`\left(m, n\right)`
The leading :math:`m\times n` part of the array :math:`\mathrm{delta}` contains the sensitivity, :math:`\frac{{\partial P}}{{\partial S}}`, of the option price to change in the price of the underlying asset.
**gamma** : float, ndarray, shape :math:`\left(m, n\right)`
The leading :math:`m\times n` part of the array :math:`\mathrm{gamma}` contains the sensitivity, :math:`\frac{{\partial^2P}}{{\partial S^2}}`, of :math:`\mathrm{delta}` to change in the price of the underlying asset.
**vega** : float, ndarray, shape :math:`\left(m, n\right)`
:math:`\mathrm{vega}[i-1,j-1]`, contains the first-order Greek measuring the sensitivity of the option price :math:`P_{{ij}}` to change in the volatility of the underlying asset, i.e., :math:`\frac{{\partial P_{{ij}}}}{{\partial \sigma }}`, for :math:`i = 1,2,\ldots,m` and :math:`j = 1,2,\ldots,n`.
**theta** : float, ndarray, shape :math:`\left(m, n\right)`
:math:`\mathrm{theta}[i-1,j-1]`, contains the first-order Greek measuring the sensitivity of the option price :math:`P_{{ij}}` to change in time, i.e., :math:`-\frac{{\partial P_{{ij}}}}{{\partial T}}`, for :math:`i = 1,2,\ldots,m` and :math:`j = 1,2,\ldots,n`, where :math:`b = r-q`.
**rho** : float, ndarray, shape :math:`\left(m, n\right)`
:math:`\mathrm{rho}[i-1,j-1]`, contains the first-order Greek measuring the sensitivity of the option price :math:`P_{{ij}}` to change in the annual risk-free interest rate, i.e., :math:`-\frac{{\partial P_{{ij}}}}{{\partial r}}`, for :math:`i = 1,2,\ldots,m` and :math:`j = 1,2,\ldots,n`.
**crho** : float, ndarray, shape :math:`\left(m, n\right)`
:math:`\mathrm{crho}[i-1,j-1]`, contains the first-order Greek measuring the sensitivity of the option price :math:`P_{{ij}}` to change in the annual cost of carry rate, i.e., :math:`-\frac{{\partial P_{{ij}}}}{{\partial b}}`, for :math:`i = 1,2,\ldots,m` and :math:`j = 1,2,\ldots,n`, where :math:`b = r-q`.
**vanna** : float, ndarray, shape :math:`\left(m, n\right)`
:math:`\mathrm{vanna}[i-1,j-1]`, contains the second-order Greek measuring the sensitivity of the first-order Greek :math:`\Delta_{{ij}}` to change in the volatility of the asset price, i.e., :math:`-\frac{{\partial \Delta_{{ij}}}}{{\partial T}} = -\frac{{\partial^2P_{{ij}}}}{{\partial S\partial \sigma }}`, for :math:`i = 1,2,\ldots,m` and :math:`j = 1,2,\ldots,n`.
**charm** : float, ndarray, shape :math:`\left(m, n\right)`
:math:`\mathrm{charm}[i-1,j-1]`, contains the second-order Greek measuring the sensitivity of the first-order Greek :math:`\Delta_{{ij}}` to change in the time, i.e., :math:`-\frac{{\partial \Delta_{{ij}}}}{{\partial T}} = -\frac{{\partial^2P_{{ij}}}}{{\partial S\partial T}}`, for :math:`i = 1,2,\ldots,m` and :math:`j = 1,2,\ldots,n`.
**speed** : float, ndarray, shape :math:`\left(m, n\right)`
:math:`\mathrm{speed}[i-1,j-1]`, contains the third-order Greek measuring the sensitivity of the second-order Greek :math:`\Gamma_{{ij}}` to change in the price of the underlying asset, i.e., :math:`-\frac{{\partial \Gamma_{{ij}}}}{{\partial S}} = -\frac{{\partial^3P_{{ij}}}}{{\partial S^3}}`, for :math:`i = 1,2,\ldots,m` and :math:`j = 1,2,\ldots,n`.
**colour** : float, ndarray, shape :math:`\left(m, n\right)`
:math:`\mathrm{colour}[i-1,j-1]`, contains the third-order Greek measuring the sensitivity of the second-order Greek :math:`\Gamma_{{ij}}` to change in the time, i.e., :math:`-\frac{{\partial \Gamma_{{ij}}}}{{\partial T}} = -\frac{{\partial^3P_{{ij}}}}{{\partial S\partial T}}`, for :math:`i = 1,2,\ldots,m` and :math:`j = 1,2,\ldots,n`.
**zomma** : float, ndarray, shape :math:`\left(m, n\right)`
:math:`\mathrm{zomma}[i-1,j-1]`, contains the third-order Greek measuring the sensitivity of the second-order Greek :math:`\Gamma_{{ij}}` to change in the volatility of the underlying asset, i.e., :math:`-\frac{{\partial \Gamma_{{ij}}}}{{\partial \sigma }} = -\frac{{\partial^3P_{{ij}}}}{{\partial S^2\partial \sigma }}`, for :math:`i = 1,2,\ldots,m` and :math:`j = 1,2,\ldots,n`.
**vomma** : float, ndarray, shape :math:`\left(m, n\right)`
:math:`\mathrm{vomma}[i-1,j-1]`, contains the second-order Greek measuring the sensitivity of the first-order Greek :math:`\Delta_{{ij}}` to change in the volatility of the underlying asset, i.e., :math:`-\frac{{\partial \Delta_{{ij}}}}{{\partial \sigma }} = -\frac{{\partial^2P_{{ij}}}}{{\partial \sigma^2}}`, for :math:`i = 1,2,\ldots,m` and :math:`j = 1,2,\ldots,n`.
.. _s30cb-py2-py-errors:
**Raises**
**NagValueError**
(`errno` :math:`1`)
On entry, :math:`\mathrm{calput} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{calput} = \text{‘C'} \text{ or } \text{‘P'}`.
(`errno` :math:`2`)
On entry, :math:`m = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`m\geq 1`.
(`errno` :math:`3`)
On entry, :math:`n = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`n\geq 1`.
(`errno` :math:`4`)
On entry, :math:`\mathrm{x}[\langle\mathit{\boldsymbol{value}}\rangle] = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{x}[i]\geq \langle\mathit{\boldsymbol{value}}\rangle` and :math:`\mathrm{x}[i]\leq \langle\mathit{\boldsymbol{value}}\rangle`.
(`errno` :math:`5`)
On entry, :math:`\mathrm{s} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{s}\geq \langle\mathit{\boldsymbol{value}}\rangle` and :math:`\mathrm{s}\leq \langle\mathit{\boldsymbol{value}}\rangle`.
(`errno` :math:`6`)
On entry, :math:`\mathrm{k} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{k}\geq 0.0`.
(`errno` :math:`7`)
On entry, :math:`\mathrm{t}[\langle\mathit{\boldsymbol{value}}\rangle] = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{t}[i]\geq \langle\mathit{\boldsymbol{value}}\rangle`.
(`errno` :math:`8`)
On entry, :math:`\mathrm{sigma} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{sigma} > 0.0`.
(`errno` :math:`9`)
On entry, :math:`\mathrm{r} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{r}\geq 0.0`.
(`errno` :math:`10`)
On entry, :math:`\mathrm{q} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{q}\geq 0.0`.
.. _s30cb-py2-py-notes:
**Notes**
``opt_binary_con_greeks`` computes the price of a binary or digital cash-or-nothing option, together with the Greeks or sensitivities, which are the partial derivatives of the option price with respect to certain of the other input parameters.
This option pays a fixed amount, :math:`K`, at expiration if the option is in-the-money (see `the S Introduction <https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/sintro.html#bg_optionpricing>`__).
For a strike price, :math:`X`, underlying asset price, :math:`S`, and time to expiry, :math:`T`, the payoff is, therefore, :math:`K`, if :math:`S > X` for a call or :math:`S < X` for a put.
Nothing is paid out when this condition is not met.
The price of a call with volatility, :math:`\sigma`, risk-free interest rate, :math:`r`, and annualised dividend yield, :math:`q`, is
.. math::
P_{\mathrm{call}} = Ke^{{-rT}}\Phi \left(d_2\right)
and for a put,
.. math::
P_{\mathrm{put}} = Ke^{{-rT}}\Phi \left(-d_2\right)
where :math:`\Phi` is the cumulative Normal distribution function,
.. math::
\Phi \left(x\right) = \frac{1}{{\sqrt{2\pi }}}\int_{{-\infty }}^x\mathrm{exp}\left(-y^2/2\right)dy\text{,}
and
.. math::
d_2 = \frac{{\mathrm{ln}\left(S/X\right)+\left(r-q-\sigma^2/2\right)T}}{{\sigma \sqrt{T}}}\text{.}
The option price :math:`P_{{ij}} = P\left({X = X_i}, {T = T_j}\right)` is computed for each strike price in a set :math:`X_i`, :math:`i = 1,2,\ldots,m`, and for each expiry time in a set :math:`T_j`, :math:`j = 1,2,\ldots,n`.
.. _s30cb-py2-py-references:
**References**
Reiner, E and Rubinstein, M, 1991, `Unscrambling the binary code`, Risk (4)
"""
raise NotImplementedError
[docs]def opt_binary_aon_price(calput, x, s, t, sigma, r, q):
r"""
``opt_binary_aon_price`` computes the price of a binary or digital asset-or-nothing option.
.. _s30cc-py2-py-doc:
For full information please refer to the NAG Library document for s30cc
https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s30ccf.html
.. _s30cc-py2-py-parameters:
**Parameters**
**calput** : str, length 1
Determines whether the option is a call or a put.
:math:`\mathrm{calput} = \text{‘C'}`
A call; the holder has a right to buy.
:math:`\mathrm{calput} = \text{‘P'}`
A put; the holder has a right to sell.
**x** : float, array-like, shape :math:`\left(m\right)`
:math:`\mathrm{x}[i-1]` must contain :math:`X_{\textit{i}}`, the :math:`\textit{i}`\ th strike price, for :math:`\textit{i} = 1,2,\ldots,m`.
**s** : float
:math:`S`, the price of the underlying asset.
**t** : float, array-like, shape :math:`\left(n\right)`
:math:`\mathrm{t}[i-1]` must contain :math:`T_{\textit{i}}`, the :math:`\textit{i}`\ th time, in years, to expiry, for :math:`\textit{i} = 1,2,\ldots,n`.
**sigma** : float
:math:`\sigma`, the volatility of the underlying asset. Note that a rate of 15% should be entered as :math:`0.15`.
**r** : float
:math:`r`, the annual risk-free interest rate, continuously compounded. Note that a rate of 5% should be entered as :math:`0.05`.
**q** : float
:math:`q`, the annual continuous yield rate. Note that a rate of 8% should be entered as :math:`0.08`.
**Returns**
**p** : float, ndarray, shape :math:`\left(m, n\right)`
:math:`\mathrm{p}[i-1,j-1]` contains :math:`P_{{ij}}`, the option price evaluated for the strike price :math:`\mathrm{x}_i` at expiry :math:`\mathrm{t}_j` for :math:`i = 1,2,\ldots,m` and :math:`j = 1,2,\ldots,n`.
.. _s30cc-py2-py-errors:
**Raises**
**NagValueError**
(`errno` :math:`1`)
On entry, :math:`\mathrm{calput} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{calput} = \text{‘C'} \text{ or } \text{‘P'}`.
(`errno` :math:`2`)
On entry, :math:`m = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`m\geq 1`.
(`errno` :math:`3`)
On entry, :math:`n = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`n\geq 1`.
(`errno` :math:`4`)
On entry, :math:`\mathrm{x}[\langle\mathit{\boldsymbol{value}}\rangle] = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{x}[i]\geq \langle\mathit{\boldsymbol{value}}\rangle` and :math:`\mathrm{x}[i]\leq \langle\mathit{\boldsymbol{value}}\rangle`.
(`errno` :math:`5`)
On entry, :math:`\mathrm{s} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{s}\geq \langle\mathit{\boldsymbol{value}}\rangle` and :math:`\mathrm{s}\leq \langle\mathit{\boldsymbol{value}}\rangle`.
(`errno` :math:`6`)
On entry, :math:`\mathrm{t}[\langle\mathit{\boldsymbol{value}}\rangle] = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{t}[i]\geq \langle\mathit{\boldsymbol{value}}\rangle`.
(`errno` :math:`7`)
On entry, :math:`\mathrm{sigma} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{sigma} > 0.0`.
(`errno` :math:`8`)
On entry, :math:`\mathrm{r} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{r}\geq 0.0`.
(`errno` :math:`9`)
On entry, :math:`\mathrm{q} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{q}\geq 0.0`.
.. _s30cc-py2-py-notes:
**Notes**
``opt_binary_aon_price`` computes the price of a binary or digital asset-or-nothing option which pays the underlying asset itself, :math:`S`, at expiration if the option is in-the-money (see `the S Introduction <https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/sintro.html#bg_optionpricing>`__).
For a strike price, :math:`X`, underlying asset price, :math:`S`, and time to expiry, :math:`T`, the payoff is, therefore, :math:`S`, if :math:`S > X` for a call or :math:`S < X` for a put.
Nothing is paid out when this condition is not met.
The price of a call with volatility, :math:`\sigma`, risk-free interest rate, :math:`r`, and annualised dividend yield, :math:`q`, is
.. math::
P_{\mathrm{call}} = Se^{{-qT}}\Phi \left(d_1\right)
and for a put,
.. math::
P_{\mathrm{put}} = Se^{{-qT}}\Phi \left(-d_1\right)
where :math:`\Phi` is the cumulative Normal distribution function,
.. math::
\Phi \left(x\right) = \frac{1}{{\sqrt{2\pi }}}\int_{{-\infty }}^x\mathrm{exp}\left({-y}^2/2\right)dy\text{,}
and
.. math::
d_1 = \frac{{\mathrm{ln}\left(S/X\right)+\left(r-q+\sigma^2/2\right)T}}{{\sigma \sqrt{T}}}\text{.}
The option price :math:`P_{{ij}} = P\left({X = X_i}, {T = T_j}\right)` is computed for each strike price in a set :math:`X_i`, :math:`i = 1,2,\ldots,m`, and for each expiry time in a set :math:`T_j`, :math:`j = 1,2,\ldots,n`.
.. _s30cc-py2-py-references:
**References**
Reiner, E and Rubinstein, M, 1991, `Unscrambling the binary code`, Risk (4)
"""
raise NotImplementedError
[docs]def opt_binary_aon_greeks(calput, x, s, t, sigma, r, q):
r"""
``opt_binary_aon_greeks`` computes the price of a binary or digital asset-or-nothing option together with its sensitivities (Greeks).
.. _s30cd-py2-py-doc:
For full information please refer to the NAG Library document for s30cd
https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s30cdf.html
.. _s30cd-py2-py-parameters:
**Parameters**
**calput** : str, length 1
Determines whether the option is a call or a put.
:math:`\mathrm{calput} = \text{‘C'}`
A call; the holder has a right to buy.
:math:`\mathrm{calput} = \text{‘P'}`
A put; the holder has a right to sell.
**x** : float, array-like, shape :math:`\left(m\right)`
:math:`\mathrm{x}[i-1]` must contain :math:`X_{\textit{i}}`, the :math:`\textit{i}`\ th strike price, for :math:`\textit{i} = 1,2,\ldots,m`.
**s** : float
:math:`S`, the price of the underlying asset.
**t** : float, array-like, shape :math:`\left(n\right)`
:math:`\mathrm{t}[i-1]` must contain :math:`T_{\textit{i}}`, the :math:`\textit{i}`\ th time, in years, to expiry, for :math:`\textit{i} = 1,2,\ldots,n`.
**sigma** : float
:math:`\sigma`, the volatility of the underlying asset. Note that a rate of 15% should be entered as :math:`0.15`.
**r** : float
:math:`r`, the annual risk-free interest rate, continuously compounded. Note that a rate of 5% should be entered as :math:`0.05`.
**q** : float
:math:`q`, the annual continuous yield rate. Note that a rate of 8% should be entered as :math:`0.08`.
**Returns**
**p** : float, ndarray, shape :math:`\left(m, n\right)`
:math:`\mathrm{p}[i-1,j-1]` contains :math:`P_{{ij}}`, the option price evaluated for the strike price :math:`\mathrm{x}_i` at expiry :math:`\mathrm{t}_j` for :math:`i = 1,2,\ldots,m` and :math:`j = 1,2,\ldots,n`.
**delta** : float, ndarray, shape :math:`\left(m, n\right)`
The leading :math:`m\times n` part of the array :math:`\mathrm{delta}` contains the sensitivity, :math:`\frac{{\partial P}}{{\partial S}}`, of the option price to change in the price of the underlying asset.
**gamma** : float, ndarray, shape :math:`\left(m, n\right)`
The leading :math:`m\times n` part of the array :math:`\mathrm{gamma}` contains the sensitivity, :math:`\frac{{\partial^2P}}{{\partial S^2}}`, of :math:`\mathrm{delta}` to change in the price of the underlying asset.
**vega** : float, ndarray, shape :math:`\left(m, n\right)`
:math:`\mathrm{vega}[i-1,j-1]`, contains the first-order Greek measuring the sensitivity of the option price :math:`P_{{ij}}` to change in the volatility of the underlying asset, i.e., :math:`\frac{{\partial P_{{ij}}}}{{\partial \sigma }}`, for :math:`i = 1,2,\ldots,m` and :math:`j = 1,2,\ldots,n`.
**theta** : float, ndarray, shape :math:`\left(m, n\right)`
:math:`\mathrm{theta}[i-1,j-1]`, contains the first-order Greek measuring the sensitivity of the option price :math:`P_{{ij}}` to change in time, i.e., :math:`-\frac{{\partial P_{{ij}}}}{{\partial T}}`, for :math:`i = 1,2,\ldots,m` and :math:`j = 1,2,\ldots,n`, where :math:`b = r-q`.
**rho** : float, ndarray, shape :math:`\left(m, n\right)`
:math:`\mathrm{rho}[i-1,j-1]`, contains the first-order Greek measuring the sensitivity of the option price :math:`P_{{ij}}` to change in the annual risk-free interest rate, i.e., :math:`-\frac{{\partial P_{{ij}}}}{{\partial r}}`, for :math:`i = 1,2,\ldots,m` and :math:`j = 1,2,\ldots,n`.
**crho** : float, ndarray, shape :math:`\left(m, n\right)`
:math:`\mathrm{crho}[i-1,j-1]`, contains the first-order Greek measuring the sensitivity of the option price :math:`P_{{ij}}` to change in the annual cost of carry rate, i.e., :math:`-\frac{{\partial P_{{ij}}}}{{\partial b}}`, for :math:`i = 1,2,\ldots,m` and :math:`j = 1,2,\ldots,n`, where :math:`b = r-q`.
**vanna** : float, ndarray, shape :math:`\left(m, n\right)`
:math:`\mathrm{vanna}[i-1,j-1]`, contains the second-order Greek measuring the sensitivity of the first-order Greek :math:`\Delta_{{ij}}` to change in the volatility of the asset price, i.e., :math:`-\frac{{\partial \Delta_{{ij}}}}{{\partial T}} = -\frac{{\partial^2P_{{ij}}}}{{\partial S\partial \sigma }}`, for :math:`i = 1,2,\ldots,m` and :math:`j = 1,2,\ldots,n`.
**charm** : float, ndarray, shape :math:`\left(m, n\right)`
:math:`\mathrm{charm}[i-1,j-1]`, contains the second-order Greek measuring the sensitivity of the first-order Greek :math:`\Delta_{{ij}}` to change in the time, i.e., :math:`-\frac{{\partial \Delta_{{ij}}}}{{\partial T}} = -\frac{{\partial^2P_{{ij}}}}{{\partial S\partial T}}`, for :math:`i = 1,2,\ldots,m` and :math:`j = 1,2,\ldots,n`.
**speed** : float, ndarray, shape :math:`\left(m, n\right)`
:math:`\mathrm{speed}[i-1,j-1]`, contains the third-order Greek measuring the sensitivity of the second-order Greek :math:`\Gamma_{{ij}}` to change in the price of the underlying asset, i.e., :math:`-\frac{{\partial \Gamma_{{ij}}}}{{\partial S}} = -\frac{{\partial^3P_{{ij}}}}{{\partial S^3}}`, for :math:`i = 1,2,\ldots,m` and :math:`j = 1,2,\ldots,n`.
**colour** : float, ndarray, shape :math:`\left(m, n\right)`
:math:`\mathrm{colour}[i-1,j-1]`, contains the third-order Greek measuring the sensitivity of the second-order Greek :math:`\Gamma_{{ij}}` to change in the time, i.e., :math:`-\frac{{\partial \Gamma_{{ij}}}}{{\partial T}} = -\frac{{\partial^3P_{{ij}}}}{{\partial S\partial T}}`, for :math:`i = 1,2,\ldots,m` and :math:`j = 1,2,\ldots,n`.
**zomma** : float, ndarray, shape :math:`\left(m, n\right)`
:math:`\mathrm{zomma}[i-1,j-1]`, contains the third-order Greek measuring the sensitivity of the second-order Greek :math:`\Gamma_{{ij}}` to change in the volatility of the underlying asset, i.e., :math:`-\frac{{\partial \Gamma_{{ij}}}}{{\partial \sigma }} = -\frac{{\partial^3P_{{ij}}}}{{\partial S^2\partial \sigma }}`, for :math:`i = 1,2,\ldots,m` and :math:`j = 1,2,\ldots,n`.
**vomma** : float, ndarray, shape :math:`\left(m, n\right)`
:math:`\mathrm{vomma}[i-1,j-1]`, contains the second-order Greek measuring the sensitivity of the first-order Greek :math:`\Delta_{{ij}}` to change in the volatility of the underlying asset, i.e., :math:`-\frac{{\partial \Delta_{{ij}}}}{{\partial \sigma }} = -\frac{{\partial^2P_{{ij}}}}{{\partial \sigma^2}}`, for :math:`i = 1,2,\ldots,m` and :math:`j = 1,2,\ldots,n`.
.. _s30cd-py2-py-errors:
**Raises**
**NagValueError**
(`errno` :math:`1`)
On entry, :math:`\mathrm{calput} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{calput} = \text{‘C'} \text{ or } \text{‘P'}`.
(`errno` :math:`2`)
On entry, :math:`m = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`m\geq 1`.
(`errno` :math:`3`)
On entry, :math:`n = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`n\geq 1`.
(`errno` :math:`4`)
On entry, :math:`\mathrm{x}[\langle\mathit{\boldsymbol{value}}\rangle] = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{x}[i]\geq \langle\mathit{\boldsymbol{value}}\rangle` and :math:`\mathrm{x}[i]\leq \langle\mathit{\boldsymbol{value}}\rangle`.
(`errno` :math:`5`)
On entry, :math:`\mathrm{s} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{s}\geq \langle\mathit{\boldsymbol{value}}\rangle` and :math:`\mathrm{s}\leq \langle\mathit{\boldsymbol{value}}\rangle`.
(`errno` :math:`6`)
On entry, :math:`\mathrm{t}[\langle\mathit{\boldsymbol{value}}\rangle] = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{t}[i]\geq \langle\mathit{\boldsymbol{value}}\rangle`.
(`errno` :math:`7`)
On entry, :math:`\mathrm{sigma} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{sigma} > 0.0`.
(`errno` :math:`8`)
On entry, :math:`\mathrm{r} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{r}\geq 0.0`.
(`errno` :math:`9`)
On entry, :math:`\mathrm{q} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{q}\geq 0.0`.
.. _s30cd-py2-py-notes:
**Notes**
``opt_binary_aon_greeks`` computes the price of a binary or digital asset-or-nothing option, together with the Greeks or sensitivities, which are the partial derivatives of the option price with respect to certain of the other input parameters.
This option pays the underlying asset itself, :math:`S`, at expiration if the option is in-the-money (see `the S Introduction <https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/sintro.html#bg_optionpricing>`__).
For a strike price, :math:`X`, underlying asset price, :math:`S`, and time to expiry, :math:`T`, the payoff is, therefore, :math:`S`, if :math:`S > X` for a call or :math:`S < X` for a put.
Nothing is paid out when this condition is not met.
The price of a call with volatility, :math:`\sigma`, risk-free interest rate, :math:`r`, and annualised dividend yield, :math:`q`, is
.. math::
P_{\mathrm{call}} = Se^{{-qT}}\Phi \left(d_1\right)
and for a put,
.. math::
P_{\mathrm{put}} = Se^{{-qT}}\Phi \left(-d_1\right)
where :math:`\Phi` is the cumulative Normal distribution function,
.. math::
\Phi \left(x\right) = \frac{1}{{\sqrt{2\pi }}}\int_{{-\infty }}^x\mathrm{exp}\left({-y}^2/2\right)dy\text{,}
and
.. math::
d_1 = \frac{{\mathrm{ln}\left(S/X\right)+\left(r-q+\sigma^2/2\right)T}}{{\sigma \sqrt{T}}}\text{.}
The option price :math:`P_{{ij}} = P\left({X = X_i}, {T = T_j}\right)` is computed for each strike price in a set :math:`X_i`, :math:`i = 1,2,\ldots,m`, and for each expiry time in a set :math:`T_j`, :math:`j = 1,2,\ldots,n`.
.. _s30cd-py2-py-references:
**References**
Reiner, E and Rubinstein, M, 1991, `Unscrambling the binary code`, Risk (4)
"""
raise NotImplementedError
[docs]def opt_barrier_std_price(calput, btype, x, s, h, k, t, sigma, r, q):
r"""
``opt_barrier_std_price`` computes the price of a standard barrier option.
.. _s30fa-py2-py-doc:
For full information please refer to the NAG Library document for s30fa
https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s30faf.html
.. _s30fa-py2-py-parameters:
**Parameters**
**calput** : str, length 1
Determines whether the option is a call or a put.
:math:`\mathrm{calput} = \text{‘C'}`
A call; the holder has a right to buy.
:math:`\mathrm{calput} = \text{‘P'}`
A put; the holder has a right to sell.
**btype** : str, length 2
Indicates the barrier type as **In** or **Out** and its relation to the price of the underlying asset as **Up** or **Down**.
:math:`\mathrm{btype} = \text{‘DI'}`
Down-and-In.
:math:`\mathrm{btype} = \text{‘DO'}`
Down-and-Out.
:math:`\mathrm{btype} = \text{‘UI'}`
Up-and-In.
:math:`\mathrm{btype} = \text{‘UO'}`
Up-and-Out.
**x** : float, array-like, shape :math:`\left(m\right)`
:math:`\mathrm{x}[i-1]` must contain :math:`X_{\textit{i}}`, the :math:`\textit{i}`\ th strike price, for :math:`\textit{i} = 1,2,\ldots,m`.
**s** : float
:math:`S`, the price of the underlying asset.
**h** : float
The barrier price.
**k** : float
The value of a possible cash rebate to be paid if the option has not been knocked in (or out) before expiration.
**t** : float, array-like, shape :math:`\left(n\right)`
:math:`\mathrm{t}[i-1]` must contain :math:`T_{\textit{i}}`, the :math:`\textit{i}`\ th time, in years, to expiry, for :math:`\textit{i} = 1,2,\ldots,n`.
**sigma** : float
:math:`\sigma`, the volatility of the underlying asset. Note that a rate of 15% should be entered as :math:`0.15`.
**r** : float
:math:`r`, the annual risk-free interest rate, continuously compounded. Note that a rate of 5% should be entered as :math:`0.05`.
**q** : float
:math:`q`, the annual continuous yield rate. Note that a rate of 8% should be entered as :math:`0.08`.
**Returns**
**p** : float, ndarray, shape :math:`\left(m, n\right)`
:math:`\mathrm{p}[i-1,j-1]` contains :math:`P_{{ij}}`, the option price evaluated for the strike price :math:`\mathrm{x}_i` at expiry :math:`\mathrm{t}_j` for :math:`i = 1,2,\ldots,m` and :math:`j = 1,2,\ldots,n`.
.. _s30fa-py2-py-errors:
**Raises**
**NagValueError**
(`errno` :math:`1`)
On entry, :math:`\mathrm{calput} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{calput} = \text{‘C'} \text{ or } \text{‘P'}`.
(`errno` :math:`2`)
On entry, :math:`\mathrm{btype} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{btype} = \text{‘DI'}, \text{‘DO'}, \text{‘UI'} \text{ or } \text{‘UO'}`.
(`errno` :math:`3`)
On entry, :math:`m = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`m\geq 1`.
(`errno` :math:`4`)
On entry, :math:`n = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`n\geq 1`.
(`errno` :math:`5`)
On entry, :math:`\mathrm{x}[\langle\mathit{\boldsymbol{value}}\rangle] = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{x}[i]\geq \langle\mathit{\boldsymbol{value}}\rangle` and :math:`\mathrm{x}[i]\leq \langle\mathit{\boldsymbol{value}}\rangle`.
(`errno` :math:`6`)
On entry, :math:`\mathrm{s} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{s}\geq \langle\mathit{\boldsymbol{value}}\rangle` and :math:`\mathrm{s}\leq \langle\mathit{\boldsymbol{value}}\rangle`.
(`errno` :math:`7`)
On entry, :math:`\mathrm{h} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{h}\geq \langle\mathit{\boldsymbol{value}}\rangle` and :math:`\mathrm{h}\leq \langle\mathit{\boldsymbol{value}}\rangle`.
(`errno` :math:`8`)
On entry, :math:`\mathrm{k} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{k}\geq 0.0`.
(`errno` :math:`9`)
On entry, :math:`\mathrm{t}[\langle\mathit{\boldsymbol{value}}\rangle] = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{t}[i]\geq \langle\mathit{\boldsymbol{value}}\rangle`.
(`errno` :math:`10`)
On entry, :math:`\mathrm{sigma} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{sigma} > 0.0`.
(`errno` :math:`11`)
On entry, :math:`\mathrm{r} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{r}\geq 0.0`.
(`errno` :math:`12`)
On entry, :math:`\mathrm{q} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{q}\geq 0.0`.
(`errno` :math:`15`)
On entry, :math:`\mathrm{s}` and :math:`\mathrm{h}` are inconsistent with :math:`\mathrm{btype}`: :math:`\mathrm{s} = \langle\mathit{\boldsymbol{value}}\rangle` and :math:`\mathrm{h} = \langle\mathit{\boldsymbol{value}}\rangle`.
.. _s30fa-py2-py-notes:
**Notes**
``opt_barrier_std_price`` computes the price of a standard barrier option, where the exercise, for a given strike price, :math:`X`, depends on the underlying asset price, :math:`S`, reaching or crossing a specified barrier level, :math:`H`.
Barrier options of type **In** only become active (are knocked in) if the underlying asset price attains the pre-determined barrier level during the lifetime of the contract.
Those of type **Out** start active and are knocked out if the underlying asset price attains the barrier level during the lifetime of the contract.
A cash rebate, :math:`K`, may be paid if the option is inactive at expiration.
The option may also be described as **Up** (the underlying price starts below the barrier level) or **Down** (the underlying price starts above the barrier level).
This gives the following options which can be specified as put or call contracts.
**Down-and-In:** the option starts inactive with the underlying asset price above the barrier level.
It is knocked in if the underlying price moves down to hit the barrier level before expiration.
**Down-and-Out:** the option starts active with the underlying asset price above the barrier level.
It is knocked out if the underlying price moves down to hit the barrier level before expiration.
**Up-and-In:** the option starts inactive with the underlying asset price below the barrier level.
It is knocked in if the underlying price moves up to hit the barrier level before expiration.
**Up-and-Out:** the option starts active with the underlying asset price below the barrier level.
It is knocked out if the underlying price moves up to hit the barrier level before expiration.
The payoff is :math:`\mathrm{max}\left({S-X}, 0\right)` for a call or :math:`\mathrm{max}\left({X-S}, 0\right)` for a put, if the option is active at expiration, otherwise it may pay a pre-specified cash rebate, :math:`K`.
Following Haug (2007), the prices of the various standard barrier options can be written as shown below.
The volatility, :math:`\sigma`, risk-free interest rate, :math:`r`, and annualised dividend yield, :math:`q`, are constants.
The integer parameters, :math:`j` and :math:`k`, take the values :math:`\pm 1`, depending on the type of barrier.
.. math::
\begin{array}{l} A = j S e^{{-qT}} \Phi \left(jx_1\right) - j X e^{{-rT}} \Phi \left(j\left[x_1-\sigma \sqrt{T}\right]\right) \\ B = j S e^{{-qT}} \Phi \left(jx_2\right) - j X e^{{-rT}} \Phi \left(j\left[x_2-\sigma \sqrt{T}\right]\right) \\ C = j S e^{{-qT}} \left(\frac{H}{S}\right)^{{2\left(\mu +1\right)}} \Phi \left(ky_1\right) - j X e^{{-rT}} \left(\frac{H}{S}\right)^{{2\mu }} \Phi \left(k\left[y_1-\sigma \sqrt{T}\right]\right) \\ D = j S e^{{-qT}} \left(\frac{H}{S}\right)^{{2\left(\mu +1\right)}} \Phi \left(ky_2\right) - j X e^{{-rT}} \left(\frac{H}{S}\right)^{{2\mu }} \Phi \left(k\left[y_2-\sigma \sqrt{T}\right]\right) \\ E = K e^{{-rT}} \left\{\Phi \left(k\left[x_2-\sigma \sqrt{T}\right]\right)-\left(\frac{H}{S}\right)^{{2\mu }}\Phi \left(k\left[y_2-\sigma \sqrt{T}\right]\right)\right\} \\ F = K \left\{\left(\frac{H}{S}\right)^{{\mu +\lambda }}\Phi \left(kz\right)+\left(\frac{H}{S}\right)^{{\mu -\lambda }}\Phi \left(k\left[z-\sigma \sqrt{T}\right]\right)\right\} \end{array}
with
.. math::
\begin{array}{l} x_1 = \frac{{\mathrm{ln}\left(S/X\right)}}{{\sigma \sqrt{T}}} + \left(1+\mu \right) \sigma \sqrt{T} \\ x_2 = \frac{{\mathrm{ln}\left(S/H\right)}}{{\sigma \sqrt{T}}} + \left(1+\mu \right) \sigma \sqrt{T} \\ y_1 = \frac{{\mathrm{ln}\left(H^2/\left(SX\right)\right)}}{{\sigma \sqrt{T}}} + \left(1+\mu \right)\sigma \sqrt{T} \\ y_2 = \frac{{\mathrm{ln}\left(H/S\right)}}{{\sigma \sqrt{T}}} + \left(1+\mu \right)\sigma \sqrt{T} \\ z = \frac{{\mathrm{ln}\left(H/S\right)}}{{\sigma \sqrt{T}}} + \lambda \sigma \sqrt{T} \\ \mu = \frac{{{r-q-\sigma }^2/2}}{\sigma^2} \\ \lambda = \sqrt{\mu^2+\frac{{2r}}{\sigma^2}} \end{array}
and where :math:`\Phi` denotes the cumulative Normal distribution function,
.. math::
\Phi \left(x\right) = \frac{1}{\sqrt{2\pi }}\int_{{-\infty }}^x\mathrm{exp}\left(-y^2/2\right)dy\text{.}
**Down-and-In (** :math:`S > H` **)**:
When :math:`X\geq H`, with :math:`j = k = 1`,
.. math::
P_{\mathrm{call}} = C+E
and with :math:`j = {-1}`, :math:`k = 1`
.. math::
P_{\mathrm{put}} = B-C+D+E
When :math:`X < H`, with :math:`j = k = 1`
.. math::
P_{\mathrm{call}} = A-B+D+E
and with :math:`j = {-1}`, :math:`k = 1`
.. math::
P_{\mathrm{put}} = A+E\text{.}
**Down-and-Out (** :math:`S > H` **)**:
When :math:`X\geq H`, with :math:`j = k = 1`,
.. math::
P_{\mathrm{call}} = A-C+F
and with :math:`j = {-1}`, :math:`k = 1`
.. math::
P_{\mathrm{put}} = A-B+C-D+F
When :math:`X < H`, with :math:`j = k = 1`,
.. math::
P_{\mathrm{call}} = B-D+F
and with :math:`j = {-1}`, :math:`k = 1`
.. math::
P_{\mathrm{put}} = F\text{.}
**Up-and-In (** :math:`S < H` **)**:
When :math:`X\geq H`, with :math:`j = 1`, :math:`k = {-1}`,
.. math::
P_{\mathrm{call}} = A+E
and with :math:`j = k = {-1}`,
.. math::
P_{\mathrm{put}} = A-B+D+E
When :math:`X < H`, with :math:`j = 1`, :math:`k = {-1}`,
.. math::
P_{\mathrm{call}} = B-C+D+E
and with :math:`j = k = {-1}`,
.. math::
P_{\mathrm{put}} = C+E\text{.}
**Up-and-Out (** :math:`S < H` **):**
When :math:`X\geq H`, with :math:`j = 1`, :math:`k = {-1}`,
.. math::
P_{\mathrm{call}} = F
and with :math:`j = k = {-1}`,
.. math::
P_{\mathrm{put}} = B-D+F
When :math:`X < H`, with :math:`j = 1`, :math:`k = {-1}`,
.. math::
P_{\mathrm{call}} = A-B+C-D+F
and with :math:`j = k = {-1}`,
.. math::
P_{\mathrm{put}} = A-C+F\text{.}
The option price :math:`P_{{ij}} = P\left({X = X_i}, {T = T_j}\right)` is computed for each strike price in a set :math:`X_i`, :math:`i = 1,2,\ldots,m`, and for each expiry time in a set :math:`T_j`, :math:`j = 1,2,\ldots,n`.
.. _s30fa-py2-py-references:
**References**
Haug, E G, 2007, `The Complete Guide to Option Pricing Formulas`, (2nd Edition), McGraw-Hill
"""
raise NotImplementedError
[docs]def opt_jumpdiff_merton_price(calput, x, s, t, sigma, r, lamda, jvol):
r"""
``opt_jumpdiff_merton_price`` computes the European option price using the Merton jump-diffusion model.
.. _s30ja-py2-py-doc:
For full information please refer to the NAG Library document for s30ja
https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s30jaf.html
.. _s30ja-py2-py-parameters:
**Parameters**
**calput** : str, length 1
Determines whether the option is a call or a put.
:math:`\mathrm{calput} = \text{‘C'}`
A call; the holder has a right to buy.
:math:`\mathrm{calput} = \text{‘P'}`
A put; the holder has a right to sell.
**x** : float, array-like, shape :math:`\left(m\right)`
:math:`\mathrm{x}[i-1]` must contain :math:`X_{\textit{i}}`, the :math:`\textit{i}`\ th strike price, for :math:`\textit{i} = 1,2,\ldots,m`.
**s** : float
:math:`S`, the price of the underlying asset.
**t** : float, array-like, shape :math:`\left(n\right)`
:math:`\mathrm{t}[i-1]` must contain :math:`T_{\textit{i}}`, the :math:`\textit{i}`\ th time, in years, to expiry, for :math:`\textit{i} = 1,2,\ldots,n`.
**sigma** : float
:math:`\sigma`, the annual total volatility, including jumps.
**r** : float
:math:`r`, the annual risk-free interest rate, continuously compounded. Note that a rate of 5% should be entered as :math:`0.05`.
**lamda** : float
:math:`\lambda`, the number of expected jumps per year.
**jvol** : float
The proportion of the total volatility associated with jumps.
**Returns**
**p** : float, ndarray, shape :math:`\left(m, n\right)`
:math:`\mathrm{p}[i-1,j-1]` contains :math:`P_{{ij}}`, the option price evaluated for the strike price :math:`\mathrm{x}_i` at expiry :math:`\mathrm{t}_j` for :math:`i = 1,2,\ldots,m` and :math:`j = 1,2,\ldots,n`.
.. _s30ja-py2-py-errors:
**Raises**
**NagValueError**
(`errno` :math:`1`)
On entry, :math:`\mathrm{calput} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{calput} = \text{‘C'} \text{ or } \text{‘P'}`.
(`errno` :math:`2`)
On entry, :math:`m = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`m\geq 1`.
(`errno` :math:`3`)
On entry, :math:`n = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`n\geq 1`.
(`errno` :math:`4`)
On entry, :math:`\mathrm{x}[\langle\mathit{\boldsymbol{value}}\rangle] = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{x}[i]\geq \langle\mathit{\boldsymbol{value}}\rangle` and :math:`\mathrm{x}[i]\leq \langle\mathit{\boldsymbol{value}}\rangle`.
(`errno` :math:`5`)
On entry, :math:`\mathrm{s} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{s}\geq \langle\mathit{\boldsymbol{value}}\rangle` and :math:`\mathrm{s}\leq \langle\mathit{\boldsymbol{value}}\rangle`.
(`errno` :math:`6`)
On entry, :math:`\mathrm{t}[\langle\mathit{\boldsymbol{value}}\rangle] = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{t}[i]\geq \langle\mathit{\boldsymbol{value}}\rangle`.
(`errno` :math:`7`)
On entry, :math:`\mathrm{sigma} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{sigma} > 0.0`.
(`errno` :math:`8`)
On entry, :math:`\mathrm{r} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{r}\geq 0.0`.
(`errno` :math:`9`)
On entry, :math:`\mathrm{lamda} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{lamda} > 0.0`.
(`errno` :math:`10`)
On entry, :math:`\mathrm{jvol} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{jvol}\geq 0.0` and :math:`\mathrm{jvol} < 1.0`.
.. _s30ja-py2-py-notes:
**Notes**
``opt_jumpdiff_merton_price`` uses Merton's jump-diffusion model (Merton (1976)) to compute the price of a European option.
This assumes that the asset price is described by a Brownian motion with drift, as in the Black--Scholes--Merton case, together with a compound Poisson process to model the jumps.
The corresponding stochastic differential equation is,
.. math::
\frac{{dS}}{{S}} = \left(\alpha -\lambda k\right)dt+\hat{\sigma }{dW}_t+{dq}_t\text{.}
Here :math:`\alpha` is the instantaneous expected return on the asset price, :math:`S`; :math:`\hat{\sigma }^2` is the instantaneous variance of the return when the Poisson event does not occur; :math:`{dW}_t` is a standard Brownian motion; :math:`q_t` is the independent Poisson process and :math:`k = E\left[Y-1\right]` where :math:`Y-1` is the random variable change in the stock price if the Poisson event occurs and :math:`E` is the expectation operator over the random variable :math:`Y`.
This leads to the following price for a European option (see Haug (2007))
.. math::
P_{\mathrm{call}} = \sum_{{j = 0}}^{{\infty }}\frac{{e^{{-\lambda T}}\left(\lambda T\right)^j}}{{j!}}C_j\left(S,X,T,r,\sigma_j^{\prime }\right)\text{,}
where :math:`T` is the time to expiry; :math:`X` is the strike price; :math:`r` is the annual risk-free interest rate; :math:`C_j\left(S,X,T,r,\sigma_j^{\prime }\right)` is the Black--Scholes--Merton option pricing formula for a European call (see :meth:`opt_bsm_price`).
.. math::
\begin{array}{l} \sigma_j^{\prime } = \sqrt{z^2+\delta^2\left(\frac{j}{T}\right)} \text{,} \\ z^2 = \sigma^2 - \lambda \delta^2 \text{,} \\ \delta^2 = \frac{{\gamma \sigma^2}}{{\lambda }} \text{,} \end{array}
where :math:`\sigma` is the total volatility including jumps; :math:`\lambda` is the expected number of jumps given as an average per year; :math:`\gamma` is the proportion of the total volatility due to jumps.
The value of a put is obtained by substituting the Black--Scholes--Merton put price for :math:`C_j\left(S,X,T,r,\sigma_j^{\prime }\right)`.
The option price :math:`P_{{ij}} = P\left({X = X_i}, {T = T_j}\right)` is computed for each strike price in a set :math:`X_i`, :math:`i = 1,2,\ldots,m`, and for each expiry time in a set :math:`T_j`, :math:`j = 1,2,\ldots,n`.
.. _s30ja-py2-py-references:
**References**
Haug, E G, 2007, `The Complete Guide to Option Pricing Formulas`, (2nd Edition), McGraw-Hill
Merton, R C, 1976, `Option pricing when underlying stock returns are discontinuous`, Journal of Financial Economics (3), 125--144
"""
raise NotImplementedError
[docs]def opt_jumpdiff_merton_greeks(calput, x, s, t, sigma, r, lamda, jvol):
r"""
``opt_jumpdiff_merton_greeks`` computes the European option price together with its sensitivities (Greeks) using the Merton jump-diffusion model.
.. _s30jb-py2-py-doc:
For full information please refer to the NAG Library document for s30jb
https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s30jbf.html
.. _s30jb-py2-py-parameters:
**Parameters**
**calput** : str, length 1
Determines whether the option is a call or a put.
:math:`\mathrm{calput} = \text{‘C'}`
A call; the holder has a right to buy.
:math:`\mathrm{calput} = \text{‘P'}`
A put; the holder has a right to sell.
**x** : float, array-like, shape :math:`\left(m\right)`
:math:`\mathrm{x}[i-1]` must contain :math:`X_{\textit{i}}`, the :math:`\textit{i}`\ th strike price, for :math:`\textit{i} = 1,2,\ldots,m`.
**s** : float
:math:`S`, the price of the underlying asset.
**t** : float, array-like, shape :math:`\left(n\right)`
:math:`\mathrm{t}[i-1]` must contain :math:`T_{\textit{i}}`, the :math:`\textit{i}`\ th time, in years, to expiry, for :math:`\textit{i} = 1,2,\ldots,n`.
**sigma** : float
:math:`\sigma`, the annual total volatility, including jumps.
**r** : float
:math:`r`, the annual risk-free interest rate, continuously compounded. Note that a rate of 5% should be entered as :math:`0.05`.
**lamda** : float
:math:`\lambda`, the number of expected jumps per year.
**jvol** : float
The proportion of the total volatility associated with jumps.
**Returns**
**p** : float, ndarray, shape :math:`\left(m, n\right)`
:math:`\mathrm{p}[i-1,j-1]` contains :math:`P_{{ij}}`, the option price evaluated for the strike price :math:`\mathrm{x}_i` at expiry :math:`\mathrm{t}_j` for :math:`i = 1,2,\ldots,m` and :math:`j = 1,2,\ldots,n`.
**delta** : float, ndarray, shape :math:`\left(m, n\right)`
The leading :math:`m\times n` part of the array :math:`\mathrm{delta}` contains the sensitivity, :math:`\frac{{\partial P}}{{\partial S}}`, of the option price to change in the price of the underlying asset.
**gamma** : float, ndarray, shape :math:`\left(m, n\right)`
The leading :math:`m\times n` part of the array :math:`\mathrm{gamma}` contains the sensitivity, :math:`\frac{{\partial^2P}}{{\partial S^2}}`, of :math:`\mathrm{delta}` to change in the price of the underlying asset.
**vega** : float, ndarray, shape :math:`\left(m, n\right)`
:math:`\mathrm{vega}[i-1,j-1]`, contains the first-order Greek measuring the sensitivity of the option price :math:`P_{{ij}}` to change in the volatility of the underlying asset, i.e., :math:`\frac{{\partial P_{{ij}}}}{{\partial \sigma }}`, for :math:`i = 1,2,\ldots,m` and :math:`j = 1,2,\ldots,n`.
**theta** : float, ndarray, shape :math:`\left(m, n\right)`
:math:`\mathrm{theta}[i-1,j-1]`, contains the first-order Greek measuring the sensitivity of the option price :math:`P_{{ij}}` to change in time, i.e., :math:`-\frac{{\partial P_{{ij}}}}{{\partial T}}`, for :math:`i = 1,2,\ldots,m` and :math:`j = 1,2,\ldots,n`, where :math:`b = r-q`.
**rho** : float, ndarray, shape :math:`\left(m, n\right)`
:math:`\mathrm{rho}[i-1,j-1]`, contains the first-order Greek measuring the sensitivity of the option price :math:`P_{{ij}}` to change in the annual risk-free interest rate, i.e., :math:`-\frac{{\partial P_{{ij}}}}{{\partial r}}`, for :math:`i = 1,2,\ldots,m` and :math:`j = 1,2,\ldots,n`.
**vanna** : float, ndarray, shape :math:`\left(m, n\right)`
:math:`\mathrm{vanna}[i-1,j-1]`, contains the second-order Greek measuring the sensitivity of the first-order Greek :math:`\Delta_{{ij}}` to change in the volatility of the asset price, i.e., :math:`-\frac{{\partial \Delta_{{ij}}}}{{\partial T}} = -\frac{{\partial^2P_{{ij}}}}{{\partial S\partial \sigma }}`, for :math:`i = 1,2,\ldots,m` and :math:`j = 1,2,\ldots,n`.
**charm** : float, ndarray, shape :math:`\left(m, n\right)`
:math:`\mathrm{charm}[i-1,j-1]`, contains the second-order Greek measuring the sensitivity of the first-order Greek :math:`\Delta_{{ij}}` to change in the time, i.e., :math:`-\frac{{\partial \Delta_{{ij}}}}{{\partial T}} = -\frac{{\partial^2P_{{ij}}}}{{\partial S\partial T}}`, for :math:`i = 1,2,\ldots,m` and :math:`j = 1,2,\ldots,n`.
**speed** : float, ndarray, shape :math:`\left(m, n\right)`
:math:`\mathrm{speed}[i-1,j-1]`, contains the third-order Greek measuring the sensitivity of the second-order Greek :math:`\Gamma_{{ij}}` to change in the price of the underlying asset, i.e., :math:`-\frac{{\partial \Gamma_{{ij}}}}{{\partial S}} = -\frac{{\partial^3P_{{ij}}}}{{\partial S^3}}`, for :math:`i = 1,2,\ldots,m` and :math:`j = 1,2,\ldots,n`.
**colour** : float, ndarray, shape :math:`\left(m, n\right)`
:math:`\mathrm{colour}[i-1,j-1]`, contains the third-order Greek measuring the sensitivity of the second-order Greek :math:`\Gamma_{{ij}}` to change in the time, i.e., :math:`-\frac{{\partial \Gamma_{{ij}}}}{{\partial T}} = -\frac{{\partial^3P_{{ij}}}}{{\partial S\partial T}}`, for :math:`i = 1,2,\ldots,m` and :math:`j = 1,2,\ldots,n`.
**zomma** : float, ndarray, shape :math:`\left(m, n\right)`
:math:`\mathrm{zomma}[i-1,j-1]`, contains the third-order Greek measuring the sensitivity of the second-order Greek :math:`\Gamma_{{ij}}` to change in the volatility of the underlying asset, i.e., :math:`-\frac{{\partial \Gamma_{{ij}}}}{{\partial \sigma }} = -\frac{{\partial^3P_{{ij}}}}{{\partial S^2\partial \sigma }}`, for :math:`i = 1,2,\ldots,m` and :math:`j = 1,2,\ldots,n`.
**vomma** : float, ndarray, shape :math:`\left(m, n\right)`
:math:`\mathrm{vomma}[i-1,j-1]`, contains the second-order Greek measuring the sensitivity of the first-order Greek :math:`\Delta_{{ij}}` to change in the volatility of the underlying asset, i.e., :math:`-\frac{{\partial \Delta_{{ij}}}}{{\partial \sigma }} = -\frac{{\partial^2P_{{ij}}}}{{\partial \sigma^2}}`, for :math:`i = 1,2,\ldots,m` and :math:`j = 1,2,\ldots,n`.
.. _s30jb-py2-py-errors:
**Raises**
**NagValueError**
(`errno` :math:`1`)
On entry, :math:`\mathrm{calput} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{calput} = \text{‘C'} \text{ or } \text{‘P'}`.
(`errno` :math:`2`)
On entry, :math:`m = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`m\geq 1`.
(`errno` :math:`3`)
On entry, :math:`n = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`n\geq 1`.
(`errno` :math:`4`)
On entry, :math:`\mathrm{x}[\langle\mathit{\boldsymbol{value}}\rangle] = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{x}[i]\geq \langle\mathit{\boldsymbol{value}}\rangle` and :math:`\mathrm{x}[i]\leq \langle\mathit{\boldsymbol{value}}\rangle`.
(`errno` :math:`5`)
On entry, :math:`\mathrm{s} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{s}\geq \langle\mathit{\boldsymbol{value}}\rangle` and :math:`\mathrm{s}\leq \langle\mathit{\boldsymbol{value}}\rangle`.
(`errno` :math:`6`)
On entry, :math:`\mathrm{t}[\langle\mathit{\boldsymbol{value}}\rangle] = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{t}[i]\geq \langle\mathit{\boldsymbol{value}}\rangle`.
(`errno` :math:`7`)
On entry, :math:`\mathrm{sigma} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{sigma} > 0.0`.
(`errno` :math:`8`)
On entry, :math:`\mathrm{r} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{r}\geq 0.0`.
(`errno` :math:`9`)
On entry, :math:`\mathrm{lamda} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{lamda} > 0.0`.
(`errno` :math:`10`)
On entry, :math:`\mathrm{jvol} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{jvol}\geq 0.0` and :math:`\mathrm{jvol} < 1.0`.
.. _s30jb-py2-py-notes:
**Notes**
``opt_jumpdiff_merton_greeks`` uses Merton's jump-diffusion model (Merton (1976)) to compute the price of a European option, together with the Greeks or sensitivities, which are the partial derivatives of the option price with respect to certain of the other input parameters.
Merton's model assumes that the asset price is described by a Brownian motion with drift, as in the Black--Scholes--Merton case, together with a compound Poisson process to model the jumps.
The corresponding stochastic differential equation is,
.. math::
\frac{{dS}}{{S}} = \left(\alpha -\lambda k\right)dt+\hat{\sigma }{dW}_t+{dq}_t\text{.}
Here :math:`\alpha` is the instantaneous expected return on the asset price, :math:`S`; :math:`\hat{\sigma }^2` is the instantaneous variance of the return when the Poisson event does not occur; :math:`{dW}_t` is a standard Brownian motion; :math:`q_t` is the independent Poisson process and :math:`k = E\left[Y-1\right]` where :math:`Y-1` is the random variable change in the stock price if the Poisson event occurs and :math:`E` is the expectation operator over the random variable :math:`Y`.
This leads to the following price for a European option (see Haug (2007))
.. math::
P_{\mathrm{call}} = \sum_{{j = 0}}^{{\infty }}\frac{{e^{{-\lambda T}}\left(\lambda T\right)^j}}{{j!}}C_j\left(S,X,T,r,\sigma_j^{\prime }\right)\text{,}
where :math:`T` is the time to expiry; :math:`X` is the strike price; :math:`r` is the annual risk-free interest rate; :math:`C_j\left(S,X,T,r,\sigma_j^{\prime }\right)` is the Black--Scholes--Merton option pricing formula for a European call (see :meth:`opt_bsm_price`).
.. math::
\begin{array}{l} \sigma_j^{\prime } = \sqrt{z^2+\delta^2\left(\frac{j}{T}\right)} \text{,} \\\\ z^2 = \sigma^2 - \lambda \delta^2 \text{,} \\\\ \delta^2 = \frac{{\gamma \sigma^2}}{{\lambda }} \text{,} \end{array}
where :math:`\sigma` is the total volatility including jumps; :math:`\lambda` is the expected number of jumps given as an average per year; :math:`\gamma` is the proportion of the total volatility due to jumps.
The value of a put is obtained by substituting the Black--Scholes--Merton put price for :math:`C_j\left(S,X,T,r,\sigma_j^{\prime }\right)`.
The option price :math:`P_{{ij}} = P\left({X = X_i}, {T = T_j}\right)` is computed for each strike price in a set :math:`X_i`, :math:`i = 1,2,\ldots,m`, and for each expiry time in a set :math:`T_j`, :math:`j = 1,2,\ldots,n`.
.. _s30jb-py2-py-references:
**References**
Haug, E G, 2007, `The Complete Guide to Option Pricing Formulas`, (2nd Edition), McGraw-Hill
Merton, R C, 1976, `Option pricing when underlying stock returns are discontinuous`, Journal of Financial Economics (3), 125--144
"""
raise NotImplementedError
[docs]def opt_heston_price(calput, x, s, t, sigmav, kappa, corr, var0, eta, grisk, r, q):
r"""
``opt_heston_price`` computes the European option price given by Heston's stochastic volatility model.
.. _s30na-py2-py-doc:
For full information please refer to the NAG Library document for s30na
https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s30naf.html
.. _s30na-py2-py-parameters:
**Parameters**
**calput** : str, length 1
Determines whether the option is a call or a put.
:math:`\mathrm{calput} = \text{‘C'}`
A call; the holder has a right to buy.
:math:`\mathrm{calput} = \text{‘P'}`
A put; the holder has a right to sell.
**x** : float, array-like, shape :math:`\left(m\right)`
:math:`\mathrm{x}[i-1]` must contain :math:`X_{\textit{i}}`, the :math:`\textit{i}`\ th strike price, for :math:`\textit{i} = 1,2,\ldots,m`.
**s** : float
:math:`S`, the price of the underlying asset.
**t** : float, array-like, shape :math:`\left(n\right)`
:math:`\mathrm{t}[i-1]` must contain :math:`T_{\textit{i}}`, the :math:`\textit{i}`\ th time, in years, to expiry, for :math:`\textit{i} = 1,2,\ldots,n`.
**sigmav** : float
The volatility, :math:`\sigma_v`, of the volatility process, :math:`\sqrt{v_t}`. Note that a rate of 20% should be entered as :math:`0.2`.
**kappa** : float
:math:`\kappa`, the long term mean reversion rate of the volatility.
**corr** : float
The correlation between the two standard Brownian motions for the asset price and the volatility.
**var0** : float
The initial value of the variance, :math:`v_t`, of the asset price.
**eta** : float
:math:`\eta`, the long term mean of the variance of the asset price.
**grisk** : float
The risk aversion parameter, :math:`\gamma`, of the representative agent.
**r** : float
:math:`r`, the annual risk-free interest rate, continuously compounded. Note that a rate of 5% should be entered as :math:`0.05`.
**q** : float
:math:`q`, the annual continuous yield rate. Note that a rate of 8% should be entered as :math:`0.08`.
**Returns**
**p** : float, ndarray, shape :math:`\left(m, n\right)`
:math:`\mathrm{p}[i-1,j-1]` contains :math:`P_{{ij}}`, the option price evaluated for the strike price :math:`\mathrm{x}_i` at expiry :math:`\mathrm{t}_j` for :math:`i = 1,2,\ldots,m` and :math:`j = 1,2,\ldots,n`.
.. _s30na-py2-py-errors:
**Raises**
**NagValueError**
(`errno` :math:`1`)
On entry, :math:`\mathrm{calput} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{calput} = \text{‘C'} \text{ or } \text{‘P'}`.
(`errno` :math:`2`)
On entry, :math:`m = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`m\geq 1`.
(`errno` :math:`3`)
On entry, :math:`n = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`n\geq 1`.
(`errno` :math:`4`)
On entry, :math:`\mathrm{x}[\langle\mathit{\boldsymbol{value}}\rangle] = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{x}[i-1]\geq \langle\mathit{\boldsymbol{value}}\rangle` and :math:`\mathrm{x}[i-1]\leq \langle\mathit{\boldsymbol{value}}\rangle`.
(`errno` :math:`5`)
On entry, :math:`\mathrm{s} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{s}\geq \langle\mathit{\boldsymbol{value}}\rangle` and :math:`\mathrm{s}\leq \langle\mathit{\boldsymbol{value}}\rangle`.
(`errno` :math:`6`)
On entry, :math:`\mathrm{t}[\langle\mathit{\boldsymbol{value}}\rangle] = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{t}[i-1]\geq \langle\mathit{\boldsymbol{value}}\rangle`.
(`errno` :math:`7`)
On entry, :math:`\mathrm{sigmav} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{sigmav} > 0.0`.
(`errno` :math:`8`)
On entry, :math:`\mathrm{kappa} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{kappa} > 0.0`.
(`errno` :math:`9`)
On entry, :math:`\mathrm{corr} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\left\lvert \mathrm{corr}\right\rvert \leq 1.0`.
(`errno` :math:`10`)
On entry, :math:`\mathrm{var0} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{var0}\geq 0.0`.
(`errno` :math:`11`)
On entry, :math:`\mathrm{eta} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{eta} > 0.0`.
(`errno` :math:`12`)
On entry, :math:`\mathrm{grisk} = \langle\mathit{\boldsymbol{value}}\rangle`, :math:`\mathrm{sigmav} = \langle\mathit{\boldsymbol{value}}\rangle` and :math:`\mathrm{kappa} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`0.0\leq \mathrm{grisk}\leq 1.0` and :math:`\mathrm{grisk}\times \left(1.0-\mathrm{grisk}\right)\times \mathrm{sigmav}^2\leq \mathrm{kappa}^2`.
(`errno` :math:`13`)
On entry, :math:`\mathrm{r} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{r}\geq 0.0`.
(`errno` :math:`14`)
On entry, :math:`\mathrm{q} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{q}\geq 0.0`.
**Warns**
**NagAlgorithmicWarning**
(`errno` :math:`17`)
Quadrature has not converged to the specified accuracy. However, the result should be a reasonable approximation.
(`errno` :math:`18`)
Solution cannot be computed accurately. Check values of input arguments.
.. _s30na-py2-py-notes:
**Notes**
``opt_heston_price`` computes the price of a European option using Heston's stochastic volatility model.
The return on the asset price, :math:`S`, is
.. math::
\frac{{dS}}{S} = \left(r-q\right)dt+\sqrt{v_t}dW_t^{\left(1\right)}
and the instantaneous variance, :math:`v_t`, is defined by a mean-reverting square root stochastic process,
.. math::
dv_t = \kappa \left(\eta -v_t\right)dt+\sigma_v\sqrt{v_t}dW_t^{\left(2\right)}\text{,}
where :math:`r` is the risk free annual interest rate; :math:`q` is the annual dividend rate; :math:`v_t` is the variance of the asset price; :math:`\sigma_v` is the volatility of the volatility, :math:`\sqrt{v_t}`; :math:`\kappa` is the mean reversion rate; :math:`\eta` is the long term variance. :math:`dW_t^{\left(\textit{i}\right)}`, for :math:`\textit{i} = 1,2,\ldots,2`, denotes two correlated standard Brownian motions with
.. math::
\mathrm{ℂov}\left[{dW_t^{\left(1\right)}}, {dW_t^{\left(2\right)}}\right] = \rho dt\text{.}
The option price is computed by evaluating the integral transform given by Lewis (2000) using the form of the characteristic function discussed by Albrecher `et al.` (2007), see also Kilin (2006).
.. math::
P_{\mathrm{call}} = Se^{{-qT}}-Xe^{{-rT}}\frac{1}{\pi }\mathrm{Re}\left[\int_{{0+i/2}}^{{\infty +i/2}}e^{{-ik\bar{X}}}\frac{{\hat{H}\left(k, v, T\right)}}{{k^2-ik}}\mathrm{d}k\right]\text{,}
where :math:`\bar{X} = \mathrm{ln}\left(S/X\right)+\left(r-q\right)T` and
.. math::
\hat{H}\left(k, v, T\right) = \mathrm{exp}\left(\frac{{2\kappa \eta }}{\sigma_v^2}\left[t\textit{g }-\mathrm{ln}\left(\frac{{1-he^{{-\xi t}}}}{{1-h}}\right)\right]+v_tg\left[\frac{{1-e^{{-\xi t}}}}{{1-he^{{-\xi t}}}}\right]\right)\text{,}
.. math::
g = \frac{1}{2}\left(b-\xi \right)\text{, }\quad h = \frac{{b-\xi }}{{b+\xi }}\text{, }\quad t = \sigma_v^2T/2\text{,}
.. math::
\xi = \left[b^2+4\frac{{k^2-ik}}{{\sigma_v^2}}\right]^{\frac{1}{2}}\text{,}
.. math::
b = \frac{2}{{\sigma_v^2}}\left[\left(1-\gamma +ik\right)\rho \sigma_v+\sqrt{\kappa^2-\gamma \left(1-\gamma \right)\sigma_v^2}\right]
with :math:`t = \sigma_v^2T/2`.
Here :math:`\gamma` is the risk aversion parameter of the representative agent with :math:`0\leq \gamma \leq 1` and :math:`\gamma \left(1-\gamma \right)\sigma_v^2\leq \kappa^2`.
The value :math:`\gamma = 1` corresponds to :math:`\lambda = 0`, where :math:`\lambda` is the market price of risk in Heston (1993) (see Lewis (2000) and Rouah and Vainberg (2007)).
The price of a put option is obtained by put-call parity.
The option price :math:`P_{{ij}} = P\left({X = X_i}, {T = T_j}\right)` is computed for each strike price in a set :math:`X_i`, :math:`i = 1,2,\ldots,m`, and for each expiry time in a set :math:`T_j`, :math:`j = 1,2,\ldots,n`.
.. _s30na-py2-py-references:
**References**
Albrecher, H, Mayer, P, Schoutens, W and Tistaert, J, 2007, `The little Heston trap`, Wilmott Magazine (January 2007), 83--92
Heston, S, 1993, `A closed-form solution for options with stochastic volatility with applications to bond and currency options`, Review of Financial Studies (6), 327--343
Kilin, F, 2006, `Accelerating the calibration of stochastic volatility models`, MPRA Paper No. 2975, https://mpra.ub.uni-muenchen.de/2975/
Lewis, A L, 2000, `Option valuation under stochastic volatility`, Finance Press, USA
Rouah, F D and Vainberg, G, 2007, `Option Pricing Models and Volatility using Excel-VBA`, John Wiley and Sons, Inc
"""
raise NotImplementedError
[docs]def opt_heston_greeks(calput, x, s, t, sigmav, kappa, corr, var0, eta, grisk, r, q):
r"""
``opt_heston_greeks`` computes the European option price given by Heston's stochastic volatility model together with its sensitivities (Greeks).
.. _s30nb-py2-py-doc:
For full information please refer to the NAG Library document for s30nb
https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s30nbf.html
.. _s30nb-py2-py-parameters:
**Parameters**
**calput** : str, length 1
Determines whether the option is a call or a put.
:math:`\mathrm{calput} = \text{‘C'}`
A call; the holder has a right to buy.
:math:`\mathrm{calput} = \text{‘P'}`
A put; the holder has a right to sell.
**x** : float, array-like, shape :math:`\left(m\right)`
:math:`\mathrm{x}[i-1]` must contain :math:`X_{\textit{i}}`, the :math:`\textit{i}`\ th strike price, for :math:`\textit{i} = 1,2,\ldots,m`.
**s** : float
:math:`S`, the price of the underlying asset.
**t** : float, array-like, shape :math:`\left(n\right)`
:math:`\mathrm{t}[i-1]` must contain :math:`T_{\textit{i}}`, the :math:`\textit{i}`\ th time, in years, to expiry, for :math:`\textit{i} = 1,2,\ldots,n`.
**sigmav** : float
The volatility, :math:`\sigma_v`, of the volatility process, :math:`\sqrt{v_t}`. Note that a rate of 20% should be entered as :math:`0.2`.
**kappa** : float
:math:`\kappa`, the long term mean reversion rate of the volatility.
**corr** : float
The correlation between the two standard Brownian motions for the asset price and the volatility.
**var0** : float
The initial value of the variance, :math:`v_t`, of the asset price.
**eta** : float
:math:`\eta`, the long term mean of the variance of the asset price.
**grisk** : float
The risk aversion parameter, :math:`\gamma`, of the representative agent.
**r** : float
:math:`r`, the annual risk-free interest rate, continuously compounded. Note that a rate of 5% should be entered as :math:`0.05`.
**q** : float
:math:`q`, the annual continuous yield rate. Note that a rate of 8% should be entered as :math:`0.08`.
**Returns**
**p** : float, ndarray, shape :math:`\left(m, n\right)`
:math:`\mathrm{p}[i-1,j-1]` contains :math:`P_{{ij}}`, the option price evaluated for the strike price :math:`\mathrm{x}_i` at expiry :math:`\mathrm{t}_j` for :math:`i = 1,2,\ldots,m` and :math:`j = 1,2,\ldots,n`.
**delta** : float, ndarray, shape :math:`\left(m, n\right)`
The leading :math:`m\times n` part of the array :math:`\mathrm{delta}` contains the sensitivity, :math:`\frac{{\partial P}}{{\partial S}}`, of the option price to change in the price of the underlying asset.
**gamma** : float, ndarray, shape :math:`\left(m, n\right)`
The leading :math:`m\times n` part of the array :math:`\mathrm{gamma}` contains the sensitivity, :math:`\frac{{\partial^2P}}{{\partial S^2}}`, of :math:`\mathrm{delta}` to change in the price of the underlying asset.
**vega** : float, ndarray, shape :math:`\left(m, n\right)`
:math:`\mathrm{vega}[i-1,j-1]`, contains the first-order Greek measuring the sensitivity of the option price :math:`P_{{ij}}` to change in the volatility of the underlying asset, i.e., :math:`\frac{{\partial P_{{ij}}}}{{\partial \sigma }}`, for :math:`i = 1,2,\ldots,m` and :math:`j = 1,2,\ldots,n`.
**theta** : float, ndarray, shape :math:`\left(m, n\right)`
:math:`\mathrm{theta}[i-1,j-1]`, contains the first-order Greek measuring the sensitivity of the option price :math:`P_{{ij}}` to change in time, i.e., :math:`-\frac{{\partial P_{{ij}}}}{{\partial T}}`, for :math:`i = 1,2,\ldots,m` and :math:`j = 1,2,\ldots,n`, where :math:`b = r-q`.
**rho** : float, ndarray, shape :math:`\left(m, n\right)`
:math:`\mathrm{rho}[i-1,j-1]`, contains the first-order Greek measuring the sensitivity of the option price :math:`P_{{ij}}` to change in the annual risk-free interest rate, i.e., :math:`\frac{{\partial P_{{ij}}}}{{\partial r}}`, for :math:`i = 1,2,\ldots,m` and :math:`j = 1,2,\ldots,n`.
**vanna** : float, ndarray, shape :math:`\left(m, n\right)`
:math:`\mathrm{vanna}[i-1,j-1]`, contains the second-order Greek measuring the sensitivity of the first-order Greek :math:`\Delta_{{ij}}` to change in the volatility of the asset price, i.e., :math:`\frac{{\partial \Delta_{{ij}}}}{{\partial \sigma }} = \frac{{\partial^2P_{{ij}}}}{{\partial S\partial \sigma }}`, for :math:`i = 1,2,\ldots,m` and :math:`j = 1,2,\ldots,n`.
**charm** : float, ndarray, shape :math:`\left(m, n\right)`
:math:`\mathrm{charm}[i-1,j-1]`, contains the second-order Greek measuring the sensitivity of the first-order Greek :math:`\Delta_{{ij}}` to change in the time, i.e., :math:`-\frac{{\partial \Delta_{{ij}}}}{{\partial T}} = -\frac{{\partial^2P_{{ij}}}}{{\partial S\partial T}}`, for :math:`i = 1,2,\ldots,m` and :math:`j = 1,2,\ldots,n`.
**speed** : float, ndarray, shape :math:`\left(m, n\right)`
:math:`\mathrm{speed}[i-1,j-1]`, contains the third-order Greek measuring the sensitivity of the second-order Greek :math:`\Gamma_{{ij}}` to change in the price of the underlying asset, i.e., :math:`\frac{{\partial \Gamma_{{ij}}}}{{\partial S}} = \frac{{\partial^3P_{{ij}}}}{{\partial S^3}}`, for :math:`i = 1,2,\ldots,m` and :math:`j = 1,2,\ldots,n`.
**zomma** : float, ndarray, shape :math:`\left(m, n\right)`
:math:`\mathrm{zomma}[i-1,j-1]`, contains the third-order Greek measuring the sensitivity of the second-order Greek :math:`\Gamma_{{ij}}` to change in the volatility of the underlying asset, i.e., :math:`\frac{{\partial \Gamma_{{ij}}}}{{\partial \sigma }} = \frac{{\partial^3P_{{ij}}}}{{\partial S^2\partial \sigma }}`, for :math:`i = 1,2,\ldots,m` and :math:`j = 1,2,\ldots,n`.
**vomma** : float, ndarray, shape :math:`\left(m, n\right)`
:math:`\mathrm{vomma}[i-1,j-1]`, contains the second-order Greek measuring the sensitivity of the option price :math:`P_{{ij}}` to second-order changes in the volatility of the underlying asset, i.e., :math:`\frac{{\partial^2P_{{ij}}}}{{\partial \sigma^2}}`, for :math:`i = 1,2,\ldots,m` and :math:`j = 1,2,\ldots,n`.
.. _s30nb-py2-py-errors:
**Raises**
**NagValueError**
(`errno` :math:`1`)
On entry, :math:`\mathrm{calput} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{calput} = \text{‘C'} \text{ or } \text{‘P'}`.
(`errno` :math:`2`)
On entry, :math:`m = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`m\geq 1`.
(`errno` :math:`3`)
On entry, :math:`n = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`n\geq 1`.
(`errno` :math:`4`)
On entry, :math:`\mathrm{x}[\langle\mathit{\boldsymbol{value}}\rangle] = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{x}[i-1]\geq \langle\mathit{\boldsymbol{value}}\rangle` and :math:`\mathrm{x}[i-1]\leq \langle\mathit{\boldsymbol{value}}\rangle`.
(`errno` :math:`5`)
On entry, :math:`\mathrm{s} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{s}\geq \langle\mathit{\boldsymbol{value}}\rangle` and :math:`\mathrm{s}\leq \langle\mathit{\boldsymbol{value}}\rangle`.
(`errno` :math:`6`)
On entry, :math:`\mathrm{t}[\langle\mathit{\boldsymbol{value}}\rangle] = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{t}[i-1]\geq \langle\mathit{\boldsymbol{value}}\rangle`.
(`errno` :math:`7`)
On entry, :math:`\mathrm{sigmav} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{sigmav} > 0.0`.
(`errno` :math:`8`)
On entry, :math:`\mathrm{kappa} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{kappa} > 0.0`.
(`errno` :math:`9`)
On entry, :math:`\mathrm{corr} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\left\lvert \mathrm{corr}\right\rvert \leq 1.0`.
(`errno` :math:`10`)
On entry, :math:`\mathrm{var0} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{var0}\geq 0.0`.
(`errno` :math:`11`)
On entry, :math:`\mathrm{eta} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{eta} > 0.0`.
(`errno` :math:`12`)
On entry, :math:`\mathrm{grisk} = \langle\mathit{\boldsymbol{value}}\rangle`, :math:`\mathrm{sigmav} = \langle\mathit{\boldsymbol{value}}\rangle` and :math:`\mathrm{kappa} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`0.0\leq \mathrm{grisk}\leq 1.0` and :math:`\mathrm{grisk}\times \left(1.0-\mathrm{grisk}\right)\times \mathrm{sigmav}^2\leq \mathrm{kappa}^2`.
(`errno` :math:`13`)
On entry, :math:`\mathrm{r} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{r}\geq 0.0`.
(`errno` :math:`14`)
On entry, :math:`\mathrm{q} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{q}\geq 0.0`.
**Warns**
**NagAlgorithmicWarning**
(`errno` :math:`17`)
Quadrature has not converged to the required accuracy. However, the result should be a reasonable approximation.
(`errno` :math:`18`)
Solution cannot be computed accurately. Check values of input arguments.
.. _s30nb-py2-py-notes:
**Notes**
``opt_heston_greeks`` computes the price and sensitivities of a European option using Heston's stochastic volatility model.
The return on the asset price, :math:`S`, is
.. math::
\frac{{dS}}{S} = \left(r-q\right)dt+\sqrt{v_t}dW_t^{\left(1\right)}
and the instantaneous variance, :math:`v_t`, is defined by a mean-reverting square root stochastic process,
.. math::
dv_t = \kappa \left(\eta -v_t\right)dt+\sigma_v\sqrt{v_t}dW_t^{\left(2\right)}\text{,}
where :math:`r` is the risk free annual interest rate; :math:`q` is the annual dividend rate; :math:`v_t` is the variance of the asset price; :math:`\sigma_v` is the volatility of the volatility, :math:`\sqrt{v_t}`; :math:`\kappa` is the mean reversion rate; :math:`\eta` is the long term variance. :math:`dW_t^{\left(\textit{i}\right)}`, for :math:`\textit{i} = 1,2,\ldots,2`, denotes two correlated standard Brownian motions with
.. math::
\mathrm{ℂov}\left[{dW_t^{\left(1\right)}}, {dW_t^{\left(2\right)}}\right] = \rho dt\text{.}
The option price is computed by evaluating the integral transform given by Lewis (2000) using the form of the characteristic function discussed by Albrecher `et al.` (2007), see also Kilin (2006).
.. math::
P_{\mathrm{call}} = Se^{{-qT}}-Xe^{{-rT}}\frac{1}{\pi }\mathrm{Re}\left[\int_{{0+i/2}}^{{\infty +i/2}}e^{{-ik\bar{X}}}\frac{{\hat{H}\left(k, v, T\right)}}{{k^2-ik}}\mathrm{d}k\right]\text{,}
where :math:`\bar{X} = \mathrm{ln}\left(S/X\right)+\left(r-q\right)T` and
.. math::
\hat{H}\left(k, v, T\right) = \mathrm{exp}\left(\frac{{2\kappa \eta }}{\sigma_v^2}\left[t\textit{g }-\mathrm{ln}\left(\frac{{1-he^{{-\xi t}}}}{{1-h}}\right)\right]+v_tg\left[\frac{{1-e^{{-\xi t}}}}{{1-he^{{-\xi t}}}}\right]\right)\text{,}
.. math::
g = \frac{1}{2}\left(b-\xi \right)\text{, }\quad h = \frac{{b-\xi }}{{b+\xi }}\text{, }\quad t = \sigma_v^2T/2\text{,}
.. math::
\xi = \left[b^2+4\frac{{k^2-ik}}{{\sigma_v^2}}\right]^{\frac{1}{2}}\text{,}
.. math::
b = \frac{2}{{\sigma_v^2}}\left[\left(1-\gamma +ik\right)\rho \sigma_v+\sqrt{\kappa^2-\gamma \left(1-\gamma \right)\sigma_v^2}\right]
with :math:`t = \sigma_v^2T/2`.
Here :math:`\gamma` is the risk aversion parameter of the representative agent with :math:`0\leq \gamma \leq 1` and :math:`\gamma \left(1-\gamma \right)\sigma_v^2\leq \kappa^2`.
The value :math:`\gamma = 1` corresponds to :math:`\lambda = 0`, where :math:`\lambda` is the market price of risk in Heston (1993) (see Lewis (2000) and Rouah and Vainberg (2007)).
The price of a put option is obtained by put-call parity.
.. math::
P_{\mathrm{put}} = P_{\mathrm{call}}+Xe^{{-rT}}-Se^{{-qT}}\text{.}
Writing the expression for the price of a call option as
.. math::
P_{\mathrm{call}} = Se^{{-qT}}-Xe^{{-rT}}\frac{1}{\pi }\mathrm{Re}\left[\int_{{0+i/2}}^{{\infty +i/2}}I\left(k, r, S, T, v\right)\mathrm{d}k\right]
then the sensitivities or Greeks can be obtained in the following manner,
Delta
.. math::
\frac{{\partial P_{\mathrm{call}}}}{{\partial S}} = e^{{-qT}}+\frac{{Xe^{{-rT}}}}{S}\frac{1}{\pi }\mathrm{Re}\left[\int_{{0+i/2}}^{{\infty +i/2}}\left(ik\right)I\left(k, r, S, T, v\right)\mathrm{d}k\right]\text{,}
Vega
.. math::
\frac{{\partial P}}{{\partial v}} = -Xe^{{-rT}}\frac{1}{\pi }\mathrm{Re}\left[\int_{{0-i/2}}^{{0+i/2}}f_2I\left(k, r, j, S, T, v\right)\mathrm{d}k\right]\text{, where }f_2 = g\left[\frac{{1-e^{{-\xi t}}}}{{1-he^{{-\xi t}}}}\right]\text{,}
Rho
.. math::
\frac{{\partial P_{\mathrm{call}}}}{{\partial r}} = TXe^{{-rT}}\frac{1}{\pi }\mathrm{Re}\left[\int_{{0+i/2}}^{{\infty +i/2}}\left(1+ik\right)I\left(k, r, S, T, v\right)\mathrm{d}k\right]\text{.}
The option price :math:`P_{{ij}} = P\left({X = X_i}, {T = T_j}\right)` is computed for each strike price in a set :math:`X_i`, :math:`i = 1,2,\ldots,m`, and for each expiry time in a set :math:`T_j`, :math:`j = 1,2,\ldots,n`.
.. _s30nb-py2-py-references:
**References**
Albrecher, H, Mayer, P, Schoutens, W and Tistaert, J, 2007, `The little Heston trap`, Wilmott Magazine (January 2007), 83--92
Heston, S, 1993, `A closed-form solution for options with stochastic volatility with applications to bond and currency options`, Review of Financial Studies (6), 327--343
Kilin, F, 2006, `Accelerating the calibration of stochastic volatility models`, MPRA Paper No. 2975, https://mpra.ub.uni-muenchen.de/2975/
Lewis, A L, 2000, `Option valuation under stochastic volatility`, Finance Press, USA
Rouah, F D and Vainberg, G, 2007, `Option Pricing Models and Volatility using Excel-VBA`, John Wiley and Sons, Inc
"""
raise NotImplementedError
[docs]def opt_heston_term(calput, x, fwd, disc, ts, t, alpha, lamda, corr, sigmat, var0):
r"""
``opt_heston_term`` computes the European option price given by Heston's stochastic volatility model with term structure.
.. _s30nc-py2-py-doc:
For full information please refer to the NAG Library document for s30nc
https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s30ncf.html
.. _s30nc-py2-py-parameters:
**Parameters**
**calput** : str, length 1
Determines whether the option is a call or a put.
:math:`\mathrm{calput} = \text{‘C'}`
A call; the holder has a right to buy.
:math:`\mathrm{calput} = \text{‘P'}`
A put; the holder has a right to sell.
**x** : float, array-like, shape :math:`\left(m\right)`
:math:`\mathrm{x}[i-1]` contains the :math:`\textit{i}`\ th strike price, for :math:`\textit{i} = 1,2,\ldots,m`.
**fwd** : float
The forward price of the asset.
**disc** : float
The discount factor, where the current price of the underlying asset, :math:`S_0`, is given as :math:`S_0 = \mathrm{disc}\times \mathrm{fwd}`.
**ts** : float, array-like, shape :math:`\left(\textit{numts}\right)`
:math:`\mathrm{ts}[\textit{i}-1]` must contain the length of the time intervals for which the corresponding element of :math:`\mathrm{alpha}`, :math:`\mathrm{lamda}`, :math:`\mathrm{corr}` and :math:`\mathrm{sigmat}` apply. These should be ordered as they occur in time i.e., :math:`\Delta t_{\textit{i}} = t_{\textit{i}}-t_{{\textit{i}-1}}`.
**t** : float
:math:`\mathrm{t}` contains the time to expiry. If :math:`T > \sum \Delta t_{\textit{i}}` then the parameters associated with the last time interval are extended to the expiry time. If :math:`T < \sum \Delta t_{\textit{i}}` then the parameters specified are used up until the expiry time. The rest are ignored.
**alpha** : float, array-like, shape :math:`\left(\textit{numts}\right)`
:math:`\mathrm{alpha}[i-1]` must contain the value of :math:`\alpha_t`, the value of the volatility of the scaled volatility, :math:`\sqrt{\nu }`, over time subinterval :math:`\Delta t_i`.
**lamda** : float, array-like, shape :math:`\left(\textit{numts}\right)`
:math:`\mathrm{lamda}[i-1]` must contain the value, :math:`\lambda_t`, of the mean reversion parameter over the time subinterval :math:`\Delta t_i`.
**corr** : float, array-like, shape :math:`\left(\textit{numts}\right)`
:math:`\mathrm{corr}[i-1]` must contain the value, :math:`\rho_t`, of the correlation parameter over the time subinterval :math:`\Delta t_i`.
**sigmat** : float, array-like, shape :math:`\left(\textit{numts}\right)`
:math:`\mathrm{sigmat}[i-1]` must contain the value, :math:`\sigma_t`, of the variance scale factor over the time subinterval :math:`\Delta t_i`.
**var0** : float
:math:`\nu_0`, the initial scaled variance.
**Returns**
**p** : float, ndarray, shape :math:`\left(m\right)`
:math:`\mathrm{p}[\textit{i}-1]` contains the computed option price at the expiry time, :math:`T`, corresponding to strike :math:`\mathrm{x}[\textit{i}-1]` for the specified term structure, for :math:`\textit{i} = 1,2,\ldots,m`.
.. _s30nc-py2-py-errors:
**Raises**
**NagValueError**
(`errno` :math:`1`)
On entry, :math:`\mathrm{calput} != \text{‘C'} \text{ or } \text{‘P'}`.
(`errno` :math:`2`)
On entry, :math:`m = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`m\geq 1`.
(`errno` :math:`3`)
On entry, :math:`\textit{numts} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\textit{numts}\geq 1`.
(`errno` :math:`4`)
On entry, :math:`\mathrm{x}[\langle\mathit{\boldsymbol{value}}\rangle] = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\langle\mathit{\boldsymbol{value}}\rangle\leq \mathrm{x}[i-1]\leq \langle\mathit{\boldsymbol{value}}\rangle`.
(`errno` :math:`5`)
On entry, :math:`\mathrm{fwd} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\langle\mathit{\boldsymbol{value}}\rangle\leq \mathrm{fwd}\leq \langle\mathit{\boldsymbol{value}}\rangle`.
(`errno` :math:`6`)
On entry, :math:`\mathrm{disc} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\langle\mathit{\boldsymbol{value}}\rangle\leq \mathrm{disc}\leq \langle\mathit{\boldsymbol{value}}\rangle`.
(`errno` :math:`7`)
On entry, :math:`\mathrm{ts}[\langle\mathit{\boldsymbol{value}}\rangle] = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\langle\mathit{\boldsymbol{value}}\rangle\leq \mathrm{ts}[i-1]\leq \langle\mathit{\boldsymbol{value}}\rangle`.
(`errno` :math:`8`)
On entry, :math:`\mathrm{t} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{t}\geq \langle\mathit{\boldsymbol{value}}\rangle`.
(`errno` :math:`9`)
On entry, :math:`\mathrm{alpha}[\langle\mathit{\boldsymbol{value}}\rangle] = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\langle\mathit{\boldsymbol{value}}\rangle\leq \mathrm{alpha}[i-1]\leq \langle\mathit{\boldsymbol{value}}\rangle`.
(`errno` :math:`10`)
On entry, :math:`\mathrm{lamda}[\langle\mathit{\boldsymbol{value}}\rangle] = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\langle\mathit{\boldsymbol{value}}\rangle\leq \mathrm{lamda}[i-1]\leq \langle\mathit{\boldsymbol{value}}\rangle`.
(`errno` :math:`11`)
On entry, :math:`\mathrm{corr}[\langle\mathit{\boldsymbol{value}}\rangle] = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\left\lvert \mathrm{corr}[i-1]\right\rvert \leq 1.0`.
(`errno` :math:`12`)
On entry, :math:`\mathrm{sigmat}[\langle\mathit{\boldsymbol{value}}\rangle] = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\langle\mathit{\boldsymbol{value}}\rangle\leq \mathrm{sigmat}[i-1]\leq \langle\mathit{\boldsymbol{value}}\rangle`.
(`errno` :math:`13`)
On entry, :math:`\mathrm{var0} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{var0} > 0.0`.
(`errno` :math:`14`)
Quadrature has not converged to the specified accuracy. However, the result should be a reasonable approximation.
(`errno` :math:`15`)
Solution cannot be computed accurately. Check values of input arguments.
.. _s30nc-py2-py-notes:
**Notes**
``opt_heston_term`` computes the price of a European option for Heston's stochastic volatility model with time-dependent parameters which are piecewise constant.
Starting from the stochastic volatility model given by the Stochastic Differential Equation (SDE) system defined by Heston (1993), a scaling of the variance process is introduced, together with a normalization, setting the long run variance, :math:`\eta`, equal to :math:`1`.
This leads to
.. math::
\frac{{\mathrm{d}S_t}}{{S_t}} = \mu_t\mathrm{d}t+\sigma_t\sqrt{\nu_t}\mathrm{d}W_t^{\left(1\right)}\text{,}
.. math::
\mathrm{d}\nu_t = \lambda_t\left(1-\nu_t\right)\mathrm{d}t+\alpha_t\sqrt{\nu_t}\mathrm{d}W_t^{\left(2\right)}\text{,}
.. math::
\mathrm{Cov}\left[{\mathrm{d}W_t^{\left(1\right)}}, {\mathrm{d}W_t^{\left(2\right)}}\right] = \rho_t\mathrm{d}t\text{,}
where :math:`\mu_t = r_t-q_t` is the drift term representing the contribution of interest rates, :math:`r_t`, and dividends, :math:`q_t`, while :math:`\sigma_t` is the scaling parameter, :math:`\nu_t` is the scaled variance, :math:`\lambda_t` is the mean reversion rate and :math:`\alpha_t` is the volatility of the scaled volatility, :math:`\sqrt{\nu_t}`.
Then, :math:`W_t^{\left(\textit{i}\right)}`, for :math:`\textit{i} = 1,2,\ldots,2`, are two standard Brownian motions with correlation parameter :math:`\rho_t`.
Without loss of generality, the drift term, :math:`\mu_t`, is eliminated by modelling the forward price, :math:`F_t`, directly, instead of the spot price, :math:`S_t`, with
.. math::
F_t = S_0\mathrm{exp}\left(\int_0^t\mu_s\mathrm{d}s\right)\text{.}
If required, the spot can be expressed as, :math:`S_0 = DF_t`, where :math:`D` is the discount factor.
The option price is computed by dividing the time to expiry, :math:`T`, into :math:`n_s` subintervals :math:`\left[t_0, t_1\right],\ldots,\left[t_{{i-1}}, t_i\right],\ldots,\left[t_{{n_s-1}}, T\right]` and applying the method of characteristic functions to each subinterval, with appropriate initial conditions.
Thus, a pair of ordinary differential equations (one of which is a Riccati equation) is solved on each subinterval as outlined in Elices (2008) and Mikhailov and Nögel (2003).
Reversing time by taking :math:`\tau = T-t`, the characteristic function solution for the first time subinterval, starting at :math:`\tau = 0`, is given by Heston (1993), while the solution on each following subinterval uses the solution of the preceding subinterval as initial condition to compute the value of the characteristic function.
In the case of a 'flat' term structure, i.e., the parameters are constant over the time of the option, :math:`T`, the form of the SDE system given by Heston (1993) can be recovered by setting :math:`\kappa = \lambda_t`, :math:`\eta = \sigma_t^2`, :math:`\sigma_v = \sigma_t\alpha_t` and :math:`V_0 = \sigma_t^2V_0`.
Conversely, given the Heston form of the SDE pair, to get the term structure form set :math:`\lambda_t = \kappa`, :math:`\sigma_t = \sqrt{\eta }`, :math:`\alpha_t = \frac{\sigma_v}{\sqrt{\eta }}` and :math:`V_0 = \frac{V_0}{\eta }`.
.. _s30nc-py2-py-references:
**References**
Bain, A, 2011, `Private communication`
Elices, A, 2008, `Models with time-dependent parameters using transform methods: application to Heston’s model`, arXiv:0708.2020v2
Heston, S, 1993, `A closed-form solution for options with stochastic volatility with applications to bond and currency options`, Review of Financial Studies (6), 327--343
Mikhailov, S and Nögel, U, 2003, `Heston’s Stochastic Volatility Model Implementation, Calibration and Some Extensions`, Wilmott Magazine July/August, 74--79
"""
raise NotImplementedError
[docs]def opt_heston_more_greeks(calput, x, s, t, sigmav, kappa, corr, var0, eta, grisk, r, q):
r"""
``opt_heston_more_greeks`` computes the European option price given by Heston's stochastic volatility model together with its sensitivities (Greeks), including sensitivities with respect to model parameters, and allowing negative rates.
.. _s30nd-py2-py-doc:
For full information please refer to the NAG Library document for s30nd
https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s30ndf.html
.. _s30nd-py2-py-parameters:
**Parameters**
**calput** : str, length 1
Determines whether the option is a call or a put.
:math:`\mathrm{calput} = \text{‘C'}`
A call; the holder has a right to buy.
:math:`\mathrm{calput} = \text{‘P'}`
A put; the holder has a right to sell.
**x** : float, array-like, shape :math:`\left(m\right)`
:math:`\mathrm{x}[i-1]` must contain :math:`X_{\textit{i}}`, the :math:`\textit{i}`\ th strike price, for :math:`\textit{i} = 1,2,\ldots,m`.
**s** : float
:math:`S`, the price of the underlying asset.
**t** : float, array-like, shape :math:`\left(n\right)`
:math:`\mathrm{t}[i-1]` must contain :math:`T_{\textit{i}}`, the :math:`\textit{i}`\ th time, in years, to expiry, for :math:`\textit{i} = 1,2,\ldots,n`.
**sigmav** : float
The volatility, :math:`\sigma_v`, of the volatility process, :math:`\sqrt{v_t}`. Note that a rate of 20% should be entered as :math:`0.2`.
**kappa** : float
:math:`\kappa`, the long term mean reversion rate of the volatility.
**corr** : float
The correlation between the two standard Brownian motions for the asset price and the volatility.
**var0** : float
The initial value of the variance, :math:`v_t`, of the asset price.
**eta** : float
:math:`\eta`, the long term mean of the variance of the asset price.
**grisk** : float
The risk aversion parameter, :math:`\gamma`, of the representative agent.
**r** : float, array-like, shape :math:`\left(n\right)`
:math:`\mathrm{r}[i-1]` must contain :math:`R_{\textit{i}}`, the :math:`\textit{i}`\ th annual risk-free interest rate, continuously compounded, for :math:`\textit{i} = 1,2,\ldots,n`. Note that a rate of 5% should be entered as :math:`0.05`.
**q** : float, array-like, shape :math:`\left(n\right)`
:math:`\mathrm{q}[i-1]` must contain :math:`Q_{\textit{i}}`, the :math:`\textit{i}`\ th annual continuous yield rate, for :math:`\textit{i} = 1,2,\ldots,n`. Note that a rate of 8% should be entered as :math:`0.08`.
**Returns**
**p** : float, ndarray, shape :math:`\left(m, n\right)`
:math:`\mathrm{p}[i-1,j-1]` contains :math:`P_{{ij}}`, the option price evaluated for the strike price :math:`\mathrm{x}_i` at expiry :math:`\mathrm{t}_j` for :math:`i = 1,2,\ldots,m` and :math:`j = 1,2,\ldots,n`.
**delta** : float, ndarray, shape :math:`\left(m, n\right)`
The leading :math:`m\times n` part of the array :math:`\mathrm{delta}` contains the sensitivity, :math:`\frac{{\partial P}}{{\partial S}}`, of the option price to change in the price of the underlying asset.
**gamma** : float, ndarray, shape :math:`\left(m, n\right)`
The leading :math:`m\times n` part of the array :math:`\mathrm{gamma}` contains the sensitivity, :math:`\frac{{\partial^2P}}{{\partial S^2}}`, of :math:`\mathrm{delta}` to change in the price of the underlying asset.
**vega** : float, ndarray, shape :math:`\left(m, n\right)`
:math:`\mathrm{vega}[i-1,j-1]`, contains the first-order Greek measuring the sensitivity of the option price :math:`P_{{ij}}` to change in the volatility of the underlying asset, i.e., :math:`\frac{{\partial P_{{ij}}}}{{\partial v_t}}`, for :math:`i = 1,2,\ldots,m` and :math:`j = 1,2,\ldots,n`.
**theta** : float, ndarray, shape :math:`\left(m, n\right)`
:math:`\mathrm{theta}[i-1,j-1]`, contains the first-order Greek measuring the sensitivity of the option price :math:`P_{{ij}}` to change in time, i.e., :math:`-\frac{{\partial P_{{ij}}}}{{\partial T}}`, for :math:`i = 1,2,\ldots,m` and :math:`j = 1,2,\ldots,n`.
**rho** : float, ndarray, shape :math:`\left(m, n\right)`
:math:`\mathrm{rho}[i-1,j-1]`, contains the first-order Greek measuring the sensitivity of the option price :math:`P_{{ij}}` to change in the annual risk-free interest rate, i.e., :math:`\frac{{\partial P_{{ij}}}}{{\partial r_i}}`, for :math:`i = 1,2,\ldots,m` and :math:`j = 1,2,\ldots,n`.
**vanna** : float, ndarray, shape :math:`\left(m, n\right)`
:math:`\mathrm{vanna}[i-1,j-1]`, contains the second-order Greek measuring the sensitivity of the first-order Greek :math:`\Delta_{{ij}}` to change in the volatility of the asset price, i.e., :math:`\frac{{\partial \Delta_{{ij}}}}{{\partial \sigma }} = \frac{{\partial^2P_{{ij}}}}{{\partial S\partial \sigma }}`, for :math:`i = 1,2,\ldots,m` and :math:`j = 1,2,\ldots,n`.
**charm** : float, ndarray, shape :math:`\left(m, n\right)`
:math:`\mathrm{charm}[i-1,j-1]`, contains the second-order Greek measuring the sensitivity of the first-order Greek :math:`\Delta_{{ij}}` to change in the time, i.e., :math:`-\frac{{\partial \Delta_{{ij}}}}{{\partial T}} = -\frac{{\partial^2P_{{ij}}}}{{\partial S\partial T}}`, for :math:`i = 1,2,\ldots,m` and :math:`j = 1,2,\ldots,n`.
**speed** : float, ndarray, shape :math:`\left(m, n\right)`
:math:`\mathrm{speed}[i-1,j-1]`, contains the third-order Greek measuring the sensitivity of the second-order Greek :math:`\Gamma_{{ij}}` to change in the price of the underlying asset, i.e., :math:`\frac{{\partial \Gamma_{{ij}}}}{{\partial S}} = \frac{{\partial^3P_{{ij}}}}{{\partial S^3}}`, for :math:`i = 1,2,\ldots,m` and :math:`j = 1,2,\ldots,n`.
**zomma** : float, ndarray, shape :math:`\left(m, n\right)`
:math:`\mathrm{zomma}[i-1,j-1]`, contains the third-order Greek measuring the sensitivity of the second-order Greek :math:`\Gamma_{{ij}}` to change in the volatility of the underlying asset, i.e., :math:`\frac{{\partial \Gamma_{{ij}}}}{{\partial \sigma }} = \frac{{\partial^3P_{{ij}}}}{{\partial S^2\partial \sigma }}`, for :math:`i = 1,2,\ldots,m` and :math:`j = 1,2,\ldots,n`.
**vomma** : float, ndarray, shape :math:`\left(m, n\right)`
:math:`\mathrm{vomma}[i-1,j-1]`, contains the second-order Greek measuring the sensitivity of the option price :math:`P_{{ij}}` to second-order changes in the volatility of the underlying asset, i.e., :math:`\frac{{\partial^2P_{{ij}}}}{{\partial \sigma^2}}`, for :math:`i = 1,2,\ldots,m` and :math:`j = 1,2,\ldots,n`.
**dp_dx** : float, ndarray, shape :math:`\left(m, n\right)`
:math:`\mathrm{dp\_dx}[i-1,j-1]`, contains the derivative measuring the sensitivity of the option price :math:`P_{{ij}}` to change in the strick price, :math:`X_i`, i.e., :math:`\frac{{\partial P_{{ij}}}}{{\partial X_i}}`, for :math:`i = 1,2,\ldots,m` and :math:`j = 1,2,\ldots,n`.
**dp_dq** : float, ndarray, shape :math:`\left(m, n\right)`
:math:`\mathrm{dp\_dq}[i-1,j-1]`, contains the derivative measuring the sensitivity of the option price :math:`P_{{ij}}` to change in the annual continuous yield rate, :math:`q_j`, i.e., :math:`\frac{{\partial P_{{ij}}}}{{\partial q_j}}`, for :math:`i = 1,2,\ldots,m` and :math:`j = 1,2,\ldots,n`.
**dp_deta** : float, ndarray, shape :math:`\left(m, n\right)`
:math:`\mathrm{dp\_deta}[i-1,j-1]`, contains the derivative measuring the sensitivity of the option price :math:`P_{{ij}}` to change in the long term mean of the variance :math:`\eta` of the asset price, i.e., :math:`\frac{{\partial P_{{ij}}}}{{\partial \eta }}`, for :math:`i = 1,2,\ldots,m` and :math:`j = 1,2,\ldots,n`.
**dp_dkappa** : float, ndarray, shape :math:`\left(m, n\right)`
:math:`\mathrm{dp\_dkappa}[i-1,j-1]`, contains the derivative measuring the sensitivity of the option price :math:`P_{{ij}}` to change in the long term mean reversion rate :math:`\kappa` of the volatility, i.e., :math:`\frac{{\partial P_{{ij}}}}{{\partial \kappa }}`, for :math:`i = 1,2,\ldots,m` and :math:`j = 1,2,\ldots,n`.
**dp_dsigmav** : float, ndarray, shape :math:`\left(m, n\right)`
:math:`\mathrm{dp\_dsigmav}[i-1,j-1]`, contains the derivative measuring the sensitivity of the option price :math:`P_{{ij}}` to change in the volatility :math:`\sigma_v` of the volatility process, :math:`\sqrt{v_t}`, i.e., :math:`\frac{{\partial P_{{ij}}}}{{\partial \sigma_v}}`, for :math:`i = 1,2,\ldots,m` and :math:`j = 1,2,\ldots,n`.
**dp_dcorr** : float, ndarray, shape :math:`\left(m, n\right)`
:math:`\mathrm{dp\_dcorr}[i-1,j-1]`, contains the derivative measuring the sensitivity of the option price :math:`P_{{ij}}` to change in the correlation :math:`\rho` between the two standard Brownian motions for the asset price and the volatility, i.e., :math:`\frac{{\partial P_{{ij}}}}{{\partial \rho }}`, for :math:`i = 1,2,\ldots,m` and :math:`j = 1,2,\ldots,n`.
**dp_dgrisk** : float, ndarray, shape :math:`\left(m, n\right)`
:math:`\mathrm{dp\_dgrisk}[i-1,j-1]`, contains the derivative measuring the sensitivity of the option price :math:`P_{{ij}}` to change in the risk aversion parameter :math:`\gamma` of the representative agent,, i.e., :math:`\frac{{\partial P_{{ij}}}}{{\partial \gamma }}`, for :math:`i = 1,2,\ldots,m` and :math:`j = 1,2,\ldots,n`.
.. _s30nd-py2-py-errors:
**Raises**
**NagValueError**
(`errno` :math:`1`)
On entry, :math:`\mathrm{calput} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{calput} = \text{‘C'} \text{ or } \text{‘P'}`.
(`errno` :math:`2`)
On entry, :math:`m = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`m\geq 1`.
(`errno` :math:`3`)
On entry, :math:`n = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`n\geq 1`.
(`errno` :math:`4`)
On entry, :math:`\mathrm{x}[\langle\mathit{\boldsymbol{value}}\rangle] = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{x}[i-1]\geq \langle\mathit{\boldsymbol{value}}\rangle` and :math:`\mathrm{x}[i-1]\leq \langle\mathit{\boldsymbol{value}}\rangle`.
(`errno` :math:`5`)
On entry, :math:`\mathrm{s} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{s}\geq \langle\mathit{\boldsymbol{value}}\rangle` and :math:`\mathrm{s}\leq \langle\mathit{\boldsymbol{value}}\rangle`.
(`errno` :math:`6`)
On entry, :math:`\mathrm{t}[\langle\mathit{\boldsymbol{value}}\rangle] = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{t}[i-1]\geq \langle\mathit{\boldsymbol{value}}\rangle`.
(`errno` :math:`7`)
On entry, :math:`\mathrm{sigmav} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{sigmav} > 0.0`.
(`errno` :math:`8`)
On entry, :math:`\mathrm{kappa} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{kappa} > 0.0`.
(`errno` :math:`9`)
On entry, :math:`\mathrm{corr} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\left\lvert \mathrm{corr}\right\rvert \leq 1.0`.
(`errno` :math:`10`)
On entry, :math:`\mathrm{var0} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{var0}\geq 0.0`.
(`errno` :math:`11`)
On entry, :math:`\mathrm{eta} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{eta} > 0.0`.
(`errno` :math:`12`)
On entry, :math:`\mathrm{grisk} = \langle\mathit{\boldsymbol{value}}\rangle`, :math:`\mathrm{sigmav} = \langle\mathit{\boldsymbol{value}}\rangle` and :math:`\mathrm{kappa} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`0.0\leq \mathrm{grisk}\leq 1.0` and :math:`\mathrm{grisk}\times \left(1.0-\mathrm{grisk}\right)\times \mathrm{sigmav}^2\leq \mathrm{kappa}^2`.
**Warns**
**NagAlgorithmicWarning**
(`errno` :math:`17`)
Quadrature has not converged to the required accuracy. However, the result should be a reasonable approximation.
(`errno` :math:`18`)
Solution cannot be computed accurately. Check values of input arguments.
.. _s30nd-py2-py-notes:
**Notes**
``opt_heston_more_greeks`` computes the price and sensitivities of a European option using Heston's stochastic volatility model.
The return on the asset price, :math:`S`, is
.. math::
\frac{{dS}}{S} = \left(r-q\right)dt+\sqrt{v_t}dW_t^{\left(1\right)}
and the instantaneous variance, :math:`v_t`, is defined by a mean-reverting square root stochastic process,
.. math::
dv_t = \kappa \left(\eta -v_t\right)dt+\sigma_v\sqrt{v_t}dW_t^{\left(2\right)}\text{,}
where :math:`r` is the risk free annual interest rate; :math:`q` is the annual dividend rate; :math:`v_t` is the variance of the asset price; :math:`\sigma_v` is the volatility of the volatility, :math:`\sqrt{v_t}`; :math:`\kappa` is the mean reversion rate; :math:`\eta` is the long term variance. :math:`dW_t^{\left(\textit{i}\right)}`, for :math:`\textit{i} = 1,2,\ldots,2`, denotes two correlated standard Brownian motions with
.. math::
\mathrm{ℂov}\left[{dW_t^{\left(1\right)}}, {dW_t^{\left(2\right)}}\right] = \rho dt\text{.}
The option price is computed by evaluating the integral transform given by Lewis (2000) using the form of the characteristic function discussed by Albrecher `et al.` (2007), see also Kilin (2006).
.. math::
P_{\mathrm{call}} = Se^{{-qT}}-Xe^{{-rT}}\frac{1}{\pi }\mathrm{Re}\left[\int_{{0+i/2}}^{{\infty +i/2}}e^{{-ik\bar{X}}}\frac{{\hat{H}\left(k, v, T\right)}}{{k^2-ik}}\mathrm{d}k\right]\text{,}
where :math:`\bar{X} = \mathrm{ln}\left(S/X\right)+\left(r-q\right)T` and
.. math::
\hat{H}\left(k, v, T\right) = \mathrm{exp}\left(\frac{{2\kappa \eta }}{\sigma_v^2}\left[t\textit{g }-\mathrm{ln}\left(\frac{{1-he^{{-\xi t}}}}{{1-h}}\right)\right]+v_tg\left[\frac{{1-e^{{-\xi t}}}}{{1-he^{{-\xi t}}}}\right]\right)\text{,}
.. math::
g = \frac{1}{2}\left(b-\xi \right)\text{, }\quad h = \frac{{b-\xi }}{{b+\xi }}\text{, }\quad t = \sigma_v^2T/2\text{,}
.. math::
\xi = \left[b^2+4\frac{{k^2-ik}}{{\sigma_v^2}}\right]^{\frac{1}{2}}\text{,}
.. math::
b = \frac{2}{{\sigma_v^2}}\left[\left(1-\gamma +ik\right)\rho \sigma_v+\sqrt{\kappa^2-\gamma \left(1-\gamma \right)\sigma_v^2}\right]
with :math:`t = \sigma_v^2T/2`.
Here :math:`\gamma` is the risk aversion parameter of the representative agent with :math:`0\leq \gamma \leq 1` and :math:`\gamma \left(1-\gamma \right)\sigma_v^2\leq \kappa^2`.
The value :math:`\gamma = 1` corresponds to :math:`\lambda = 0`, where :math:`\lambda` is the market price of risk in Heston (1993) (see Lewis (2000) and Rouah and Vainberg (2007)).
The price of a put option is obtained by put-call parity.
.. math::
P_{\mathrm{put}} = P_{\mathrm{call}}+Xe^{{-rT}}-Se^{{-qT}}\text{.}
Writing the expression for the price of a call option as
.. math::
P_{\mathrm{call}} = Se^{{-qT}}-Xe^{{-rT}}\frac{1}{\pi }\mathrm{Re}\left[\int_{{0+i/2}}^{{\infty +i/2}}I\left(k, r, S, T, v\right)\mathrm{d}k\right]
then the sensitivities or Greeks can be obtained in the following manner,
Delta
.. math::
\frac{{\partial P_{\mathrm{call}}}}{{\partial S}} = e^{{-qT}}+\frac{{Xe^{{-rT}}}}{S}\frac{1}{\pi }\mathrm{Re}\left[\int_{{0+i/2}}^{{\infty +i/2}}\left(ik\right)I\left(k, r, S, T, v\right)\mathrm{d}k\right]\text{,}
Vega
.. math::
\frac{{\partial P}}{{\partial v}} = -Xe^{{-rT}}\frac{1}{\pi }\mathrm{Re}\left[\int_{{0-i/2}}^{{0+i/2}}f_2I\left(k, r, j, S, T, v\right)\mathrm{d}k\right]\text{, where }f_2 = g\left[\frac{{1-e^{{-\xi t}}}}{{1-he^{{-\xi t}}}}\right]\text{,}
Rho
.. math::
\frac{{\partial P_{\mathrm{call}}}}{{\partial r}} = TXe^{{-rT}}\frac{1}{\pi }\mathrm{Re}\left[\int_{{0+i/2}}^{{\infty +i/2}}\left(1+ik\right)I\left(k, r, S, T, v\right)\mathrm{d}k\right]\text{.}
The option price :math:`P_{{ij}} = P\left({X = X_i}, {T = T_j}, {r = r_j}, {q = q_j}\right)` is computed for each strike price in a set :math:`X_i`, :math:`i = 1,2,\ldots,m`, and for each expiry time in a set :math:`T_j`, :math:`j = 1,2,\ldots,n`.
The continuously compounded annual risk-free interest rate used is :math:`r_j`, :math:`j = 1,2,\ldots,n`, and the annual continuous yield rate used is :math:`q_j`, :math:`j = 1,2,\ldots,n`.
.. _s30nd-py2-py-references:
**References**
Albrecher, H, Mayer, P, Schoutens, W and Tistaert, J, 2007, `The little Heston trap`, Wilmott Magazine (January 2007), 83--92
Heston, S, 1993, `A closed-form solution for options with stochastic volatility with applications to bond and currency options`, Review of Financial Studies (6), 327--343
Kilin, F, 2006, `Accelerating the calibration of stochastic volatility models`, MPRA Paper No. 2975, https://mpra.ub.uni-muenchen.de/2975/
Lewis, A L, 2000, `Option valuation under stochastic volatility`, Finance Press, USA
Rouah, F D and Vainberg, G, 2007, `Option Pricing Models and Volatility using Excel-VBA`, John Wiley and Sons, Inc
See Also
--------
:meth:`naginterfaces.library.examples.specfun.opt_heston_more_greeks_ex.main`
"""
raise NotImplementedError
[docs]def opt_amer_bs_price(calput, x, s, t, sigma, r, q):
r"""
``opt_amer_bs_price`` computes the Bjerksund and Stensland (2002) approximation to the price of an American option.
.. _s30qc-py2-py-doc:
For full information please refer to the NAG Library document for s30qc
https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s30qcf.html
.. _s30qc-py2-py-parameters:
**Parameters**
**calput** : str, length 1
Determines whether the option is a call or a put.
:math:`\mathrm{calput} = \text{‘C'}`
A call; the holder has a right to buy.
:math:`\mathrm{calput} = \text{‘P'}`
A put; the holder has a right to sell.
**x** : float, array-like, shape :math:`\left(m\right)`
:math:`\mathrm{x}[i-1]` must contain :math:`X_{\textit{i}}`, the :math:`\textit{i}`\ th strike price, for :math:`\textit{i} = 1,2,\ldots,m`.
**s** : float
:math:`S`, the price of the underlying asset.
**t** : float, array-like, shape :math:`\left(n\right)`
:math:`\mathrm{t}[i-1]` must contain :math:`T_{\textit{i}}`, the :math:`\textit{i}`\ th time, in years, to expiry, for :math:`\textit{i} = 1,2,\ldots,n`.
**sigma** : float
:math:`\sigma`, the volatility of the underlying asset. Note that a rate of 15% should be entered as :math:`0.15`.
**r** : float
:math:`r`, the annual risk-free interest rate, continuously compounded. Note that a rate of 5% should be entered as :math:`0.05`.
**q** : float
:math:`q`, the annual continuous yield rate. Note that a rate of 8% should be entered as :math:`0.08`.
**Returns**
**p** : float, ndarray, shape :math:`\left(m, n\right)`
:math:`\mathrm{p}[i-1,j-1]` contains :math:`P_{{ij}}`, the option price evaluated for the strike price :math:`\mathrm{x}_i` at expiry :math:`\mathrm{t}_j` for :math:`i = 1,2,\ldots,m` and :math:`j = 1,2,\ldots,n`.
.. _s30qc-py2-py-errors:
**Raises**
**NagValueError**
(`errno` :math:`1`)
On entry, :math:`\mathrm{calput} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{calput} = \text{‘C'} \text{ or } \text{‘P'}`.
(`errno` :math:`2`)
On entry, :math:`m = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`m\geq 1`.
(`errno` :math:`3`)
On entry, :math:`n = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`n\geq 1`.
(`errno` :math:`4`)
On entry, :math:`\mathrm{x}[\langle\mathit{\boldsymbol{value}}\rangle] = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{x}[i]\geq \langle\mathit{\boldsymbol{value}}\rangle` and :math:`\mathrm{x}[i]\leq \langle\mathit{\boldsymbol{value}}\rangle`.
(`errno` :math:`5`)
On entry, :math:`\mathrm{s} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{s}\geq \langle\mathit{\boldsymbol{value}}\rangle` and :math:`\mathrm{s}\leq \langle\mathit{\boldsymbol{value}}\rangle`.
(`errno` :math:`6`)
On entry, :math:`\mathrm{t}[\langle\mathit{\boldsymbol{value}}\rangle] = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{t}[i]\geq \langle\mathit{\boldsymbol{value}}\rangle`.
(`errno` :math:`7`)
On entry, :math:`\mathrm{sigma} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{sigma} > 0.0`.
(`errno` :math:`8`)
On entry, :math:`\mathrm{r} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{r}\geq 0.0`.
(`errno` :math:`9`)
On entry, :math:`\mathrm{q} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{q}\geq 0.0`.
(`errno` :math:`14`)
On entry, :math:`\mathrm{s} = \langle\mathit{\boldsymbol{value}}\rangle` and :math:`\beta = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{s}^{\beta } < \langle\mathit{\boldsymbol{value}}\rangle`.
.. _s30qc-py2-py-notes:
**Notes**
``opt_amer_bs_price`` computes the price of an American option using the closed form approximation of Bjerksund and Stensland (2002).
The time to maturity, :math:`T`, is divided into two periods, each with a flat early exercise boundary, by choosing a time :math:`t \in \left[0, T\right]`, such that :math:`t = \frac{1}{2}\left(\sqrt{5}-1\right)T`.
The two boundary values are defined as :math:`\tilde{x} = \tilde{X}\left(t\right)`, :math:`\tilde{X} = \tilde{X}\left(T\right)` with
.. math::
\tilde{X}\left(\tau \right) = B_0+\left(B_{\infty }-B_0\right)\left(1-\mathrm{exp}\left\{h\left(\tau \right)\right\}\right)\text{,}
where
.. math::
h\left(\tau \right) = -\left(b\tau +2\sigma \sqrt{\tau }\right)\left(\frac{X^2}{{\left(B_{\infty }-B_0\right)B_0}}\right)\text{,}
.. math::
B_{\infty }\equiv \frac{\beta }{{\beta -1}}X\text{, }\quad B_0\equiv \mathrm{max}\left\{X, {\left(\frac{r}{{r-b}}\right)X}\right\}\text{,}
.. math::
\beta = \left(\frac{1}{2}-\frac{b}{\sigma^2}\right)+\sqrt{\left(\frac{b}{\sigma^2}-\frac{1}{2}\right)^2+2\frac{r}{\sigma^2}}\text{.}
with :math:`b = r-q`, the cost of carry, where :math:`r` is the risk-free interest rate and :math:`q` is the annual dividend rate.
Here :math:`X` is the strike price and :math:`\sigma` is the annual volatility.
The price of an American call option is approximated as
.. math::
\begin{array}{ccc}P_{\mathrm{call}}& = & \alpha \left(\tilde{X}\right) S^{\beta } - \alpha \left(\tilde{X}\right) \phi \left(S, {t|\beta }, \tilde{X}, \tilde{X}\right)+ \\&& \phi \left(S, {t|1}, \tilde{X}, \tilde{X}\right) - \phi \left(S, {t|1}, \tilde{x}, \tilde{X}\right) - \\&& X \phi \left(S, {t|0}, \tilde{X}, \tilde{X}\right) + X \phi \left(S, {t|0}, \tilde{x}, \tilde{X}\right) + \\&& \alpha \left(\tilde{x}\right) \phi \left(S, {t|\beta }, \tilde{x}, \tilde{X}\right) - \alpha \left(\tilde{x}\right) \Psi \left(S, {T|\beta }, \tilde{x}, \tilde{X}, \tilde{x}, t\right) + \\&& \Psi \left(S, {T|1}, \tilde{x}, \tilde{X}, \tilde{x}, t\right) - \Psi \left(S, {T|1}, X, \tilde{X}, \tilde{x}, t\right) - \\&& X \Psi \left(S, {T|0}, \tilde{x}, \tilde{X}, \tilde{x}, t\right) + X \Psi \left(S, {T|0}, X, \tilde{X}, \tilde{x}, t\right) \text{,} \end{array}
where :math:`\alpha`, :math:`\phi` and :math:`\Psi` are as defined in Bjerksund and Stensland (2002).
The price of a put option is obtained by the put-call transformation,
.. math::
P_{\mathrm{put}}\left(X, S, T, \sigma, r, q\right) = P_{\mathrm{call}}\left(S, X, T, \sigma, q, r\right)\text{.}
The option price :math:`P_{{ij}} = P\left({X = X_i}, {T = T_j}\right)` is computed for each strike price in a set :math:`X_i`, :math:`i = 1,2,\ldots,m`, and for each expiry time in a set :math:`T_j`, :math:`j = 1,2,\ldots,n`.
.. _s30qc-py2-py-references:
**References**
Bjerksund, P and Stensland, G, 2002, `Closed form valuation of American options` (Discussion Paper 2002/09), NHH Bergen Norway
Genz, A, 2004, `Numerical computation of rectangular bivariate and trivariate Normal and` :math:`t` `probabilities`, Statistics and Computing (14), 151--160
"""
raise NotImplementedError
[docs]def opt_asian_geom_price(calput, x, s, t, sigma, r, b):
r"""
``opt_asian_geom_price`` computes the Asian geometric continuous average-rate option price.
.. _s30sa-py2-py-doc:
For full information please refer to the NAG Library document for s30sa
https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s30saf.html
.. _s30sa-py2-py-parameters:
**Parameters**
**calput** : str, length 1
Determines whether the option is a call or a put.
:math:`\mathrm{calput} = \text{‘C'}`
A call; the holder has a right to buy.
:math:`\mathrm{calput} = \text{‘P'}`
A put; the holder has a right to sell.
**x** : float, array-like, shape :math:`\left(m\right)`
:math:`\mathrm{x}[i-1]` must contain :math:`X_{\textit{i}}`, the :math:`\textit{i}`\ th strike price, for :math:`\textit{i} = 1,2,\ldots,m`.
**s** : float
:math:`S`, the price of the underlying asset.
**t** : float, array-like, shape :math:`\left(n\right)`
:math:`\mathrm{t}[i-1]` must contain :math:`T_{\textit{i}}`, the :math:`\textit{i}`\ th time, in years, to expiry, for :math:`\textit{i} = 1,2,\ldots,n`.
**sigma** : float
:math:`\sigma`, the volatility of the underlying asset. Note that a rate of 15% should be entered as :math:`0.15`.
**r** : float
:math:`r`, the annual risk-free interest rate, continuously compounded. Note that a rate of 5% should be entered as :math:`0.05`.
**b** : float
:math:`b`, the annual cost of carry rate. Note that a rate of 8% should be entered as :math:`0.08`.
**Returns**
**p** : float, ndarray, shape :math:`\left(m, n\right)`
:math:`\mathrm{p}[i-1,j-1]` contains :math:`P_{{ij}}`, the option price evaluated for the strike price :math:`\mathrm{x}_i` at expiry :math:`\mathrm{t}_j` for :math:`i = 1,2,\ldots,m` and :math:`j = 1,2,\ldots,n`.
.. _s30sa-py2-py-errors:
**Raises**
**NagValueError**
(`errno` :math:`1`)
On entry, :math:`\mathrm{calput} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{calput} = \text{‘C'} \text{ or } \text{‘P'}`.
(`errno` :math:`2`)
On entry, :math:`m = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`m\geq 1`.
(`errno` :math:`3`)
On entry, :math:`n = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`n\geq 1`.
(`errno` :math:`4`)
On entry, :math:`\mathrm{x}[\langle\mathit{\boldsymbol{value}}\rangle] = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{x}[i]\geq \langle\mathit{\boldsymbol{value}}\rangle` and :math:`\mathrm{x}[i]\leq \langle\mathit{\boldsymbol{value}}\rangle`.
(`errno` :math:`5`)
On entry, :math:`\mathrm{s} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{s}\geq \langle\mathit{\boldsymbol{value}}\rangle` and :math:`\mathrm{s}\leq \langle\mathit{\boldsymbol{value}}\rangle`.
(`errno` :math:`6`)
On entry, :math:`\mathrm{t}[\langle\mathit{\boldsymbol{value}}\rangle] = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{t}[i]\geq \langle\mathit{\boldsymbol{value}}\rangle`.
(`errno` :math:`7`)
On entry, :math:`\mathrm{sigma} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{sigma} > 0.0`.
(`errno` :math:`8`)
On entry, :math:`\mathrm{r} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{r}\geq 0.0`.
.. _s30sa-py2-py-notes:
**Notes**
``opt_asian_geom_price`` computes the price of an Asian geometric continuous average-rate option for constant volatility, :math:`\sigma`, risk-free rate, :math:`r`, and cost of carry, :math:`b` (see Kemna and Vorst (1990)).
For a given strike price, :math:`X`, the price of a call option with underlying price, :math:`S`, and time to expiry, :math:`T`, is
.. math::
P_{\mathrm{call}} = Se^{{\left(\bar{b}-r\right)T}}\Phi \left(\bar{d}_1\right)-Xe^{{-rT}}\Phi \left(\bar{d}_2\right)\text{,}
and the corresponding put option price is
.. math::
P_{\mathrm{put}} = Xe^{{-rT}}\Phi \left(-\bar{d}_2\right)-Se^{{\left(\bar{b}-r\right)T}}\Phi \left(-\bar{d}_1\right)\text{,}
where
.. math::
\bar{d}_1 = \frac{{\mathrm{ln}\left(S/X\right)+\left(\bar{b}+\bar{\sigma }^2/2\right)T}}{{\bar{\sigma }\sqrt{T}}}
and
.. math::
\bar{d}_2 = \bar{d}_1-\bar{\sigma }\sqrt{T}\text{,}
with
.. math::
\bar{\sigma } = \frac{\sigma }{\sqrt{3}}\text{, }\quad \bar{b} = \frac{1}{2}\left(r-\frac{\sigma^2}{6}\right)\text{.}
:math:`\Phi` is the cumulative Normal distribution function,
.. math::
\Phi \left(x\right) = \frac{1}{{\sqrt{2\pi }}}\int_{{-\infty }}^x\mathrm{exp}\left({-y^2}/2\right)dy\text{.}
The option price :math:`P_{{ij}} = P\left({X = X_i}, {T = T_j}\right)` is computed for each strike price in a set :math:`X_i`, :math:`i = 1,2,\ldots,m`, and for each expiry time in a set :math:`T_j`, :math:`j = 1,2,\ldots,n`.
.. _s30sa-py2-py-references:
**References**
Kemna, A and Vorst, A, 1990, `A pricing method for options based on average asset values`, Journal of Banking and Finance (14), 113--129
"""
raise NotImplementedError
[docs]def opt_asian_geom_greeks(calput, x, s, t, sigma, r, b):
r"""
``opt_asian_geom_greeks`` computes the Asian geometric continuous average-rate option price together with its sensitivities (Greeks).
.. _s30sb-py2-py-doc:
For full information please refer to the NAG Library document for s30sb
https://support.nag.com/numeric/nl/nagdoc_30.3/flhtml/s/s30sbf.html
.. _s30sb-py2-py-parameters:
**Parameters**
**calput** : str, length 1
Determines whether the option is a call or a put.
:math:`\mathrm{calput} = \text{‘C'}`
A call; the holder has a right to buy.
:math:`\mathrm{calput} = \text{‘P'}`
A put; the holder has a right to sell.
**x** : float, array-like, shape :math:`\left(m\right)`
:math:`\mathrm{x}[i-1]` must contain :math:`X_{\textit{i}}`, the :math:`\textit{i}`\ th strike price, for :math:`\textit{i} = 1,2,\ldots,m`.
**s** : float
:math:`S`, the price of the underlying asset.
**t** : float, array-like, shape :math:`\left(n\right)`
:math:`\mathrm{t}[i-1]` must contain :math:`T_{\textit{i}}`, the :math:`\textit{i}`\ th time, in years, to expiry, for :math:`\textit{i} = 1,2,\ldots,n`.
**sigma** : float
:math:`\sigma`, the volatility of the underlying asset. Note that a rate of 15% should be entered as :math:`0.15`.
**r** : float
:math:`r`, the annual risk-free interest rate, continuously compounded. Note that a rate of 5% should be entered as :math:`0.05`.
**b** : float
:math:`b`, the annual cost of carry rate. Note that a rate of 8% should be entered as :math:`0.08`.
**Returns**
**p** : float, ndarray, shape :math:`\left(m, n\right)`
:math:`\mathrm{p}[i-1,j-1]` contains :math:`P_{{ij}}`, the option price evaluated for the strike price :math:`\mathrm{x}_i` at expiry :math:`\mathrm{t}_j` for :math:`i = 1,2,\ldots,m` and :math:`j = 1,2,\ldots,n`.
**delta** : float, ndarray, shape :math:`\left(m, n\right)`
The leading :math:`m\times n` part of the array :math:`\mathrm{delta}` contains the sensitivity, :math:`\frac{{\partial P}}{{\partial S}}`, of the option price to change in the price of the underlying asset.
**gamma** : float, ndarray, shape :math:`\left(m, n\right)`
The leading :math:`m\times n` part of the array :math:`\mathrm{gamma}` contains the sensitivity, :math:`\frac{{\partial^2P}}{{\partial S^2}}`, of :math:`\mathrm{delta}` to change in the price of the underlying asset.
**vega** : float, ndarray, shape :math:`\left(m, n\right)`
:math:`\mathrm{vega}[i-1,j-1]`, contains the first-order Greek measuring the sensitivity of the option price :math:`P_{{ij}}` to change in the volatility of the underlying asset, i.e., :math:`\frac{{\partial P_{{ij}}}}{{\partial \sigma }}`, for :math:`i = 1,2,\ldots,m` and :math:`j = 1,2,\ldots,n`.
**theta** : float, ndarray, shape :math:`\left(m, n\right)`
:math:`\mathrm{theta}[i-1,j-1]`, contains the first-order Greek measuring the sensitivity of the option price :math:`P_{{ij}}` to change in time, i.e., :math:`-\frac{{\partial P_{{ij}}}}{{\partial T}}`, for :math:`i = 1,2,\ldots,m` and :math:`j = 1,2,\ldots,n`, where :math:`b = r-q`.
**rho** : float, ndarray, shape :math:`\left(m, n\right)`
:math:`\mathrm{rho}[i-1,j-1]`, contains the first-order Greek measuring the sensitivity of the option price :math:`P_{{ij}}` to change in the annual risk-free interest rate, i.e., :math:`-\frac{{\partial P_{{ij}}}}{{\partial r}}`, for :math:`i = 1,2,\ldots,m` and :math:`j = 1,2,\ldots,n`.
**crho** : float, ndarray, shape :math:`\left(m, n\right)`
:math:`\mathrm{delta}[i-1,j-1]`, contains the first-order Greek measuring the sensitivity of the option price :math:`P_{{ij}}` to change in the price of the underlying asset, i.e., :math:`-\frac{{\partial P_{{ij}}}}{{\partial S}}`, for :math:`i = 1,2,\ldots,m` and :math:`j = 1,2,\ldots,n`.
**vanna** : float, ndarray, shape :math:`\left(m, n\right)`
:math:`\mathrm{vanna}[i-1,j-1]`, contains the second-order Greek measuring the sensitivity of the first-order Greek :math:`\Delta_{{ij}}` to change in the volatility of the asset price, i.e., :math:`-\frac{{\partial \Delta_{{ij}}}}{{\partial T}} = -\frac{{\partial^2P_{{ij}}}}{{\partial S\partial \sigma }}`, for :math:`i = 1,2,\ldots,m` and :math:`j = 1,2,\ldots,n`.
**charm** : float, ndarray, shape :math:`\left(m, n\right)`
:math:`\mathrm{charm}[i-1,j-1]`, contains the second-order Greek measuring the sensitivity of the first-order Greek :math:`\Delta_{{ij}}` to change in the time, i.e., :math:`-\frac{{\partial \Delta_{{ij}}}}{{\partial T}} = -\frac{{\partial^2P_{{ij}}}}{{\partial S\partial T}}`, for :math:`i = 1,2,\ldots,m` and :math:`j = 1,2,\ldots,n`.
**speed** : float, ndarray, shape :math:`\left(m, n\right)`
:math:`\mathrm{speed}[i-1,j-1]`, contains the third-order Greek measuring the sensitivity of the second-order Greek :math:`\Gamma_{{ij}}` to change in the price of the underlying asset, i.e., :math:`-\frac{{\partial \Gamma_{{ij}}}}{{\partial S}} = -\frac{{\partial^3P_{{ij}}}}{{\partial S^3}}`, for :math:`i = 1,2,\ldots,m` and :math:`j = 1,2,\ldots,n`.
**colour** : float, ndarray, shape :math:`\left(m, n\right)`
:math:`\mathrm{colour}[i-1,j-1]`, contains the third-order Greek measuring the sensitivity of the second-order Greek :math:`\Gamma_{{ij}}` to change in the time, i.e., :math:`-\frac{{\partial \Gamma_{{ij}}}}{{\partial T}} = -\frac{{\partial^3P_{{ij}}}}{{\partial S\partial T}}`, for :math:`i = 1,2,\ldots,m` and :math:`j = 1,2,\ldots,n`.
**zomma** : float, ndarray, shape :math:`\left(m, n\right)`
:math:`\mathrm{zomma}[i-1,j-1]`, contains the third-order Greek measuring the sensitivity of the second-order Greek :math:`\Gamma_{{ij}}` to change in the volatility of the underlying asset, i.e., :math:`-\frac{{\partial \Gamma_{{ij}}}}{{\partial \sigma }} = -\frac{{\partial^3P_{{ij}}}}{{\partial S^2\partial \sigma }}`, for :math:`i = 1,2,\ldots,m` and :math:`j = 1,2,\ldots,n`.
**vomma** : float, ndarray, shape :math:`\left(m, n\right)`
:math:`\mathrm{vomma}[i-1,j-1]`, contains the second-order Greek measuring the sensitivity of the first-order Greek :math:`\Delta_{{ij}}` to change in the volatility of the underlying asset, i.e., :math:`-\frac{{\partial \Delta_{{ij}}}}{{\partial \sigma }} = -\frac{{\partial^2P_{{ij}}}}{{\partial \sigma^2}}`, for :math:`i = 1,2,\ldots,m` and :math:`j = 1,2,\ldots,n`.
.. _s30sb-py2-py-errors:
**Raises**
**NagValueError**
(`errno` :math:`1`)
On entry, :math:`\mathrm{calput} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{calput} = \text{‘C'} \text{ or } \text{‘P'}`.
(`errno` :math:`2`)
On entry, :math:`m = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`m\geq 1`.
(`errno` :math:`3`)
On entry, :math:`n = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`n\geq 1`.
(`errno` :math:`4`)
On entry, :math:`\mathrm{x}[\langle\mathit{\boldsymbol{value}}\rangle] = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{x}[i]\geq \langle\mathit{\boldsymbol{value}}\rangle` and :math:`\mathrm{x}[i]\leq \langle\mathit{\boldsymbol{value}}\rangle`.
(`errno` :math:`5`)
On entry, :math:`\mathrm{s} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{s}\geq \langle\mathit{\boldsymbol{value}}\rangle` and :math:`\mathrm{s}\leq \langle\mathit{\boldsymbol{value}}\rangle`.
(`errno` :math:`6`)
On entry, :math:`\mathrm{t}[\langle\mathit{\boldsymbol{value}}\rangle] = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{t}[i]\geq \langle\mathit{\boldsymbol{value}}\rangle`.
(`errno` :math:`7`)
On entry, :math:`\mathrm{sigma} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{sigma} > 0.0`.
(`errno` :math:`8`)
On entry, :math:`\mathrm{r} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{r}\geq 0.0`.
.. _s30sb-py2-py-notes:
**Notes**
``opt_asian_geom_greeks`` computes the price of an Asian geometric continuous average-rate option, together with the Greeks or sensitivities, which are the partial derivatives of the option price with respect to certain of the other input parameters.
The annual volatility, :math:`\sigma`, risk-free rate, :math:`r`, and cost of carry, :math:`b`, are constants (see Kemna and Vorst (1990)).
For a given strike price, :math:`X`, the price of a call option with underlying price, :math:`S`, and time to expiry, :math:`T`, is
.. math::
P_{\mathrm{call}} = Se^{{\left(\bar{b}-r\right)T}}\Phi \left(\bar{d}_1\right)-Xe^{{-rT}}\Phi \left(\bar{d}_2\right)\text{,}
and the corresponding put option price is
.. math::
P_{\mathrm{put}} = Xe^{{-rT}}\Phi \left(-\bar{d}_2\right)-Se^{{\left(\bar{b}-r\right)T}}\Phi \left(-\bar{d}_1\right)\text{,}
where
.. math::
\bar{d}_1 = \frac{{\mathrm{ln}\left(S/X\right)+\left(\bar{b}+\bar{\sigma }^2/2\right)T}}{{\bar{\sigma }\sqrt{T}}}
and
.. math::
\bar{d}_2 = \bar{d}_1-\bar{\sigma }\sqrt{T}\text{,}
with
.. math::
\bar{\sigma } = \frac{\sigma }{\sqrt{3}}\text{, }\quad \bar{b} = \frac{1}{2}\left(b-\frac{\sigma^2}{6}\right)\text{.}
:math:`\Phi` is the cumulative Normal distribution function,
.. math::
\Phi \left(x\right) = \frac{1}{{\sqrt{2\pi }}}\int_{{-\infty }}^x\mathrm{exp}\left({-y^2}/2\right)dy\text{.}
The option price :math:`P_{{ij}} = P\left({X = X_i}, {T = T_j}\right)` is computed for each strike price in a set :math:`X_i`, :math:`i = 1,2,\ldots,m`, and for each expiry time in a set :math:`T_j`, :math:`j = 1,2,\ldots,n`.
.. _s30sb-py2-py-references:
**References**
Kemna, A and Vorst, A, 1990, `A pricing method for options based on average asset values`, Journal of Banking and Finance (14), 113--129
"""
raise NotImplementedError