up follow livre
This commit is contained in:
parent
70a5c3465c
commit
cffb31c1ef
12198 changed files with 2562132 additions and 35 deletions
|
|
@ -0,0 +1 @@
|
|||
from scipy.special cimport cython_special
|
||||
841
venv/lib/python3.13/site-packages/scipy/special/__init__.py
Normal file
841
venv/lib/python3.13/site-packages/scipy/special/__init__.py
Normal file
|
|
@ -0,0 +1,841 @@
|
|||
"""
|
||||
========================================
|
||||
Special functions (:mod:`scipy.special`)
|
||||
========================================
|
||||
|
||||
.. currentmodule:: scipy.special
|
||||
|
||||
Almost all of the functions below accept NumPy arrays as input
|
||||
arguments as well as single numbers. This means they follow
|
||||
broadcasting and automatic array-looping rules. Technically,
|
||||
they are `NumPy universal functions
|
||||
<https://numpy.org/doc/stable/user/basics.ufuncs.html#ufuncs-basics>`_.
|
||||
Functions which do not accept NumPy arrays are marked by a warning
|
||||
in the section description.
|
||||
|
||||
.. seealso::
|
||||
|
||||
`scipy.special.cython_special` -- Typed Cython versions of special functions
|
||||
|
||||
|
||||
Error handling
|
||||
==============
|
||||
|
||||
Errors are handled by returning NaNs or other appropriate values.
|
||||
Some of the special function routines can emit warnings or raise
|
||||
exceptions when an error occurs. By default this is disabled, except
|
||||
for memory allocation errors, which result in an exception being raised.
|
||||
To query and control the current error handling state the following
|
||||
functions are provided.
|
||||
|
||||
.. autosummary::
|
||||
:toctree: generated/
|
||||
|
||||
geterr -- Get the current way of handling special-function errors.
|
||||
seterr -- Set how special-function errors are handled.
|
||||
errstate -- Context manager for special-function error handling.
|
||||
SpecialFunctionWarning -- Warning that can be emitted by special functions.
|
||||
SpecialFunctionError -- Exception that can be raised by special functions.
|
||||
|
||||
Available functions
|
||||
===================
|
||||
|
||||
Airy functions
|
||||
--------------
|
||||
|
||||
.. autosummary::
|
||||
:toctree: generated/
|
||||
|
||||
airy -- Airy functions and their derivatives.
|
||||
airye -- Exponentially scaled Airy functions and their derivatives.
|
||||
ai_zeros -- Compute `nt` zeros and values of the Airy function Ai and its derivative.
|
||||
bi_zeros -- Compute `nt` zeros and values of the Airy function Bi and its derivative.
|
||||
itairy -- Integrals of Airy functions
|
||||
|
||||
|
||||
Elliptic functions and integrals
|
||||
--------------------------------
|
||||
|
||||
.. autosummary::
|
||||
:toctree: generated/
|
||||
|
||||
ellipj -- Jacobian elliptic functions.
|
||||
ellipk -- Complete elliptic integral of the first kind.
|
||||
ellipkm1 -- Complete elliptic integral of the first kind around `m` = 1.
|
||||
ellipkinc -- Incomplete elliptic integral of the first kind.
|
||||
ellipe -- Complete elliptic integral of the second kind.
|
||||
ellipeinc -- Incomplete elliptic integral of the second kind.
|
||||
elliprc -- Degenerate symmetric integral RC.
|
||||
elliprd -- Symmetric elliptic integral of the second kind.
|
||||
elliprf -- Completely-symmetric elliptic integral of the first kind.
|
||||
elliprg -- Completely-symmetric elliptic integral of the second kind.
|
||||
elliprj -- Symmetric elliptic integral of the third kind.
|
||||
|
||||
Bessel functions
|
||||
----------------
|
||||
|
||||
.. autosummary::
|
||||
:toctree: generated/
|
||||
|
||||
jv -- Bessel function of the first kind of real order and \
|
||||
complex argument.
|
||||
jve -- Exponentially scaled Bessel function of order `v`.
|
||||
yn -- Bessel function of the second kind of integer order and \
|
||||
real argument.
|
||||
yv -- Bessel function of the second kind of real order and \
|
||||
complex argument.
|
||||
yve -- Exponentially scaled Bessel function of the second kind \
|
||||
of real order.
|
||||
kn -- Modified Bessel function of the second kind of integer \
|
||||
order `n`
|
||||
kv -- Modified Bessel function of the second kind of real order \
|
||||
`v`
|
||||
kve -- Exponentially scaled modified Bessel function of the \
|
||||
second kind.
|
||||
iv -- Modified Bessel function of the first kind of real order.
|
||||
ive -- Exponentially scaled modified Bessel function of the \
|
||||
first kind.
|
||||
hankel1 -- Hankel function of the first kind.
|
||||
hankel1e -- Exponentially scaled Hankel function of the first kind.
|
||||
hankel2 -- Hankel function of the second kind.
|
||||
hankel2e -- Exponentially scaled Hankel function of the second kind.
|
||||
wright_bessel -- Wright's generalized Bessel function.
|
||||
log_wright_bessel -- Logarithm of Wright's generalized Bessel function.
|
||||
|
||||
The following function does not accept NumPy arrays (it is not a
|
||||
universal function):
|
||||
|
||||
.. autosummary::
|
||||
:toctree: generated/
|
||||
|
||||
lmbda -- Jahnke-Emden Lambda function, Lambdav(x).
|
||||
|
||||
Zeros of Bessel functions
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
The following functions do not accept NumPy arrays (they are not
|
||||
universal functions):
|
||||
|
||||
.. autosummary::
|
||||
:toctree: generated/
|
||||
|
||||
jnjnp_zeros -- Compute zeros of integer-order Bessel functions Jn and Jn'.
|
||||
jnyn_zeros -- Compute nt zeros of Bessel functions Jn(x), Jn'(x), Yn(x), and Yn'(x).
|
||||
jn_zeros -- Compute zeros of integer-order Bessel function Jn(x).
|
||||
jnp_zeros -- Compute zeros of integer-order Bessel function derivative Jn'(x).
|
||||
yn_zeros -- Compute zeros of integer-order Bessel function Yn(x).
|
||||
ynp_zeros -- Compute zeros of integer-order Bessel function derivative Yn'(x).
|
||||
y0_zeros -- Compute nt zeros of Bessel function Y0(z), and derivative at each zero.
|
||||
y1_zeros -- Compute nt zeros of Bessel function Y1(z), and derivative at each zero.
|
||||
y1p_zeros -- Compute nt zeros of Bessel derivative Y1'(z), and value at each zero.
|
||||
|
||||
Faster versions of common Bessel functions
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. autosummary::
|
||||
:toctree: generated/
|
||||
|
||||
j0 -- Bessel function of the first kind of order 0.
|
||||
j1 -- Bessel function of the first kind of order 1.
|
||||
y0 -- Bessel function of the second kind of order 0.
|
||||
y1 -- Bessel function of the second kind of order 1.
|
||||
i0 -- Modified Bessel function of order 0.
|
||||
i0e -- Exponentially scaled modified Bessel function of order 0.
|
||||
i1 -- Modified Bessel function of order 1.
|
||||
i1e -- Exponentially scaled modified Bessel function of order 1.
|
||||
k0 -- Modified Bessel function of the second kind of order 0, :math:`K_0`.
|
||||
k0e -- Exponentially scaled modified Bessel function K of order 0
|
||||
k1 -- Modified Bessel function of the second kind of order 1, :math:`K_1(x)`.
|
||||
k1e -- Exponentially scaled modified Bessel function K of order 1.
|
||||
|
||||
Integrals of Bessel functions
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. autosummary::
|
||||
:toctree: generated/
|
||||
|
||||
itj0y0 -- Integrals of Bessel functions of order 0.
|
||||
it2j0y0 -- Integrals related to Bessel functions of order 0.
|
||||
iti0k0 -- Integrals of modified Bessel functions of order 0.
|
||||
it2i0k0 -- Integrals related to modified Bessel functions of order 0.
|
||||
besselpoly -- Weighted integral of a Bessel function.
|
||||
|
||||
Derivatives of Bessel functions
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. autosummary::
|
||||
:toctree: generated/
|
||||
|
||||
jvp -- Compute nth derivative of Bessel function Jv(z) with respect to `z`.
|
||||
yvp -- Compute nth derivative of Bessel function Yv(z) with respect to `z`.
|
||||
kvp -- Compute nth derivative of real-order modified Bessel function Kv(z)
|
||||
ivp -- Compute nth derivative of modified Bessel function Iv(z) with respect to `z`.
|
||||
h1vp -- Compute nth derivative of Hankel function H1v(z) with respect to `z`.
|
||||
h2vp -- Compute nth derivative of Hankel function H2v(z) with respect to `z`.
|
||||
|
||||
Spherical Bessel functions
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. autosummary::
|
||||
:toctree: generated/
|
||||
|
||||
spherical_jn -- Spherical Bessel function of the first kind or its derivative.
|
||||
spherical_yn -- Spherical Bessel function of the second kind or its derivative.
|
||||
spherical_in -- Modified spherical Bessel function of the first kind or its derivative.
|
||||
spherical_kn -- Modified spherical Bessel function of the second kind or its derivative.
|
||||
|
||||
Riccati-Bessel functions
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
The following functions do not accept NumPy arrays (they are not
|
||||
universal functions):
|
||||
|
||||
.. autosummary::
|
||||
:toctree: generated/
|
||||
|
||||
riccati_jn -- Compute Ricatti-Bessel function of the first kind and its derivative.
|
||||
riccati_yn -- Compute Ricatti-Bessel function of the second kind and its derivative.
|
||||
|
||||
Struve functions
|
||||
----------------
|
||||
|
||||
.. autosummary::
|
||||
:toctree: generated/
|
||||
|
||||
struve -- Struve function.
|
||||
modstruve -- Modified Struve function.
|
||||
itstruve0 -- Integral of the Struve function of order 0.
|
||||
it2struve0 -- Integral related to the Struve function of order 0.
|
||||
itmodstruve0 -- Integral of the modified Struve function of order 0.
|
||||
|
||||
|
||||
Raw statistical functions
|
||||
-------------------------
|
||||
|
||||
.. seealso:: :mod:`scipy.stats`: Friendly versions of these functions.
|
||||
|
||||
Binomial distribution
|
||||
^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. autosummary::
|
||||
:toctree: generated/
|
||||
|
||||
bdtr -- Binomial distribution cumulative distribution function.
|
||||
bdtrc -- Binomial distribution survival function.
|
||||
bdtri -- Inverse function to `bdtr` with respect to `p`.
|
||||
bdtrik -- Inverse function to `bdtr` with respect to `k`.
|
||||
bdtrin -- Inverse function to `bdtr` with respect to `n`.
|
||||
|
||||
Beta distribution
|
||||
^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. autosummary::
|
||||
:toctree: generated/
|
||||
|
||||
btdtria -- Inverse of `betainc` with respect to `a`.
|
||||
btdtrib -- Inverse of `betainc` with respect to `b`.
|
||||
|
||||
F distribution
|
||||
^^^^^^^^^^^^^^
|
||||
|
||||
.. autosummary::
|
||||
:toctree: generated/
|
||||
|
||||
fdtr -- F cumulative distribution function.
|
||||
fdtrc -- F survival function.
|
||||
fdtri -- The `p`-th quantile of the F-distribution.
|
||||
fdtridfd -- Inverse to `fdtr` vs dfd.
|
||||
|
||||
Gamma distribution
|
||||
^^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. autosummary::
|
||||
:toctree: generated/
|
||||
|
||||
gdtr -- Gamma distribution cumulative distribution function.
|
||||
gdtrc -- Gamma distribution survival function.
|
||||
gdtria -- Inverse of `gdtr` vs a.
|
||||
gdtrib -- Inverse of `gdtr` vs b.
|
||||
gdtrix -- Inverse of `gdtr` vs x.
|
||||
|
||||
Negative binomial distribution
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. autosummary::
|
||||
:toctree: generated/
|
||||
|
||||
nbdtr -- Negative binomial cumulative distribution function.
|
||||
nbdtrc -- Negative binomial survival function.
|
||||
nbdtri -- Inverse of `nbdtr` vs `p`.
|
||||
nbdtrik -- Inverse of `nbdtr` vs `k`.
|
||||
nbdtrin -- Inverse of `nbdtr` vs `n`.
|
||||
|
||||
Noncentral F distribution
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. autosummary::
|
||||
:toctree: generated/
|
||||
|
||||
ncfdtr -- Cumulative distribution function of the non-central F distribution.
|
||||
ncfdtridfd -- Calculate degrees of freedom (denominator) for the noncentral F-distribution.
|
||||
ncfdtridfn -- Calculate degrees of freedom (numerator) for the noncentral F-distribution.
|
||||
ncfdtri -- Inverse cumulative distribution function of the non-central F distribution.
|
||||
ncfdtrinc -- Calculate non-centrality parameter for non-central F distribution.
|
||||
|
||||
Noncentral t distribution
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. autosummary::
|
||||
:toctree: generated/
|
||||
|
||||
nctdtr -- Cumulative distribution function of the non-central `t` distribution.
|
||||
nctdtridf -- Calculate degrees of freedom for non-central t distribution.
|
||||
nctdtrit -- Inverse cumulative distribution function of the non-central t distribution.
|
||||
nctdtrinc -- Calculate non-centrality parameter for non-central t distribution.
|
||||
|
||||
Normal distribution
|
||||
^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. autosummary::
|
||||
:toctree: generated/
|
||||
|
||||
nrdtrimn -- Calculate mean of normal distribution given other params.
|
||||
nrdtrisd -- Calculate standard deviation of normal distribution given other params.
|
||||
ndtr -- Normal cumulative distribution function.
|
||||
log_ndtr -- Logarithm of normal cumulative distribution function.
|
||||
ndtri -- Inverse of `ndtr` vs x.
|
||||
ndtri_exp -- Inverse of `log_ndtr` vs x.
|
||||
|
||||
Poisson distribution
|
||||
^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. autosummary::
|
||||
:toctree: generated/
|
||||
|
||||
pdtr -- Poisson cumulative distribution function.
|
||||
pdtrc -- Poisson survival function.
|
||||
pdtri -- Inverse to `pdtr` vs m.
|
||||
pdtrik -- Inverse to `pdtr` vs k.
|
||||
|
||||
Student t distribution
|
||||
^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. autosummary::
|
||||
:toctree: generated/
|
||||
|
||||
stdtr -- Student t distribution cumulative distribution function.
|
||||
stdtridf -- Inverse of `stdtr` vs df.
|
||||
stdtrit -- Inverse of `stdtr` vs `t`.
|
||||
|
||||
Chi square distribution
|
||||
^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. autosummary::
|
||||
:toctree: generated/
|
||||
|
||||
chdtr -- Chi square cumulative distribution function.
|
||||
chdtrc -- Chi square survival function.
|
||||
chdtri -- Inverse to `chdtrc`.
|
||||
chdtriv -- Inverse to `chdtr` vs `v`.
|
||||
|
||||
Non-central chi square distribution
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. autosummary::
|
||||
:toctree: generated/
|
||||
|
||||
chndtr -- Non-central chi square cumulative distribution function.
|
||||
chndtridf -- Inverse to `chndtr` vs `df`.
|
||||
chndtrinc -- Inverse to `chndtr` vs `nc`.
|
||||
chndtrix -- Inverse to `chndtr` vs `x`.
|
||||
|
||||
Kolmogorov distribution
|
||||
^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. autosummary::
|
||||
:toctree: generated/
|
||||
|
||||
smirnov -- Kolmogorov-Smirnov complementary cumulative distribution function.
|
||||
smirnovi -- Inverse to `smirnov`.
|
||||
kolmogorov -- Complementary cumulative distribution function of Kolmogorov distribution.
|
||||
kolmogi -- Inverse function to `kolmogorov`.
|
||||
|
||||
Box-Cox transformation
|
||||
^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. autosummary::
|
||||
:toctree: generated/
|
||||
|
||||
boxcox -- Compute the Box-Cox transformation.
|
||||
boxcox1p -- Compute the Box-Cox transformation of 1 + `x`.
|
||||
inv_boxcox -- Compute the inverse of the Box-Cox transformation.
|
||||
inv_boxcox1p -- Compute the inverse of the Box-Cox transformation.
|
||||
|
||||
|
||||
Sigmoidal functions
|
||||
^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. autosummary::
|
||||
:toctree: generated/
|
||||
|
||||
logit -- Logit ufunc for ndarrays.
|
||||
expit -- Logistic sigmoid function.
|
||||
log_expit -- Logarithm of the logistic sigmoid function.
|
||||
|
||||
Miscellaneous
|
||||
^^^^^^^^^^^^^
|
||||
|
||||
.. autosummary::
|
||||
:toctree: generated/
|
||||
|
||||
tklmbda -- Tukey-Lambda cumulative distribution function.
|
||||
owens_t -- Owen's T Function.
|
||||
|
||||
|
||||
Information Theory functions
|
||||
----------------------------
|
||||
|
||||
.. autosummary::
|
||||
:toctree: generated/
|
||||
|
||||
entr -- Elementwise function for computing entropy.
|
||||
rel_entr -- Elementwise function for computing relative entropy.
|
||||
kl_div -- Elementwise function for computing Kullback-Leibler divergence.
|
||||
huber -- Huber loss function.
|
||||
pseudo_huber -- Pseudo-Huber loss function.
|
||||
|
||||
|
||||
Gamma and related functions
|
||||
---------------------------
|
||||
|
||||
.. autosummary::
|
||||
:toctree: generated/
|
||||
|
||||
gamma -- Gamma function.
|
||||
gammaln -- Logarithm of the absolute value of the Gamma function for real inputs.
|
||||
loggamma -- Principal branch of the logarithm of the Gamma function.
|
||||
gammasgn -- Sign of the gamma function.
|
||||
gammainc -- Regularized lower incomplete gamma function.
|
||||
gammaincinv -- Inverse to `gammainc`.
|
||||
gammaincc -- Regularized upper incomplete gamma function.
|
||||
gammainccinv -- Inverse to `gammaincc`.
|
||||
beta -- Beta function.
|
||||
betaln -- Natural logarithm of absolute value of beta function.
|
||||
betainc -- Incomplete beta integral.
|
||||
betaincc -- Complemented incomplete beta integral.
|
||||
betaincinv -- Inverse function to beta integral.
|
||||
betainccinv -- Inverse of the complemented incomplete beta integral.
|
||||
psi -- The digamma function.
|
||||
rgamma -- Gamma function inverted.
|
||||
polygamma -- Polygamma function n.
|
||||
multigammaln -- Returns the log of multivariate gamma, also sometimes called the generalized gamma.
|
||||
digamma -- psi(x[, out]).
|
||||
poch -- Rising factorial (z)_m.
|
||||
|
||||
Error function and Fresnel integrals
|
||||
------------------------------------
|
||||
|
||||
.. autosummary::
|
||||
:toctree: generated/
|
||||
|
||||
erf -- Returns the error function of complex argument.
|
||||
erfc -- Complementary error function, ``1 - erf(x)``.
|
||||
erfcx -- Scaled complementary error function, ``exp(x**2) * erfc(x)``.
|
||||
erfi -- Imaginary error function, ``-i erf(i z)``.
|
||||
erfinv -- Inverse function for erf.
|
||||
erfcinv -- Inverse function for erfc.
|
||||
wofz -- Faddeeva function.
|
||||
dawsn -- Dawson's integral.
|
||||
fresnel -- Fresnel sin and cos integrals.
|
||||
fresnel_zeros -- Compute nt complex zeros of sine and cosine Fresnel integrals S(z) and C(z).
|
||||
modfresnelp -- Modified Fresnel positive integrals.
|
||||
modfresnelm -- Modified Fresnel negative integrals.
|
||||
voigt_profile -- Voigt profile.
|
||||
|
||||
The following functions do not accept NumPy arrays (they are not
|
||||
universal functions):
|
||||
|
||||
.. autosummary::
|
||||
:toctree: generated/
|
||||
|
||||
erf_zeros -- Compute nt complex zeros of error function erf(z).
|
||||
fresnelc_zeros -- Compute nt complex zeros of cosine Fresnel integral C(z).
|
||||
fresnels_zeros -- Compute nt complex zeros of sine Fresnel integral S(z).
|
||||
|
||||
Legendre functions
|
||||
------------------
|
||||
|
||||
.. autosummary::
|
||||
:toctree: generated/
|
||||
|
||||
legendre_p -- Legendre polynomials of the first kind.
|
||||
legendre_p_all -- All Legendre polynomials of the first kind up to a specified order.
|
||||
assoc_legendre_p -- Associated Legendre polynomials of the first kind.
|
||||
assoc_legendre_p_all -- All associated Legendre polynomials of the first kind up to a specified order and degree.
|
||||
sph_legendre_p -- Spherical Legendre polynomials of the first kind.
|
||||
sph_legendre_p_all -- All spherical Legendre polynomials of the first kind up to a specified order and degree.
|
||||
sph_harm_y -- Spherical harmonics.
|
||||
sph_harm_y_all -- All spherical harmonics up to a specified order and degree.
|
||||
|
||||
The following functions are in the process of being deprecated in favor of the above,
|
||||
which provide a more flexible and consistent interface.
|
||||
|
||||
.. autosummary::
|
||||
:toctree: generated/
|
||||
|
||||
lpmv -- Associated Legendre function of integer order and real degree.
|
||||
sph_harm -- Compute spherical harmonics.
|
||||
clpmn -- Associated Legendre function of the first kind for complex arguments.
|
||||
lpn -- Legendre function of the first kind.
|
||||
lqn -- Legendre function of the second kind.
|
||||
lpmn -- Sequence of associated Legendre functions of the first kind.
|
||||
lqmn -- Sequence of associated Legendre functions of the second kind.
|
||||
|
||||
Ellipsoidal harmonics
|
||||
---------------------
|
||||
|
||||
.. autosummary::
|
||||
:toctree: generated/
|
||||
|
||||
ellip_harm -- Ellipsoidal harmonic functions E^p_n(l).
|
||||
ellip_harm_2 -- Ellipsoidal harmonic functions F^p_n(l).
|
||||
ellip_normal -- Ellipsoidal harmonic normalization constants gamma^p_n.
|
||||
|
||||
Orthogonal polynomials
|
||||
----------------------
|
||||
|
||||
The following functions evaluate values of orthogonal polynomials:
|
||||
|
||||
.. autosummary::
|
||||
:toctree: generated/
|
||||
|
||||
assoc_laguerre -- Compute the generalized (associated) Laguerre polynomial of degree n and order k.
|
||||
eval_legendre -- Evaluate Legendre polynomial at a point.
|
||||
eval_chebyt -- Evaluate Chebyshev polynomial of the first kind at a point.
|
||||
eval_chebyu -- Evaluate Chebyshev polynomial of the second kind at a point.
|
||||
eval_chebyc -- Evaluate Chebyshev polynomial of the first kind on [-2, 2] at a point.
|
||||
eval_chebys -- Evaluate Chebyshev polynomial of the second kind on [-2, 2] at a point.
|
||||
eval_jacobi -- Evaluate Jacobi polynomial at a point.
|
||||
eval_laguerre -- Evaluate Laguerre polynomial at a point.
|
||||
eval_genlaguerre -- Evaluate generalized Laguerre polynomial at a point.
|
||||
eval_hermite -- Evaluate physicist's Hermite polynomial at a point.
|
||||
eval_hermitenorm -- Evaluate probabilist's (normalized) Hermite polynomial at a point.
|
||||
eval_gegenbauer -- Evaluate Gegenbauer polynomial at a point.
|
||||
eval_sh_legendre -- Evaluate shifted Legendre polynomial at a point.
|
||||
eval_sh_chebyt -- Evaluate shifted Chebyshev polynomial of the first kind at a point.
|
||||
eval_sh_chebyu -- Evaluate shifted Chebyshev polynomial of the second kind at a point.
|
||||
eval_sh_jacobi -- Evaluate shifted Jacobi polynomial at a point.
|
||||
|
||||
The following functions compute roots and quadrature weights for
|
||||
orthogonal polynomials:
|
||||
|
||||
.. autosummary::
|
||||
:toctree: generated/
|
||||
|
||||
roots_legendre -- Gauss-Legendre quadrature.
|
||||
roots_chebyt -- Gauss-Chebyshev (first kind) quadrature.
|
||||
roots_chebyu -- Gauss-Chebyshev (second kind) quadrature.
|
||||
roots_chebyc -- Gauss-Chebyshev (first kind) quadrature.
|
||||
roots_chebys -- Gauss-Chebyshev (second kind) quadrature.
|
||||
roots_jacobi -- Gauss-Jacobi quadrature.
|
||||
roots_laguerre -- Gauss-Laguerre quadrature.
|
||||
roots_genlaguerre -- Gauss-generalized Laguerre quadrature.
|
||||
roots_hermite -- Gauss-Hermite (physicist's) quadrature.
|
||||
roots_hermitenorm -- Gauss-Hermite (statistician's) quadrature.
|
||||
roots_gegenbauer -- Gauss-Gegenbauer quadrature.
|
||||
roots_sh_legendre -- Gauss-Legendre (shifted) quadrature.
|
||||
roots_sh_chebyt -- Gauss-Chebyshev (first kind, shifted) quadrature.
|
||||
roots_sh_chebyu -- Gauss-Chebyshev (second kind, shifted) quadrature.
|
||||
roots_sh_jacobi -- Gauss-Jacobi (shifted) quadrature.
|
||||
|
||||
The functions below, in turn, return the polynomial coefficients in
|
||||
``orthopoly1d`` objects, which function similarly as `numpy.poly1d`.
|
||||
The ``orthopoly1d`` class also has an attribute ``weights``, which returns
|
||||
the roots, weights, and total weights for the appropriate form of Gaussian
|
||||
quadrature. These are returned in an ``n x 3`` array with roots in the first
|
||||
column, weights in the second column, and total weights in the final column.
|
||||
Note that ``orthopoly1d`` objects are converted to `~numpy.poly1d` when doing
|
||||
arithmetic, and lose information of the original orthogonal polynomial.
|
||||
|
||||
.. autosummary::
|
||||
:toctree: generated/
|
||||
|
||||
legendre -- Legendre polynomial.
|
||||
chebyt -- Chebyshev polynomial of the first kind.
|
||||
chebyu -- Chebyshev polynomial of the second kind.
|
||||
chebyc -- Chebyshev polynomial of the first kind on :math:`[-2, 2]`.
|
||||
chebys -- Chebyshev polynomial of the second kind on :math:`[-2, 2]`.
|
||||
jacobi -- Jacobi polynomial.
|
||||
laguerre -- Laguerre polynomial.
|
||||
genlaguerre -- Generalized (associated) Laguerre polynomial.
|
||||
hermite -- Physicist's Hermite polynomial.
|
||||
hermitenorm -- Normalized (probabilist's) Hermite polynomial.
|
||||
gegenbauer -- Gegenbauer (ultraspherical) polynomial.
|
||||
sh_legendre -- Shifted Legendre polynomial.
|
||||
sh_chebyt -- Shifted Chebyshev polynomial of the first kind.
|
||||
sh_chebyu -- Shifted Chebyshev polynomial of the second kind.
|
||||
sh_jacobi -- Shifted Jacobi polynomial.
|
||||
|
||||
.. warning::
|
||||
|
||||
Computing values of high-order polynomials (around ``order > 20``) using
|
||||
polynomial coefficients is numerically unstable. To evaluate polynomial
|
||||
values, the ``eval_*`` functions should be used instead.
|
||||
|
||||
|
||||
Hypergeometric functions
|
||||
------------------------
|
||||
|
||||
.. autosummary::
|
||||
:toctree: generated/
|
||||
|
||||
hyp2f1 -- Gauss hypergeometric function 2F1(a, b; c; z).
|
||||
hyp1f1 -- Confluent hypergeometric function 1F1(a, b; x).
|
||||
hyperu -- Confluent hypergeometric function U(a, b, x) of the second kind.
|
||||
hyp0f1 -- Confluent hypergeometric limit function 0F1.
|
||||
|
||||
|
||||
Parabolic cylinder functions
|
||||
----------------------------
|
||||
|
||||
.. autosummary::
|
||||
:toctree: generated/
|
||||
|
||||
pbdv -- Parabolic cylinder function D.
|
||||
pbvv -- Parabolic cylinder function V.
|
||||
pbwa -- Parabolic cylinder function W.
|
||||
|
||||
The following functions do not accept NumPy arrays (they are not
|
||||
universal functions):
|
||||
|
||||
.. autosummary::
|
||||
:toctree: generated/
|
||||
|
||||
pbdv_seq -- Parabolic cylinder functions Dv(x) and derivatives.
|
||||
pbvv_seq -- Parabolic cylinder functions Vv(x) and derivatives.
|
||||
pbdn_seq -- Parabolic cylinder functions Dn(z) and derivatives.
|
||||
|
||||
Mathieu and related functions
|
||||
-----------------------------
|
||||
|
||||
.. autosummary::
|
||||
:toctree: generated/
|
||||
|
||||
mathieu_a -- Characteristic value of even Mathieu functions.
|
||||
mathieu_b -- Characteristic value of odd Mathieu functions.
|
||||
|
||||
The following functions do not accept NumPy arrays (they are not
|
||||
universal functions):
|
||||
|
||||
.. autosummary::
|
||||
:toctree: generated/
|
||||
|
||||
mathieu_even_coef -- Fourier coefficients for even Mathieu and modified Mathieu functions.
|
||||
mathieu_odd_coef -- Fourier coefficients for even Mathieu and modified Mathieu functions.
|
||||
|
||||
The following return both function and first derivative:
|
||||
|
||||
.. autosummary::
|
||||
:toctree: generated/
|
||||
|
||||
mathieu_cem -- Even Mathieu function and its derivative.
|
||||
mathieu_sem -- Odd Mathieu function and its derivative.
|
||||
mathieu_modcem1 -- Even modified Mathieu function of the first kind and its derivative.
|
||||
mathieu_modcem2 -- Even modified Mathieu function of the second kind and its derivative.
|
||||
mathieu_modsem1 -- Odd modified Mathieu function of the first kind and its derivative.
|
||||
mathieu_modsem2 -- Odd modified Mathieu function of the second kind and its derivative.
|
||||
|
||||
Spheroidal wave functions
|
||||
-------------------------
|
||||
|
||||
.. autosummary::
|
||||
:toctree: generated/
|
||||
|
||||
pro_ang1 -- Prolate spheroidal angular function of the first kind and its derivative.
|
||||
pro_rad1 -- Prolate spheroidal radial function of the first kind and its derivative.
|
||||
pro_rad2 -- Prolate spheroidal radial function of the second kind and its derivative.
|
||||
obl_ang1 -- Oblate spheroidal angular function of the first kind and its derivative.
|
||||
obl_rad1 -- Oblate spheroidal radial function of the first kind and its derivative.
|
||||
obl_rad2 -- Oblate spheroidal radial function of the second kind and its derivative.
|
||||
pro_cv -- Characteristic value of prolate spheroidal function.
|
||||
obl_cv -- Characteristic value of oblate spheroidal function.
|
||||
pro_cv_seq -- Characteristic values for prolate spheroidal wave functions.
|
||||
obl_cv_seq -- Characteristic values for oblate spheroidal wave functions.
|
||||
|
||||
The following functions require pre-computed characteristic value:
|
||||
|
||||
.. autosummary::
|
||||
:toctree: generated/
|
||||
|
||||
pro_ang1_cv -- Prolate spheroidal angular function pro_ang1 for precomputed characteristic value.
|
||||
pro_rad1_cv -- Prolate spheroidal radial function pro_rad1 for precomputed characteristic value.
|
||||
pro_rad2_cv -- Prolate spheroidal radial function pro_rad2 for precomputed characteristic value.
|
||||
obl_ang1_cv -- Oblate spheroidal angular function obl_ang1 for precomputed characteristic value.
|
||||
obl_rad1_cv -- Oblate spheroidal radial function obl_rad1 for precomputed characteristic value.
|
||||
obl_rad2_cv -- Oblate spheroidal radial function obl_rad2 for precomputed characteristic value.
|
||||
|
||||
Kelvin functions
|
||||
----------------
|
||||
|
||||
.. autosummary::
|
||||
:toctree: generated/
|
||||
|
||||
kelvin -- Kelvin functions as complex numbers.
|
||||
kelvin_zeros -- Compute nt zeros of all Kelvin functions.
|
||||
ber -- Kelvin function ber.
|
||||
bei -- Kelvin function bei
|
||||
berp -- Derivative of the Kelvin function `ber`.
|
||||
beip -- Derivative of the Kelvin function `bei`.
|
||||
ker -- Kelvin function ker.
|
||||
kei -- Kelvin function ker.
|
||||
kerp -- Derivative of the Kelvin function ker.
|
||||
keip -- Derivative of the Kelvin function kei.
|
||||
|
||||
The following functions do not accept NumPy arrays (they are not
|
||||
universal functions):
|
||||
|
||||
.. autosummary::
|
||||
:toctree: generated/
|
||||
|
||||
ber_zeros -- Compute nt zeros of the Kelvin function ber(x).
|
||||
bei_zeros -- Compute nt zeros of the Kelvin function bei(x).
|
||||
berp_zeros -- Compute nt zeros of the Kelvin function ber'(x).
|
||||
beip_zeros -- Compute nt zeros of the Kelvin function bei'(x).
|
||||
ker_zeros -- Compute nt zeros of the Kelvin function ker(x).
|
||||
kei_zeros -- Compute nt zeros of the Kelvin function kei(x).
|
||||
kerp_zeros -- Compute nt zeros of the Kelvin function ker'(x).
|
||||
keip_zeros -- Compute nt zeros of the Kelvin function kei'(x).
|
||||
|
||||
Combinatorics
|
||||
-------------
|
||||
|
||||
.. autosummary::
|
||||
:toctree: generated/
|
||||
|
||||
comb -- The number of combinations of N things taken k at a time.
|
||||
perm -- Permutations of N things taken k at a time, i.e., k-permutations of N.
|
||||
stirling2 -- Stirling numbers of the second kind.
|
||||
|
||||
Lambert W and related functions
|
||||
-------------------------------
|
||||
|
||||
.. autosummary::
|
||||
:toctree: generated/
|
||||
|
||||
lambertw -- Lambert W function.
|
||||
wrightomega -- Wright Omega function.
|
||||
|
||||
Other special functions
|
||||
-----------------------
|
||||
|
||||
.. autosummary::
|
||||
:toctree: generated/
|
||||
|
||||
agm -- Arithmetic, Geometric Mean.
|
||||
bernoulli -- Bernoulli numbers B0..Bn (inclusive).
|
||||
binom -- Binomial coefficient
|
||||
diric -- Periodic sinc function, also called the Dirichlet function.
|
||||
euler -- Euler numbers E0..En (inclusive).
|
||||
expn -- Exponential integral E_n.
|
||||
exp1 -- Exponential integral E_1 of complex argument z.
|
||||
expi -- Exponential integral Ei.
|
||||
factorial -- The factorial of a number or array of numbers.
|
||||
factorial2 -- Double factorial.
|
||||
factorialk -- Multifactorial of n of order k, n(!!...!).
|
||||
shichi -- Hyperbolic sine and cosine integrals.
|
||||
sici -- Sine and cosine integrals.
|
||||
softmax -- Softmax function.
|
||||
log_softmax -- Logarithm of softmax function.
|
||||
spence -- Spence's function, also known as the dilogarithm.
|
||||
zeta -- Riemann zeta function.
|
||||
zetac -- Riemann zeta function minus 1.
|
||||
softplus -- Softplus function.
|
||||
|
||||
Convenience functions
|
||||
---------------------
|
||||
|
||||
.. autosummary::
|
||||
:toctree: generated/
|
||||
|
||||
cbrt -- Cube root of `x`.
|
||||
exp10 -- 10**x.
|
||||
exp2 -- 2**x.
|
||||
radian -- Convert from degrees to radians.
|
||||
cosdg -- Cosine of the angle `x` given in degrees.
|
||||
sindg -- Sine of angle given in degrees.
|
||||
tandg -- Tangent of angle x given in degrees.
|
||||
cotdg -- Cotangent of the angle `x` given in degrees.
|
||||
log1p -- Calculates log(1+x) for use when `x` is near zero.
|
||||
expm1 -- ``exp(x) - 1`` for use when `x` is near zero.
|
||||
cosm1 -- ``cos(x) - 1`` for use when `x` is near zero.
|
||||
powm1 -- ``x**y - 1`` for use when `y` is near zero or `x` is near 1.
|
||||
round -- Round to nearest integer.
|
||||
xlogy -- Compute ``x*log(y)`` so that the result is 0 if ``x = 0``.
|
||||
xlog1py -- Compute ``x*log1p(y)`` so that the result is 0 if ``x = 0``.
|
||||
logsumexp -- Compute the log of the sum of exponentials of input elements.
|
||||
exprel -- Relative error exponential, (exp(x)-1)/x, for use when `x` is near zero.
|
||||
sinc -- Return the sinc function.
|
||||
|
||||
""" # noqa: E501
|
||||
|
||||
|
||||
from ._sf_error import SpecialFunctionWarning, SpecialFunctionError
|
||||
|
||||
from . import _ufuncs
|
||||
from ._ufuncs import *
|
||||
|
||||
# Replace some function definitions from _ufuncs to add Array API support
|
||||
from ._support_alternative_backends import *
|
||||
|
||||
from . import _basic
|
||||
from ._basic import *
|
||||
|
||||
from ._logsumexp import logsumexp, softmax, log_softmax
|
||||
|
||||
from . import _multiufuncs
|
||||
from ._multiufuncs import *
|
||||
|
||||
from . import _orthogonal
|
||||
from ._orthogonal import *
|
||||
|
||||
from ._spfun_stats import multigammaln
|
||||
from ._ellip_harm import (
|
||||
ellip_harm,
|
||||
ellip_harm_2,
|
||||
ellip_normal
|
||||
)
|
||||
from ._lambertw import lambertw
|
||||
from ._spherical_bessel import (
|
||||
spherical_jn,
|
||||
spherical_yn,
|
||||
spherical_in,
|
||||
spherical_kn
|
||||
)
|
||||
|
||||
# Deprecated namespaces, to be removed in v2.0.0
|
||||
from . import add_newdocs, basic, orthogonal, specfun, sf_error, spfun_stats
|
||||
|
||||
# We replace some function definitions from _ufuncs with those from
|
||||
# _support_alternative_backends above, but those are all listed in _ufuncs.__all__,
|
||||
# so there is no need to consider _support_alternative_backends.__all__ here.
|
||||
__all__ = _ufuncs.__all__ + _basic.__all__ + _orthogonal.__all__ + _multiufuncs.__all__
|
||||
__all__ += [
|
||||
'SpecialFunctionWarning',
|
||||
'SpecialFunctionError',
|
||||
'logsumexp',
|
||||
'softmax',
|
||||
'log_softmax',
|
||||
'multigammaln',
|
||||
'ellip_harm',
|
||||
'ellip_harm_2',
|
||||
'ellip_normal',
|
||||
'lambertw',
|
||||
'spherical_jn',
|
||||
'spherical_yn',
|
||||
'spherical_in',
|
||||
'spherical_kn',
|
||||
]
|
||||
|
||||
from scipy._lib._testutils import PytestTester
|
||||
test = PytestTester(__name__)
|
||||
del PytestTester
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
9961
venv/lib/python3.13/site-packages/scipy/special/_add_newdocs.py
Normal file
9961
venv/lib/python3.13/site-packages/scipy/special/_add_newdocs.py
Normal file
File diff suppressed because it is too large
Load diff
3576
venv/lib/python3.13/site-packages/scipy/special/_basic.py
Normal file
3576
venv/lib/python3.13/site-packages/scipy/special/_basic.py
Normal file
File diff suppressed because it is too large
Load diff
Binary file not shown.
214
venv/lib/python3.13/site-packages/scipy/special/_ellip_harm.py
Normal file
214
venv/lib/python3.13/site-packages/scipy/special/_ellip_harm.py
Normal file
|
|
@ -0,0 +1,214 @@
|
|||
import numpy as np
|
||||
|
||||
from ._ufuncs import _ellip_harm
|
||||
from ._ellip_harm_2 import _ellipsoid, _ellipsoid_norm
|
||||
|
||||
|
||||
def ellip_harm(h2, k2, n, p, s, signm=1, signn=1):
|
||||
r"""
|
||||
Ellipsoidal harmonic functions E^p_n(l)
|
||||
|
||||
These are also known as Lame functions of the first kind, and are
|
||||
solutions to the Lame equation:
|
||||
|
||||
.. math:: (s^2 - h^2)(s^2 - k^2)E''(s)
|
||||
+ s(2s^2 - h^2 - k^2)E'(s) + (a - q s^2)E(s) = 0
|
||||
|
||||
where :math:`q = (n+1)n` and :math:`a` is the eigenvalue (not
|
||||
returned) corresponding to the solutions.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
h2 : float
|
||||
``h**2``
|
||||
k2 : float
|
||||
``k**2``; should be larger than ``h**2``
|
||||
n : int
|
||||
Degree
|
||||
s : float
|
||||
Coordinate
|
||||
p : int
|
||||
Order, can range between [1,2n+1]
|
||||
signm : {1, -1}, optional
|
||||
Sign of prefactor of functions. Can be +/-1. See Notes.
|
||||
signn : {1, -1}, optional
|
||||
Sign of prefactor of functions. Can be +/-1. See Notes.
|
||||
|
||||
Returns
|
||||
-------
|
||||
E : float
|
||||
the harmonic :math:`E^p_n(s)`
|
||||
|
||||
See Also
|
||||
--------
|
||||
ellip_harm_2, ellip_normal
|
||||
|
||||
Notes
|
||||
-----
|
||||
The geometric interpretation of the ellipsoidal functions is
|
||||
explained in [2]_, [3]_, [4]_. The `signm` and `signn` arguments control the
|
||||
sign of prefactors for functions according to their type::
|
||||
|
||||
K : +1
|
||||
L : signm
|
||||
M : signn
|
||||
N : signm*signn
|
||||
|
||||
.. versionadded:: 0.15.0
|
||||
|
||||
References
|
||||
----------
|
||||
.. [1] Digital Library of Mathematical Functions 29.12
|
||||
https://dlmf.nist.gov/29.12
|
||||
.. [2] Bardhan and Knepley, "Computational science and
|
||||
re-discovery: open-source implementations of
|
||||
ellipsoidal harmonics for problems in potential theory",
|
||||
Comput. Sci. Disc. 5, 014006 (2012)
|
||||
:doi:`10.1088/1749-4699/5/1/014006`.
|
||||
.. [3] David J.and Dechambre P, "Computation of Ellipsoidal
|
||||
Gravity Field Harmonics for small solar system bodies"
|
||||
pp. 30-36, 2000
|
||||
.. [4] George Dassios, "Ellipsoidal Harmonics: Theory and Applications"
|
||||
pp. 418, 2012
|
||||
|
||||
Examples
|
||||
--------
|
||||
>>> from scipy.special import ellip_harm
|
||||
>>> w = ellip_harm(5,8,1,1,2.5)
|
||||
>>> w
|
||||
2.5
|
||||
|
||||
Check that the functions indeed are solutions to the Lame equation:
|
||||
|
||||
>>> import numpy as np
|
||||
>>> from scipy.interpolate import UnivariateSpline
|
||||
>>> def eigenvalue(f, df, ddf):
|
||||
... r = (((s**2 - h**2) * (s**2 - k**2) * ddf
|
||||
... + s * (2*s**2 - h**2 - k**2) * df
|
||||
... - n * (n + 1)*s**2*f) / f)
|
||||
... return -r.mean(), r.std()
|
||||
>>> s = np.linspace(0.1, 10, 200)
|
||||
>>> k, h, n, p = 8.0, 2.2, 3, 2
|
||||
>>> E = ellip_harm(h**2, k**2, n, p, s)
|
||||
>>> E_spl = UnivariateSpline(s, E)
|
||||
>>> a, a_err = eigenvalue(E_spl(s), E_spl(s,1), E_spl(s,2))
|
||||
>>> a, a_err
|
||||
(583.44366156701483, 6.4580890640310646e-11)
|
||||
|
||||
""" # noqa: E501
|
||||
return _ellip_harm(h2, k2, n, p, s, signm, signn)
|
||||
|
||||
|
||||
_ellip_harm_2_vec = np.vectorize(_ellipsoid, otypes='d')
|
||||
|
||||
|
||||
def ellip_harm_2(h2, k2, n, p, s):
|
||||
r"""
|
||||
Ellipsoidal harmonic functions F^p_n(l)
|
||||
|
||||
These are also known as Lame functions of the second kind, and are
|
||||
solutions to the Lame equation:
|
||||
|
||||
.. math:: (s^2 - h^2)(s^2 - k^2)F''(s)
|
||||
+ s(2s^2 - h^2 - k^2)F'(s) + (a - q s^2)F(s) = 0
|
||||
|
||||
where :math:`q = (n+1)n` and :math:`a` is the eigenvalue (not
|
||||
returned) corresponding to the solutions.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
h2 : float
|
||||
``h**2``
|
||||
k2 : float
|
||||
``k**2``; should be larger than ``h**2``
|
||||
n : int
|
||||
Degree.
|
||||
p : int
|
||||
Order, can range between [1,2n+1].
|
||||
s : float
|
||||
Coordinate
|
||||
|
||||
Returns
|
||||
-------
|
||||
F : float
|
||||
The harmonic :math:`F^p_n(s)`
|
||||
|
||||
See Also
|
||||
--------
|
||||
ellip_harm, ellip_normal
|
||||
|
||||
Notes
|
||||
-----
|
||||
Lame functions of the second kind are related to the functions of the first kind:
|
||||
|
||||
.. math::
|
||||
|
||||
F^p_n(s)=(2n + 1)E^p_n(s)\int_{0}^{1/s}
|
||||
\frac{du}{(E^p_n(1/u))^2\sqrt{(1-u^2k^2)(1-u^2h^2)}}
|
||||
|
||||
.. versionadded:: 0.15.0
|
||||
|
||||
Examples
|
||||
--------
|
||||
>>> from scipy.special import ellip_harm_2
|
||||
>>> w = ellip_harm_2(5,8,2,1,10)
|
||||
>>> w
|
||||
0.00108056853382
|
||||
|
||||
"""
|
||||
with np.errstate(all='ignore'):
|
||||
return _ellip_harm_2_vec(h2, k2, n, p, s)
|
||||
|
||||
|
||||
def _ellip_normal_vec(h2, k2, n, p):
|
||||
return _ellipsoid_norm(h2, k2, n, p)
|
||||
|
||||
|
||||
_ellip_normal_vec = np.vectorize(_ellip_normal_vec, otypes='d')
|
||||
|
||||
|
||||
def ellip_normal(h2, k2, n, p):
|
||||
r"""
|
||||
Ellipsoidal harmonic normalization constants gamma^p_n
|
||||
|
||||
The normalization constant is defined as
|
||||
|
||||
.. math::
|
||||
|
||||
\gamma^p_n=8\int_{0}^{h}dx\int_{h}^{k}dy
|
||||
\frac{(y^2-x^2)(E^p_n(y)E^p_n(x))^2}{\sqrt((k^2-y^2)(y^2-h^2)(h^2-x^2)(k^2-x^2)}
|
||||
|
||||
Parameters
|
||||
----------
|
||||
h2 : float
|
||||
``h**2``
|
||||
k2 : float
|
||||
``k**2``; should be larger than ``h**2``
|
||||
n : int
|
||||
Degree.
|
||||
p : int
|
||||
Order, can range between [1,2n+1].
|
||||
|
||||
Returns
|
||||
-------
|
||||
gamma : float
|
||||
The normalization constant :math:`\gamma^p_n`
|
||||
|
||||
See Also
|
||||
--------
|
||||
ellip_harm, ellip_harm_2
|
||||
|
||||
Notes
|
||||
-----
|
||||
.. versionadded:: 0.15.0
|
||||
|
||||
Examples
|
||||
--------
|
||||
>>> from scipy.special import ellip_normal
|
||||
>>> w = ellip_normal(5,8,3,7)
|
||||
>>> w
|
||||
1723.38796997
|
||||
|
||||
"""
|
||||
with np.errstate(all='ignore'):
|
||||
return _ellip_normal_vec(h2, k2, n, p)
|
||||
Binary file not shown.
Binary file not shown.
|
|
@ -0,0 +1,17 @@
|
|||
import math
|
||||
import operator
|
||||
|
||||
def _nonneg_int_or_fail(n, var_name, strict=True):
|
||||
try:
|
||||
if strict:
|
||||
# Raises an exception if float
|
||||
n = operator.index(n)
|
||||
elif n == math.floor(n):
|
||||
n = int(n)
|
||||
else:
|
||||
raise ValueError()
|
||||
if n < 0:
|
||||
raise ValueError()
|
||||
except (ValueError, TypeError) as err:
|
||||
raise err.__class__(f"{var_name} must be a non-negative integer") from err
|
||||
return n
|
||||
149
venv/lib/python3.13/site-packages/scipy/special/_lambertw.py
Normal file
149
venv/lib/python3.13/site-packages/scipy/special/_lambertw.py
Normal file
|
|
@ -0,0 +1,149 @@
|
|||
from ._ufuncs import _lambertw
|
||||
|
||||
import numpy as np
|
||||
|
||||
|
||||
def lambertw(z, k=0, tol=1e-8):
|
||||
r"""
|
||||
lambertw(z, k=0, tol=1e-8)
|
||||
|
||||
Lambert W function.
|
||||
|
||||
The Lambert W function `W(z)` is defined as the inverse function
|
||||
of ``w * exp(w)``. In other words, the value of ``W(z)`` is
|
||||
such that ``z = W(z) * exp(W(z))`` for any complex number
|
||||
``z``.
|
||||
|
||||
The Lambert W function is a multivalued function with infinitely
|
||||
many branches. Each branch gives a separate solution of the
|
||||
equation ``z = w exp(w)``. Here, the branches are indexed by the
|
||||
integer `k`.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
z : array_like
|
||||
Input argument.
|
||||
k : int, optional
|
||||
Branch index.
|
||||
tol : float, optional
|
||||
Evaluation tolerance.
|
||||
|
||||
Returns
|
||||
-------
|
||||
w : array
|
||||
`w` will have the same shape as `z`.
|
||||
|
||||
See Also
|
||||
--------
|
||||
wrightomega : the Wright Omega function
|
||||
|
||||
Notes
|
||||
-----
|
||||
All branches are supported by `lambertw`:
|
||||
|
||||
* ``lambertw(z)`` gives the principal solution (branch 0)
|
||||
* ``lambertw(z, k)`` gives the solution on branch `k`
|
||||
|
||||
The Lambert W function has two partially real branches: the
|
||||
principal branch (`k = 0`) is real for real ``z > -1/e``, and the
|
||||
``k = -1`` branch is real for ``-1/e < z < 0``. All branches except
|
||||
``k = 0`` have a logarithmic singularity at ``z = 0``.
|
||||
|
||||
**Possible issues**
|
||||
|
||||
The evaluation can become inaccurate very close to the branch point
|
||||
at ``-1/e``. In some corner cases, `lambertw` might currently
|
||||
fail to converge, or can end up on the wrong branch.
|
||||
|
||||
**Algorithm**
|
||||
|
||||
Halley's iteration is used to invert ``w * exp(w)``, using a first-order
|
||||
asymptotic approximation (O(log(w)) or `O(w)`) as the initial estimate.
|
||||
|
||||
The definition, implementation and choice of branches is based on [2]_.
|
||||
|
||||
References
|
||||
----------
|
||||
.. [1] https://en.wikipedia.org/wiki/Lambert_W_function
|
||||
.. [2] Corless et al, "On the Lambert W function", Adv. Comp. Math. 5
|
||||
(1996) 329-359.
|
||||
https://cs.uwaterloo.ca/research/tr/1993/03/W.pdf
|
||||
|
||||
Examples
|
||||
--------
|
||||
The Lambert W function is the inverse of ``w exp(w)``:
|
||||
|
||||
>>> import numpy as np
|
||||
>>> from scipy.special import lambertw
|
||||
>>> w = lambertw(1)
|
||||
>>> w
|
||||
(0.56714329040978384+0j)
|
||||
>>> w * np.exp(w)
|
||||
(1.0+0j)
|
||||
|
||||
Any branch gives a valid inverse:
|
||||
|
||||
>>> w = lambertw(1, k=3)
|
||||
>>> w
|
||||
(-2.8535817554090377+17.113535539412148j)
|
||||
>>> w*np.exp(w)
|
||||
(1.0000000000000002+1.609823385706477e-15j)
|
||||
|
||||
**Applications to equation-solving**
|
||||
|
||||
The Lambert W function may be used to solve various kinds of
|
||||
equations. We give two examples here.
|
||||
|
||||
First, the function can be used to solve implicit equations of the
|
||||
form
|
||||
|
||||
:math:`x = a + b e^{c x}`
|
||||
|
||||
for :math:`x`. We assume :math:`c` is not zero. After a little
|
||||
algebra, the equation may be written
|
||||
|
||||
:math:`z e^z = -b c e^{a c}`
|
||||
|
||||
where :math:`z = c (a - x)`. :math:`z` may then be expressed using
|
||||
the Lambert W function
|
||||
|
||||
:math:`z = W(-b c e^{a c})`
|
||||
|
||||
giving
|
||||
|
||||
:math:`x = a - W(-b c e^{a c})/c`
|
||||
|
||||
For example,
|
||||
|
||||
>>> a = 3
|
||||
>>> b = 2
|
||||
>>> c = -0.5
|
||||
|
||||
The solution to :math:`x = a + b e^{c x}` is:
|
||||
|
||||
>>> x = a - lambertw(-b*c*np.exp(a*c))/c
|
||||
>>> x
|
||||
(3.3707498368978794+0j)
|
||||
|
||||
Verify that it solves the equation:
|
||||
|
||||
>>> a + b*np.exp(c*x)
|
||||
(3.37074983689788+0j)
|
||||
|
||||
The Lambert W function may also be used find the value of the infinite
|
||||
power tower :math:`z^{z^{z^{\ldots}}}`:
|
||||
|
||||
>>> def tower(z, n):
|
||||
... if n == 0:
|
||||
... return z
|
||||
... return z ** tower(z, n-1)
|
||||
...
|
||||
>>> tower(0.5, 100)
|
||||
0.641185744504986
|
||||
>>> -lambertw(-np.log(0.5)) / np.log(0.5)
|
||||
(0.64118574450498589+0j)
|
||||
"""
|
||||
# TODO: special expert should inspect this
|
||||
# interception; better place to do it?
|
||||
k = np.asarray(k, dtype=np.dtype("long"))
|
||||
return _lambertw(z, k, tol)
|
||||
426
venv/lib/python3.13/site-packages/scipy/special/_logsumexp.py
Normal file
426
venv/lib/python3.13/site-packages/scipy/special/_logsumexp.py
Normal file
|
|
@ -0,0 +1,426 @@
|
|||
import numpy as np
|
||||
from scipy._lib._array_api import (
|
||||
array_namespace,
|
||||
xp_capabilities,
|
||||
xp_device,
|
||||
xp_size,
|
||||
xp_promote,
|
||||
xp_float_to_complex,
|
||||
)
|
||||
from scipy._lib import array_api_extra as xpx
|
||||
|
||||
__all__ = ["logsumexp", "softmax", "log_softmax"]
|
||||
|
||||
|
||||
@xp_capabilities()
|
||||
def logsumexp(a, axis=None, b=None, keepdims=False, return_sign=False):
|
||||
"""Compute the log of the sum of exponentials of input elements.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
a : array_like
|
||||
Input array.
|
||||
axis : None or int or tuple of ints, optional
|
||||
Axis or axes over which the sum is taken. By default `axis` is None,
|
||||
and all elements are summed.
|
||||
|
||||
.. versionadded:: 0.11.0
|
||||
b : array-like, optional
|
||||
Scaling factor for exp(`a`) must be of the same shape as `a` or
|
||||
broadcastable to `a`. These values may be negative in order to
|
||||
implement subtraction.
|
||||
|
||||
.. versionadded:: 0.12.0
|
||||
keepdims : bool, optional
|
||||
If this is set to True, the axes which are reduced are left in the
|
||||
result as dimensions with size one. With this option, the result
|
||||
will broadcast correctly against the original array.
|
||||
|
||||
.. versionadded:: 0.15.0
|
||||
return_sign : bool, optional
|
||||
If this is set to True, the result will be a pair containing sign
|
||||
information; if False, results that are negative will be returned
|
||||
as NaN. Default is False (no sign information).
|
||||
|
||||
.. versionadded:: 0.16.0
|
||||
|
||||
Returns
|
||||
-------
|
||||
res : ndarray
|
||||
The result, ``np.log(np.sum(np.exp(a)))`` calculated in a numerically
|
||||
more stable way. If `b` is given then ``np.log(np.sum(b*np.exp(a)))``
|
||||
is returned. If ``return_sign`` is True, ``res`` contains the log of
|
||||
the absolute value of the argument.
|
||||
sgn : ndarray
|
||||
If ``return_sign`` is True, this will be an array of floating-point
|
||||
numbers matching res containing +1, 0, -1 (for real-valued inputs)
|
||||
or a complex phase (for complex inputs). This gives the sign of the
|
||||
argument of the logarithm in ``res``.
|
||||
If ``return_sign`` is False, only one result is returned.
|
||||
|
||||
See Also
|
||||
--------
|
||||
:data:`numpy.logaddexp`
|
||||
:data:`numpy.logaddexp2`
|
||||
|
||||
Notes
|
||||
-----
|
||||
NumPy has a logaddexp function which is very similar to `logsumexp`, but
|
||||
only handles two arguments. `logaddexp.reduce` is similar to this
|
||||
function, but may be less stable.
|
||||
|
||||
The logarithm is a multivalued function: for each :math:`x` there is an
|
||||
infinite number of :math:`z` such that :math:`exp(z) = x`. The convention
|
||||
is to return the :math:`z` whose imaginary part lies in :math:`(-pi, pi]`.
|
||||
|
||||
Examples
|
||||
--------
|
||||
>>> import numpy as np
|
||||
>>> from scipy.special import logsumexp
|
||||
>>> a = np.arange(10)
|
||||
>>> logsumexp(a)
|
||||
9.4586297444267107
|
||||
>>> np.log(np.sum(np.exp(a)))
|
||||
9.4586297444267107
|
||||
|
||||
With weights
|
||||
|
||||
>>> a = np.arange(10)
|
||||
>>> b = np.arange(10, 0, -1)
|
||||
>>> logsumexp(a, b=b)
|
||||
9.9170178533034665
|
||||
>>> np.log(np.sum(b*np.exp(a)))
|
||||
9.9170178533034647
|
||||
|
||||
Returning a sign flag
|
||||
|
||||
>>> logsumexp([1,2],b=[1,-1],return_sign=True)
|
||||
(1.5413248546129181, -1.0)
|
||||
|
||||
Notice that `logsumexp` does not directly support masked arrays. To use it
|
||||
on a masked array, convert the mask into zero weights:
|
||||
|
||||
>>> a = np.ma.array([np.log(2), 2, np.log(3)],
|
||||
... mask=[False, True, False])
|
||||
>>> b = (~a.mask).astype(int)
|
||||
>>> logsumexp(a.data, b=b), np.log(5)
|
||||
1.6094379124341005, 1.6094379124341005
|
||||
|
||||
"""
|
||||
xp = array_namespace(a, b)
|
||||
a, b = xp_promote(a, b, broadcast=True, force_floating=True, xp=xp)
|
||||
a = xpx.atleast_nd(a, ndim=1, xp=xp)
|
||||
b = xpx.atleast_nd(b, ndim=1, xp=xp) if b is not None else b
|
||||
axis = tuple(range(a.ndim)) if axis is None else axis
|
||||
|
||||
if xp_size(a) != 0:
|
||||
with np.errstate(divide='ignore', invalid='ignore', over='ignore'):
|
||||
# Where result is infinite, we use the direct logsumexp calculation to
|
||||
# delegate edge case handling to the behavior of `xp.log` and `xp.exp`,
|
||||
# which should follow the C99 standard for complex values.
|
||||
b_exp_a = xp.exp(a) if b is None else b * xp.exp(a)
|
||||
sum_ = xp.sum(b_exp_a, axis=axis, keepdims=True)
|
||||
sgn_inf = _sign(sum_, xp=xp) if return_sign else None
|
||||
sum_ = xp.abs(sum_) if return_sign else sum_
|
||||
out_inf = xp.log(sum_)
|
||||
|
||||
with np.errstate(divide='ignore', invalid='ignore'): # log of zero is OK
|
||||
out, sgn = _logsumexp(a, b, axis=axis, return_sign=return_sign, xp=xp)
|
||||
|
||||
# Replace infinite results. This probably could be done with an
|
||||
# `apply_where`-like strategy to avoid redundant calculation, but currently
|
||||
# `apply_where` itself is only for elementwise functions.
|
||||
out_finite = xp.isfinite(out)
|
||||
out = xp.where(out_finite, out, out_inf)
|
||||
sgn = xp.where(out_finite, sgn, sgn_inf) if return_sign else sgn
|
||||
else:
|
||||
shape = np.asarray(a.shape) # NumPy is convenient for shape manipulation
|
||||
shape[axis] = 1
|
||||
out = xp.full(tuple(shape), -xp.inf, dtype=a.dtype, device=xp_device(a))
|
||||
sgn = xp.sign(out)
|
||||
|
||||
if xp.isdtype(out.dtype, 'complex floating'):
|
||||
if return_sign:
|
||||
real = xp.real(sgn)
|
||||
imag = xp_float_to_complex(_wrap_radians(xp.imag(sgn), xp=xp), xp=xp)
|
||||
sgn = real + imag*1j
|
||||
else:
|
||||
real = xp.real(out)
|
||||
imag = xp_float_to_complex(_wrap_radians(xp.imag(out), xp=xp), xp=xp)
|
||||
out = real + imag*1j
|
||||
|
||||
# Deal with shape details - reducing dimensions and convert 0-D to scalar for NumPy
|
||||
out = xp.squeeze(out, axis=axis) if not keepdims else out
|
||||
sgn = xp.squeeze(sgn, axis=axis) if (sgn is not None and not keepdims) else sgn
|
||||
out = out[()] if out.ndim == 0 else out
|
||||
sgn = sgn[()] if (sgn is not None and sgn.ndim == 0) else sgn
|
||||
|
||||
return (out, sgn) if return_sign else out
|
||||
|
||||
|
||||
def _wrap_radians(x, *, xp):
|
||||
# Wrap radians to (-pi, pi] interval
|
||||
wrapped = -((-x + xp.pi) % (2 * xp.pi) - xp.pi)
|
||||
# preserve relative precision
|
||||
no_wrap = xp.abs(x) < xp.pi
|
||||
return xp.where(no_wrap, x, wrapped)
|
||||
|
||||
|
||||
def _elements_and_indices_with_max_real(a, *, axis=-1, xp):
|
||||
# This is an array-API compatible `max` function that works something
|
||||
# like `np.max` for complex input. The important part is that it finds
|
||||
# the element with maximum real part. When there are multiple complex values
|
||||
# with this real part, it doesn't matter which we choose.
|
||||
# We could use `argmax` on real component, but array API doesn't yet have
|
||||
# `take_along_axis`, and even if it did, we would have problems with axis tuples.
|
||||
# Feel free to rewrite! It's ugly, but it's not the purpose of the PR, and
|
||||
# it gets the job done.
|
||||
|
||||
if xp.isdtype(a.dtype, "complex floating"):
|
||||
# select all elements with max real part.
|
||||
real_a = xp.real(a)
|
||||
max_ = xp.max(real_a, axis=axis, keepdims=True)
|
||||
mask = real_a == max_
|
||||
|
||||
# Of those, choose one arbitrarily. This is a reasonably
|
||||
# simple, array-API compatible way of doing so that doesn't
|
||||
# have a problem with `axis` being a tuple or None.
|
||||
i = xp.reshape(xp.arange(xp_size(a), device=xp_device(a)), a.shape)
|
||||
i = xpx.at(i, ~mask).set(-1)
|
||||
max_i = xp.max(i, axis=axis, keepdims=True)
|
||||
mask = i == max_i
|
||||
a = xp.where(mask, a, 0.)
|
||||
max_ = xp.sum(a, axis=axis, dtype=a.dtype, keepdims=True)
|
||||
else:
|
||||
max_ = xp.max(a, axis=axis, keepdims=True)
|
||||
mask = a == max_
|
||||
|
||||
return max_, mask
|
||||
|
||||
|
||||
def _sign(x, *, xp):
|
||||
return x / xp.where(x == 0, 1., xp.abs(x))
|
||||
|
||||
|
||||
def _logsumexp(a, b, *, axis, return_sign, xp):
|
||||
# This has been around for about a decade, so let's consider it a feature:
|
||||
# Even if element of `a` is infinite or NaN, it adds nothing to the sum if
|
||||
# the corresponding weight is zero.
|
||||
if b is not None:
|
||||
a = xpx.at(a, b == 0).set(-xp.inf, copy=True)
|
||||
|
||||
# Find element with maximum real part, since this is what affects the magnitude
|
||||
# of the exponential. Possible enhancement: include log of `b` magnitude in `a`.
|
||||
a_max, i_max = _elements_and_indices_with_max_real(a, axis=axis, xp=xp)
|
||||
|
||||
# for precision, these terms are separated out of the main sum.
|
||||
a = xpx.at(a, i_max).set(-xp.inf, copy=True if b is None else None)
|
||||
i_max_dt = xp.astype(i_max, a.dtype)
|
||||
# This is an inefficient way of getting `m` because it is the sum of a sparse
|
||||
# array; however, this is the simplest way I can think of to get the right shape.
|
||||
b_i_max = i_max_dt if b is None else b * i_max_dt
|
||||
m = xp.sum(b_i_max, axis=axis, keepdims=True, dtype=a.dtype)
|
||||
|
||||
# Shift, exponentiate, scale, and sum
|
||||
exp = b * xp.exp(a - a_max) if b is not None else xp.exp(a - a_max)
|
||||
s = xp.sum(exp, axis=axis, keepdims=True, dtype=exp.dtype)
|
||||
s = xp.where(s == 0, s, s/m)
|
||||
|
||||
# Separate sign/magnitude information
|
||||
# Originally, this was only performed if `return_sign=True`.
|
||||
# However, this is also needed if any elements of `m < 0` or `s < -1`.
|
||||
# An improvement would be to perform the calculations only on these entries.
|
||||
|
||||
# Use the numpy>=2.0 convention for sign.
|
||||
# When all array libraries agree, this can become sng = xp.sign(s).
|
||||
sgn = _sign(s + 1, xp=xp) * _sign(m, xp=xp)
|
||||
|
||||
if xp.isdtype(s.dtype, "real floating"):
|
||||
# The log functions need positive arguments
|
||||
s = xp.where(s < -1, -s - 2, s)
|
||||
m = xp.abs(m)
|
||||
else:
|
||||
# `a_max` can have a sign component for complex input
|
||||
sgn = sgn * xp.exp(xp.imag(a_max) * 1.0j)
|
||||
|
||||
# Take log and undo shift
|
||||
out = xp.log1p(s) + xp.log(m) + a_max
|
||||
|
||||
if return_sign:
|
||||
out = xp.real(out)
|
||||
elif xp.isdtype(out.dtype, 'real floating'):
|
||||
out = xpx.at(out)[sgn < 0].set(xp.nan)
|
||||
|
||||
return out, sgn
|
||||
|
||||
|
||||
@xp_capabilities()
|
||||
def softmax(x, axis=None):
|
||||
r"""Compute the softmax function.
|
||||
|
||||
The softmax function transforms each element of a collection by
|
||||
computing the exponential of each element divided by the sum of the
|
||||
exponentials of all the elements. That is, if `x` is a one-dimensional
|
||||
numpy array::
|
||||
|
||||
softmax(x) = np.exp(x)/sum(np.exp(x))
|
||||
|
||||
Parameters
|
||||
----------
|
||||
x : array_like
|
||||
Input array.
|
||||
axis : int or tuple of ints, optional
|
||||
Axis to compute values along. Default is None and softmax will be
|
||||
computed over the entire array `x`.
|
||||
|
||||
Returns
|
||||
-------
|
||||
s : ndarray
|
||||
An array the same shape as `x`. The result will sum to 1 along the
|
||||
specified axis.
|
||||
|
||||
Notes
|
||||
-----
|
||||
The formula for the softmax function :math:`\sigma(x)` for a vector
|
||||
:math:`x = \{x_0, x_1, ..., x_{n-1}\}` is
|
||||
|
||||
.. math:: \sigma(x)_j = \frac{e^{x_j}}{\sum_k e^{x_k}}
|
||||
|
||||
The `softmax` function is the gradient of `logsumexp`.
|
||||
|
||||
The implementation uses shifting to avoid overflow. See [1]_ for more
|
||||
details.
|
||||
|
||||
.. versionadded:: 1.2.0
|
||||
|
||||
References
|
||||
----------
|
||||
.. [1] P. Blanchard, D.J. Higham, N.J. Higham, "Accurately computing the
|
||||
log-sum-exp and softmax functions", IMA Journal of Numerical Analysis,
|
||||
Vol.41(4), :doi:`10.1093/imanum/draa038`.
|
||||
|
||||
Examples
|
||||
--------
|
||||
>>> import numpy as np
|
||||
>>> from scipy.special import softmax
|
||||
>>> np.set_printoptions(precision=5)
|
||||
|
||||
>>> x = np.array([[1, 0.5, 0.2, 3],
|
||||
... [1, -1, 7, 3],
|
||||
... [2, 12, 13, 3]])
|
||||
...
|
||||
|
||||
Compute the softmax transformation over the entire array.
|
||||
|
||||
>>> m = softmax(x)
|
||||
>>> m
|
||||
array([[ 4.48309e-06, 2.71913e-06, 2.01438e-06, 3.31258e-05],
|
||||
[ 4.48309e-06, 6.06720e-07, 1.80861e-03, 3.31258e-05],
|
||||
[ 1.21863e-05, 2.68421e-01, 7.29644e-01, 3.31258e-05]])
|
||||
|
||||
>>> m.sum()
|
||||
1.0
|
||||
|
||||
Compute the softmax transformation along the first axis (i.e., the
|
||||
columns).
|
||||
|
||||
>>> m = softmax(x, axis=0)
|
||||
|
||||
>>> m
|
||||
array([[ 2.11942e-01, 1.01300e-05, 2.75394e-06, 3.33333e-01],
|
||||
[ 2.11942e-01, 2.26030e-06, 2.47262e-03, 3.33333e-01],
|
||||
[ 5.76117e-01, 9.99988e-01, 9.97525e-01, 3.33333e-01]])
|
||||
|
||||
>>> m.sum(axis=0)
|
||||
array([ 1., 1., 1., 1.])
|
||||
|
||||
Compute the softmax transformation along the second axis (i.e., the rows).
|
||||
|
||||
>>> m = softmax(x, axis=1)
|
||||
>>> m
|
||||
array([[ 1.05877e-01, 6.42177e-02, 4.75736e-02, 7.82332e-01],
|
||||
[ 2.42746e-03, 3.28521e-04, 9.79307e-01, 1.79366e-02],
|
||||
[ 1.22094e-05, 2.68929e-01, 7.31025e-01, 3.31885e-05]])
|
||||
|
||||
>>> m.sum(axis=1)
|
||||
array([ 1., 1., 1.])
|
||||
|
||||
"""
|
||||
xp = array_namespace(x)
|
||||
x = xp.asarray(x)
|
||||
x_max = xp.max(x, axis=axis, keepdims=True)
|
||||
exp_x_shifted = xp.exp(x - x_max)
|
||||
return exp_x_shifted / xp.sum(exp_x_shifted, axis=axis, keepdims=True)
|
||||
|
||||
|
||||
@xp_capabilities()
|
||||
def log_softmax(x, axis=None):
|
||||
r"""Compute the logarithm of the softmax function.
|
||||
|
||||
In principle::
|
||||
|
||||
log_softmax(x) = log(softmax(x))
|
||||
|
||||
but using a more accurate implementation.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
x : array_like
|
||||
Input array.
|
||||
axis : int or tuple of ints, optional
|
||||
Axis to compute values along. Default is None and softmax will be
|
||||
computed over the entire array `x`.
|
||||
|
||||
Returns
|
||||
-------
|
||||
s : ndarray or scalar
|
||||
An array with the same shape as `x`. Exponential of the result will
|
||||
sum to 1 along the specified axis. If `x` is a scalar, a scalar is
|
||||
returned.
|
||||
|
||||
Notes
|
||||
-----
|
||||
`log_softmax` is more accurate than ``np.log(softmax(x))`` with inputs that
|
||||
make `softmax` saturate (see examples below).
|
||||
|
||||
.. versionadded:: 1.5.0
|
||||
|
||||
Examples
|
||||
--------
|
||||
>>> import numpy as np
|
||||
>>> from scipy.special import log_softmax
|
||||
>>> from scipy.special import softmax
|
||||
>>> np.set_printoptions(precision=5)
|
||||
|
||||
>>> x = np.array([1000.0, 1.0])
|
||||
|
||||
>>> y = log_softmax(x)
|
||||
>>> y
|
||||
array([ 0., -999.])
|
||||
|
||||
>>> with np.errstate(divide='ignore'):
|
||||
... y = np.log(softmax(x))
|
||||
...
|
||||
>>> y
|
||||
array([ 0., -inf])
|
||||
|
||||
"""
|
||||
xp = array_namespace(x)
|
||||
x = xp.asarray(x)
|
||||
|
||||
x_max = xp.max(x, axis=axis, keepdims=True)
|
||||
|
||||
if x_max.ndim > 0:
|
||||
x_max = xpx.at(x_max, ~xp.isfinite(x_max)).set(0)
|
||||
elif not xp.isfinite(x_max):
|
||||
x_max = 0
|
||||
|
||||
tmp = x - x_max
|
||||
exp_tmp = xp.exp(tmp)
|
||||
|
||||
# suppress warnings about log of zero
|
||||
with np.errstate(divide='ignore'):
|
||||
s = xp.sum(exp_tmp, axis=axis, keepdims=True)
|
||||
out = xp.log(s)
|
||||
|
||||
return tmp - out
|
||||
453
venv/lib/python3.13/site-packages/scipy/special/_mptestutils.py
Normal file
453
venv/lib/python3.13/site-packages/scipy/special/_mptestutils.py
Normal file
|
|
@ -0,0 +1,453 @@
|
|||
import os
|
||||
import sys
|
||||
import time
|
||||
from itertools import zip_longest
|
||||
|
||||
import numpy as np
|
||||
from numpy.testing import assert_
|
||||
import pytest
|
||||
|
||||
from scipy.special._testutils import assert_func_equal
|
||||
|
||||
try:
|
||||
import mpmath
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Machinery for systematic tests with mpmath
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
class Arg:
|
||||
"""Generate a set of numbers on the real axis, concentrating on
|
||||
'interesting' regions and covering all orders of magnitude.
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self, a=-np.inf, b=np.inf, inclusive_a=True, inclusive_b=True):
|
||||
if a > b:
|
||||
raise ValueError("a should be less than or equal to b")
|
||||
if a == -np.inf:
|
||||
a = -0.5*np.finfo(float).max
|
||||
if b == np.inf:
|
||||
b = 0.5*np.finfo(float).max
|
||||
self.a, self.b = a, b
|
||||
|
||||
self.inclusive_a, self.inclusive_b = inclusive_a, inclusive_b
|
||||
|
||||
def _positive_values(self, a, b, n):
|
||||
if a < 0:
|
||||
raise ValueError("a should be positive")
|
||||
|
||||
# Try to put half of the points into a linspace between a and
|
||||
# 10 the other half in a logspace.
|
||||
if n % 2 == 0:
|
||||
nlogpts = n//2
|
||||
nlinpts = nlogpts
|
||||
else:
|
||||
nlogpts = n//2
|
||||
nlinpts = nlogpts + 1
|
||||
|
||||
if a >= 10:
|
||||
# Outside of linspace range; just return a logspace.
|
||||
pts = np.logspace(np.log10(a), np.log10(b), n)
|
||||
elif a > 0 and b < 10:
|
||||
# Outside of logspace range; just return a linspace
|
||||
pts = np.linspace(a, b, n)
|
||||
elif a > 0:
|
||||
# Linspace between a and 10 and a logspace between 10 and
|
||||
# b.
|
||||
linpts = np.linspace(a, 10, nlinpts, endpoint=False)
|
||||
logpts = np.logspace(1, np.log10(b), nlogpts)
|
||||
pts = np.hstack((linpts, logpts))
|
||||
elif a == 0 and b <= 10:
|
||||
# Linspace between 0 and b and a logspace between 0 and
|
||||
# the smallest positive point of the linspace
|
||||
linpts = np.linspace(0, b, nlinpts)
|
||||
if linpts.size > 1:
|
||||
right = np.log10(linpts[1])
|
||||
else:
|
||||
right = -30
|
||||
logpts = np.logspace(-30, right, nlogpts, endpoint=False)
|
||||
pts = np.hstack((logpts, linpts))
|
||||
else:
|
||||
# Linspace between 0 and 10, logspace between 0 and the
|
||||
# smallest positive point of the linspace, and a logspace
|
||||
# between 10 and b.
|
||||
if nlogpts % 2 == 0:
|
||||
nlogpts1 = nlogpts//2
|
||||
nlogpts2 = nlogpts1
|
||||
else:
|
||||
nlogpts1 = nlogpts//2
|
||||
nlogpts2 = nlogpts1 + 1
|
||||
linpts = np.linspace(0, 10, nlinpts, endpoint=False)
|
||||
if linpts.size > 1:
|
||||
right = np.log10(linpts[1])
|
||||
else:
|
||||
right = -30
|
||||
logpts1 = np.logspace(-30, right, nlogpts1, endpoint=False)
|
||||
logpts2 = np.logspace(1, np.log10(b), nlogpts2)
|
||||
pts = np.hstack((logpts1, linpts, logpts2))
|
||||
|
||||
return np.sort(pts)
|
||||
|
||||
def values(self, n):
|
||||
"""Return an array containing n numbers."""
|
||||
a, b = self.a, self.b
|
||||
if a == b:
|
||||
return np.zeros(n)
|
||||
|
||||
if not self.inclusive_a:
|
||||
n += 1
|
||||
if not self.inclusive_b:
|
||||
n += 1
|
||||
|
||||
if n % 2 == 0:
|
||||
n1 = n//2
|
||||
n2 = n1
|
||||
else:
|
||||
n1 = n//2
|
||||
n2 = n1 + 1
|
||||
|
||||
if a >= 0:
|
||||
pospts = self._positive_values(a, b, n)
|
||||
negpts = []
|
||||
elif b <= 0:
|
||||
pospts = []
|
||||
negpts = -self._positive_values(-b, -a, n)
|
||||
else:
|
||||
pospts = self._positive_values(0, b, n1)
|
||||
negpts = -self._positive_values(0, -a, n2 + 1)
|
||||
# Don't want to get zero twice
|
||||
negpts = negpts[1:]
|
||||
pts = np.hstack((negpts[::-1], pospts))
|
||||
|
||||
if not self.inclusive_a:
|
||||
pts = pts[1:]
|
||||
if not self.inclusive_b:
|
||||
pts = pts[:-1]
|
||||
return pts
|
||||
|
||||
|
||||
class FixedArg:
|
||||
def __init__(self, values):
|
||||
self._values = np.asarray(values)
|
||||
|
||||
def values(self, n):
|
||||
return self._values
|
||||
|
||||
|
||||
class ComplexArg:
|
||||
def __init__(self, a=complex(-np.inf, -np.inf), b=complex(np.inf, np.inf)):
|
||||
self.real = Arg(a.real, b.real)
|
||||
self.imag = Arg(a.imag, b.imag)
|
||||
|
||||
def values(self, n):
|
||||
m = int(np.floor(np.sqrt(n)))
|
||||
x = self.real.values(m)
|
||||
y = self.imag.values(m + 1)
|
||||
return (x[:,None] + 1j*y[None,:]).ravel()
|
||||
|
||||
|
||||
class IntArg:
|
||||
def __init__(self, a=-1000, b=1000):
|
||||
self.a = a
|
||||
self.b = b
|
||||
|
||||
def values(self, n):
|
||||
v1 = Arg(self.a, self.b).values(max(1 + n//2, n-5)).astype(int)
|
||||
v2 = np.arange(-5, 5)
|
||||
v = np.unique(np.r_[v1, v2])
|
||||
v = v[(v >= self.a) & (v < self.b)]
|
||||
return v
|
||||
|
||||
|
||||
def get_args(argspec, n):
|
||||
if isinstance(argspec, np.ndarray):
|
||||
args = argspec.copy()
|
||||
else:
|
||||
nargs = len(argspec)
|
||||
ms = np.asarray(
|
||||
[1.5 if isinstance(spec, ComplexArg) else 1.0 for spec in argspec]
|
||||
)
|
||||
ms = (n**(ms/sum(ms))).astype(int) + 1
|
||||
|
||||
args = [spec.values(m) for spec, m in zip(argspec, ms)]
|
||||
args = np.array(np.broadcast_arrays(*np.ix_(*args))).reshape(nargs, -1).T
|
||||
|
||||
return args
|
||||
|
||||
|
||||
class MpmathData:
|
||||
def __init__(self, scipy_func, mpmath_func, arg_spec, name=None,
|
||||
dps=None, prec=None, n=None, rtol=1e-7, atol=1e-300,
|
||||
ignore_inf_sign=False, distinguish_nan_and_inf=True,
|
||||
nan_ok=True, param_filter=None):
|
||||
|
||||
# mpmath tests are really slow (see gh-6989). Use a small number of
|
||||
# points by default, increase back to 5000 (old default) if XSLOW is
|
||||
# set
|
||||
if n is None:
|
||||
try:
|
||||
is_xslow = int(os.environ.get('SCIPY_XSLOW', '0'))
|
||||
except ValueError:
|
||||
is_xslow = False
|
||||
|
||||
n = 5000 if is_xslow else 500
|
||||
|
||||
self.scipy_func = scipy_func
|
||||
self.mpmath_func = mpmath_func
|
||||
self.arg_spec = arg_spec
|
||||
self.dps = dps
|
||||
self.prec = prec
|
||||
self.n = n
|
||||
self.rtol = rtol
|
||||
self.atol = atol
|
||||
self.ignore_inf_sign = ignore_inf_sign
|
||||
self.nan_ok = nan_ok
|
||||
if isinstance(self.arg_spec, np.ndarray):
|
||||
self.is_complex = np.issubdtype(self.arg_spec.dtype, np.complexfloating)
|
||||
else:
|
||||
self.is_complex = any(
|
||||
[isinstance(arg, ComplexArg) for arg in self.arg_spec]
|
||||
)
|
||||
self.ignore_inf_sign = ignore_inf_sign
|
||||
self.distinguish_nan_and_inf = distinguish_nan_and_inf
|
||||
if not name or name == '<lambda>':
|
||||
name = getattr(scipy_func, '__name__', None)
|
||||
if not name or name == '<lambda>':
|
||||
name = getattr(mpmath_func, '__name__', None)
|
||||
self.name = name
|
||||
self.param_filter = param_filter
|
||||
|
||||
def check(self):
|
||||
np.random.seed(1234)
|
||||
|
||||
# Generate values for the arguments
|
||||
argarr = get_args(self.arg_spec, self.n)
|
||||
|
||||
# Check
|
||||
old_dps, old_prec = mpmath.mp.dps, mpmath.mp.prec
|
||||
try:
|
||||
if self.dps is not None:
|
||||
dps_list = [self.dps]
|
||||
else:
|
||||
dps_list = [20]
|
||||
if self.prec is not None:
|
||||
mpmath.mp.prec = self.prec
|
||||
|
||||
# Proper casting of mpmath input and output types. Using
|
||||
# native mpmath types as inputs gives improved precision
|
||||
# in some cases.
|
||||
if np.issubdtype(argarr.dtype, np.complexfloating):
|
||||
pytype = mpc2complex
|
||||
|
||||
def mptype(x):
|
||||
return mpmath.mpc(complex(x))
|
||||
else:
|
||||
def mptype(x):
|
||||
return mpmath.mpf(float(x))
|
||||
|
||||
def pytype(x):
|
||||
if abs(x.imag) > 1e-16*(1 + abs(x.real)):
|
||||
return np.nan
|
||||
else:
|
||||
return mpf2float(x.real)
|
||||
|
||||
# Try out different dps until one (or none) works
|
||||
for j, dps in enumerate(dps_list):
|
||||
mpmath.mp.dps = dps
|
||||
|
||||
try:
|
||||
assert_func_equal(
|
||||
self.scipy_func,
|
||||
lambda *a: pytype(self.mpmath_func(*map(mptype, a))),
|
||||
argarr,
|
||||
vectorized=False,
|
||||
rtol=self.rtol,
|
||||
atol=self.atol,
|
||||
ignore_inf_sign=self.ignore_inf_sign,
|
||||
distinguish_nan_and_inf=self.distinguish_nan_and_inf,
|
||||
nan_ok=self.nan_ok,
|
||||
param_filter=self.param_filter
|
||||
)
|
||||
break
|
||||
except AssertionError:
|
||||
if j >= len(dps_list)-1:
|
||||
# reraise the Exception
|
||||
tp, value, tb = sys.exc_info()
|
||||
if value.__traceback__ is not tb:
|
||||
raise value.with_traceback(tb)
|
||||
raise value
|
||||
finally:
|
||||
mpmath.mp.dps, mpmath.mp.prec = old_dps, old_prec
|
||||
|
||||
def __repr__(self):
|
||||
if self.is_complex:
|
||||
return f"<MpmathData: {self.name} (complex)>"
|
||||
else:
|
||||
return f"<MpmathData: {self.name}>"
|
||||
|
||||
|
||||
def assert_mpmath_equal(*a, **kw):
|
||||
d = MpmathData(*a, **kw)
|
||||
d.check()
|
||||
|
||||
|
||||
def nonfunctional_tooslow(func):
|
||||
return pytest.mark.skip(
|
||||
reason=" Test not yet functional (too slow), needs more work."
|
||||
)(func)
|
||||
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Tools for dealing with mpmath quirks
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
def mpf2float(x):
|
||||
"""
|
||||
Convert an mpf to the nearest floating point number. Just using
|
||||
float directly doesn't work because of results like this:
|
||||
|
||||
with mp.workdps(50):
|
||||
float(mpf("0.99999999999999999")) = 0.9999999999999999
|
||||
|
||||
"""
|
||||
return float(mpmath.nstr(x, 17, min_fixed=0, max_fixed=0))
|
||||
|
||||
|
||||
def mpc2complex(x):
|
||||
return complex(mpf2float(x.real), mpf2float(x.imag))
|
||||
|
||||
|
||||
def trace_args(func):
|
||||
def tofloat(x):
|
||||
if isinstance(x, mpmath.mpc):
|
||||
return complex(x)
|
||||
else:
|
||||
return float(x)
|
||||
|
||||
def wrap(*a, **kw):
|
||||
sys.stderr.write(f"{tuple(map(tofloat, a))!r}: ")
|
||||
sys.stderr.flush()
|
||||
try:
|
||||
r = func(*a, **kw)
|
||||
sys.stderr.write(f"-> {r!r}")
|
||||
finally:
|
||||
sys.stderr.write("\n")
|
||||
sys.stderr.flush()
|
||||
return r
|
||||
return wrap
|
||||
|
||||
|
||||
try:
|
||||
import signal
|
||||
POSIX = ('setitimer' in dir(signal))
|
||||
except ImportError:
|
||||
POSIX = False
|
||||
|
||||
|
||||
class TimeoutError(Exception):
|
||||
pass
|
||||
|
||||
|
||||
def time_limited(timeout=0.5, return_val=np.nan, use_sigalrm=True):
|
||||
"""
|
||||
Decorator for setting a timeout for pure-Python functions.
|
||||
|
||||
If the function does not return within `timeout` seconds, the
|
||||
value `return_val` is returned instead.
|
||||
|
||||
On POSIX this uses SIGALRM by default. On non-POSIX, settrace is
|
||||
used. Do not use this with threads: the SIGALRM implementation
|
||||
does probably not work well. The settrace implementation only
|
||||
traces the current thread.
|
||||
|
||||
The settrace implementation slows down execution speed. Slowdown
|
||||
by a factor around 10 is probably typical.
|
||||
"""
|
||||
if POSIX and use_sigalrm:
|
||||
def sigalrm_handler(signum, frame):
|
||||
raise TimeoutError()
|
||||
|
||||
def deco(func):
|
||||
def wrap(*a, **kw):
|
||||
old_handler = signal.signal(signal.SIGALRM, sigalrm_handler)
|
||||
signal.setitimer(signal.ITIMER_REAL, timeout)
|
||||
try:
|
||||
return func(*a, **kw)
|
||||
except TimeoutError:
|
||||
return return_val
|
||||
finally:
|
||||
signal.setitimer(signal.ITIMER_REAL, 0)
|
||||
signal.signal(signal.SIGALRM, old_handler)
|
||||
return wrap
|
||||
else:
|
||||
def deco(func):
|
||||
def wrap(*a, **kw):
|
||||
start_time = time.time()
|
||||
|
||||
def trace(frame, event, arg):
|
||||
if time.time() - start_time > timeout:
|
||||
raise TimeoutError()
|
||||
return trace
|
||||
sys.settrace(trace)
|
||||
try:
|
||||
return func(*a, **kw)
|
||||
except TimeoutError:
|
||||
sys.settrace(None)
|
||||
return return_val
|
||||
finally:
|
||||
sys.settrace(None)
|
||||
return wrap
|
||||
return deco
|
||||
|
||||
|
||||
def exception_to_nan(func):
|
||||
"""Decorate function to return nan if it raises an exception"""
|
||||
def wrap(*a, **kw):
|
||||
try:
|
||||
return func(*a, **kw)
|
||||
except Exception:
|
||||
return np.nan
|
||||
return wrap
|
||||
|
||||
|
||||
def inf_to_nan(func):
|
||||
"""Decorate function to return nan if it returns inf"""
|
||||
def wrap(*a, **kw):
|
||||
v = func(*a, **kw)
|
||||
if not np.isfinite(v):
|
||||
return np.nan
|
||||
return v
|
||||
return wrap
|
||||
|
||||
|
||||
def mp_assert_allclose(res, std, atol=0, rtol=1e-17):
|
||||
"""
|
||||
Compare lists of mpmath.mpf's or mpmath.mpc's directly so that it
|
||||
can be done to higher precision than double.
|
||||
"""
|
||||
failures = []
|
||||
for k, (resval, stdval) in enumerate(zip_longest(res, std)):
|
||||
if resval is None or stdval is None:
|
||||
raise ValueError('Lengths of inputs res and std are not equal.')
|
||||
if mpmath.fabs(resval - stdval) > atol + rtol*mpmath.fabs(stdval):
|
||||
failures.append((k, resval, stdval))
|
||||
|
||||
nfail = len(failures)
|
||||
if nfail > 0:
|
||||
ndigits = int(abs(np.log10(rtol)))
|
||||
msg = [""]
|
||||
msg.append(f"Bad results ({nfail} out of {k + 1}) for the following points:")
|
||||
for k, resval, stdval in failures:
|
||||
resrep = mpmath.nstr(resval, ndigits, min_fixed=0, max_fixed=0)
|
||||
stdrep = mpmath.nstr(stdval, ndigits, min_fixed=0, max_fixed=0)
|
||||
if stdval == 0:
|
||||
rdiff = "inf"
|
||||
else:
|
||||
rdiff = mpmath.fabs((resval - stdval)/stdval)
|
||||
rdiff = mpmath.nstr(rdiff, 3)
|
||||
msg.append(f"{k}: {resrep} != {stdrep} (rdiff {rdiff})")
|
||||
assert_(False, "\n".join(msg))
|
||||
610
venv/lib/python3.13/site-packages/scipy/special/_multiufuncs.py
Normal file
610
venv/lib/python3.13/site-packages/scipy/special/_multiufuncs.py
Normal file
|
|
@ -0,0 +1,610 @@
|
|||
import collections
|
||||
import numbers
|
||||
import numpy as np
|
||||
|
||||
from ._input_validation import _nonneg_int_or_fail
|
||||
|
||||
from ._special_ufuncs import (legendre_p, assoc_legendre_p,
|
||||
sph_legendre_p, sph_harm_y)
|
||||
from ._gufuncs import (legendre_p_all, assoc_legendre_p_all,
|
||||
sph_legendre_p_all, sph_harm_y_all)
|
||||
|
||||
__all__ = [
|
||||
"assoc_legendre_p",
|
||||
"assoc_legendre_p_all",
|
||||
"legendre_p",
|
||||
"legendre_p_all",
|
||||
"sph_harm_y",
|
||||
"sph_harm_y_all",
|
||||
"sph_legendre_p",
|
||||
"sph_legendre_p_all",
|
||||
]
|
||||
|
||||
|
||||
class MultiUFunc:
|
||||
def __init__(self, ufunc_or_ufuncs, doc=None, *,
|
||||
force_complex_output=False, **default_kwargs):
|
||||
if not isinstance(ufunc_or_ufuncs, np.ufunc):
|
||||
if isinstance(ufunc_or_ufuncs, collections.abc.Mapping):
|
||||
ufuncs_iter = ufunc_or_ufuncs.values()
|
||||
elif isinstance(ufunc_or_ufuncs, collections.abc.Iterable):
|
||||
ufuncs_iter = ufunc_or_ufuncs
|
||||
else:
|
||||
raise ValueError("ufunc_or_ufuncs should be a ufunc or a"
|
||||
" ufunc collection")
|
||||
|
||||
# Perform input validation to ensure all ufuncs in ufuncs are
|
||||
# actually ufuncs and all take the same input types.
|
||||
seen_input_types = set()
|
||||
for ufunc in ufuncs_iter:
|
||||
if not isinstance(ufunc, np.ufunc):
|
||||
raise ValueError("All ufuncs must have type `numpy.ufunc`."
|
||||
f" Received {ufunc_or_ufuncs}")
|
||||
seen_input_types.add(frozenset(x.split("->")[0] for x in ufunc.types))
|
||||
if len(seen_input_types) > 1:
|
||||
raise ValueError("All ufuncs must take the same input types.")
|
||||
|
||||
self._ufunc_or_ufuncs = ufunc_or_ufuncs
|
||||
self.__doc = doc
|
||||
self.__force_complex_output = force_complex_output
|
||||
self._default_kwargs = default_kwargs
|
||||
self._resolve_out_shapes = None
|
||||
self._finalize_out = None
|
||||
self._key = None
|
||||
self._ufunc_default_args = lambda *args, **kwargs: ()
|
||||
self._ufunc_default_kwargs = lambda *args, **kwargs: {}
|
||||
|
||||
@property
|
||||
def __doc__(self):
|
||||
return self.__doc
|
||||
|
||||
def _override_key(self, func):
|
||||
"""Set `key` method by decorating a function.
|
||||
"""
|
||||
self._key = func
|
||||
|
||||
def _override_ufunc_default_args(self, func):
|
||||
self._ufunc_default_args = func
|
||||
|
||||
def _override_ufunc_default_kwargs(self, func):
|
||||
self._ufunc_default_kwargs = func
|
||||
|
||||
def _override_resolve_out_shapes(self, func):
|
||||
"""Set `resolve_out_shapes` method by decorating a function."""
|
||||
if func.__doc__ is None:
|
||||
func.__doc__ = \
|
||||
"""Resolve to output shapes based on relevant inputs."""
|
||||
func.__name__ = "resolve_out_shapes"
|
||||
self._resolve_out_shapes = func
|
||||
|
||||
def _override_finalize_out(self, func):
|
||||
self._finalize_out = func
|
||||
|
||||
def _resolve_ufunc(self, **kwargs):
|
||||
"""Resolve to a ufunc based on keyword arguments."""
|
||||
|
||||
if isinstance(self._ufunc_or_ufuncs, np.ufunc):
|
||||
return self._ufunc_or_ufuncs
|
||||
|
||||
ufunc_key = self._key(**kwargs)
|
||||
return self._ufunc_or_ufuncs[ufunc_key]
|
||||
|
||||
def __call__(self, *args, **kwargs):
|
||||
kwargs = self._default_kwargs | kwargs
|
||||
|
||||
args += self._ufunc_default_args(**kwargs)
|
||||
|
||||
ufunc = self._resolve_ufunc(**kwargs)
|
||||
|
||||
# array arguments to be passed to the ufunc
|
||||
ufunc_args = [np.asarray(arg) for arg in args[-ufunc.nin:]]
|
||||
|
||||
ufunc_kwargs = self._ufunc_default_kwargs(**kwargs)
|
||||
|
||||
if (self._resolve_out_shapes is not None):
|
||||
ufunc_arg_shapes = tuple(np.shape(ufunc_arg) for ufunc_arg in ufunc_args)
|
||||
ufunc_out_shapes = self._resolve_out_shapes(*args[:-ufunc.nin],
|
||||
*ufunc_arg_shapes, ufunc.nout,
|
||||
**kwargs)
|
||||
|
||||
ufunc_arg_dtypes = tuple(ufunc_arg.dtype if hasattr(ufunc_arg, 'dtype')
|
||||
else np.dtype(type(ufunc_arg))
|
||||
for ufunc_arg in ufunc_args)
|
||||
|
||||
if hasattr(ufunc, 'resolve_dtypes'):
|
||||
ufunc_dtypes = ufunc_arg_dtypes + ufunc.nout * (None,)
|
||||
ufunc_dtypes = ufunc.resolve_dtypes(ufunc_dtypes)
|
||||
ufunc_out_dtypes = ufunc_dtypes[-ufunc.nout:]
|
||||
else:
|
||||
ufunc_out_dtype = np.result_type(*ufunc_arg_dtypes)
|
||||
if (not np.issubdtype(ufunc_out_dtype, np.inexact)):
|
||||
ufunc_out_dtype = np.float64
|
||||
|
||||
ufunc_out_dtypes = ufunc.nout * (ufunc_out_dtype,)
|
||||
|
||||
if self.__force_complex_output:
|
||||
ufunc_out_dtypes = tuple(np.result_type(1j, ufunc_out_dtype)
|
||||
for ufunc_out_dtype in ufunc_out_dtypes)
|
||||
|
||||
out = tuple(np.empty(ufunc_out_shape, dtype=ufunc_out_dtype)
|
||||
for ufunc_out_shape, ufunc_out_dtype
|
||||
in zip(ufunc_out_shapes, ufunc_out_dtypes))
|
||||
|
||||
ufunc_kwargs['out'] = out
|
||||
|
||||
out = ufunc(*ufunc_args, **ufunc_kwargs)
|
||||
if (self._finalize_out is not None):
|
||||
out = self._finalize_out(out)
|
||||
|
||||
return out
|
||||
|
||||
|
||||
sph_legendre_p = MultiUFunc(
|
||||
sph_legendre_p,
|
||||
r"""sph_legendre_p(n, m, theta, *, diff_n=0)
|
||||
|
||||
Spherical Legendre polynomial of the first kind.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
n : ArrayLike[int]
|
||||
Degree of the spherical Legendre polynomial. Must have ``n >= 0``.
|
||||
m : ArrayLike[int]
|
||||
Order of the spherical Legendre polynomial.
|
||||
theta : ArrayLike[float]
|
||||
Input value.
|
||||
diff_n : Optional[int]
|
||||
A non-negative integer. Compute and return all derivatives up
|
||||
to order ``diff_n``. Default is 0.
|
||||
|
||||
Returns
|
||||
-------
|
||||
p : ndarray or tuple[ndarray]
|
||||
Spherical Legendre polynomial with ``diff_n`` derivatives.
|
||||
|
||||
Notes
|
||||
-----
|
||||
The spherical counterpart of an (unnormalized) associated Legendre polynomial has
|
||||
the additional factor
|
||||
|
||||
.. math::
|
||||
|
||||
\sqrt{\frac{(2 n + 1) (n - m)!}{4 \pi (n + m)!}}
|
||||
|
||||
It is the same as the spherical harmonic :math:`Y_{n}^{m}(\theta, \phi)`
|
||||
with :math:`\phi = 0`.
|
||||
""", diff_n=0
|
||||
)
|
||||
|
||||
|
||||
@sph_legendre_p._override_key
|
||||
def _(diff_n):
|
||||
diff_n = _nonneg_int_or_fail(diff_n, "diff_n", strict=False)
|
||||
if not 0 <= diff_n <= 2:
|
||||
raise ValueError(
|
||||
"diff_n is currently only implemented for orders 0, 1, and 2,"
|
||||
f" received: {diff_n}."
|
||||
)
|
||||
return diff_n
|
||||
|
||||
|
||||
@sph_legendre_p._override_finalize_out
|
||||
def _(out):
|
||||
return np.moveaxis(out, -1, 0)
|
||||
|
||||
|
||||
sph_legendre_p_all = MultiUFunc(
|
||||
sph_legendre_p_all,
|
||||
"""sph_legendre_p_all(n, m, theta, *, diff_n=0)
|
||||
|
||||
All spherical Legendre polynomials of the first kind up to the
|
||||
specified degree ``n`` and order ``m``.
|
||||
|
||||
Output shape is ``(n + 1, 2 * m + 1, ...)``. The entry at ``(j, i)``
|
||||
corresponds to degree ``j`` and order ``i`` for all ``0 <= j <= n``
|
||||
and ``-m <= i <= m``.
|
||||
|
||||
See Also
|
||||
--------
|
||||
sph_legendre_p
|
||||
""", diff_n=0
|
||||
)
|
||||
|
||||
|
||||
@sph_legendre_p_all._override_key
|
||||
def _(diff_n):
|
||||
diff_n = _nonneg_int_or_fail(diff_n, "diff_n", strict=False)
|
||||
if not 0 <= diff_n <= 2:
|
||||
raise ValueError(
|
||||
"diff_n is currently only implemented for orders 0, 1, and 2,"
|
||||
f" received: {diff_n}."
|
||||
)
|
||||
return diff_n
|
||||
|
||||
|
||||
@sph_legendre_p_all._override_ufunc_default_kwargs
|
||||
def _(diff_n):
|
||||
return {'axes': [()] + [(0, 1, -1)]}
|
||||
|
||||
|
||||
@sph_legendre_p_all._override_resolve_out_shapes
|
||||
def _(n, m, theta_shape, nout, diff_n):
|
||||
if not isinstance(n, numbers.Integral) or (n < 0):
|
||||
raise ValueError("n must be a non-negative integer.")
|
||||
|
||||
return ((n + 1, 2 * abs(m) + 1) + theta_shape + (diff_n + 1,),)
|
||||
|
||||
|
||||
@sph_legendre_p_all._override_finalize_out
|
||||
def _(out):
|
||||
return np.moveaxis(out, -1, 0)
|
||||
|
||||
|
||||
assoc_legendre_p = MultiUFunc(
|
||||
assoc_legendre_p,
|
||||
r"""assoc_legendre_p(n, m, z, *, branch_cut=2, norm=False, diff_n=0)
|
||||
|
||||
Associated Legendre polynomial of the first kind.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
n : ArrayLike[int]
|
||||
Degree of the associated Legendre polynomial. Must have ``n >= 0``.
|
||||
m : ArrayLike[int]
|
||||
order of the associated Legendre polynomial.
|
||||
z : ArrayLike[float | complex]
|
||||
Input value.
|
||||
branch_cut : Optional[ArrayLike[int]]
|
||||
Selects branch cut. Must be 2 (default) or 3.
|
||||
2: cut on the real axis ``|z| > 1``
|
||||
3: cut on the real axis ``-1 < z < 1``
|
||||
norm : Optional[bool]
|
||||
If ``True``, compute the normalized associated Legendre polynomial.
|
||||
Default is ``False``.
|
||||
diff_n : Optional[int]
|
||||
A non-negative integer. Compute and return all derivatives up
|
||||
to order ``diff_n``. Default is 0.
|
||||
|
||||
Returns
|
||||
-------
|
||||
p : ndarray or tuple[ndarray]
|
||||
Associated Legendre polynomial with ``diff_n`` derivatives.
|
||||
|
||||
Notes
|
||||
-----
|
||||
The normalized counterpart of an (unnormalized) associated Legendre
|
||||
polynomial has the additional factor
|
||||
|
||||
.. math::
|
||||
|
||||
\sqrt{\frac{(2 n + 1) (n - m)!}{2 (n + m)!}}
|
||||
""", branch_cut=2, norm=False, diff_n=0
|
||||
)
|
||||
|
||||
|
||||
@assoc_legendre_p._override_key
|
||||
def _(branch_cut, norm, diff_n):
|
||||
diff_n = _nonneg_int_or_fail(diff_n, "diff_n", strict=False)
|
||||
if not 0 <= diff_n <= 2:
|
||||
raise ValueError(
|
||||
"diff_n is currently only implemented for orders 0, 1, and 2,"
|
||||
f" received: {diff_n}."
|
||||
)
|
||||
return norm, diff_n
|
||||
|
||||
|
||||
@assoc_legendre_p._override_ufunc_default_args
|
||||
def _(branch_cut, norm, diff_n):
|
||||
return branch_cut,
|
||||
|
||||
|
||||
@assoc_legendre_p._override_finalize_out
|
||||
def _(out):
|
||||
return np.moveaxis(out, -1, 0)
|
||||
|
||||
|
||||
assoc_legendre_p_all = MultiUFunc(
|
||||
assoc_legendre_p_all,
|
||||
"""assoc_legendre_p_all(n, m, z, *, branch_cut=2, norm=False, diff_n=0)
|
||||
|
||||
All associated Legendre polynomials of the first kind up to the
|
||||
specified degree ``n`` and order ``m``.
|
||||
|
||||
Output shape is ``(n + 1, 2 * m + 1, ...)``. The entry at ``(j, i)``
|
||||
corresponds to degree ``j`` and order ``i`` for all ``0 <= j <= n``
|
||||
and ``-m <= i <= m``.
|
||||
|
||||
See Also
|
||||
--------
|
||||
assoc_legendre_p
|
||||
""", branch_cut=2, norm=False, diff_n=0
|
||||
)
|
||||
|
||||
|
||||
@assoc_legendre_p_all._override_key
|
||||
def _(branch_cut, norm, diff_n):
|
||||
if not ((isinstance(diff_n, numbers.Integral))
|
||||
and diff_n >= 0):
|
||||
raise ValueError(
|
||||
f"diff_n must be a non-negative integer, received: {diff_n}."
|
||||
)
|
||||
if not 0 <= diff_n <= 2:
|
||||
raise ValueError(
|
||||
"diff_n is currently only implemented for orders 0, 1, and 2,"
|
||||
f" received: {diff_n}."
|
||||
)
|
||||
return norm, diff_n
|
||||
|
||||
|
||||
@assoc_legendre_p_all._override_ufunc_default_args
|
||||
def _(branch_cut, norm, diff_n):
|
||||
return branch_cut,
|
||||
|
||||
|
||||
@assoc_legendre_p_all._override_ufunc_default_kwargs
|
||||
def _(branch_cut, norm, diff_n):
|
||||
return {'axes': [(), ()] + [(0, 1, -1)]}
|
||||
|
||||
|
||||
@assoc_legendre_p_all._override_resolve_out_shapes
|
||||
def _(n, m, z_shape, branch_cut_shape, nout, **kwargs):
|
||||
diff_n = kwargs['diff_n']
|
||||
|
||||
if not isinstance(n, numbers.Integral) or (n < 0):
|
||||
raise ValueError("n must be a non-negative integer.")
|
||||
if not isinstance(m, numbers.Integral) or (m < 0):
|
||||
raise ValueError("m must be a non-negative integer.")
|
||||
|
||||
return ((n + 1, 2 * abs(m) + 1) +
|
||||
np.broadcast_shapes(z_shape, branch_cut_shape) + (diff_n + 1,),)
|
||||
|
||||
|
||||
@assoc_legendre_p_all._override_finalize_out
|
||||
def _(out):
|
||||
return np.moveaxis(out, -1, 0)
|
||||
|
||||
|
||||
legendre_p = MultiUFunc(
|
||||
legendre_p,
|
||||
"""legendre_p(n, z, *, diff_n=0)
|
||||
|
||||
Legendre polynomial of the first kind.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
n : ArrayLike[int]
|
||||
Degree of the Legendre polynomial. Must have ``n >= 0``.
|
||||
z : ArrayLike[float]
|
||||
Input value.
|
||||
diff_n : Optional[int]
|
||||
A non-negative integer. Compute and return all derivatives up
|
||||
to order ``diff_n``. Default is 0.
|
||||
|
||||
Returns
|
||||
-------
|
||||
p : ndarray or tuple[ndarray]
|
||||
Legendre polynomial with ``diff_n`` derivatives.
|
||||
|
||||
See Also
|
||||
--------
|
||||
legendre
|
||||
|
||||
References
|
||||
----------
|
||||
.. [1] Zhang, Shanjie and Jin, Jianming. "Computation of Special
|
||||
Functions", John Wiley and Sons, 1996.
|
||||
https://people.sc.fsu.edu/~jburkardt/f77_src/special_functions/special_functions.html
|
||||
""", diff_n=0
|
||||
)
|
||||
|
||||
|
||||
@legendre_p._override_key
|
||||
def _(diff_n):
|
||||
if (not isinstance(diff_n, numbers.Integral)) or (diff_n < 0):
|
||||
raise ValueError(
|
||||
f"diff_n must be a non-negative integer, received: {diff_n}."
|
||||
)
|
||||
if not 0 <= diff_n <= 2:
|
||||
raise NotImplementedError(
|
||||
"diff_n is currently only implemented for orders 0, 1, and 2,"
|
||||
f" received: {diff_n}."
|
||||
)
|
||||
return diff_n
|
||||
|
||||
|
||||
@legendre_p._override_finalize_out
|
||||
def _(out):
|
||||
return np.moveaxis(out, -1, 0)
|
||||
|
||||
|
||||
legendre_p_all = MultiUFunc(
|
||||
legendre_p_all,
|
||||
"""legendre_p_all(n, z, *, diff_n=0)
|
||||
|
||||
All Legendre polynomials of the first kind up to the
|
||||
specified degree ``n``.
|
||||
|
||||
Output shape is ``(n + 1, ...)``. The entry at ``j``
|
||||
corresponds to degree ``j`` for all ``0 <= j <= n``.
|
||||
|
||||
See Also
|
||||
--------
|
||||
legendre_p
|
||||
""", diff_n=0
|
||||
)
|
||||
|
||||
|
||||
@legendre_p_all._override_key
|
||||
def _(diff_n):
|
||||
diff_n = _nonneg_int_or_fail(diff_n, "diff_n", strict=False)
|
||||
if not 0 <= diff_n <= 2:
|
||||
raise ValueError(
|
||||
"diff_n is currently only implemented for orders 0, 1, and 2,"
|
||||
f" received: {diff_n}."
|
||||
)
|
||||
return diff_n
|
||||
|
||||
|
||||
@legendre_p_all._override_ufunc_default_kwargs
|
||||
def _(diff_n):
|
||||
return {'axes': [(), (0, -1)]}
|
||||
|
||||
|
||||
@legendre_p_all._override_resolve_out_shapes
|
||||
def _(n, z_shape, nout, diff_n):
|
||||
n = _nonneg_int_or_fail(n, 'n', strict=False)
|
||||
|
||||
return nout * ((n + 1,) + z_shape + (diff_n + 1,),)
|
||||
|
||||
|
||||
@legendre_p_all._override_finalize_out
|
||||
def _(out):
|
||||
return np.moveaxis(out, -1, 0)
|
||||
|
||||
|
||||
sph_harm_y = MultiUFunc(
|
||||
sph_harm_y,
|
||||
r"""sph_harm_y(n, m, theta, phi, *, diff_n=0)
|
||||
|
||||
Spherical harmonics. They are defined as
|
||||
|
||||
.. math::
|
||||
|
||||
Y_n^m(\theta,\phi) = \sqrt{\frac{2 n + 1}{4 \pi} \frac{(n - m)!}{(n + m)!}}
|
||||
P_n^m(\cos(\theta)) e^{i m \phi}
|
||||
|
||||
where :math:`P_n^m` are the (unnormalized) associated Legendre polynomials.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
n : ArrayLike[int]
|
||||
Degree of the harmonic. Must have ``n >= 0``. This is
|
||||
often denoted by ``l`` (lower case L) in descriptions of
|
||||
spherical harmonics.
|
||||
m : ArrayLike[int]
|
||||
Order of the harmonic.
|
||||
theta : ArrayLike[float]
|
||||
Polar (colatitudinal) coordinate; must be in ``[0, pi]``.
|
||||
phi : ArrayLike[float]
|
||||
Azimuthal (longitudinal) coordinate; must be in ``[0, 2*pi]``.
|
||||
diff_n : Optional[int]
|
||||
A non-negative integer. Compute and return all derivatives up
|
||||
to order ``diff_n``. Default is 0.
|
||||
|
||||
Returns
|
||||
-------
|
||||
y : ndarray[complex] or tuple[ndarray[complex]]
|
||||
Spherical harmonics with ``diff_n`` derivatives.
|
||||
|
||||
Notes
|
||||
-----
|
||||
There are different conventions for the meanings of the input
|
||||
arguments ``theta`` and ``phi``. In SciPy ``theta`` is the
|
||||
polar angle and ``phi`` is the azimuthal angle. It is common to
|
||||
see the opposite convention, that is, ``theta`` as the azimuthal angle
|
||||
and ``phi`` as the polar angle.
|
||||
|
||||
Note that SciPy's spherical harmonics include the Condon-Shortley
|
||||
phase [2]_ because it is part of `sph_legendre_p`.
|
||||
|
||||
With SciPy's conventions, the first several spherical harmonics
|
||||
are
|
||||
|
||||
.. math::
|
||||
|
||||
Y_0^0(\theta, \phi) &= \frac{1}{2} \sqrt{\frac{1}{\pi}} \\
|
||||
Y_1^{-1}(\theta, \phi) &= \frac{1}{2} \sqrt{\frac{3}{2\pi}}
|
||||
e^{-i\phi} \sin(\theta) \\
|
||||
Y_1^0(\theta, \phi) &= \frac{1}{2} \sqrt{\frac{3}{\pi}}
|
||||
\cos(\theta) \\
|
||||
Y_1^1(\theta, \phi) &= -\frac{1}{2} \sqrt{\frac{3}{2\pi}}
|
||||
e^{i\phi} \sin(\theta).
|
||||
|
||||
References
|
||||
----------
|
||||
.. [1] Digital Library of Mathematical Functions, 14.30.
|
||||
https://dlmf.nist.gov/14.30
|
||||
.. [2] https://en.wikipedia.org/wiki/Spherical_harmonics#Condon.E2.80.93Shortley_phase
|
||||
""", force_complex_output=True, diff_n=0
|
||||
)
|
||||
|
||||
|
||||
@sph_harm_y._override_key
|
||||
def _(diff_n):
|
||||
diff_n = _nonneg_int_or_fail(diff_n, "diff_n", strict=False)
|
||||
if not 0 <= diff_n <= 2:
|
||||
raise ValueError(
|
||||
"diff_n is currently only implemented for orders 0, 1, and 2,"
|
||||
f" received: {diff_n}."
|
||||
)
|
||||
return diff_n
|
||||
|
||||
|
||||
@sph_harm_y._override_finalize_out
|
||||
def _(out):
|
||||
if (out.shape[-1] == 1):
|
||||
return out[..., 0, 0]
|
||||
|
||||
if (out.shape[-1] == 2):
|
||||
return out[..., 0, 0], out[..., [1, 0], [0, 1]]
|
||||
|
||||
if (out.shape[-1] == 3):
|
||||
return (out[..., 0, 0], out[..., [1, 0], [0, 1]],
|
||||
out[..., [[2, 1], [1, 0]], [[0, 1], [1, 2]]])
|
||||
|
||||
|
||||
sph_harm_y_all = MultiUFunc(
|
||||
sph_harm_y_all,
|
||||
"""sph_harm_y_all(n, m, theta, phi, *, diff_n=0)
|
||||
|
||||
All spherical harmonics up to the specified degree ``n`` and order ``m``.
|
||||
|
||||
Output shape is ``(n + 1, 2 * m + 1, ...)``. The entry at ``(j, i)``
|
||||
corresponds to degree ``j`` and order ``i`` for all ``0 <= j <= n``
|
||||
and ``-m <= i <= m``.
|
||||
|
||||
See Also
|
||||
--------
|
||||
sph_harm_y
|
||||
""", force_complex_output=True, diff_n=0
|
||||
)
|
||||
|
||||
|
||||
@sph_harm_y_all._override_key
|
||||
def _(diff_n):
|
||||
diff_n = _nonneg_int_or_fail(diff_n, "diff_n", strict=False)
|
||||
if not 0 <= diff_n <= 2:
|
||||
raise ValueError(
|
||||
"diff_n is currently only implemented for orders 2,"
|
||||
f" received: {diff_n}."
|
||||
)
|
||||
return diff_n
|
||||
|
||||
|
||||
@sph_harm_y_all._override_ufunc_default_kwargs
|
||||
def _(diff_n):
|
||||
return {'axes': [(), ()] + [(0, 1, -2, -1)]}
|
||||
|
||||
|
||||
@sph_harm_y_all._override_resolve_out_shapes
|
||||
def _(n, m, theta_shape, phi_shape, nout, **kwargs):
|
||||
diff_n = kwargs['diff_n']
|
||||
|
||||
if not isinstance(n, numbers.Integral) or (n < 0):
|
||||
raise ValueError("n must be a non-negative integer.")
|
||||
|
||||
return ((n + 1, 2 * abs(m) + 1) + np.broadcast_shapes(theta_shape, phi_shape) +
|
||||
(diff_n + 1, diff_n + 1),)
|
||||
|
||||
|
||||
@sph_harm_y_all._override_finalize_out
|
||||
def _(out):
|
||||
if (out.shape[-1] == 1):
|
||||
return out[..., 0, 0]
|
||||
|
||||
if (out.shape[-1] == 2):
|
||||
return out[..., 0, 0], out[..., [1, 0], [0, 1]]
|
||||
|
||||
if (out.shape[-1] == 3):
|
||||
return (out[..., 0, 0], out[..., [1, 0], [0, 1]],
|
||||
out[..., [[2, 1], [1, 0]], [[0, 1], [1, 2]]])
|
||||
2592
venv/lib/python3.13/site-packages/scipy/special/_orthogonal.py
Normal file
2592
venv/lib/python3.13/site-packages/scipy/special/_orthogonal.py
Normal file
File diff suppressed because it is too large
Load diff
330
venv/lib/python3.13/site-packages/scipy/special/_orthogonal.pyi
Normal file
330
venv/lib/python3.13/site-packages/scipy/special/_orthogonal.pyi
Normal file
|
|
@ -0,0 +1,330 @@
|
|||
from typing import (
|
||||
Any,
|
||||
Literal,
|
||||
Optional,
|
||||
overload,
|
||||
)
|
||||
from collections.abc import Callable
|
||||
|
||||
import numpy as np
|
||||
|
||||
_IntegerType = int | np.integer
|
||||
_FloatingType = float | np.floating
|
||||
_PointsAndWeights = tuple[np.ndarray, np.ndarray]
|
||||
_PointsAndWeightsAndMu = tuple[np.ndarray, np.ndarray, float]
|
||||
|
||||
_ArrayLike0D = bool | int | float | complex | str | bytes | np.generic
|
||||
|
||||
__all__ = [
|
||||
'legendre',
|
||||
'chebyt',
|
||||
'chebyu',
|
||||
'chebyc',
|
||||
'chebys',
|
||||
'jacobi',
|
||||
'laguerre',
|
||||
'genlaguerre',
|
||||
'hermite',
|
||||
'hermitenorm',
|
||||
'gegenbauer',
|
||||
'sh_legendre',
|
||||
'sh_chebyt',
|
||||
'sh_chebyu',
|
||||
'sh_jacobi',
|
||||
'roots_legendre',
|
||||
'roots_chebyt',
|
||||
'roots_chebyu',
|
||||
'roots_chebyc',
|
||||
'roots_chebys',
|
||||
'roots_jacobi',
|
||||
'roots_laguerre',
|
||||
'roots_genlaguerre',
|
||||
'roots_hermite',
|
||||
'roots_hermitenorm',
|
||||
'roots_gegenbauer',
|
||||
'roots_sh_legendre',
|
||||
'roots_sh_chebyt',
|
||||
'roots_sh_chebyu',
|
||||
'roots_sh_jacobi',
|
||||
]
|
||||
|
||||
@overload
|
||||
def roots_jacobi(
|
||||
n: _IntegerType,
|
||||
alpha: _FloatingType,
|
||||
beta: _FloatingType,
|
||||
) -> _PointsAndWeights: ...
|
||||
@overload
|
||||
def roots_jacobi(
|
||||
n: _IntegerType,
|
||||
alpha: _FloatingType,
|
||||
beta: _FloatingType,
|
||||
mu: Literal[False],
|
||||
) -> _PointsAndWeights: ...
|
||||
@overload
|
||||
def roots_jacobi(
|
||||
n: _IntegerType,
|
||||
alpha: _FloatingType,
|
||||
beta: _FloatingType,
|
||||
mu: Literal[True],
|
||||
) -> _PointsAndWeightsAndMu: ...
|
||||
|
||||
@overload
|
||||
def roots_sh_jacobi(
|
||||
n: _IntegerType,
|
||||
p1: _FloatingType,
|
||||
q1: _FloatingType,
|
||||
) -> _PointsAndWeights: ...
|
||||
@overload
|
||||
def roots_sh_jacobi(
|
||||
n: _IntegerType,
|
||||
p1: _FloatingType,
|
||||
q1: _FloatingType,
|
||||
mu: Literal[False],
|
||||
) -> _PointsAndWeights: ...
|
||||
@overload
|
||||
def roots_sh_jacobi(
|
||||
n: _IntegerType,
|
||||
p1: _FloatingType,
|
||||
q1: _FloatingType,
|
||||
mu: Literal[True],
|
||||
) -> _PointsAndWeightsAndMu: ...
|
||||
|
||||
@overload
|
||||
def roots_genlaguerre(
|
||||
n: _IntegerType,
|
||||
alpha: _FloatingType,
|
||||
) -> _PointsAndWeights: ...
|
||||
@overload
|
||||
def roots_genlaguerre(
|
||||
n: _IntegerType,
|
||||
alpha: _FloatingType,
|
||||
mu: Literal[False],
|
||||
) -> _PointsAndWeights: ...
|
||||
@overload
|
||||
def roots_genlaguerre(
|
||||
n: _IntegerType,
|
||||
alpha: _FloatingType,
|
||||
mu: Literal[True],
|
||||
) -> _PointsAndWeightsAndMu: ...
|
||||
|
||||
@overload
|
||||
def roots_laguerre(n: _IntegerType) -> _PointsAndWeights: ...
|
||||
@overload
|
||||
def roots_laguerre(
|
||||
n: _IntegerType,
|
||||
mu: Literal[False],
|
||||
) -> _PointsAndWeights: ...
|
||||
@overload
|
||||
def roots_laguerre(
|
||||
n: _IntegerType,
|
||||
mu: Literal[True],
|
||||
) -> _PointsAndWeightsAndMu: ...
|
||||
|
||||
@overload
|
||||
def roots_hermite(n: _IntegerType) -> _PointsAndWeights: ...
|
||||
@overload
|
||||
def roots_hermite(
|
||||
n: _IntegerType,
|
||||
mu: Literal[False],
|
||||
) -> _PointsAndWeights: ...
|
||||
@overload
|
||||
def roots_hermite(
|
||||
n: _IntegerType,
|
||||
mu: Literal[True],
|
||||
) -> _PointsAndWeightsAndMu: ...
|
||||
|
||||
@overload
|
||||
def roots_hermitenorm(n: _IntegerType) -> _PointsAndWeights: ...
|
||||
@overload
|
||||
def roots_hermitenorm(
|
||||
n: _IntegerType,
|
||||
mu: Literal[False],
|
||||
) -> _PointsAndWeights: ...
|
||||
@overload
|
||||
def roots_hermitenorm(
|
||||
n: _IntegerType,
|
||||
mu: Literal[True],
|
||||
) -> _PointsAndWeightsAndMu: ...
|
||||
|
||||
@overload
|
||||
def roots_gegenbauer(
|
||||
n: _IntegerType,
|
||||
alpha: _FloatingType,
|
||||
) -> _PointsAndWeights: ...
|
||||
@overload
|
||||
def roots_gegenbauer(
|
||||
n: _IntegerType,
|
||||
alpha: _FloatingType,
|
||||
mu: Literal[False],
|
||||
) -> _PointsAndWeights: ...
|
||||
@overload
|
||||
def roots_gegenbauer(
|
||||
n: _IntegerType,
|
||||
alpha: _FloatingType,
|
||||
mu: Literal[True],
|
||||
) -> _PointsAndWeightsAndMu: ...
|
||||
|
||||
@overload
|
||||
def roots_chebyt(n: _IntegerType) -> _PointsAndWeights: ...
|
||||
@overload
|
||||
def roots_chebyt(
|
||||
n: _IntegerType,
|
||||
mu: Literal[False],
|
||||
) -> _PointsAndWeights: ...
|
||||
@overload
|
||||
def roots_chebyt(
|
||||
n: _IntegerType,
|
||||
mu: Literal[True],
|
||||
) -> _PointsAndWeightsAndMu: ...
|
||||
|
||||
@overload
|
||||
def roots_chebyu(n: _IntegerType) -> _PointsAndWeights: ...
|
||||
@overload
|
||||
def roots_chebyu(
|
||||
n: _IntegerType,
|
||||
mu: Literal[False],
|
||||
) -> _PointsAndWeights: ...
|
||||
@overload
|
||||
def roots_chebyu(
|
||||
n: _IntegerType,
|
||||
mu: Literal[True],
|
||||
) -> _PointsAndWeightsAndMu: ...
|
||||
|
||||
@overload
|
||||
def roots_chebyc(n: _IntegerType) -> _PointsAndWeights: ...
|
||||
@overload
|
||||
def roots_chebyc(
|
||||
n: _IntegerType,
|
||||
mu: Literal[False],
|
||||
) -> _PointsAndWeights: ...
|
||||
@overload
|
||||
def roots_chebyc(
|
||||
n: _IntegerType,
|
||||
mu: Literal[True],
|
||||
) -> _PointsAndWeightsAndMu: ...
|
||||
|
||||
@overload
|
||||
def roots_chebys(n: _IntegerType) -> _PointsAndWeights: ...
|
||||
@overload
|
||||
def roots_chebys(
|
||||
n: _IntegerType,
|
||||
mu: Literal[False],
|
||||
) -> _PointsAndWeights: ...
|
||||
@overload
|
||||
def roots_chebys(
|
||||
n: _IntegerType,
|
||||
mu: Literal[True],
|
||||
) -> _PointsAndWeightsAndMu: ...
|
||||
|
||||
@overload
|
||||
def roots_sh_chebyt(n: _IntegerType) -> _PointsAndWeights: ...
|
||||
@overload
|
||||
def roots_sh_chebyt(
|
||||
n: _IntegerType,
|
||||
mu: Literal[False],
|
||||
) -> _PointsAndWeights: ...
|
||||
@overload
|
||||
def roots_sh_chebyt(
|
||||
n: _IntegerType,
|
||||
mu: Literal[True],
|
||||
) -> _PointsAndWeightsAndMu: ...
|
||||
|
||||
@overload
|
||||
def roots_sh_chebyu(n: _IntegerType) -> _PointsAndWeights: ...
|
||||
@overload
|
||||
def roots_sh_chebyu(
|
||||
n: _IntegerType,
|
||||
mu: Literal[False],
|
||||
) -> _PointsAndWeights: ...
|
||||
@overload
|
||||
def roots_sh_chebyu(
|
||||
n: _IntegerType,
|
||||
mu: Literal[True],
|
||||
) -> _PointsAndWeightsAndMu: ...
|
||||
|
||||
@overload
|
||||
def roots_legendre(n: _IntegerType) -> _PointsAndWeights: ...
|
||||
@overload
|
||||
def roots_legendre(
|
||||
n: _IntegerType,
|
||||
mu: Literal[False],
|
||||
) -> _PointsAndWeights: ...
|
||||
@overload
|
||||
def roots_legendre(
|
||||
n: _IntegerType,
|
||||
mu: Literal[True],
|
||||
) -> _PointsAndWeightsAndMu: ...
|
||||
|
||||
@overload
|
||||
def roots_sh_legendre(n: _IntegerType) -> _PointsAndWeights: ...
|
||||
@overload
|
||||
def roots_sh_legendre(
|
||||
n: _IntegerType,
|
||||
mu: Literal[False],
|
||||
) -> _PointsAndWeights: ...
|
||||
@overload
|
||||
def roots_sh_legendre(
|
||||
n: _IntegerType,
|
||||
mu: Literal[True],
|
||||
) -> _PointsAndWeightsAndMu: ...
|
||||
|
||||
class orthopoly1d(np.poly1d):
|
||||
def __init__(
|
||||
self,
|
||||
roots: np.typing.ArrayLike,
|
||||
weights: np.typing.ArrayLike | None,
|
||||
hn: float = ...,
|
||||
kn: float = ...,
|
||||
wfunc = Optional[Callable[[float], float]], # noqa: UP007
|
||||
limits = tuple[float, float] | None,
|
||||
monic: bool = ...,
|
||||
eval_func: np.ufunc = ...,
|
||||
) -> None: ...
|
||||
@property
|
||||
def limits(self) -> tuple[float, float]: ...
|
||||
def weight_func(self, x: float) -> float: ...
|
||||
@overload
|
||||
def __call__(self, x: _ArrayLike0D) -> Any: ...
|
||||
@overload
|
||||
def __call__(self, x: np.poly1d) -> np.poly1d: ... # type: ignore[overload-overlap]
|
||||
@overload
|
||||
def __call__(self, x: np.typing.ArrayLike) -> np.ndarray: ...
|
||||
|
||||
def legendre(n: _IntegerType, monic: bool = ...) -> orthopoly1d: ...
|
||||
def chebyt(n: _IntegerType, monic: bool = ...) -> orthopoly1d: ...
|
||||
def chebyu(n: _IntegerType, monic: bool = ...) -> orthopoly1d: ...
|
||||
def chebyc(n: _IntegerType, monic: bool = ...) -> orthopoly1d: ...
|
||||
def chebys(n: _IntegerType, monic: bool = ...) -> orthopoly1d: ...
|
||||
def jacobi(
|
||||
n: _IntegerType,
|
||||
alpha: _FloatingType,
|
||||
beta: _FloatingType,
|
||||
monic: bool = ...,
|
||||
) -> orthopoly1d: ...
|
||||
def laguerre(n: _IntegerType, monic: bool = ...) -> orthopoly1d: ...
|
||||
def genlaguerre(
|
||||
n: _IntegerType,
|
||||
alpha: _FloatingType,
|
||||
monic: bool = ...,
|
||||
) -> orthopoly1d: ...
|
||||
def hermite(n: _IntegerType, monic: bool = ...) -> orthopoly1d: ...
|
||||
def hermitenorm(n: _IntegerType, monic: bool = ...) -> orthopoly1d: ...
|
||||
def gegenbauer(
|
||||
n: _IntegerType,
|
||||
alpha: _FloatingType,
|
||||
monic: bool = ...,
|
||||
) -> orthopoly1d: ...
|
||||
def sh_legendre(n: _IntegerType, monic: bool = ...) -> orthopoly1d: ...
|
||||
def sh_chebyt(n: _IntegerType, monic: bool = ...) -> orthopoly1d: ...
|
||||
def sh_chebyu(n: _IntegerType, monic: bool = ...) -> orthopoly1d: ...
|
||||
def sh_jacobi(
|
||||
n: _IntegerType,
|
||||
p: _FloatingType,
|
||||
q: _FloatingType,
|
||||
monic: bool = ...,
|
||||
) -> orthopoly1d: ...
|
||||
|
||||
# These functions are not public, but still need stubs because they
|
||||
# get checked in the tests.
|
||||
def _roots_hermite_asy(n: _IntegerType) -> _PointsAndWeights: ...
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -0,0 +1,17 @@
|
|||
import mpmath
|
||||
|
||||
|
||||
def f(x):
|
||||
return (mpmath.pi + x + mpmath.sin(x)) / (2*mpmath.pi)
|
||||
|
||||
|
||||
# Note: 40 digits might be overkill; a few more digits than the default
|
||||
# might be sufficient.
|
||||
mpmath.mp.dps = 40
|
||||
ts = mpmath.taylor(f, -mpmath.pi, 20)
|
||||
p, q = mpmath.pade(ts, 9, 10)
|
||||
|
||||
p = [float(c) for c in p]
|
||||
q = [float(c) for c in q]
|
||||
print('p =', p)
|
||||
print('q =', q)
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
"""Precompute the polynomials for the asymptotic expansion of the
|
||||
generalized exponential integral.
|
||||
|
||||
Sources
|
||||
-------
|
||||
[1] NIST, Digital Library of Mathematical Functions,
|
||||
https://dlmf.nist.gov/8.20#ii
|
||||
|
||||
"""
|
||||
import os
|
||||
|
||||
try:
|
||||
import sympy
|
||||
from sympy import Poly
|
||||
x = sympy.symbols('x')
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
|
||||
def generate_A(K):
|
||||
A = [Poly(1, x)]
|
||||
for k in range(K):
|
||||
A.append(Poly(1 - 2*k*x, x)*A[k] + Poly(x*(x + 1))*A[k].diff())
|
||||
return A
|
||||
|
||||
|
||||
WARNING = """\
|
||||
/* This file was automatically generated by _precompute/expn_asy.py.
|
||||
* Do not edit it manually!
|
||||
*/
|
||||
"""
|
||||
|
||||
|
||||
def main():
|
||||
print(__doc__)
|
||||
fn = os.path.join('..', 'cephes', 'expn.h')
|
||||
|
||||
K = 12
|
||||
A = generate_A(K)
|
||||
with open(fn + '.new', 'w') as f:
|
||||
f.write(WARNING)
|
||||
f.write(f"#define nA {len(A)}\n")
|
||||
for k, Ak in enumerate(A):
|
||||
', '.join([str(x.evalf(18)) for x in Ak.coeffs()])
|
||||
f.write(f"static const double A{k}[] = {{tmp}};\n")
|
||||
", ".join([f"A{k}" for k in range(K + 1)])
|
||||
f.write("static const double *A[] = {{tmp}};\n")
|
||||
", ".join([str(Ak.degree()) for Ak in A])
|
||||
f.write("static const int Adegs[] = {{tmp}};\n")
|
||||
os.rename(fn + '.new', fn)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
|
@ -0,0 +1,116 @@
|
|||
"""
|
||||
Precompute coefficients of Temme's asymptotic expansion for gammainc.
|
||||
|
||||
This takes about 8 hours to run on a 2.3 GHz Macbook Pro with 4GB ram.
|
||||
|
||||
Sources:
|
||||
[1] NIST, "Digital Library of Mathematical Functions",
|
||||
https://dlmf.nist.gov/
|
||||
|
||||
"""
|
||||
import os
|
||||
from scipy.special._precompute.utils import lagrange_inversion
|
||||
|
||||
try:
|
||||
import mpmath as mp
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
|
||||
def compute_a(n):
|
||||
"""a_k from DLMF 5.11.6"""
|
||||
a = [mp.sqrt(2)/2]
|
||||
for k in range(1, n):
|
||||
ak = a[-1]/k
|
||||
for j in range(1, len(a)):
|
||||
ak -= a[j]*a[-j]/(j + 1)
|
||||
ak /= a[0]*(1 + mp.mpf(1)/(k + 1))
|
||||
a.append(ak)
|
||||
return a
|
||||
|
||||
|
||||
def compute_g(n):
|
||||
"""g_k from DLMF 5.11.3/5.11.5"""
|
||||
a = compute_a(2*n)
|
||||
g = [mp.sqrt(2)*mp.rf(0.5, k)*a[2*k] for k in range(n)]
|
||||
return g
|
||||
|
||||
|
||||
def eta(lam):
|
||||
"""Function from DLMF 8.12.1 shifted to be centered at 0."""
|
||||
if lam > 0:
|
||||
return mp.sqrt(2*(lam - mp.log(lam + 1)))
|
||||
elif lam < 0:
|
||||
return -mp.sqrt(2*(lam - mp.log(lam + 1)))
|
||||
else:
|
||||
return 0
|
||||
|
||||
|
||||
def compute_alpha(n):
|
||||
"""alpha_n from DLMF 8.12.13"""
|
||||
coeffs = mp.taylor(eta, 0, n - 1)
|
||||
return lagrange_inversion(coeffs)
|
||||
|
||||
|
||||
def compute_d(K, N):
|
||||
"""d_{k, n} from DLMF 8.12.12"""
|
||||
M = N + 2*K
|
||||
d0 = [-mp.mpf(1)/3]
|
||||
alpha = compute_alpha(M + 2)
|
||||
for n in range(1, M):
|
||||
d0.append((n + 2)*alpha[n+2])
|
||||
d = [d0]
|
||||
g = compute_g(K)
|
||||
for k in range(1, K):
|
||||
dk = []
|
||||
for n in range(M - 2*k):
|
||||
dk.append((-1)**k*g[k]*d[0][n] + (n + 2)*d[k-1][n+2])
|
||||
d.append(dk)
|
||||
for k in range(K):
|
||||
d[k] = d[k][:N]
|
||||
return d
|
||||
|
||||
|
||||
header = \
|
||||
r"""/* This file was automatically generated by _precomp/gammainc.py.
|
||||
* Do not edit it manually!
|
||||
*/
|
||||
|
||||
#ifndef IGAM_H
|
||||
#define IGAM_H
|
||||
|
||||
#define K {}
|
||||
#define N {}
|
||||
|
||||
static const double d[K][N] =
|
||||
{{"""
|
||||
|
||||
footer = \
|
||||
r"""
|
||||
#endif
|
||||
"""
|
||||
|
||||
|
||||
def main():
|
||||
print(__doc__)
|
||||
K = 25
|
||||
N = 25
|
||||
with mp.workdps(50):
|
||||
d = compute_d(K, N)
|
||||
fn = os.path.join(os.path.dirname(__file__), '..', 'cephes', 'igam.h')
|
||||
with open(fn + '.new', 'w') as f:
|
||||
f.write(header.format(K, N))
|
||||
for k, row in enumerate(d):
|
||||
row = [mp.nstr(x, 17, min_fixed=0, max_fixed=0) for x in row]
|
||||
f.write('{')
|
||||
f.write(", ".join(row))
|
||||
if k < K - 1:
|
||||
f.write('},\n')
|
||||
else:
|
||||
f.write('}};\n')
|
||||
f.write(footer)
|
||||
os.rename(fn + '.new', fn)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
|
@ -0,0 +1,124 @@
|
|||
"""Compute gammainc and gammaincc for large arguments and parameters
|
||||
and save the values to data files for use in tests. We can't just
|
||||
compare to mpmath's gammainc in test_mpmath.TestSystematic because it
|
||||
would take too long.
|
||||
|
||||
Note that mpmath's gammainc is computed using hypercomb, but since it
|
||||
doesn't allow the user to increase the maximum number of terms used in
|
||||
the series it doesn't converge for many arguments. To get around this
|
||||
we copy the mpmath implementation but use more terms.
|
||||
|
||||
This takes about 17 minutes to run on a 2.3 GHz Macbook Pro with 4GB
|
||||
ram.
|
||||
|
||||
Sources:
|
||||
[1] Fredrik Johansson and others. mpmath: a Python library for
|
||||
arbitrary-precision floating-point arithmetic (version 0.19),
|
||||
December 2013. http://mpmath.org/.
|
||||
|
||||
"""
|
||||
import os
|
||||
from time import time
|
||||
import numpy as np
|
||||
from numpy import pi
|
||||
|
||||
from scipy.special._mptestutils import mpf2float
|
||||
|
||||
try:
|
||||
import mpmath as mp
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
|
||||
def gammainc(a, x, dps=50, maxterms=10**8):
|
||||
"""Compute gammainc exactly like mpmath does but allow for more
|
||||
summands in hypercomb. See
|
||||
|
||||
mpmath/functions/expintegrals.py#L134
|
||||
|
||||
in the mpmath GitHub repository.
|
||||
|
||||
"""
|
||||
with mp.workdps(dps):
|
||||
z, a, b = mp.mpf(a), mp.mpf(x), mp.mpf(x)
|
||||
G = [z]
|
||||
negb = mp.fneg(b, exact=True)
|
||||
|
||||
def h(z):
|
||||
T1 = [mp.exp(negb), b, z], [1, z, -1], [], G, [1], [1+z], b
|
||||
return (T1,)
|
||||
|
||||
res = mp.hypercomb(h, [z], maxterms=maxterms)
|
||||
return mpf2float(res)
|
||||
|
||||
|
||||
def gammaincc(a, x, dps=50, maxterms=10**8):
|
||||
"""Compute gammaincc exactly like mpmath does but allow for more
|
||||
terms in hypercomb. See
|
||||
|
||||
mpmath/functions/expintegrals.py#L187
|
||||
|
||||
in the mpmath GitHub repository.
|
||||
|
||||
"""
|
||||
with mp.workdps(dps):
|
||||
z, a = a, x
|
||||
|
||||
if mp.isint(z):
|
||||
try:
|
||||
# mpmath has a fast integer path
|
||||
return mpf2float(mp.gammainc(z, a=a, regularized=True))
|
||||
except mp.libmp.NoConvergence:
|
||||
pass
|
||||
nega = mp.fneg(a, exact=True)
|
||||
G = [z]
|
||||
# Use 2F0 series when possible; fall back to lower gamma representation
|
||||
try:
|
||||
def h(z):
|
||||
r = z-1
|
||||
return [([mp.exp(nega), a], [1, r], [], G, [1, -r], [], 1/nega)]
|
||||
return mpf2float(mp.hypercomb(h, [z], force_series=True))
|
||||
except mp.libmp.NoConvergence:
|
||||
def h(z):
|
||||
T1 = [], [1, z-1], [z], G, [], [], 0
|
||||
T2 = [-mp.exp(nega), a, z], [1, z, -1], [], G, [1], [1+z], a
|
||||
return T1, T2
|
||||
return mpf2float(mp.hypercomb(h, [z], maxterms=maxterms))
|
||||
|
||||
|
||||
def main():
|
||||
t0 = time()
|
||||
# It would be nice to have data for larger values, but either this
|
||||
# requires prohibitively large precision (dps > 800) or mpmath has
|
||||
# a bug. For example, gammainc(1e20, 1e20, dps=800) returns a
|
||||
# value around 0.03, while the true value should be close to 0.5
|
||||
# (DLMF 8.12.15).
|
||||
print(__doc__)
|
||||
pwd = os.path.dirname(__file__)
|
||||
r = np.logspace(4, 14, 30)
|
||||
ltheta = np.logspace(np.log10(pi/4), np.log10(np.arctan(0.6)), 30)
|
||||
utheta = np.logspace(np.log10(pi/4), np.log10(np.arctan(1.4)), 30)
|
||||
|
||||
regimes = [(gammainc, ltheta), (gammaincc, utheta)]
|
||||
for func, theta in regimes:
|
||||
rg, thetag = np.meshgrid(r, theta)
|
||||
a, x = rg*np.cos(thetag), rg*np.sin(thetag)
|
||||
a, x = a.flatten(), x.flatten()
|
||||
dataset = []
|
||||
for i, (a0, x0) in enumerate(zip(a, x)):
|
||||
if func == gammaincc:
|
||||
# Exploit the fast integer path in gammaincc whenever
|
||||
# possible so that the computation doesn't take too
|
||||
# long
|
||||
a0, x0 = np.floor(a0), np.floor(x0)
|
||||
dataset.append((a0, x0, func(a0, x0)))
|
||||
dataset = np.array(dataset)
|
||||
filename = os.path.join(pwd, '..', 'tests', 'data', 'local',
|
||||
f'{func.__name__}.txt')
|
||||
np.savetxt(filename, dataset)
|
||||
|
||||
print(f"{(time() - t0)/60} minutes elapsed")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
|
@ -0,0 +1,484 @@
|
|||
"""This script evaluates scipy's implementation of hyp2f1 against mpmath's.
|
||||
|
||||
Author: Albert Steppi
|
||||
|
||||
This script is long running and generates a large output file. With default
|
||||
arguments, the generated file is roughly 700MB in size and it takes around
|
||||
40 minutes using an Intel(R) Core(TM) i5-8250U CPU with n_jobs set to 8
|
||||
(full utilization). There are optional arguments which can be used to restrict
|
||||
(or enlarge) the computations performed. These are described below.
|
||||
The output of this script can be analyzed to identify suitable test cases and
|
||||
to find parameter and argument regions where hyp2f1 needs to be improved.
|
||||
|
||||
The script has one mandatory positional argument for specifying the path to
|
||||
the location where the output file is to be placed, and 4 optional arguments
|
||||
--n_jobs, --grid_size, --regions, and --parameter_groups. --n_jobs specifies
|
||||
the number of processes to use if running in parallel. The default value is 1.
|
||||
The other optional arguments are explained below.
|
||||
|
||||
Produces a tab separated values file with 11 columns. The first four columns
|
||||
contain the parameters a, b, c and the argument z. The next two contain |z| and
|
||||
a region code for which region of the complex plane belongs to. The regions are
|
||||
|
||||
0) z == 1
|
||||
1) |z| < 0.9 and real(z) >= 0
|
||||
2) |z| <= 1 and real(z) < 0
|
||||
3) 0.9 <= |z| <= 1 and |1 - z| < 0.9:
|
||||
4) 0.9 <= |z| <= 1 and |1 - z| >= 0.9 and real(z) >= 0:
|
||||
5) 1 < |z| < 1.1 and |1 - z| >= 0.9 and real(z) >= 0
|
||||
6) |z| > 1 and not in 5)
|
||||
|
||||
The --regions optional argument allows the user to specify a list of regions
|
||||
to which computation will be restricted.
|
||||
|
||||
Parameters a, b, c are taken from a 10 * 10 * 10 grid with values at
|
||||
|
||||
-16, -8, -4, -2, -1, 1, 2, 4, 8, 16
|
||||
|
||||
with random perturbations applied.
|
||||
|
||||
There are 9 parameter groups handling the following cases.
|
||||
|
||||
1) A, B, C, B - A, C - A, C - B, C - A - B all non-integral.
|
||||
2) B - A integral
|
||||
3) C - A integral
|
||||
4) C - B integral
|
||||
5) C - A - B integral
|
||||
6) A integral
|
||||
7) B integral
|
||||
8) C integral
|
||||
9) Wider range with c - a - b > 0.
|
||||
|
||||
The seventh column of the output file is an integer between 1 and 8 specifying
|
||||
the parameter group as above.
|
||||
|
||||
The --parameter_groups optional argument allows the user to specify a list of
|
||||
parameter groups to which computation will be restricted.
|
||||
|
||||
The argument z is taken from a grid in the box
|
||||
-box_size <= real(z) <= box_size, -box_size <= imag(z) <= box_size.
|
||||
with grid size specified using the optional command line argument --grid_size,
|
||||
and box_size specified with the command line argument --box_size.
|
||||
The default value of grid_size is 20 and the default value of box_size is 2.0,
|
||||
yielding a 20 * 20 grid in the box with corners -2-2j, -2+2j, 2-2j, 2+2j.
|
||||
|
||||
The final four columns have the expected value of hyp2f1 for the given
|
||||
parameters and argument as calculated with mpmath, the observed value
|
||||
calculated with scipy's hyp2f1, the relative error, and the absolute error.
|
||||
|
||||
As special cases of hyp2f1 are moved from the original Fortran implementation
|
||||
into Cython, this script can be used to ensure that no regressions occur and
|
||||
to point out where improvements are needed.
|
||||
"""
|
||||
|
||||
|
||||
import os
|
||||
import csv
|
||||
import argparse
|
||||
import numpy as np
|
||||
from itertools import product
|
||||
from multiprocessing import Pool
|
||||
|
||||
|
||||
from scipy.special import hyp2f1
|
||||
from scipy.special.tests.test_hyp2f1 import mp_hyp2f1
|
||||
|
||||
|
||||
def get_region(z):
|
||||
"""Assign numbers for regions where hyp2f1 must be handled differently."""
|
||||
if z == 1 + 0j:
|
||||
return 0
|
||||
elif abs(z) < 0.9 and z.real >= 0:
|
||||
return 1
|
||||
elif abs(z) <= 1 and z.real < 0:
|
||||
return 2
|
||||
elif 0.9 <= abs(z) <= 1 and abs(1 - z) < 0.9:
|
||||
return 3
|
||||
elif 0.9 <= abs(z) <= 1 and abs(1 - z) >= 0.9:
|
||||
return 4
|
||||
elif 1 < abs(z) < 1.1 and abs(1 - z) >= 0.9 and z.real >= 0:
|
||||
return 5
|
||||
else:
|
||||
return 6
|
||||
|
||||
|
||||
def get_result(a, b, c, z, group):
|
||||
"""Get results for given parameter and value combination."""
|
||||
expected, observed = mp_hyp2f1(a, b, c, z), hyp2f1(a, b, c, z)
|
||||
if (
|
||||
np.isnan(observed) and np.isnan(expected) or
|
||||
expected == observed
|
||||
):
|
||||
relative_error = 0.0
|
||||
absolute_error = 0.0
|
||||
elif np.isnan(observed):
|
||||
# Set error to infinity if result is nan when not expected to be.
|
||||
# Makes results easier to interpret.
|
||||
relative_error = float("inf")
|
||||
absolute_error = float("inf")
|
||||
else:
|
||||
absolute_error = abs(expected - observed)
|
||||
relative_error = absolute_error / abs(expected)
|
||||
|
||||
return (
|
||||
a,
|
||||
b,
|
||||
c,
|
||||
z,
|
||||
abs(z),
|
||||
get_region(z),
|
||||
group,
|
||||
expected,
|
||||
observed,
|
||||
relative_error,
|
||||
absolute_error,
|
||||
)
|
||||
|
||||
|
||||
def get_result_no_mp(a, b, c, z, group):
|
||||
"""Get results for given parameter and value combination."""
|
||||
expected, observed = complex('nan'), hyp2f1(a, b, c, z)
|
||||
relative_error, absolute_error = float('nan'), float('nan')
|
||||
return (
|
||||
a,
|
||||
b,
|
||||
c,
|
||||
z,
|
||||
abs(z),
|
||||
get_region(z),
|
||||
group,
|
||||
expected,
|
||||
observed,
|
||||
relative_error,
|
||||
absolute_error,
|
||||
)
|
||||
|
||||
|
||||
def get_results(params, Z, n_jobs=1, compute_mp=True):
|
||||
"""Batch compute results for multiple parameter and argument values.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
params : iterable
|
||||
iterable of tuples of floats (a, b, c) specifying parameter values
|
||||
a, b, c for hyp2f1
|
||||
Z : iterable of complex
|
||||
Arguments at which to evaluate hyp2f1
|
||||
n_jobs : Optional[int]
|
||||
Number of jobs for parallel execution.
|
||||
|
||||
Returns
|
||||
-------
|
||||
list
|
||||
List of tuples of results values. See return value in source code
|
||||
of `get_result`.
|
||||
"""
|
||||
input_ = (
|
||||
(a, b, c, z, group) for (a, b, c, group), z in product(params, Z)
|
||||
)
|
||||
|
||||
with Pool(n_jobs) as pool:
|
||||
rows = pool.starmap(
|
||||
get_result if compute_mp else get_result_no_mp,
|
||||
input_
|
||||
)
|
||||
return rows
|
||||
|
||||
|
||||
def _make_hyp2f1_test_case(a, b, c, z, rtol):
|
||||
"""Generate string for single test case as used in test_hyp2f1.py."""
|
||||
expected = mp_hyp2f1(a, b, c, z)
|
||||
return (
|
||||
" pytest.param(\n"
|
||||
" Hyp2f1TestCase(\n"
|
||||
f" a={a},\n"
|
||||
f" b={b},\n"
|
||||
f" c={c},\n"
|
||||
f" z={z},\n"
|
||||
f" expected={expected},\n"
|
||||
f" rtol={rtol},\n"
|
||||
" ),\n"
|
||||
" ),"
|
||||
)
|
||||
|
||||
|
||||
def make_hyp2f1_test_cases(rows):
|
||||
"""Generate string for a list of test cases for test_hyp2f1.py.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
rows : list
|
||||
List of lists of the form [a, b, c, z, rtol] where a, b, c, z are
|
||||
parameters and the argument for hyp2f1 and rtol is an expected
|
||||
relative error for the associated test case.
|
||||
|
||||
Returns
|
||||
-------
|
||||
str
|
||||
String for a list of test cases. The output string can be printed
|
||||
or saved to a file and then copied into an argument for
|
||||
`pytest.mark.parameterize` within `scipy.special.tests.test_hyp2f1.py`.
|
||||
"""
|
||||
result = "[\n"
|
||||
result += '\n'.join(
|
||||
_make_hyp2f1_test_case(a, b, c, z, rtol)
|
||||
for a, b, c, z, rtol in rows
|
||||
)
|
||||
result += "\n]"
|
||||
return result
|
||||
|
||||
|
||||
def main(
|
||||
outpath,
|
||||
n_jobs=1,
|
||||
box_size=2.0,
|
||||
grid_size=20,
|
||||
regions=None,
|
||||
parameter_groups=None,
|
||||
compute_mp=True,
|
||||
):
|
||||
outpath = os.path.realpath(os.path.expanduser(outpath))
|
||||
|
||||
random_state = np.random.RandomState(1234)
|
||||
# Parameters a, b, c selected near these values.
|
||||
root_params = np.array(
|
||||
[-16, -8, -4, -2, -1, 1, 2, 4, 8, 16]
|
||||
)
|
||||
# Perturbations to apply to root values.
|
||||
perturbations = 0.1 * random_state.random_sample(
|
||||
size=(3, len(root_params))
|
||||
)
|
||||
|
||||
params = []
|
||||
# Parameter group 1
|
||||
# -----------------
|
||||
# No integer differences. This has been confirmed for the above seed.
|
||||
A = root_params + perturbations[0, :]
|
||||
B = root_params + perturbations[1, :]
|
||||
C = root_params + perturbations[2, :]
|
||||
params.extend(
|
||||
sorted(
|
||||
((a, b, c, 1) for a, b, c in product(A, B, C)),
|
||||
key=lambda x: max(abs(x[0]), abs(x[1])),
|
||||
)
|
||||
)
|
||||
|
||||
# Parameter group 2
|
||||
# -----------------
|
||||
# B - A an integer
|
||||
A = root_params + 0.5
|
||||
B = root_params + 0.5
|
||||
C = root_params + perturbations[1, :]
|
||||
params.extend(
|
||||
sorted(
|
||||
((a, b, c, 2) for a, b, c in product(A, B, C)),
|
||||
key=lambda x: max(abs(x[0]), abs(x[1])),
|
||||
)
|
||||
)
|
||||
|
||||
# Parameter group 3
|
||||
# -----------------
|
||||
# C - A an integer
|
||||
A = root_params + 0.5
|
||||
B = root_params + perturbations[1, :]
|
||||
C = root_params + 0.5
|
||||
params.extend(
|
||||
sorted(
|
||||
((a, b, c, 3) for a, b, c in product(A, B, C)),
|
||||
key=lambda x: max(abs(x[0]), abs(x[1])),
|
||||
)
|
||||
)
|
||||
|
||||
# Parameter group 4
|
||||
# -----------------
|
||||
# C - B an integer
|
||||
A = root_params + perturbations[0, :]
|
||||
B = root_params + 0.5
|
||||
C = root_params + 0.5
|
||||
params.extend(
|
||||
sorted(
|
||||
((a, b, c, 4) for a, b, c in product(A, B, C)),
|
||||
key=lambda x: max(abs(x[0]), abs(x[1])),
|
||||
)
|
||||
)
|
||||
|
||||
# Parameter group 5
|
||||
# -----------------
|
||||
# C - A - B an integer
|
||||
A = root_params + 0.25
|
||||
B = root_params + 0.25
|
||||
C = root_params + 0.5
|
||||
params.extend(
|
||||
sorted(
|
||||
((a, b, c, 5) for a, b, c in product(A, B, C)),
|
||||
key=lambda x: max(abs(x[0]), abs(x[1])),
|
||||
)
|
||||
)
|
||||
|
||||
# Parameter group 6
|
||||
# -----------------
|
||||
# A an integer
|
||||
A = root_params
|
||||
B = root_params + perturbations[0, :]
|
||||
C = root_params + perturbations[1, :]
|
||||
params.extend(
|
||||
sorted(
|
||||
((a, b, c, 6) for a, b, c in product(A, B, C)),
|
||||
key=lambda x: max(abs(x[0]), abs(x[1])),
|
||||
)
|
||||
)
|
||||
|
||||
# Parameter group 7
|
||||
# -----------------
|
||||
# B an integer
|
||||
A = root_params + perturbations[0, :]
|
||||
B = root_params
|
||||
C = root_params + perturbations[1, :]
|
||||
params.extend(
|
||||
sorted(
|
||||
((a, b, c, 7) for a, b, c in product(A, B, C)),
|
||||
key=lambda x: max(abs(x[0]), abs(x[1])),
|
||||
)
|
||||
)
|
||||
|
||||
# Parameter group 8
|
||||
# -----------------
|
||||
# C an integer
|
||||
A = root_params + perturbations[0, :]
|
||||
B = root_params + perturbations[1, :]
|
||||
C = root_params
|
||||
params.extend(
|
||||
sorted(
|
||||
((a, b, c, 8) for a, b, c in product(A, B, C)),
|
||||
key=lambda x: max(abs(x[0]), abs(x[1])),
|
||||
)
|
||||
)
|
||||
|
||||
# Parameter group 9
|
||||
# -----------------
|
||||
# Wide range of magnitudes, c - a - b > 0.
|
||||
phi = (1 + np.sqrt(5))/2
|
||||
P = phi**np.arange(16)
|
||||
P = np.hstack([-P, P])
|
||||
group_9_params = sorted(
|
||||
(
|
||||
(a, b, c, 9) for a, b, c in product(P, P, P) if c - a - b > 0
|
||||
),
|
||||
key=lambda x: max(abs(x[0]), abs(x[1])),
|
||||
)
|
||||
|
||||
if parameter_groups is not None:
|
||||
# Group 9 params only used if specified in arguments.
|
||||
params.extend(group_9_params)
|
||||
params = [
|
||||
(a, b, c, group) for a, b, c, group in params
|
||||
if group in parameter_groups
|
||||
]
|
||||
|
||||
# grid_size * grid_size grid in box with corners
|
||||
# -2 - 2j, -2 + 2j, 2 - 2j, 2 + 2j
|
||||
X, Y = np.meshgrid(
|
||||
np.linspace(-box_size, box_size, grid_size),
|
||||
np.linspace(-box_size, box_size, grid_size)
|
||||
)
|
||||
Z = X + Y * 1j
|
||||
Z = Z.flatten().tolist()
|
||||
# Add z = 1 + 0j (region 0).
|
||||
Z.append(1 + 0j)
|
||||
if regions is not None:
|
||||
Z = [z for z in Z if get_region(z) in regions]
|
||||
|
||||
# Evaluate scipy and mpmath's hyp2f1 for all parameter combinations
|
||||
# above against all arguments in the grid Z
|
||||
rows = get_results(params, Z, n_jobs=n_jobs, compute_mp=compute_mp)
|
||||
|
||||
with open(outpath, "w", newline="") as f:
|
||||
writer = csv.writer(f, delimiter="\t")
|
||||
writer.writerow(
|
||||
[
|
||||
"a",
|
||||
"b",
|
||||
"c",
|
||||
"z",
|
||||
"|z|",
|
||||
"region",
|
||||
"parameter_group",
|
||||
"expected", # mpmath's hyp2f1
|
||||
"observed", # scipy's hyp2f1
|
||||
"relative_error",
|
||||
"absolute_error",
|
||||
]
|
||||
)
|
||||
for row in rows:
|
||||
writer.writerow(row)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Test scipy's hyp2f1 against mpmath's on a grid in the"
|
||||
" complex plane over a grid of parameter values. Saves output to file"
|
||||
" specified in positional argument \"outpath\"."
|
||||
" Caution: With default arguments, the generated output file is"
|
||||
" roughly 700MB in size. Script may take several hours to finish if"
|
||||
" \"--n_jobs\" is set to 1."
|
||||
)
|
||||
parser.add_argument(
|
||||
"outpath", type=str, help="Path to output tsv file."
|
||||
)
|
||||
parser.add_argument(
|
||||
"--n_jobs",
|
||||
type=int,
|
||||
default=1,
|
||||
help="Number of jobs for multiprocessing.",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--box_size",
|
||||
type=float,
|
||||
default=2.0,
|
||||
help="hyp2f1 is evaluated in box of side_length 2*box_size centered"
|
||||
" at the origin."
|
||||
)
|
||||
parser.add_argument(
|
||||
"--grid_size",
|
||||
type=int,
|
||||
default=20,
|
||||
help="hyp2f1 is evaluated on grid_size * grid_size grid in box of side"
|
||||
" length 2*box_size centered at the origin."
|
||||
)
|
||||
parser.add_argument(
|
||||
"--parameter_groups",
|
||||
type=int,
|
||||
nargs='+',
|
||||
default=None,
|
||||
help="Restrict to supplied parameter groups. See the Docstring for"
|
||||
" this module for more info on parameter groups. Calculate for all"
|
||||
" parameter groups by default."
|
||||
)
|
||||
parser.add_argument(
|
||||
"--regions",
|
||||
type=int,
|
||||
nargs='+',
|
||||
default=None,
|
||||
help="Restrict to argument z only within the supplied regions. See"
|
||||
" the Docstring for this module for more info on regions. Calculate"
|
||||
" for all regions by default."
|
||||
)
|
||||
parser.add_argument(
|
||||
"--no_mp",
|
||||
action='store_true',
|
||||
help="If this flag is set, do not compute results with mpmath. Saves"
|
||||
" time if results have already been computed elsewhere. Fills in"
|
||||
" \"expected\" column with None values."
|
||||
)
|
||||
args = parser.parse_args()
|
||||
compute_mp = not args.no_mp
|
||||
print(args.parameter_groups)
|
||||
main(
|
||||
args.outpath,
|
||||
n_jobs=args.n_jobs,
|
||||
box_size=args.box_size,
|
||||
grid_size=args.grid_size,
|
||||
parameter_groups=args.parameter_groups,
|
||||
regions=args.regions,
|
||||
compute_mp=compute_mp,
|
||||
)
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
"""Compute a Pade approximation for the principal branch of the
|
||||
Lambert W function around 0 and compare it to various other
|
||||
approximations.
|
||||
|
||||
"""
|
||||
import numpy as np
|
||||
|
||||
try:
|
||||
import mpmath
|
||||
import matplotlib.pyplot as plt
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
|
||||
def lambertw_pade():
|
||||
derivs = [mpmath.diff(mpmath.lambertw, 0, n=n) for n in range(6)]
|
||||
p, q = mpmath.pade(derivs, 3, 2)
|
||||
return p, q
|
||||
|
||||
|
||||
def main():
|
||||
print(__doc__)
|
||||
with mpmath.workdps(50):
|
||||
p, q = lambertw_pade()
|
||||
p, q = p[::-1], q[::-1]
|
||||
print(f"p = {p}")
|
||||
print(f"q = {q}")
|
||||
|
||||
x, y = np.linspace(-1.5, 1.5, 75), np.linspace(-1.5, 1.5, 75)
|
||||
x, y = np.meshgrid(x, y)
|
||||
z = x + 1j*y
|
||||
lambertw_std = []
|
||||
for z0 in z.flatten():
|
||||
lambertw_std.append(complex(mpmath.lambertw(z0)))
|
||||
lambertw_std = np.array(lambertw_std).reshape(x.shape)
|
||||
|
||||
fig, axes = plt.subplots(nrows=3, ncols=1)
|
||||
# Compare Pade approximation to true result
|
||||
p = np.array([float(p0) for p0 in p])
|
||||
q = np.array([float(q0) for q0 in q])
|
||||
pade_approx = np.polyval(p, z)/np.polyval(q, z)
|
||||
pade_err = abs(pade_approx - lambertw_std)
|
||||
axes[0].pcolormesh(x, y, pade_err)
|
||||
# Compare two terms of asymptotic series to true result
|
||||
asy_approx = np.log(z) - np.log(np.log(z))
|
||||
asy_err = abs(asy_approx - lambertw_std)
|
||||
axes[1].pcolormesh(x, y, asy_err)
|
||||
# Compare two terms of the series around the branch point to the
|
||||
# true result
|
||||
p = np.sqrt(2*(np.exp(1)*z + 1))
|
||||
series_approx = -1 + p - p**2/3
|
||||
series_err = abs(series_approx - lambertw_std)
|
||||
im = axes[2].pcolormesh(x, y, series_err)
|
||||
|
||||
fig.colorbar(im, ax=axes.ravel().tolist())
|
||||
plt.show()
|
||||
|
||||
fig, ax = plt.subplots(nrows=1, ncols=1)
|
||||
pade_better = pade_err < asy_err
|
||||
im = ax.pcolormesh(x, y, pade_better)
|
||||
t = np.linspace(-0.3, 0.3)
|
||||
ax.plot(-2.5*abs(t) - 0.2, t, 'r')
|
||||
fig.colorbar(im, ax=ax)
|
||||
plt.show()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
"""Precompute series coefficients for log-Gamma."""
|
||||
|
||||
try:
|
||||
import mpmath
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
|
||||
def stirling_series(N):
|
||||
with mpmath.workdps(100):
|
||||
coeffs = [mpmath.bernoulli(2*n)/(2*n*(2*n - 1))
|
||||
for n in range(1, N + 1)]
|
||||
return coeffs
|
||||
|
||||
|
||||
def taylor_series_at_1(N):
|
||||
coeffs = []
|
||||
with mpmath.workdps(100):
|
||||
coeffs.append(-mpmath.euler)
|
||||
for n in range(2, N + 1):
|
||||
coeffs.append((-1)**n*mpmath.zeta(n)/n)
|
||||
return coeffs
|
||||
|
||||
|
||||
def main():
|
||||
print(__doc__)
|
||||
print()
|
||||
stirling_coeffs = [mpmath.nstr(x, 20, min_fixed=0, max_fixed=0)
|
||||
for x in stirling_series(8)[::-1]]
|
||||
taylor_coeffs = [mpmath.nstr(x, 20, min_fixed=0, max_fixed=0)
|
||||
for x in taylor_series_at_1(23)[::-1]]
|
||||
print("Stirling series coefficients")
|
||||
print("----------------------------")
|
||||
print("\n".join(stirling_coeffs))
|
||||
print()
|
||||
print("Taylor series coefficients")
|
||||
print("--------------------------")
|
||||
print("\n".join(taylor_coeffs))
|
||||
print()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
|
@ -0,0 +1,131 @@
|
|||
"""
|
||||
Convergence regions of the expansions used in ``struve.c``
|
||||
|
||||
Note that for v >> z both functions tend rapidly to 0,
|
||||
and for v << -z, they tend to infinity.
|
||||
|
||||
The floating-point functions over/underflow in the lower left and right
|
||||
corners of the figure.
|
||||
|
||||
|
||||
Figure legend
|
||||
=============
|
||||
|
||||
Red region
|
||||
Power series is close (1e-12) to the mpmath result
|
||||
|
||||
Blue region
|
||||
Asymptotic series is close to the mpmath result
|
||||
|
||||
Green region
|
||||
Bessel series is close to the mpmath result
|
||||
|
||||
Dotted colored lines
|
||||
Boundaries of the regions
|
||||
|
||||
Solid colored lines
|
||||
Boundaries estimated by the routine itself. These will be used
|
||||
for determining which of the results to use.
|
||||
|
||||
Black dashed line
|
||||
The line z = 0.7*|v| + 12
|
||||
|
||||
"""
|
||||
import numpy as np
|
||||
import matplotlib.pyplot as plt
|
||||
|
||||
import mpmath
|
||||
|
||||
|
||||
def err_metric(a, b, atol=1e-290):
|
||||
m = abs(a - b) / (atol + abs(b))
|
||||
m[np.isinf(b) & (a == b)] = 0
|
||||
return m
|
||||
|
||||
|
||||
def do_plot(is_h=True):
|
||||
from scipy.special._ufuncs import (_struve_power_series,
|
||||
_struve_asymp_large_z,
|
||||
_struve_bessel_series)
|
||||
|
||||
vs = np.linspace(-1000, 1000, 91)
|
||||
zs = np.sort(np.r_[1e-5, 1.0, np.linspace(0, 700, 91)[1:]])
|
||||
|
||||
rp = _struve_power_series(vs[:,None], zs[None,:], is_h)
|
||||
ra = _struve_asymp_large_z(vs[:,None], zs[None,:], is_h)
|
||||
rb = _struve_bessel_series(vs[:,None], zs[None,:], is_h)
|
||||
|
||||
mpmath.mp.dps = 50
|
||||
if is_h:
|
||||
def sh(v, z):
|
||||
return float(mpmath.struveh(mpmath.mpf(v), mpmath.mpf(z)))
|
||||
else:
|
||||
def sh(v, z):
|
||||
return float(mpmath.struvel(mpmath.mpf(v), mpmath.mpf(z)))
|
||||
ex = np.vectorize(sh, otypes='d')(vs[:,None], zs[None,:])
|
||||
|
||||
err_a = err_metric(ra[0], ex) + 1e-300
|
||||
err_p = err_metric(rp[0], ex) + 1e-300
|
||||
err_b = err_metric(rb[0], ex) + 1e-300
|
||||
|
||||
err_est_a = abs(ra[1]/ra[0])
|
||||
err_est_p = abs(rp[1]/rp[0])
|
||||
err_est_b = abs(rb[1]/rb[0])
|
||||
|
||||
z_cutoff = 0.7*abs(vs) + 12
|
||||
|
||||
levels = [-1000, -12]
|
||||
|
||||
plt.cla()
|
||||
|
||||
plt.hold(1)
|
||||
plt.contourf(vs, zs, np.log10(err_p).T,
|
||||
levels=levels, colors=['r', 'r'], alpha=0.1)
|
||||
plt.contourf(vs, zs, np.log10(err_a).T,
|
||||
levels=levels, colors=['b', 'b'], alpha=0.1)
|
||||
plt.contourf(vs, zs, np.log10(err_b).T,
|
||||
levels=levels, colors=['g', 'g'], alpha=0.1)
|
||||
|
||||
plt.contour(vs, zs, np.log10(err_p).T,
|
||||
levels=levels, colors=['r', 'r'], linestyles=[':', ':'])
|
||||
plt.contour(vs, zs, np.log10(err_a).T,
|
||||
levels=levels, colors=['b', 'b'], linestyles=[':', ':'])
|
||||
plt.contour(vs, zs, np.log10(err_b).T,
|
||||
levels=levels, colors=['g', 'g'], linestyles=[':', ':'])
|
||||
|
||||
lp = plt.contour(vs, zs, np.log10(err_est_p).T,
|
||||
levels=levels, colors=['r', 'r'], linestyles=['-', '-'])
|
||||
la = plt.contour(vs, zs, np.log10(err_est_a).T,
|
||||
levels=levels, colors=['b', 'b'], linestyles=['-', '-'])
|
||||
lb = plt.contour(vs, zs, np.log10(err_est_b).T,
|
||||
levels=levels, colors=['g', 'g'], linestyles=['-', '-'])
|
||||
|
||||
plt.clabel(lp, fmt={-1000: 'P', -12: 'P'})
|
||||
plt.clabel(la, fmt={-1000: 'A', -12: 'A'})
|
||||
plt.clabel(lb, fmt={-1000: 'B', -12: 'B'})
|
||||
|
||||
plt.plot(vs, z_cutoff, 'k--')
|
||||
|
||||
plt.xlim(vs.min(), vs.max())
|
||||
plt.ylim(zs.min(), zs.max())
|
||||
|
||||
plt.xlabel('v')
|
||||
plt.ylabel('z')
|
||||
|
||||
|
||||
def main():
|
||||
plt.clf()
|
||||
plt.subplot(121)
|
||||
do_plot(True)
|
||||
plt.title('Struve H')
|
||||
|
||||
plt.subplot(122)
|
||||
do_plot(False)
|
||||
plt.title('Struve L')
|
||||
|
||||
plt.savefig('struve_convergence.png')
|
||||
plt.show()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
try:
|
||||
import mpmath as mp
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
try:
|
||||
from sympy.abc import x
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
|
||||
def lagrange_inversion(a):
|
||||
"""Given a series
|
||||
|
||||
f(x) = a[1]*x + a[2]*x**2 + ... + a[n-1]*x**(n - 1),
|
||||
|
||||
use the Lagrange inversion formula to compute a series
|
||||
|
||||
g(x) = b[1]*x + b[2]*x**2 + ... + b[n-1]*x**(n - 1)
|
||||
|
||||
so that f(g(x)) = g(f(x)) = x mod x**n. We must have a[0] = 0, so
|
||||
necessarily b[0] = 0 too.
|
||||
|
||||
The algorithm is naive and could be improved, but speed isn't an
|
||||
issue here and it's easy to read.
|
||||
|
||||
"""
|
||||
n = len(a)
|
||||
f = sum(a[i]*x**i for i in range(n))
|
||||
h = (x/f).series(x, 0, n).removeO()
|
||||
hpower = [h**0]
|
||||
for k in range(n):
|
||||
hpower.append((hpower[-1]*h).expand())
|
||||
b = [mp.mpf(0)]
|
||||
for k in range(1, n):
|
||||
b.append(hpower[k].coeff(x, k - 1)/k)
|
||||
b = [mp.mpf(x) for x in b]
|
||||
return b
|
||||
|
|
@ -0,0 +1,342 @@
|
|||
"""Precompute coefficients of several series expansions
|
||||
of Wright's generalized Bessel function Phi(a, b, x).
|
||||
|
||||
See https://dlmf.nist.gov/10.46.E1 with rho=a, beta=b, z=x.
|
||||
"""
|
||||
from argparse import ArgumentParser, RawTextHelpFormatter
|
||||
import numpy as np
|
||||
from scipy.integrate import quad
|
||||
from scipy.optimize import minimize_scalar, curve_fit
|
||||
from time import time
|
||||
|
||||
try:
|
||||
import sympy
|
||||
from sympy import EulerGamma, Rational, S, Sum, \
|
||||
factorial, gamma, gammasimp, pi, polygamma, symbols, zeta
|
||||
from sympy.polys.polyfuncs import horner
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
|
||||
def series_small_a():
|
||||
"""Tylor series expansion of Phi(a, b, x) in a=0 up to order 5.
|
||||
"""
|
||||
order = 5
|
||||
a, b, x, k = symbols("a b x k")
|
||||
A = [] # terms with a
|
||||
X = [] # terms with x
|
||||
B = [] # terms with b (polygammas)
|
||||
# Phi(a, b, x) = exp(x)/gamma(b) * sum(A[i] * X[i] * B[i])
|
||||
expression = Sum(x**k/factorial(k)/gamma(a*k+b), (k, 0, S.Infinity))
|
||||
expression = gamma(b)/sympy.exp(x) * expression
|
||||
|
||||
# nth term of taylor series in a=0: a^n/n! * (d^n Phi(a, b, x)/da^n at a=0)
|
||||
for n in range(0, order+1):
|
||||
term = expression.diff(a, n).subs(a, 0).simplify().doit()
|
||||
# set the whole bracket involving polygammas to 1
|
||||
x_part = (term.subs(polygamma(0, b), 1)
|
||||
.replace(polygamma, lambda *args: 0))
|
||||
# sign convention: x part always positive
|
||||
x_part *= (-1)**n
|
||||
|
||||
A.append(a**n/factorial(n))
|
||||
X.append(horner(x_part))
|
||||
B.append(horner((term/x_part).simplify()))
|
||||
|
||||
s = "Tylor series expansion of Phi(a, b, x) in a=0 up to order 5.\n"
|
||||
s += "Phi(a, b, x) = exp(x)/gamma(b) * sum(A[i] * X[i] * B[i], i=0..5)\n"
|
||||
for name, c in zip(['A', 'X', 'B'], [A, X, B]):
|
||||
for i in range(len(c)):
|
||||
s += f"\n{name}[{i}] = " + str(c[i])
|
||||
return s
|
||||
|
||||
|
||||
# expansion of digamma
|
||||
def dg_series(z, n):
|
||||
"""Symbolic expansion of digamma(z) in z=0 to order n.
|
||||
|
||||
See https://dlmf.nist.gov/5.7.E4 and with https://dlmf.nist.gov/5.5.E2
|
||||
"""
|
||||
k = symbols("k")
|
||||
return -1/z - EulerGamma + \
|
||||
sympy.summation((-1)**k * zeta(k) * z**(k-1), (k, 2, n+1))
|
||||
|
||||
|
||||
def pg_series(k, z, n):
|
||||
"""Symbolic expansion of polygamma(k, z) in z=0 to order n."""
|
||||
return sympy.diff(dg_series(z, n+k), z, k)
|
||||
|
||||
|
||||
def series_small_a_small_b():
|
||||
"""Tylor series expansion of Phi(a, b, x) in a=0 and b=0 up to order 5.
|
||||
|
||||
Be aware of cancellation of poles in b=0 of digamma(b)/Gamma(b) and
|
||||
polygamma functions.
|
||||
|
||||
digamma(b)/Gamma(b) = -1 - 2*M_EG*b + O(b^2)
|
||||
digamma(b)^2/Gamma(b) = 1/b + 3*M_EG + b*(-5/12*PI^2+7/2*M_EG^2) + O(b^2)
|
||||
polygamma(1, b)/Gamma(b) = 1/b + M_EG + b*(1/12*PI^2 + 1/2*M_EG^2) + O(b^2)
|
||||
and so on.
|
||||
"""
|
||||
order = 5
|
||||
a, b, x, k = symbols("a b x k")
|
||||
M_PI, M_EG, M_Z3 = symbols("M_PI M_EG M_Z3")
|
||||
c_subs = {pi: M_PI, EulerGamma: M_EG, zeta(3): M_Z3}
|
||||
A = [] # terms with a
|
||||
X = [] # terms with x
|
||||
B = [] # terms with b (polygammas expanded)
|
||||
C = [] # terms that generate B
|
||||
# Phi(a, b, x) = exp(x) * sum(A[i] * X[i] * B[i])
|
||||
# B[0] = 1
|
||||
# B[k] = sum(C[k] * b**k/k!, k=0..)
|
||||
# Note: C[k] can be obtained from a series expansion of 1/gamma(b).
|
||||
expression = gamma(b)/sympy.exp(x) * \
|
||||
Sum(x**k/factorial(k)/gamma(a*k+b), (k, 0, S.Infinity))
|
||||
|
||||
# nth term of taylor series in a=0: a^n/n! * (d^n Phi(a, b, x)/da^n at a=0)
|
||||
for n in range(0, order+1):
|
||||
term = expression.diff(a, n).subs(a, 0).simplify().doit()
|
||||
# set the whole bracket involving polygammas to 1
|
||||
x_part = (term.subs(polygamma(0, b), 1)
|
||||
.replace(polygamma, lambda *args: 0))
|
||||
# sign convention: x part always positive
|
||||
x_part *= (-1)**n
|
||||
# expansion of polygamma part with 1/gamma(b)
|
||||
pg_part = term/x_part/gamma(b)
|
||||
if n >= 1:
|
||||
# Note: highest term is digamma^n
|
||||
pg_part = pg_part.replace(polygamma,
|
||||
lambda k, x: pg_series(k, x, order+1+n))
|
||||
pg_part = (pg_part.series(b, 0, n=order+1-n)
|
||||
.removeO()
|
||||
.subs(polygamma(2, 1), -2*zeta(3))
|
||||
.simplify()
|
||||
)
|
||||
|
||||
A.append(a**n/factorial(n))
|
||||
X.append(horner(x_part))
|
||||
B.append(pg_part)
|
||||
|
||||
# Calculate C and put in the k!
|
||||
C = sympy.Poly(B[1].subs(c_subs), b).coeffs()
|
||||
C.reverse()
|
||||
for i in range(len(C)):
|
||||
C[i] = (C[i] * factorial(i)).simplify()
|
||||
|
||||
s = "Tylor series expansion of Phi(a, b, x) in a=0 and b=0 up to order 5."
|
||||
s += "\nPhi(a, b, x) = exp(x) * sum(A[i] * X[i] * B[i], i=0..5)\n"
|
||||
s += "B[0] = 1\n"
|
||||
s += "B[i] = sum(C[k+i-1] * b**k/k!, k=0..)\n"
|
||||
s += "\nM_PI = pi"
|
||||
s += "\nM_EG = EulerGamma"
|
||||
s += "\nM_Z3 = zeta(3)"
|
||||
for name, c in zip(['A', 'X'], [A, X]):
|
||||
for i in range(len(c)):
|
||||
s += f"\n{name}[{i}] = "
|
||||
s += str(c[i])
|
||||
# For C, do also compute the values numerically
|
||||
for i in range(len(C)):
|
||||
s += f"\n# C[{i}] = "
|
||||
s += str(C[i])
|
||||
s += f"\nC[{i}] = "
|
||||
s += str(C[i].subs({M_EG: EulerGamma, M_PI: pi, M_Z3: zeta(3)})
|
||||
.evalf(17))
|
||||
|
||||
# Does B have the assumed structure?
|
||||
s += "\n\nTest if B[i] does have the assumed structure."
|
||||
s += "\nC[i] are derived from B[1] alone."
|
||||
s += "\nTest B[2] == C[1] + b*C[2] + b^2/2*C[3] + b^3/6*C[4] + .."
|
||||
test = sum([b**k/factorial(k) * C[k+1] for k in range(order-1)])
|
||||
test = (test - B[2].subs(c_subs)).simplify()
|
||||
s += f"\ntest successful = {test==S(0)}"
|
||||
s += "\nTest B[3] == C[2] + b*C[3] + b^2/2*C[4] + .."
|
||||
test = sum([b**k/factorial(k) * C[k+2] for k in range(order-2)])
|
||||
test = (test - B[3].subs(c_subs)).simplify()
|
||||
s += f"\ntest successful = {test==S(0)}"
|
||||
return s
|
||||
|
||||
|
||||
def asymptotic_series():
|
||||
"""Asymptotic expansion for large x.
|
||||
|
||||
Phi(a, b, x) ~ Z^(1/2-b) * exp((1+a)/a * Z) * sum_k (-1)^k * C_k / Z^k
|
||||
Z = (a*x)^(1/(1+a))
|
||||
|
||||
Wright (1935) lists the coefficients C_0 and C_1 (he calls them a_0 and
|
||||
a_1). With slightly different notation, Paris (2017) lists coefficients
|
||||
c_k up to order k=3.
|
||||
Paris (2017) uses ZP = (1+a)/a * Z (ZP = Z of Paris) and
|
||||
C_k = C_0 * (-a/(1+a))^k * c_k
|
||||
"""
|
||||
order = 8
|
||||
|
||||
class g(sympy.Function):
|
||||
"""Helper function g according to Wright (1935)
|
||||
|
||||
g(n, rho, v) = (1 + (rho+2)/3 * v + (rho+2)*(rho+3)/(2*3) * v^2 + ...)
|
||||
|
||||
Note: Wright (1935) uses square root of above definition.
|
||||
"""
|
||||
nargs = 3
|
||||
|
||||
@classmethod
|
||||
def eval(cls, n, rho, v):
|
||||
if not n >= 0:
|
||||
raise ValueError("must have n >= 0")
|
||||
elif n == 0:
|
||||
return 1
|
||||
else:
|
||||
return g(n-1, rho, v) \
|
||||
+ gammasimp(gamma(rho+2+n)/gamma(rho+2)) \
|
||||
/ gammasimp(gamma(3+n)/gamma(3))*v**n
|
||||
|
||||
class coef_C(sympy.Function):
|
||||
"""Calculate coefficients C_m for integer m.
|
||||
|
||||
C_m is the coefficient of v^(2*m) in the Taylor expansion in v=0 of
|
||||
Gamma(m+1/2)/(2*pi) * (2/(rho+1))^(m+1/2) * (1-v)^(-b)
|
||||
* g(rho, v)^(-m-1/2)
|
||||
"""
|
||||
nargs = 3
|
||||
|
||||
@classmethod
|
||||
def eval(cls, m, rho, beta):
|
||||
if not m >= 0:
|
||||
raise ValueError("must have m >= 0")
|
||||
|
||||
v = symbols("v")
|
||||
expression = (1-v)**(-beta) * g(2*m, rho, v)**(-m-Rational(1, 2))
|
||||
res = expression.diff(v, 2*m).subs(v, 0) / factorial(2*m)
|
||||
res = res * (gamma(m + Rational(1, 2)) / (2*pi)
|
||||
* (2/(rho+1))**(m + Rational(1, 2)))
|
||||
return res
|
||||
|
||||
# in order to have nice ordering/sorting of expressions, we set a = xa.
|
||||
xa, b, xap1 = symbols("xa b xap1")
|
||||
C0 = coef_C(0, xa, b)
|
||||
# a1 = a(1, rho, beta)
|
||||
s = "Asymptotic expansion for large x\n"
|
||||
s += "Phi(a, b, x) = Z**(1/2-b) * exp((1+a)/a * Z) \n"
|
||||
s += " * sum((-1)**k * C[k]/Z**k, k=0..6)\n\n"
|
||||
s += "Z = pow(a * x, 1/(1+a))\n"
|
||||
s += "A[k] = pow(a, k)\n"
|
||||
s += "B[k] = pow(b, k)\n"
|
||||
s += "Ap1[k] = pow(1+a, k)\n\n"
|
||||
s += "C[0] = 1./sqrt(2. * M_PI * Ap1[1])\n"
|
||||
for i in range(1, order+1):
|
||||
expr = (coef_C(i, xa, b) / (C0/(1+xa)**i)).simplify()
|
||||
factor = [x.denominator() for x in sympy.Poly(expr).coeffs()]
|
||||
factor = sympy.lcm(factor)
|
||||
expr = (expr * factor).simplify().collect(b, sympy.factor)
|
||||
expr = expr.xreplace({xa+1: xap1})
|
||||
s += f"C[{i}] = C[0] / ({factor} * Ap1[{i}])\n"
|
||||
s += f"C[{i}] *= {str(expr)}\n\n"
|
||||
import re
|
||||
re_a = re.compile(r'xa\*\*(\d+)')
|
||||
s = re_a.sub(r'A[\1]', s)
|
||||
re_b = re.compile(r'b\*\*(\d+)')
|
||||
s = re_b.sub(r'B[\1]', s)
|
||||
s = s.replace('xap1', 'Ap1[1]')
|
||||
s = s.replace('xa', 'a')
|
||||
# max integer = 2^31-1 = 2,147,483,647. Solution: Put a point after 10
|
||||
# or more digits.
|
||||
re_digits = re.compile(r'(\d{10,})')
|
||||
s = re_digits.sub(r'\1.', s)
|
||||
return s
|
||||
|
||||
|
||||
def optimal_epsilon_integral():
|
||||
"""Fit optimal choice of epsilon for integral representation.
|
||||
|
||||
The integrand of
|
||||
int_0^pi P(eps, a, b, x, phi) * dphi
|
||||
can exhibit oscillatory behaviour. It stems from the cosine of P and can be
|
||||
minimized by minimizing the arc length of the argument
|
||||
f(phi) = eps * sin(phi) - x * eps^(-a) * sin(a * phi) + (1 - b) * phi
|
||||
of cos(f(phi)).
|
||||
We minimize the arc length in eps for a grid of values (a, b, x) and fit a
|
||||
parametric function to it.
|
||||
"""
|
||||
def fp(eps, a, b, x, phi):
|
||||
"""Derivative of f w.r.t. phi."""
|
||||
eps_a = np.power(1. * eps, -a)
|
||||
return eps * np.cos(phi) - a * x * eps_a * np.cos(a * phi) + 1 - b
|
||||
|
||||
def arclength(eps, a, b, x, epsrel=1e-2, limit=100):
|
||||
"""Compute Arc length of f.
|
||||
|
||||
Note that the arc length of a function f from t0 to t1 is given by
|
||||
int_t0^t1 sqrt(1 + f'(t)^2) dt
|
||||
"""
|
||||
return quad(lambda phi: np.sqrt(1 + fp(eps, a, b, x, phi)**2),
|
||||
0, np.pi,
|
||||
epsrel=epsrel, limit=100)[0]
|
||||
|
||||
# grid of minimal arc length values
|
||||
data_a = [1e-3, 0.1, 0.5, 0.9, 1, 2, 4, 5, 6, 8]
|
||||
data_b = [0, 1, 4, 7, 10]
|
||||
data_x = [1, 1.5, 2, 4, 10, 20, 50, 100, 200, 500, 1e3, 5e3, 1e4]
|
||||
data_a, data_b, data_x = np.meshgrid(data_a, data_b, data_x)
|
||||
data_a, data_b, data_x = (data_a.flatten(), data_b.flatten(),
|
||||
data_x.flatten())
|
||||
best_eps = []
|
||||
for i in range(data_x.size):
|
||||
best_eps.append(
|
||||
minimize_scalar(lambda eps: arclength(eps, data_a[i], data_b[i],
|
||||
data_x[i]),
|
||||
bounds=(1e-3, 1000),
|
||||
method='Bounded', options={'xatol': 1e-3}).x
|
||||
)
|
||||
best_eps = np.array(best_eps)
|
||||
# pandas would be nice, but here a dictionary is enough
|
||||
df = {'a': data_a,
|
||||
'b': data_b,
|
||||
'x': data_x,
|
||||
'eps': best_eps,
|
||||
}
|
||||
|
||||
def func(data, A0, A1, A2, A3, A4, A5):
|
||||
"""Compute parametric function to fit."""
|
||||
a = data['a']
|
||||
b = data['b']
|
||||
x = data['x']
|
||||
return (A0 * b * np.exp(-0.5 * a)
|
||||
+ np.exp(A1 + 1 / (1 + a) * np.log(x) - A2 * np.exp(-A3 * a)
|
||||
+ A4 / (1 + np.exp(A5 * a))))
|
||||
|
||||
func_params = list(curve_fit(func, df, df['eps'], method='trf')[0])
|
||||
|
||||
s = "Fit optimal eps for integrand P via minimal arc length\n"
|
||||
s += "with parametric function:\n"
|
||||
s += "optimal_eps = (A0 * b * exp(-a/2) + exp(A1 + 1 / (1 + a) * log(x)\n"
|
||||
s += " - A2 * exp(-A3 * a) + A4 / (1 + exp(A5 * a)))\n\n"
|
||||
s += "Fitted parameters A0 to A5 are:\n"
|
||||
s += ', '.join([f'{x:.5g}' for x in func_params])
|
||||
return s
|
||||
|
||||
|
||||
def main():
|
||||
t0 = time()
|
||||
parser = ArgumentParser(description=__doc__,
|
||||
formatter_class=RawTextHelpFormatter)
|
||||
parser.add_argument('action', type=int, choices=[1, 2, 3, 4],
|
||||
help='chose what expansion to precompute\n'
|
||||
'1 : Series for small a\n'
|
||||
'2 : Series for small a and small b\n'
|
||||
'3 : Asymptotic series for large x\n'
|
||||
' This may take some time (>4h).\n'
|
||||
'4 : Fit optimal eps for integral representation.'
|
||||
)
|
||||
args = parser.parse_args()
|
||||
|
||||
switch = {1: lambda: print(series_small_a()),
|
||||
2: lambda: print(series_small_a_small_b()),
|
||||
3: lambda: print(asymptotic_series()),
|
||||
4: lambda: print(optimal_epsilon_integral())
|
||||
}
|
||||
switch.get(args.action, lambda: print("Invalid input."))()
|
||||
print(f"\n{(time() - t0)/60:.1f} minutes elapsed.\n")
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
|
@ -0,0 +1,152 @@
|
|||
"""Compute a grid of values for Wright's generalized Bessel function
|
||||
and save the values to data files for use in tests. Using mpmath directly in
|
||||
tests would take too long.
|
||||
|
||||
This takes about 10 minutes to run on a 2.7 GHz i7 Macbook Pro.
|
||||
"""
|
||||
from functools import lru_cache
|
||||
import os
|
||||
from time import time
|
||||
|
||||
import numpy as np
|
||||
from scipy.special._mptestutils import mpf2float
|
||||
|
||||
try:
|
||||
import mpmath as mp
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
# exp_inf: smallest value x for which exp(x) == inf
|
||||
exp_inf = 709.78271289338403
|
||||
|
||||
|
||||
# 64 Byte per value
|
||||
@lru_cache(maxsize=100_000)
|
||||
def rgamma_cached(x, dps):
|
||||
with mp.workdps(dps):
|
||||
return mp.rgamma(x)
|
||||
|
||||
|
||||
def mp_wright_bessel(a, b, x, dps=50, maxterms=2000):
|
||||
"""Compute Wright's generalized Bessel function as Series with mpmath.
|
||||
"""
|
||||
with mp.workdps(dps):
|
||||
a, b, x = mp.mpf(a), mp.mpf(b), mp.mpf(x)
|
||||
res = mp.nsum(lambda k: x**k / mp.fac(k)
|
||||
* rgamma_cached(a * k + b, dps=dps),
|
||||
[0, mp.inf],
|
||||
tol=dps, method='s', steps=[maxterms]
|
||||
)
|
||||
return mpf2float(res)
|
||||
|
||||
|
||||
def main():
|
||||
t0 = time()
|
||||
print(__doc__)
|
||||
pwd = os.path.dirname(__file__)
|
||||
eps = np.finfo(float).eps * 100
|
||||
|
||||
a_range = np.array([eps,
|
||||
1e-4 * (1 - eps), 1e-4, 1e-4 * (1 + eps),
|
||||
1e-3 * (1 - eps), 1e-3, 1e-3 * (1 + eps),
|
||||
0.1, 0.5,
|
||||
1 * (1 - eps), 1, 1 * (1 + eps),
|
||||
1.5, 2, 4.999, 5, 10])
|
||||
b_range = np.array([0, eps, 1e-10, 1e-5, 0.1, 1, 2, 10, 20, 100])
|
||||
x_range = np.array([0, eps, 1 - eps, 1, 1 + eps,
|
||||
1.5,
|
||||
2 - eps, 2, 2 + eps,
|
||||
9 - eps, 9, 9 + eps,
|
||||
10 * (1 - eps), 10, 10 * (1 + eps),
|
||||
100 * (1 - eps), 100, 100 * (1 + eps),
|
||||
500, exp_inf, 1e3, 1e5, 1e10, 1e20])
|
||||
|
||||
a_range, b_range, x_range = np.meshgrid(a_range, b_range, x_range,
|
||||
indexing='ij')
|
||||
a_range = a_range.flatten()
|
||||
b_range = b_range.flatten()
|
||||
x_range = x_range.flatten()
|
||||
|
||||
# filter out some values, especially too large x
|
||||
bool_filter = ~((a_range < 5e-3) & (x_range >= exp_inf))
|
||||
bool_filter = bool_filter & ~((a_range < 0.2) & (x_range > exp_inf))
|
||||
bool_filter = bool_filter & ~((a_range < 0.5) & (x_range > 1e3))
|
||||
bool_filter = bool_filter & ~((a_range < 0.56) & (x_range > 5e3))
|
||||
bool_filter = bool_filter & ~((a_range < 1) & (x_range > 1e4))
|
||||
bool_filter = bool_filter & ~((a_range < 1.4) & (x_range > 1e5))
|
||||
bool_filter = bool_filter & ~((a_range < 1.8) & (x_range > 1e6))
|
||||
bool_filter = bool_filter & ~((a_range < 2.2) & (x_range > 1e7))
|
||||
bool_filter = bool_filter & ~((a_range < 2.5) & (x_range > 1e8))
|
||||
bool_filter = bool_filter & ~((a_range < 2.9) & (x_range > 1e9))
|
||||
bool_filter = bool_filter & ~((a_range < 3.3) & (x_range > 1e10))
|
||||
bool_filter = bool_filter & ~((a_range < 3.7) & (x_range > 1e11))
|
||||
bool_filter = bool_filter & ~((a_range < 4) & (x_range > 1e12))
|
||||
bool_filter = bool_filter & ~((a_range < 4.4) & (x_range > 1e13))
|
||||
bool_filter = bool_filter & ~((a_range < 4.7) & (x_range > 1e14))
|
||||
bool_filter = bool_filter & ~((a_range < 5.1) & (x_range > 1e15))
|
||||
bool_filter = bool_filter & ~((a_range < 5.4) & (x_range > 1e16))
|
||||
bool_filter = bool_filter & ~((a_range < 5.8) & (x_range > 1e17))
|
||||
bool_filter = bool_filter & ~((a_range < 6.2) & (x_range > 1e18))
|
||||
bool_filter = bool_filter & ~((a_range < 6.2) & (x_range > 1e18))
|
||||
bool_filter = bool_filter & ~((a_range < 6.5) & (x_range > 1e19))
|
||||
bool_filter = bool_filter & ~((a_range < 6.9) & (x_range > 1e20))
|
||||
|
||||
# filter out known values that do not meet the required numerical accuracy
|
||||
# see test test_wright_data_grid_failures
|
||||
failing = np.array([
|
||||
[0.1, 100, 709.7827128933841],
|
||||
[0.5, 10, 709.7827128933841],
|
||||
[0.5, 10, 1000],
|
||||
[0.5, 100, 1000],
|
||||
[1, 20, 100000],
|
||||
[1, 100, 100000],
|
||||
[1.0000000000000222, 20, 100000],
|
||||
[1.0000000000000222, 100, 100000],
|
||||
[1.5, 0, 500],
|
||||
[1.5, 2.220446049250313e-14, 500],
|
||||
[1.5, 1.e-10, 500],
|
||||
[1.5, 1.e-05, 500],
|
||||
[1.5, 0.1, 500],
|
||||
[1.5, 20, 100000],
|
||||
[1.5, 100, 100000],
|
||||
]).tolist()
|
||||
|
||||
does_fail = np.full_like(a_range, False, dtype=bool)
|
||||
for i in range(x_range.size):
|
||||
if [a_range[i], b_range[i], x_range[i]] in failing:
|
||||
does_fail[i] = True
|
||||
|
||||
# filter and flatten
|
||||
a_range = a_range[bool_filter]
|
||||
b_range = b_range[bool_filter]
|
||||
x_range = x_range[bool_filter]
|
||||
does_fail = does_fail[bool_filter]
|
||||
|
||||
dataset = []
|
||||
print(f"Computing {x_range.size} single points.")
|
||||
print("Tests will fail for the following data points:")
|
||||
for i in range(x_range.size):
|
||||
a = a_range[i]
|
||||
b = b_range[i]
|
||||
x = x_range[i]
|
||||
# take care of difficult corner cases
|
||||
maxterms = 1000
|
||||
if a < 1e-6 and x >= exp_inf/10:
|
||||
maxterms = 2000
|
||||
f = mp_wright_bessel(a, b, x, maxterms=maxterms)
|
||||
if does_fail[i]:
|
||||
print("failing data point a, b, x, value = "
|
||||
f"[{a}, {b}, {x}, {f}]")
|
||||
else:
|
||||
dataset.append((a, b, x, f))
|
||||
dataset = np.array(dataset)
|
||||
|
||||
filename = os.path.join(pwd, '..', 'tests', 'data', 'local',
|
||||
'wright_bessel.txt')
|
||||
np.savetxt(filename, dataset)
|
||||
|
||||
print(f"{(time() - t0)/60:.1f} minutes elapsed")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
import numpy as np
|
||||
|
||||
try:
|
||||
import mpmath
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
|
||||
def mpmath_wrightomega(x):
|
||||
return mpmath.lambertw(mpmath.exp(x), mpmath.mpf('-0.5'))
|
||||
|
||||
|
||||
def wrightomega_series_error(x):
|
||||
series = x
|
||||
desired = mpmath_wrightomega(x)
|
||||
return abs(series - desired) / desired
|
||||
|
||||
|
||||
def wrightomega_exp_error(x):
|
||||
exponential_approx = mpmath.exp(x)
|
||||
desired = mpmath_wrightomega(x)
|
||||
return abs(exponential_approx - desired) / desired
|
||||
|
||||
|
||||
def main():
|
||||
desired_error = 2 * np.finfo(float).eps
|
||||
print('Series Error')
|
||||
for x in [1e5, 1e10, 1e15, 1e20]:
|
||||
with mpmath.workdps(100):
|
||||
error = wrightomega_series_error(x)
|
||||
print(x, error, error < desired_error)
|
||||
|
||||
print('Exp error')
|
||||
for x in [-10, -25, -50, -100, -200, -400, -700, -740]:
|
||||
with mpmath.workdps(100):
|
||||
error = wrightomega_exp_error(x)
|
||||
print(x, error, error < desired_error)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
"""Compute the Taylor series for zeta(x) - 1 around x = 0."""
|
||||
try:
|
||||
import mpmath
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
|
||||
def zetac_series(N):
|
||||
coeffs = []
|
||||
with mpmath.workdps(100):
|
||||
coeffs.append(-1.5)
|
||||
for n in range(1, N):
|
||||
coeff = mpmath.diff(mpmath.zeta, 0, n)/mpmath.factorial(n)
|
||||
coeffs.append(coeff)
|
||||
return coeffs
|
||||
|
||||
|
||||
def main():
|
||||
print(__doc__)
|
||||
coeffs = zetac_series(10)
|
||||
coeffs = [mpmath.nstr(x, 20, min_fixed=0, max_fixed=0)
|
||||
for x in coeffs]
|
||||
print("\n".join(coeffs[::-1]))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
15
venv/lib/python3.13/site-packages/scipy/special/_sf_error.py
Normal file
15
venv/lib/python3.13/site-packages/scipy/special/_sf_error.py
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
"""Warnings and Exceptions that can be raised by special functions."""
|
||||
import warnings
|
||||
|
||||
|
||||
class SpecialFunctionWarning(Warning):
|
||||
"""Warning that can be emitted by special functions."""
|
||||
pass
|
||||
|
||||
|
||||
warnings.simplefilter("always", category=SpecialFunctionWarning)
|
||||
|
||||
|
||||
class SpecialFunctionError(Exception):
|
||||
"""Exception that can be raised by special functions."""
|
||||
pass
|
||||
Binary file not shown.
Binary file not shown.
106
venv/lib/python3.13/site-packages/scipy/special/_spfun_stats.py
Normal file
106
venv/lib/python3.13/site-packages/scipy/special/_spfun_stats.py
Normal file
|
|
@ -0,0 +1,106 @@
|
|||
# Last Change: Sat Mar 21 02:00 PM 2009 J
|
||||
|
||||
# Copyright (c) 2001, 2002 Enthought, Inc.
|
||||
#
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# a. Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
# b. Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in the
|
||||
# documentation and/or other materials provided with the distribution.
|
||||
# c. Neither the name of the Enthought nor the names of its contributors
|
||||
# may be used to endorse or promote products derived from this software
|
||||
# without specific prior written permission.
|
||||
#
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR
|
||||
# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
|
||||
# DAMAGE.
|
||||
|
||||
"""Some more special functions which may be useful for multivariate statistical
|
||||
analysis."""
|
||||
|
||||
import numpy as np
|
||||
from scipy.special import gammaln as loggam
|
||||
|
||||
|
||||
__all__ = ['multigammaln']
|
||||
|
||||
|
||||
def multigammaln(a, d):
|
||||
r"""Returns the log of multivariate gamma, also sometimes called the
|
||||
generalized gamma.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
a : ndarray
|
||||
The multivariate gamma is computed for each item of `a`.
|
||||
d : int
|
||||
The dimension of the space of integration.
|
||||
|
||||
Returns
|
||||
-------
|
||||
res : ndarray
|
||||
The values of the log multivariate gamma at the given points `a`.
|
||||
|
||||
Notes
|
||||
-----
|
||||
The formal definition of the multivariate gamma of dimension d for a real
|
||||
`a` is
|
||||
|
||||
.. math::
|
||||
|
||||
\Gamma_d(a) = \int_{A>0} e^{-tr(A)} |A|^{a - (d+1)/2} dA
|
||||
|
||||
with the condition :math:`a > (d-1)/2`, and :math:`A > 0` being the set of
|
||||
all the positive definite matrices of dimension `d`. Note that `a` is a
|
||||
scalar: the integrand only is multivariate, the argument is not (the
|
||||
function is defined over a subset of the real set).
|
||||
|
||||
This can be proven to be equal to the much friendlier equation
|
||||
|
||||
.. math::
|
||||
|
||||
\Gamma_d(a) = \pi^{d(d-1)/4} \prod_{i=1}^{d} \Gamma(a - (i-1)/2).
|
||||
|
||||
References
|
||||
----------
|
||||
R. J. Muirhead, Aspects of multivariate statistical theory (Wiley Series in
|
||||
probability and mathematical statistics).
|
||||
|
||||
Examples
|
||||
--------
|
||||
>>> import numpy as np
|
||||
>>> from scipy.special import multigammaln, gammaln
|
||||
>>> a = 23.5
|
||||
>>> d = 10
|
||||
>>> multigammaln(a, d)
|
||||
454.1488605074416
|
||||
|
||||
Verify that the result agrees with the logarithm of the equation
|
||||
shown above:
|
||||
|
||||
>>> d*(d-1)/4*np.log(np.pi) + gammaln(a - 0.5*np.arange(0, d)).sum()
|
||||
454.1488605074416
|
||||
"""
|
||||
a = np.asarray(a)
|
||||
if not np.isscalar(d) or (np.floor(d) != d):
|
||||
raise ValueError("d should be a positive integer (dimension)")
|
||||
if np.any(a <= 0.5 * (d - 1)):
|
||||
raise ValueError(f"condition a ({a:f}) > 0.5 * (d-1) ({0.5 * (d-1):f}) not met")
|
||||
|
||||
res = (d * (d-1) * 0.25) * np.log(np.pi)
|
||||
res += np.sum(loggam([(a - (j - 1.)/2) for j in range(1, d+1)]), axis=0)
|
||||
return res
|
||||
|
|
@ -0,0 +1,397 @@
|
|||
from functools import wraps
|
||||
import scipy._lib.array_api_extra as xpx
|
||||
import numpy as np
|
||||
from ._ufuncs import (_spherical_jn, _spherical_yn, _spherical_in,
|
||||
_spherical_kn, _spherical_jn_d, _spherical_yn_d,
|
||||
_spherical_in_d, _spherical_kn_d)
|
||||
|
||||
|
||||
def use_reflection(sign_n_even=None, reflection_fun=None):
|
||||
# - If reflection_fun is not specified, reflects negative `z` and multiplies
|
||||
# output by appropriate sign (indicated by `sign_n_even`).
|
||||
# - If reflection_fun is specified, calls `reflection_fun` instead of `fun`.
|
||||
# See DLMF 10.47(v) https://dlmf.nist.gov/10.47
|
||||
def decorator(fun):
|
||||
def standard_reflection(n, z, derivative):
|
||||
# sign_n_even indicates the sign when the order `n` is even
|
||||
sign = np.where(n % 2 == 0, sign_n_even, -sign_n_even)
|
||||
# By the chain rule, differentiation at `-z` adds a minus sign
|
||||
sign = -sign if derivative else sign
|
||||
# Evaluate at positive z (minus negative z) and adjust the sign
|
||||
return fun(n, -z, derivative) * sign
|
||||
|
||||
@wraps(fun)
|
||||
def wrapper(n, z, derivative=False):
|
||||
z = np.asarray(z)
|
||||
|
||||
if np.issubdtype(z.dtype, np.complexfloating):
|
||||
return fun(n, z, derivative) # complex dtype just works
|
||||
|
||||
f2 = standard_reflection if reflection_fun is None else reflection_fun
|
||||
return xpx.apply_where(z.real >= 0, (n, z),
|
||||
lambda n, z: fun(n, z, derivative),
|
||||
lambda n, z: f2(n, z, derivative))[()]
|
||||
return wrapper
|
||||
return decorator
|
||||
|
||||
|
||||
@use_reflection(+1) # See DLMF 10.47(v) https://dlmf.nist.gov/10.47
|
||||
def spherical_jn(n, z, derivative=False):
|
||||
r"""Spherical Bessel function of the first kind or its derivative.
|
||||
|
||||
Defined as [1]_,
|
||||
|
||||
.. math:: j_n(z) = \sqrt{\frac{\pi}{2z}} J_{n + 1/2}(z),
|
||||
|
||||
where :math:`J_n` is the Bessel function of the first kind.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
n : int, array_like
|
||||
Order of the Bessel function (n >= 0).
|
||||
z : complex or float, array_like
|
||||
Argument of the Bessel function.
|
||||
derivative : bool, optional
|
||||
If True, the value of the derivative (rather than the function
|
||||
itself) is returned.
|
||||
|
||||
Returns
|
||||
-------
|
||||
jn : ndarray
|
||||
|
||||
Notes
|
||||
-----
|
||||
For real arguments greater than the order, the function is computed
|
||||
using the ascending recurrence [2]_. For small real or complex
|
||||
arguments, the definitional relation to the cylindrical Bessel function
|
||||
of the first kind is used.
|
||||
|
||||
The derivative is computed using the relations [3]_,
|
||||
|
||||
.. math::
|
||||
j_n'(z) = j_{n-1}(z) - \frac{n + 1}{z} j_n(z).
|
||||
|
||||
j_0'(z) = -j_1(z)
|
||||
|
||||
|
||||
.. versionadded:: 0.18.0
|
||||
|
||||
References
|
||||
----------
|
||||
.. [1] https://dlmf.nist.gov/10.47.E3
|
||||
.. [2] https://dlmf.nist.gov/10.51.E1
|
||||
.. [3] https://dlmf.nist.gov/10.51.E2
|
||||
.. [AS] Milton Abramowitz and Irene A. Stegun, eds.
|
||||
Handbook of Mathematical Functions with Formulas,
|
||||
Graphs, and Mathematical Tables. New York: Dover, 1972.
|
||||
|
||||
Examples
|
||||
--------
|
||||
The spherical Bessel functions of the first kind :math:`j_n` accept
|
||||
both real and complex second argument. They can return a complex type:
|
||||
|
||||
>>> from scipy.special import spherical_jn
|
||||
>>> spherical_jn(0, 3+5j)
|
||||
(-9.878987731663194-8.021894345786002j)
|
||||
>>> type(spherical_jn(0, 3+5j))
|
||||
<class 'numpy.complex128'>
|
||||
|
||||
We can verify the relation for the derivative from the Notes
|
||||
for :math:`n=3` in the interval :math:`[1, 2]`:
|
||||
|
||||
>>> import numpy as np
|
||||
>>> x = np.arange(1.0, 2.0, 0.01)
|
||||
>>> np.allclose(spherical_jn(3, x, True),
|
||||
... spherical_jn(2, x) - 4/x * spherical_jn(3, x))
|
||||
True
|
||||
|
||||
The first few :math:`j_n` with real argument:
|
||||
|
||||
>>> import matplotlib.pyplot as plt
|
||||
>>> x = np.arange(0.0, 10.0, 0.01)
|
||||
>>> fig, ax = plt.subplots()
|
||||
>>> ax.set_ylim(-0.5, 1.5)
|
||||
>>> ax.set_title(r'Spherical Bessel functions $j_n$')
|
||||
>>> for n in np.arange(0, 4):
|
||||
... ax.plot(x, spherical_jn(n, x), label=rf'$j_{n}$')
|
||||
>>> plt.legend(loc='best')
|
||||
>>> plt.show()
|
||||
|
||||
"""
|
||||
n = np.asarray(n, dtype=np.dtype("long"))
|
||||
if derivative:
|
||||
return _spherical_jn_d(n, z)
|
||||
else:
|
||||
return _spherical_jn(n, z)
|
||||
|
||||
|
||||
@use_reflection(-1) # See DLMF 10.47(v) https://dlmf.nist.gov/10.47
|
||||
def spherical_yn(n, z, derivative=False):
|
||||
r"""Spherical Bessel function of the second kind or its derivative.
|
||||
|
||||
Defined as [1]_,
|
||||
|
||||
.. math:: y_n(z) = \sqrt{\frac{\pi}{2z}} Y_{n + 1/2}(z),
|
||||
|
||||
where :math:`Y_n` is the Bessel function of the second kind.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
n : int, array_like
|
||||
Order of the Bessel function (n >= 0).
|
||||
z : complex or float, array_like
|
||||
Argument of the Bessel function.
|
||||
derivative : bool, optional
|
||||
If True, the value of the derivative (rather than the function
|
||||
itself) is returned.
|
||||
|
||||
Returns
|
||||
-------
|
||||
yn : ndarray
|
||||
|
||||
Notes
|
||||
-----
|
||||
For real arguments, the function is computed using the ascending
|
||||
recurrence [2]_. For complex arguments, the definitional relation to
|
||||
the cylindrical Bessel function of the second kind is used.
|
||||
|
||||
The derivative is computed using the relations [3]_,
|
||||
|
||||
.. math::
|
||||
y_n' = y_{n-1} - \frac{n + 1}{z} y_n.
|
||||
|
||||
y_0' = -y_1
|
||||
|
||||
|
||||
.. versionadded:: 0.18.0
|
||||
|
||||
References
|
||||
----------
|
||||
.. [1] https://dlmf.nist.gov/10.47.E4
|
||||
.. [2] https://dlmf.nist.gov/10.51.E1
|
||||
.. [3] https://dlmf.nist.gov/10.51.E2
|
||||
.. [AS] Milton Abramowitz and Irene A. Stegun, eds.
|
||||
Handbook of Mathematical Functions with Formulas,
|
||||
Graphs, and Mathematical Tables. New York: Dover, 1972.
|
||||
|
||||
Examples
|
||||
--------
|
||||
The spherical Bessel functions of the second kind :math:`y_n` accept
|
||||
both real and complex second argument. They can return a complex type:
|
||||
|
||||
>>> from scipy.special import spherical_yn
|
||||
>>> spherical_yn(0, 3+5j)
|
||||
(8.022343088587197-9.880052589376795j)
|
||||
>>> type(spherical_yn(0, 3+5j))
|
||||
<class 'numpy.complex128'>
|
||||
|
||||
We can verify the relation for the derivative from the Notes
|
||||
for :math:`n=3` in the interval :math:`[1, 2]`:
|
||||
|
||||
>>> import numpy as np
|
||||
>>> x = np.arange(1.0, 2.0, 0.01)
|
||||
>>> np.allclose(spherical_yn(3, x, True),
|
||||
... spherical_yn(2, x) - 4/x * spherical_yn(3, x))
|
||||
True
|
||||
|
||||
The first few :math:`y_n` with real argument:
|
||||
|
||||
>>> import matplotlib.pyplot as plt
|
||||
>>> x = np.arange(0.0, 10.0, 0.01)
|
||||
>>> fig, ax = plt.subplots()
|
||||
>>> ax.set_ylim(-2.0, 1.0)
|
||||
>>> ax.set_title(r'Spherical Bessel functions $y_n$')
|
||||
>>> for n in np.arange(0, 4):
|
||||
... ax.plot(x, spherical_yn(n, x), label=rf'$y_{n}$')
|
||||
>>> plt.legend(loc='best')
|
||||
>>> plt.show()
|
||||
|
||||
"""
|
||||
n = np.asarray(n, dtype=np.dtype("long"))
|
||||
if derivative:
|
||||
return _spherical_yn_d(n, z)
|
||||
else:
|
||||
return _spherical_yn(n, z)
|
||||
|
||||
|
||||
@use_reflection(+1) # See DLMF 10.47(v) https://dlmf.nist.gov/10.47
|
||||
def spherical_in(n, z, derivative=False):
|
||||
r"""Modified spherical Bessel function of the first kind or its derivative.
|
||||
|
||||
Defined as [1]_,
|
||||
|
||||
.. math:: i_n(z) = \sqrt{\frac{\pi}{2z}} I_{n + 1/2}(z),
|
||||
|
||||
where :math:`I_n` is the modified Bessel function of the first kind.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
n : int, array_like
|
||||
Order of the Bessel function (n >= 0).
|
||||
z : complex or float, array_like
|
||||
Argument of the Bessel function.
|
||||
derivative : bool, optional
|
||||
If True, the value of the derivative (rather than the function
|
||||
itself) is returned.
|
||||
|
||||
Returns
|
||||
-------
|
||||
in : ndarray
|
||||
|
||||
Notes
|
||||
-----
|
||||
The function is computed using its definitional relation to the
|
||||
modified cylindrical Bessel function of the first kind.
|
||||
|
||||
The derivative is computed using the relations [2]_,
|
||||
|
||||
.. math::
|
||||
i_n' = i_{n-1} - \frac{n + 1}{z} i_n.
|
||||
|
||||
i_1' = i_0
|
||||
|
||||
|
||||
.. versionadded:: 0.18.0
|
||||
|
||||
References
|
||||
----------
|
||||
.. [1] https://dlmf.nist.gov/10.47.E7
|
||||
.. [2] https://dlmf.nist.gov/10.51.E5
|
||||
.. [AS] Milton Abramowitz and Irene A. Stegun, eds.
|
||||
Handbook of Mathematical Functions with Formulas,
|
||||
Graphs, and Mathematical Tables. New York: Dover, 1972.
|
||||
|
||||
Examples
|
||||
--------
|
||||
The modified spherical Bessel functions of the first kind :math:`i_n`
|
||||
accept both real and complex second argument.
|
||||
They can return a complex type:
|
||||
|
||||
>>> from scipy.special import spherical_in
|
||||
>>> spherical_in(0, 3+5j)
|
||||
(-1.1689867793369182-1.2697305267234222j)
|
||||
>>> type(spherical_in(0, 3+5j))
|
||||
<class 'numpy.complex128'>
|
||||
|
||||
We can verify the relation for the derivative from the Notes
|
||||
for :math:`n=3` in the interval :math:`[1, 2]`:
|
||||
|
||||
>>> import numpy as np
|
||||
>>> x = np.arange(1.0, 2.0, 0.01)
|
||||
>>> np.allclose(spherical_in(3, x, True),
|
||||
... spherical_in(2, x) - 4/x * spherical_in(3, x))
|
||||
True
|
||||
|
||||
The first few :math:`i_n` with real argument:
|
||||
|
||||
>>> import matplotlib.pyplot as plt
|
||||
>>> x = np.arange(0.0, 6.0, 0.01)
|
||||
>>> fig, ax = plt.subplots()
|
||||
>>> ax.set_ylim(-0.5, 5.0)
|
||||
>>> ax.set_title(r'Modified spherical Bessel functions $i_n$')
|
||||
>>> for n in np.arange(0, 4):
|
||||
... ax.plot(x, spherical_in(n, x), label=rf'$i_{n}$')
|
||||
>>> plt.legend(loc='best')
|
||||
>>> plt.show()
|
||||
|
||||
"""
|
||||
n = np.asarray(n, dtype=np.dtype("long"))
|
||||
if derivative:
|
||||
return _spherical_in_d(n, z)
|
||||
else:
|
||||
return _spherical_in(n, z)
|
||||
|
||||
|
||||
def spherical_kn_reflection(n, z, derivative=False):
|
||||
# More complex than the other cases, and this will likely be re-implemented
|
||||
# in C++ anyway. Would require multiple function evaluations. Probably about
|
||||
# as fast to just resort to complex math, and much simpler.
|
||||
return spherical_kn(n, z + 0j, derivative=derivative).real
|
||||
|
||||
|
||||
@use_reflection(reflection_fun=spherical_kn_reflection)
|
||||
def spherical_kn(n, z, derivative=False):
|
||||
r"""Modified spherical Bessel function of the second kind or its derivative.
|
||||
|
||||
Defined as [1]_,
|
||||
|
||||
.. math:: k_n(z) = \sqrt{\frac{\pi}{2z}} K_{n + 1/2}(z),
|
||||
|
||||
where :math:`K_n` is the modified Bessel function of the second kind.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
n : int, array_like
|
||||
Order of the Bessel function (n >= 0).
|
||||
z : complex or float, array_like
|
||||
Argument of the Bessel function.
|
||||
derivative : bool, optional
|
||||
If True, the value of the derivative (rather than the function
|
||||
itself) is returned.
|
||||
|
||||
Returns
|
||||
-------
|
||||
kn : ndarray
|
||||
|
||||
Notes
|
||||
-----
|
||||
The function is computed using its definitional relation to the
|
||||
modified cylindrical Bessel function of the second kind.
|
||||
|
||||
The derivative is computed using the relations [2]_,
|
||||
|
||||
.. math::
|
||||
k_n' = -k_{n-1} - \frac{n + 1}{z} k_n.
|
||||
|
||||
k_0' = -k_1
|
||||
|
||||
|
||||
.. versionadded:: 0.18.0
|
||||
|
||||
References
|
||||
----------
|
||||
.. [1] https://dlmf.nist.gov/10.47.E9
|
||||
.. [2] https://dlmf.nist.gov/10.51.E5
|
||||
.. [AS] Milton Abramowitz and Irene A. Stegun, eds.
|
||||
Handbook of Mathematical Functions with Formulas,
|
||||
Graphs, and Mathematical Tables. New York: Dover, 1972.
|
||||
|
||||
Examples
|
||||
--------
|
||||
The modified spherical Bessel functions of the second kind :math:`k_n`
|
||||
accept both real and complex second argument.
|
||||
They can return a complex type:
|
||||
|
||||
>>> from scipy.special import spherical_kn
|
||||
>>> spherical_kn(0, 3+5j)
|
||||
(0.012985785614001561+0.003354691603137546j)
|
||||
>>> type(spherical_kn(0, 3+5j))
|
||||
<class 'numpy.complex128'>
|
||||
|
||||
We can verify the relation for the derivative from the Notes
|
||||
for :math:`n=3` in the interval :math:`[1, 2]`:
|
||||
|
||||
>>> import numpy as np
|
||||
>>> x = np.arange(1.0, 2.0, 0.01)
|
||||
>>> np.allclose(spherical_kn(3, x, True),
|
||||
... - 4/x * spherical_kn(3, x) - spherical_kn(2, x))
|
||||
True
|
||||
|
||||
The first few :math:`k_n` with real argument:
|
||||
|
||||
>>> import matplotlib.pyplot as plt
|
||||
>>> x = np.arange(0.0, 4.0, 0.01)
|
||||
>>> fig, ax = plt.subplots()
|
||||
>>> ax.set_ylim(0.0, 5.0)
|
||||
>>> ax.set_title(r'Modified spherical Bessel functions $k_n$')
|
||||
>>> for n in np.arange(0, 4):
|
||||
... ax.plot(x, spherical_kn(n, x), label=rf'$k_{n}$')
|
||||
>>> plt.legend(loc='best')
|
||||
>>> plt.show()
|
||||
|
||||
"""
|
||||
n = np.asarray(n, dtype=np.dtype("long"))
|
||||
if derivative:
|
||||
return _spherical_kn_d(n, z)
|
||||
else:
|
||||
return _spherical_kn(n, z)
|
||||
|
|
@ -0,0 +1,295 @@
|
|||
import functools
|
||||
import operator
|
||||
from collections.abc import Callable
|
||||
from dataclasses import dataclass
|
||||
from types import ModuleType
|
||||
|
||||
import numpy as np
|
||||
from scipy._lib._array_api import (
|
||||
array_namespace, scipy_namespace_for, is_numpy, is_dask, is_marray,
|
||||
xp_promote, xp_capabilities, SCIPY_ARRAY_API
|
||||
)
|
||||
import scipy._lib.array_api_extra as xpx
|
||||
from . import _ufuncs
|
||||
|
||||
|
||||
@dataclass
|
||||
class _FuncInfo:
|
||||
# NumPy-only function. IT MUST BE ELEMENTWISE.
|
||||
func: Callable
|
||||
# Number of arguments, not counting out=
|
||||
# This is for testing purposes only, due to the fact that
|
||||
# inspect.signature() just returns *args for ufuncs.
|
||||
n_args: int
|
||||
# @xp_capabilities decorator, for the purpose of
|
||||
# documentation and unit testing. Omit to indicate
|
||||
# full support for all backends.
|
||||
xp_capabilities: Callable[[Callable], Callable] | None = None
|
||||
# Generic implementation to fall back on if there is no native dispatch
|
||||
# available. This is a function that accepts (main namespace, scipy namespace)
|
||||
# and returns the final callable, or None if not available.
|
||||
generic_impl: Callable[
|
||||
[ModuleType, ModuleType | None], Callable | None
|
||||
] | None = None
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
return self.func.__name__
|
||||
|
||||
# These are needed by @lru_cache below
|
||||
def __hash__(self):
|
||||
return hash(self.func)
|
||||
|
||||
def __eq__(self, other):
|
||||
return isinstance(other, _FuncInfo) and self.func == other.func
|
||||
|
||||
@property
|
||||
def wrapper(self):
|
||||
if self.name in globals():
|
||||
# Already initialised. We are likely in a unit test.
|
||||
# Return function potentially overridden by xpx.testing.lazy_xp_function.
|
||||
import scipy.special
|
||||
return getattr(scipy.special, self.name)
|
||||
|
||||
if SCIPY_ARRAY_API:
|
||||
@functools.wraps(self.func)
|
||||
def wrapped(*args, **kwargs):
|
||||
xp = array_namespace(*args)
|
||||
return self._wrapper_for(xp)(*args, **kwargs)
|
||||
|
||||
# Allow pickling the function. Normally this is done by @wraps,
|
||||
# but in this case it doesn't work because self.func is a ufunc.
|
||||
wrapped.__module__ = "scipy.special"
|
||||
wrapped.__qualname__ = self.name
|
||||
func = wrapped
|
||||
else:
|
||||
func = self.func
|
||||
|
||||
capabilities = self.xp_capabilities or xp_capabilities()
|
||||
# In order to retain a naked ufunc when SCIPY_ARRAY_API is
|
||||
# disabled, xp_capabilities must apply its changes in place.
|
||||
cap_func = capabilities(func)
|
||||
assert cap_func is func
|
||||
return func
|
||||
|
||||
@functools.lru_cache(1000)
|
||||
def _wrapper_for(self, xp):
|
||||
if is_numpy(xp):
|
||||
return self.func
|
||||
|
||||
# If a native implementation is available, use that
|
||||
spx = scipy_namespace_for(xp)
|
||||
f = _get_native_func(xp, spx, self.name)
|
||||
if f is not None:
|
||||
return f
|
||||
|
||||
# If generic Array API implementation is available, use that
|
||||
if self.generic_impl is not None:
|
||||
f = self.generic_impl(xp, spx)
|
||||
if f is not None:
|
||||
return f
|
||||
|
||||
if is_marray(xp):
|
||||
# Unwrap the array, apply the function on the wrapped namespace,
|
||||
# and then re-wrap it.
|
||||
# IMPORTANT: this only works because all functions in this module
|
||||
# are elementwise. Otherwise, we would not be able to define a
|
||||
# general rule for mask propagation.
|
||||
|
||||
_f = globals()[self.name] # Allow nested wrapping
|
||||
def f(*args, _f=_f, xp=xp, **kwargs):
|
||||
data_args = [arg.data for arg in args]
|
||||
out = _f(*data_args, **kwargs)
|
||||
mask = functools.reduce(operator.or_, (arg.mask for arg in args))
|
||||
return xp.asarray(out, mask=mask)
|
||||
|
||||
return f
|
||||
|
||||
if is_dask(xp):
|
||||
# Apply the function to each block of the Dask array.
|
||||
# IMPORTANT: map_blocks works only because all functions in this module
|
||||
# are elementwise. It would be a grave mistake to apply this to gufuncs
|
||||
# or any other function with reductions, as they would change their
|
||||
# output depending on chunking!
|
||||
|
||||
_f = globals()[self.name] # Allow nested wrapping
|
||||
def f(*args, _f=_f, xp=xp, **kwargs):
|
||||
# Hide dtype kwarg from map_blocks
|
||||
return xp.map_blocks(functools.partial(_f, **kwargs), *args)
|
||||
|
||||
return f
|
||||
|
||||
# As a final resort, use the NumPy/SciPy implementation
|
||||
_f = self.func
|
||||
def f(*args, _f=_f, xp=xp, **kwargs):
|
||||
# TODO use xpx.lazy_apply to add jax.jit support
|
||||
# (but dtype propagation can be non-trivial)
|
||||
args = [np.asarray(arg) for arg in args]
|
||||
out = _f(*args, **kwargs)
|
||||
return xp.asarray(out)
|
||||
|
||||
return f
|
||||
|
||||
|
||||
def _get_native_func(xp, spx, f_name):
|
||||
f = getattr(spx.special, f_name, None) if spx else None
|
||||
if f is None and hasattr(xp, 'special'):
|
||||
# Currently dead branch, in anticipation of 'special' Array API extension
|
||||
# https://github.com/data-apis/array-api/issues/725
|
||||
f = getattr(xp.special, f_name, None)
|
||||
return f
|
||||
|
||||
|
||||
def _rel_entr(xp, spx):
|
||||
def __rel_entr(x, y, *, xp=xp):
|
||||
# https://github.com/data-apis/array-api-extra/issues/160
|
||||
mxp = array_namespace(x._meta, y._meta) if is_dask(xp) else xp
|
||||
x, y = xp_promote(x, y, broadcast=True, force_floating=True, xp=xp)
|
||||
xy_pos = (x > 0) & (y > 0)
|
||||
xy_inf = xp.isinf(x) & xp.isinf(y)
|
||||
res = xpx.apply_where(
|
||||
xy_pos & ~xy_inf,
|
||||
(x, y),
|
||||
# Note: for very large x, this can overflow.
|
||||
lambda x, y: x * (mxp.log(x) - mxp.log(y)),
|
||||
fill_value=xp.inf
|
||||
)
|
||||
res = xpx.at(res)[(x == 0) & (y >= 0)].set(0)
|
||||
res = xpx.at(res)[xp.isnan(x) | xp.isnan(y) | (xy_pos & xy_inf)].set(xp.nan)
|
||||
return res
|
||||
|
||||
return __rel_entr
|
||||
|
||||
|
||||
def _xlogy(xp, spx):
|
||||
def __xlogy(x, y, *, xp=xp):
|
||||
x, y = xp_promote(x, y, force_floating=True, xp=xp)
|
||||
with np.errstate(divide='ignore', invalid='ignore'):
|
||||
temp = x * xp.log(y)
|
||||
return xp.where(x == 0., 0., temp)
|
||||
return __xlogy
|
||||
|
||||
|
||||
|
||||
def _chdtr(xp, spx):
|
||||
# The difference between this and just using `gammainc`
|
||||
# defined by `get_array_special_func` is that if `gammainc`
|
||||
# isn't found, we don't want to use the SciPy version; we'll
|
||||
# return None here and use the SciPy version of `chdtr`.
|
||||
gammainc = _get_native_func(xp, spx, 'gammainc')
|
||||
if gammainc is None:
|
||||
return None
|
||||
|
||||
def __chdtr(v, x):
|
||||
res = gammainc(v / 2, x / 2) # this is almost all we need
|
||||
# The rest can be removed when google/jax#20507 is resolved
|
||||
mask = (v == 0) & (x > 0) # JAX returns NaN
|
||||
res = xp.where(mask, 1., res)
|
||||
mask = xp.isinf(v) & xp.isinf(x) # JAX returns 1.0
|
||||
return xp.where(mask, xp.nan, res)
|
||||
return __chdtr
|
||||
|
||||
|
||||
def _chdtrc(xp, spx):
|
||||
# The difference between this and just using `gammaincc`
|
||||
# defined by `get_array_special_func` is that if `gammaincc`
|
||||
# isn't found, we don't want to use the SciPy version; we'll
|
||||
# return None here and use the SciPy version of `chdtrc`.
|
||||
gammaincc = _get_native_func(xp, spx, 'gammaincc')
|
||||
if gammaincc is None:
|
||||
return None
|
||||
|
||||
def __chdtrc(v, x):
|
||||
res = xp.where(x >= 0, gammaincc(v/2, x/2), 1)
|
||||
i_nan = ((x == 0) & (v == 0)) | xp.isnan(x) | xp.isnan(v) | (v <= 0)
|
||||
res = xp.where(i_nan, xp.nan, res)
|
||||
return res
|
||||
return __chdtrc
|
||||
|
||||
|
||||
def _betaincc(xp, spx):
|
||||
betainc = _get_native_func(xp, spx, 'betainc')
|
||||
if betainc is None:
|
||||
return None
|
||||
|
||||
def __betaincc(a, b, x):
|
||||
# not perfect; might want to just rely on SciPy
|
||||
return betainc(b, a, 1-x)
|
||||
return __betaincc
|
||||
|
||||
|
||||
def _stdtr(xp, spx):
|
||||
betainc = _get_native_func(xp, spx, 'betainc')
|
||||
if betainc is None:
|
||||
return None
|
||||
|
||||
def __stdtr(df, t):
|
||||
x = df / (t ** 2 + df)
|
||||
tail = betainc(df / 2, 0.5, x) / 2
|
||||
return xp.where(t < 0, tail, 1 - tail)
|
||||
|
||||
return __stdtr
|
||||
|
||||
|
||||
def _stdtrit(xp, spx):
|
||||
# Need either native stdtr or native betainc
|
||||
stdtr = _get_native_func(xp, spx, 'stdtr') or _stdtr(xp, spx)
|
||||
# If betainc is not defined, the root-finding would be done with `xp`
|
||||
# despite `stdtr` being evaluated with SciPy/NumPy `stdtr`. Save the
|
||||
# conversions: in this case, just evaluate `stdtrit` with SciPy/NumPy.
|
||||
if stdtr is None:
|
||||
return None
|
||||
|
||||
from scipy.optimize.elementwise import bracket_root, find_root
|
||||
|
||||
def __stdtrit(df, p):
|
||||
def fun(t, df, p): return stdtr(df, t) - p
|
||||
res_bracket = bracket_root(fun, xp.zeros_like(p), args=(df, p))
|
||||
res_root = find_root(fun, res_bracket.bracket, args=(df, p))
|
||||
return res_root.x
|
||||
|
||||
return __stdtrit
|
||||
|
||||
|
||||
# Inventory of automatically dispatched functions
|
||||
# IMPORTANT: these must all be **elementwise** functions!
|
||||
|
||||
# PyTorch doesn't implement `betainc`.
|
||||
# On torch CPU we can fall back to NumPy, but on GPU it won't work.
|
||||
_needs_betainc = xp_capabilities(cpu_only=True, exceptions=['jax.numpy', 'cupy'])
|
||||
|
||||
_special_funcs = (
|
||||
_FuncInfo(_ufuncs.betainc, 3, _needs_betainc),
|
||||
_FuncInfo(_ufuncs.betaincc, 3, _needs_betainc, generic_impl=_betaincc),
|
||||
_FuncInfo(_ufuncs.chdtr, 2, generic_impl=_chdtr),
|
||||
_FuncInfo(_ufuncs.chdtrc, 2, generic_impl=_chdtrc),
|
||||
_FuncInfo(_ufuncs.erf, 1),
|
||||
_FuncInfo(_ufuncs.erfc, 1),
|
||||
_FuncInfo(_ufuncs.entr, 1),
|
||||
_FuncInfo(_ufuncs.expit, 1),
|
||||
_FuncInfo(_ufuncs.i0, 1),
|
||||
_FuncInfo(_ufuncs.i0e, 1),
|
||||
_FuncInfo(_ufuncs.i1, 1),
|
||||
_FuncInfo(_ufuncs.i1e, 1),
|
||||
_FuncInfo(_ufuncs.log_ndtr, 1),
|
||||
_FuncInfo(_ufuncs.logit, 1),
|
||||
_FuncInfo(_ufuncs.gammaln, 1),
|
||||
_FuncInfo(_ufuncs.gammainc, 2),
|
||||
_FuncInfo(_ufuncs.gammaincc, 2),
|
||||
_FuncInfo(_ufuncs.ndtr, 1),
|
||||
_FuncInfo(_ufuncs.ndtri, 1),
|
||||
_FuncInfo(_ufuncs.rel_entr, 2, generic_impl=_rel_entr),
|
||||
_FuncInfo(_ufuncs.stdtr, 2, _needs_betainc, generic_impl=_stdtr),
|
||||
_FuncInfo(_ufuncs.stdtrit, 2,
|
||||
xp_capabilities(
|
||||
cpu_only=True, exceptions=['cupy'], # needs betainc
|
||||
skip_backends=[("jax.numpy", "no scipy.optimize support")]),
|
||||
generic_impl=_stdtrit),
|
||||
_FuncInfo(_ufuncs.xlogy, 2, generic_impl=_xlogy),
|
||||
)
|
||||
|
||||
# Override ufuncs.
|
||||
# When SCIPY_ARRAY_API is disabled, this exclusively updates the docstrings in place
|
||||
# and populates the xp_capabilities table, while retaining the original ufuncs.
|
||||
globals().update({nfo.func.__name__: nfo.wrapper for nfo in _special_funcs})
|
||||
__all__ = [nfo.func.__name__ for nfo in _special_funcs]
|
||||
Binary file not shown.
|
|
@ -0,0 +1,9 @@
|
|||
import numpy as np
|
||||
|
||||
def have_fenv() -> bool: ...
|
||||
def random_double(size: int, rng: np.random.RandomState) -> np.float64: ...
|
||||
def test_add_round(size: int, mode: str, rng: np.random.RandomState): ...
|
||||
|
||||
def _dd_exp(xhi: float, xlo: float) -> tuple[float, float]: ...
|
||||
def _dd_log(xhi: float, xlo: float) -> tuple[float, float]: ...
|
||||
def _dd_expm1(xhi: float, xlo: float) -> tuple[float, float]: ...
|
||||
321
venv/lib/python3.13/site-packages/scipy/special/_testutils.py
Normal file
321
venv/lib/python3.13/site-packages/scipy/special/_testutils.py
Normal file
|
|
@ -0,0 +1,321 @@
|
|||
import os
|
||||
import functools
|
||||
import operator
|
||||
from scipy._lib import _pep440
|
||||
|
||||
import numpy as np
|
||||
from numpy.testing import assert_
|
||||
import pytest
|
||||
|
||||
import scipy.special as sc
|
||||
|
||||
__all__ = ['with_special_errors', 'assert_func_equal', 'FuncData']
|
||||
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# Check if a module is present to be used in tests
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
class MissingModule:
|
||||
def __init__(self, name):
|
||||
self.name = name
|
||||
|
||||
|
||||
def check_version(module, min_ver):
|
||||
if type(module) is MissingModule:
|
||||
return pytest.mark.skip(reason=f"{module.name} is not installed")
|
||||
return pytest.mark.skipif(
|
||||
_pep440.parse(module.__version__) < _pep440.Version(min_ver),
|
||||
reason=f"{module.__name__} version >= {min_ver} required"
|
||||
)
|
||||
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# Enable convergence and loss of precision warnings -- turn off one by one
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
def with_special_errors(func):
|
||||
"""
|
||||
Enable special function errors (such as underflow, overflow,
|
||||
loss of precision, etc.)
|
||||
"""
|
||||
@functools.wraps(func)
|
||||
def wrapper(*a, **kw):
|
||||
with sc.errstate(all='raise'):
|
||||
res = func(*a, **kw)
|
||||
return res
|
||||
return wrapper
|
||||
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# Comparing function values at many data points at once, with helpful
|
||||
# error reports
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
def assert_func_equal(func, results, points, rtol=None, atol=None,
|
||||
param_filter=None, knownfailure=None,
|
||||
vectorized=True, dtype=None, nan_ok=False,
|
||||
ignore_inf_sign=False, distinguish_nan_and_inf=True):
|
||||
if hasattr(points, 'next'):
|
||||
# it's a generator
|
||||
points = list(points)
|
||||
|
||||
points = np.asarray(points)
|
||||
if points.ndim == 1:
|
||||
points = points[:,None]
|
||||
nparams = points.shape[1]
|
||||
|
||||
if hasattr(results, '__name__'):
|
||||
# function
|
||||
data = points
|
||||
result_columns = None
|
||||
result_func = results
|
||||
else:
|
||||
# dataset
|
||||
data = np.c_[points, results]
|
||||
result_columns = list(range(nparams, data.shape[1]))
|
||||
result_func = None
|
||||
|
||||
fdata = FuncData(func, data, list(range(nparams)),
|
||||
result_columns=result_columns, result_func=result_func,
|
||||
rtol=rtol, atol=atol, param_filter=param_filter,
|
||||
knownfailure=knownfailure, nan_ok=nan_ok, vectorized=vectorized,
|
||||
ignore_inf_sign=ignore_inf_sign,
|
||||
distinguish_nan_and_inf=distinguish_nan_and_inf)
|
||||
fdata.check()
|
||||
|
||||
|
||||
class FuncData:
|
||||
"""
|
||||
Data set for checking a special function.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
func : function
|
||||
Function to test
|
||||
data : numpy array
|
||||
columnar data to use for testing
|
||||
param_columns : int or tuple of ints
|
||||
Columns indices in which the parameters to `func` lie.
|
||||
Can be imaginary integers to indicate that the parameter
|
||||
should be cast to complex.
|
||||
result_columns : int or tuple of ints, optional
|
||||
Column indices for expected results from `func`.
|
||||
result_func : callable, optional
|
||||
Function to call to obtain results.
|
||||
rtol : float, optional
|
||||
Required relative tolerance. Default is 5*eps.
|
||||
atol : float, optional
|
||||
Required absolute tolerance. Default is 5*tiny.
|
||||
param_filter : function, or tuple of functions/Nones, optional
|
||||
Filter functions to exclude some parameter ranges.
|
||||
If omitted, no filtering is done.
|
||||
knownfailure : str, optional
|
||||
Known failure error message to raise when the test is run.
|
||||
If omitted, no exception is raised.
|
||||
nan_ok : bool, optional
|
||||
If nan is always an accepted result.
|
||||
vectorized : bool, optional
|
||||
Whether all functions passed in are vectorized.
|
||||
ignore_inf_sign : bool, optional
|
||||
Whether to ignore signs of infinities.
|
||||
(Doesn't matter for complex-valued functions.)
|
||||
distinguish_nan_and_inf : bool, optional
|
||||
If True, treat numbers which contain nans or infs as
|
||||
equal. Sets ignore_inf_sign to be True.
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self, func, data, param_columns, result_columns=None,
|
||||
result_func=None, rtol=None, atol=None, param_filter=None,
|
||||
knownfailure=None, dataname=None, nan_ok=False, vectorized=True,
|
||||
ignore_inf_sign=False, distinguish_nan_and_inf=True):
|
||||
self.func = func
|
||||
self.data = data
|
||||
self.dataname = dataname
|
||||
if not hasattr(param_columns, '__len__'):
|
||||
param_columns = (param_columns,)
|
||||
self.param_columns = tuple(param_columns)
|
||||
if result_columns is not None:
|
||||
if not hasattr(result_columns, '__len__'):
|
||||
result_columns = (result_columns,)
|
||||
self.result_columns = tuple(result_columns)
|
||||
if result_func is not None:
|
||||
message = "Only result_func or result_columns should be provided"
|
||||
raise ValueError(message)
|
||||
elif result_func is not None:
|
||||
self.result_columns = None
|
||||
else:
|
||||
raise ValueError("Either result_func or result_columns should be provided")
|
||||
self.result_func = result_func
|
||||
self.rtol = rtol
|
||||
self.atol = atol
|
||||
if not hasattr(param_filter, '__len__'):
|
||||
param_filter = (param_filter,)
|
||||
self.param_filter = param_filter
|
||||
self.knownfailure = knownfailure
|
||||
self.nan_ok = nan_ok
|
||||
self.vectorized = vectorized
|
||||
self.ignore_inf_sign = ignore_inf_sign
|
||||
self.distinguish_nan_and_inf = distinguish_nan_and_inf
|
||||
if not self.distinguish_nan_and_inf:
|
||||
self.ignore_inf_sign = True
|
||||
|
||||
def get_tolerances(self, dtype):
|
||||
if not np.issubdtype(dtype, np.inexact):
|
||||
dtype = np.dtype(float)
|
||||
info = np.finfo(dtype)
|
||||
rtol, atol = self.rtol, self.atol
|
||||
if rtol is None:
|
||||
rtol = 5*info.eps
|
||||
if atol is None:
|
||||
atol = 5*info.tiny
|
||||
return rtol, atol
|
||||
|
||||
def check(self, data=None, dtype=None, dtypes=None):
|
||||
"""Check the special function against the data."""
|
||||
__tracebackhide__ = operator.methodcaller(
|
||||
'errisinstance', AssertionError
|
||||
)
|
||||
|
||||
if self.knownfailure:
|
||||
pytest.xfail(reason=self.knownfailure)
|
||||
|
||||
if data is None:
|
||||
data = self.data
|
||||
|
||||
if dtype is None:
|
||||
dtype = data.dtype
|
||||
else:
|
||||
data = data.astype(dtype)
|
||||
|
||||
rtol, atol = self.get_tolerances(dtype)
|
||||
|
||||
# Apply given filter functions
|
||||
if self.param_filter:
|
||||
param_mask = np.ones((data.shape[0],), np.bool_)
|
||||
for j, filter in zip(self.param_columns, self.param_filter):
|
||||
if filter:
|
||||
param_mask &= list(filter(data[:,j]))
|
||||
data = data[param_mask]
|
||||
|
||||
# Pick parameters from the correct columns
|
||||
params = []
|
||||
for idx, j in enumerate(self.param_columns):
|
||||
if np.iscomplexobj(j):
|
||||
j = int(j.imag)
|
||||
params.append(data[:,j].astype(complex))
|
||||
elif dtypes and idx < len(dtypes):
|
||||
params.append(data[:, j].astype(dtypes[idx]))
|
||||
else:
|
||||
params.append(data[:,j])
|
||||
|
||||
# Helper for evaluating results
|
||||
def eval_func_at_params(func, skip_mask=None):
|
||||
if self.vectorized:
|
||||
got = func(*params)
|
||||
else:
|
||||
got = []
|
||||
for j in range(len(params[0])):
|
||||
if skip_mask is not None and skip_mask[j]:
|
||||
got.append(np.nan)
|
||||
continue
|
||||
got.append(func(*tuple([params[i][j] for i in range(len(params))])))
|
||||
got = np.asarray(got)
|
||||
if not isinstance(got, tuple):
|
||||
got = (got,)
|
||||
return got
|
||||
|
||||
# Evaluate function to be tested
|
||||
got = eval_func_at_params(self.func)
|
||||
|
||||
# Grab the correct results
|
||||
if self.result_columns is not None:
|
||||
# Correct results passed in with the data
|
||||
wanted = tuple([data[:,icol] for icol in self.result_columns])
|
||||
else:
|
||||
# Function producing correct results passed in
|
||||
skip_mask = None
|
||||
if self.nan_ok and len(got) == 1:
|
||||
# Don't spend time evaluating what doesn't need to be evaluated
|
||||
skip_mask = np.isnan(got[0])
|
||||
wanted = eval_func_at_params(self.result_func, skip_mask=skip_mask)
|
||||
|
||||
# Check the validity of each output returned
|
||||
assert_(len(got) == len(wanted))
|
||||
|
||||
for output_num, (x, y) in enumerate(zip(got, wanted)):
|
||||
if np.issubdtype(x.dtype, np.complexfloating) or self.ignore_inf_sign:
|
||||
pinf_x = np.isinf(x)
|
||||
pinf_y = np.isinf(y)
|
||||
minf_x = np.isinf(x)
|
||||
minf_y = np.isinf(y)
|
||||
else:
|
||||
pinf_x = np.isposinf(x)
|
||||
pinf_y = np.isposinf(y)
|
||||
minf_x = np.isneginf(x)
|
||||
minf_y = np.isneginf(y)
|
||||
nan_x = np.isnan(x)
|
||||
nan_y = np.isnan(y)
|
||||
|
||||
with np.errstate(all='ignore'):
|
||||
abs_y = np.absolute(y)
|
||||
abs_y[~np.isfinite(abs_y)] = 0
|
||||
diff = np.absolute(x - y)
|
||||
diff[~np.isfinite(diff)] = 0
|
||||
|
||||
rdiff = diff / np.absolute(y)
|
||||
rdiff[~np.isfinite(rdiff)] = 0
|
||||
|
||||
tol_mask = (diff <= atol + rtol*abs_y)
|
||||
pinf_mask = (pinf_x == pinf_y)
|
||||
minf_mask = (minf_x == minf_y)
|
||||
|
||||
nan_mask = (nan_x == nan_y)
|
||||
|
||||
bad_j = ~(tol_mask & pinf_mask & minf_mask & nan_mask)
|
||||
|
||||
point_count = bad_j.size
|
||||
if self.nan_ok:
|
||||
bad_j &= ~nan_x
|
||||
bad_j &= ~nan_y
|
||||
point_count -= (nan_x | nan_y).sum()
|
||||
|
||||
if not self.distinguish_nan_and_inf and not self.nan_ok:
|
||||
# If nan's are okay we've already covered all these cases
|
||||
inf_x = np.isinf(x)
|
||||
inf_y = np.isinf(y)
|
||||
both_nonfinite = (inf_x & nan_y) | (nan_x & inf_y)
|
||||
bad_j &= ~both_nonfinite
|
||||
point_count -= both_nonfinite.sum()
|
||||
|
||||
if np.any(bad_j):
|
||||
# Some bad results: inform what, where, and how bad
|
||||
msg = [""]
|
||||
msg.append(f"Max |adiff|: {diff[bad_j].max():g}")
|
||||
msg.append(f"Max |rdiff|: {rdiff[bad_j].max():g}")
|
||||
msg.append(f"Bad results ({np.sum(bad_j)} out of "
|
||||
f"{point_count}) for the following points "
|
||||
f"(in output {output_num}):")
|
||||
for j in np.nonzero(bad_j)[0]:
|
||||
j = int(j)
|
||||
def fmt(x):
|
||||
return f'{np.array2string(x[j], precision=18):30s}'
|
||||
a = " ".join(map(fmt, params))
|
||||
b = " ".join(map(fmt, got))
|
||||
c = " ".join(map(fmt, wanted))
|
||||
d = fmt(rdiff)
|
||||
msg.append(f"{a} => {b} != {c} (rdiff {d})")
|
||||
assert_(False, "\n".join(msg))
|
||||
|
||||
def __repr__(self):
|
||||
"""Pretty-printing"""
|
||||
if np.any(list(map(np.iscomplexobj, self.param_columns))):
|
||||
is_complex = " (complex)"
|
||||
else:
|
||||
is_complex = ""
|
||||
if self.dataname:
|
||||
return (f"<Data for {self.func.__name__}{is_complex}: "
|
||||
f"{os.path.basename(self.dataname)}>")
|
||||
else:
|
||||
return f"<Data for {self.func.__name__}{is_complex}>"
|
||||
Binary file not shown.
522
venv/lib/python3.13/site-packages/scipy/special/_ufuncs.pyi
Normal file
522
venv/lib/python3.13/site-packages/scipy/special/_ufuncs.pyi
Normal file
|
|
@ -0,0 +1,522 @@
|
|||
from typing import Any
|
||||
|
||||
import numpy as np
|
||||
|
||||
__all__ = [
|
||||
'geterr',
|
||||
'seterr',
|
||||
'errstate',
|
||||
'agm',
|
||||
'airy',
|
||||
'airye',
|
||||
'bdtr',
|
||||
'bdtrc',
|
||||
'bdtri',
|
||||
'bdtrik',
|
||||
'bdtrin',
|
||||
'bei',
|
||||
'beip',
|
||||
'ber',
|
||||
'berp',
|
||||
'besselpoly',
|
||||
'beta',
|
||||
'betainc',
|
||||
'betaincc',
|
||||
'betainccinv',
|
||||
'betaincinv',
|
||||
'betaln',
|
||||
'binom',
|
||||
'boxcox',
|
||||
'boxcox1p',
|
||||
'btdtria',
|
||||
'btdtrib',
|
||||
'cbrt',
|
||||
'chdtr',
|
||||
'chdtrc',
|
||||
'chdtri',
|
||||
'chdtriv',
|
||||
'chndtr',
|
||||
'chndtridf',
|
||||
'chndtrinc',
|
||||
'chndtrix',
|
||||
'cosdg',
|
||||
'cosm1',
|
||||
'cotdg',
|
||||
'dawsn',
|
||||
'ellipe',
|
||||
'ellipeinc',
|
||||
'ellipj',
|
||||
'ellipk',
|
||||
'ellipkinc',
|
||||
'ellipkm1',
|
||||
'elliprc',
|
||||
'elliprd',
|
||||
'elliprf',
|
||||
'elliprg',
|
||||
'elliprj',
|
||||
'entr',
|
||||
'erf',
|
||||
'erfc',
|
||||
'erfcinv',
|
||||
'erfcx',
|
||||
'erfi',
|
||||
'erfinv',
|
||||
'eval_chebyc',
|
||||
'eval_chebys',
|
||||
'eval_chebyt',
|
||||
'eval_chebyu',
|
||||
'eval_gegenbauer',
|
||||
'eval_genlaguerre',
|
||||
'eval_hermite',
|
||||
'eval_hermitenorm',
|
||||
'eval_jacobi',
|
||||
'eval_laguerre',
|
||||
'eval_legendre',
|
||||
'eval_sh_chebyt',
|
||||
'eval_sh_chebyu',
|
||||
'eval_sh_jacobi',
|
||||
'eval_sh_legendre',
|
||||
'exp1',
|
||||
'exp10',
|
||||
'exp2',
|
||||
'expi',
|
||||
'expit',
|
||||
'expm1',
|
||||
'expn',
|
||||
'exprel',
|
||||
'fdtr',
|
||||
'fdtrc',
|
||||
'fdtri',
|
||||
'fdtridfd',
|
||||
'fresnel',
|
||||
'gamma',
|
||||
'gammainc',
|
||||
'gammaincc',
|
||||
'gammainccinv',
|
||||
'gammaincinv',
|
||||
'gammaln',
|
||||
'gammasgn',
|
||||
'gdtr',
|
||||
'gdtrc',
|
||||
'gdtria',
|
||||
'gdtrib',
|
||||
'gdtrix',
|
||||
'hankel1',
|
||||
'hankel1e',
|
||||
'hankel2',
|
||||
'hankel2e',
|
||||
'huber',
|
||||
'hyp0f1',
|
||||
'hyp1f1',
|
||||
'hyp2f1',
|
||||
'hyperu',
|
||||
'i0',
|
||||
'i0e',
|
||||
'i1',
|
||||
'i1e',
|
||||
'inv_boxcox',
|
||||
'inv_boxcox1p',
|
||||
'it2i0k0',
|
||||
'it2j0y0',
|
||||
'it2struve0',
|
||||
'itairy',
|
||||
'iti0k0',
|
||||
'itj0y0',
|
||||
'itmodstruve0',
|
||||
'itstruve0',
|
||||
'iv',
|
||||
'ive',
|
||||
'j0',
|
||||
'j1',
|
||||
'jn',
|
||||
'jv',
|
||||
'jve',
|
||||
'k0',
|
||||
'k0e',
|
||||
'k1',
|
||||
'k1e',
|
||||
'kei',
|
||||
'keip',
|
||||
'kelvin',
|
||||
'ker',
|
||||
'kerp',
|
||||
'kl_div',
|
||||
'kn',
|
||||
'kolmogi',
|
||||
'kolmogorov',
|
||||
'kv',
|
||||
'kve',
|
||||
'log1p',
|
||||
'log_expit',
|
||||
'log_ndtr',
|
||||
'log_wright_bessel',
|
||||
'loggamma',
|
||||
'logit',
|
||||
'lpmv',
|
||||
'mathieu_a',
|
||||
'mathieu_b',
|
||||
'mathieu_cem',
|
||||
'mathieu_modcem1',
|
||||
'mathieu_modcem2',
|
||||
'mathieu_modsem1',
|
||||
'mathieu_modsem2',
|
||||
'mathieu_sem',
|
||||
'modfresnelm',
|
||||
'modfresnelp',
|
||||
'modstruve',
|
||||
'nbdtr',
|
||||
'nbdtrc',
|
||||
'nbdtri',
|
||||
'nbdtrik',
|
||||
'nbdtrin',
|
||||
'ncfdtr',
|
||||
'ncfdtri',
|
||||
'ncfdtridfd',
|
||||
'ncfdtridfn',
|
||||
'ncfdtrinc',
|
||||
'nctdtr',
|
||||
'nctdtridf',
|
||||
'nctdtrinc',
|
||||
'nctdtrit',
|
||||
'ndtr',
|
||||
'ndtri',
|
||||
'ndtri_exp',
|
||||
'nrdtrimn',
|
||||
'nrdtrisd',
|
||||
'obl_ang1',
|
||||
'obl_ang1_cv',
|
||||
'obl_cv',
|
||||
'obl_rad1',
|
||||
'obl_rad1_cv',
|
||||
'obl_rad2',
|
||||
'obl_rad2_cv',
|
||||
'owens_t',
|
||||
'pbdv',
|
||||
'pbvv',
|
||||
'pbwa',
|
||||
'pdtr',
|
||||
'pdtrc',
|
||||
'pdtri',
|
||||
'pdtrik',
|
||||
'poch',
|
||||
'powm1',
|
||||
'pro_ang1',
|
||||
'pro_ang1_cv',
|
||||
'pro_cv',
|
||||
'pro_rad1',
|
||||
'pro_rad1_cv',
|
||||
'pro_rad2',
|
||||
'pro_rad2_cv',
|
||||
'pseudo_huber',
|
||||
'psi',
|
||||
'radian',
|
||||
'rel_entr',
|
||||
'rgamma',
|
||||
'round',
|
||||
'shichi',
|
||||
'sici',
|
||||
'sindg',
|
||||
'smirnov',
|
||||
'smirnovi',
|
||||
'spence',
|
||||
'sph_harm',
|
||||
'stdtr',
|
||||
'stdtridf',
|
||||
'stdtrit',
|
||||
'struve',
|
||||
'tandg',
|
||||
'tklmbda',
|
||||
'voigt_profile',
|
||||
'wofz',
|
||||
'wright_bessel',
|
||||
'wrightomega',
|
||||
'xlog1py',
|
||||
'xlogy',
|
||||
'y0',
|
||||
'y1',
|
||||
'yn',
|
||||
'yv',
|
||||
'yve',
|
||||
'zetac'
|
||||
]
|
||||
|
||||
def geterr() -> dict[str, str]: ...
|
||||
def seterr(**kwargs: str) -> dict[str, str]: ...
|
||||
|
||||
class errstate:
|
||||
def __init__(self, **kargs: str) -> None: ...
|
||||
def __enter__(self) -> None: ...
|
||||
def __exit__(
|
||||
self,
|
||||
exc_type: Any, # Unused
|
||||
exc_value: Any, # Unused
|
||||
traceback: Any, # Unused
|
||||
) -> None: ...
|
||||
|
||||
_cosine_cdf: np.ufunc
|
||||
_cosine_invcdf: np.ufunc
|
||||
_cospi: np.ufunc
|
||||
_ellip_harm: np.ufunc
|
||||
_factorial: np.ufunc
|
||||
_igam_fac: np.ufunc
|
||||
_kolmogc: np.ufunc
|
||||
_kolmogci: np.ufunc
|
||||
_kolmogp: np.ufunc
|
||||
_lambertw: np.ufunc
|
||||
_lanczos_sum_expg_scaled: np.ufunc
|
||||
_lgam1p: np.ufunc
|
||||
_log1mexp: np.ufunc
|
||||
_log1pmx: np.ufunc
|
||||
_riemann_zeta: np.ufunc
|
||||
_scaled_exp1: np.ufunc
|
||||
_sf_error_test_function: np.ufunc
|
||||
_sinpi: np.ufunc
|
||||
_smirnovc: np.ufunc
|
||||
_smirnovci: np.ufunc
|
||||
_smirnovp: np.ufunc
|
||||
_spherical_in: np.ufunc
|
||||
_spherical_in_d: np.ufunc
|
||||
_spherical_jn: np.ufunc
|
||||
_spherical_jn_d: np.ufunc
|
||||
_spherical_kn: np.ufunc
|
||||
_spherical_kn_d: np.ufunc
|
||||
_spherical_yn: np.ufunc
|
||||
_spherical_yn_d: np.ufunc
|
||||
_stirling2_inexact: np.ufunc
|
||||
_struve_asymp_large_z: np.ufunc
|
||||
_struve_bessel_series: np.ufunc
|
||||
_struve_power_series: np.ufunc
|
||||
_zeta: np.ufunc
|
||||
agm: np.ufunc
|
||||
airy: np.ufunc
|
||||
airye: np.ufunc
|
||||
bdtr: np.ufunc
|
||||
bdtrc: np.ufunc
|
||||
bdtri: np.ufunc
|
||||
bdtrik: np.ufunc
|
||||
bdtrin: np.ufunc
|
||||
bei: np.ufunc
|
||||
beip: np.ufunc
|
||||
ber: np.ufunc
|
||||
berp: np.ufunc
|
||||
besselpoly: np.ufunc
|
||||
beta: np.ufunc
|
||||
betainc: np.ufunc
|
||||
betaincc: np.ufunc
|
||||
betainccinv: np.ufunc
|
||||
betaincinv: np.ufunc
|
||||
betaln: np.ufunc
|
||||
binom: np.ufunc
|
||||
boxcox1p: np.ufunc
|
||||
boxcox: np.ufunc
|
||||
btdtria: np.ufunc
|
||||
btdtrib: np.ufunc
|
||||
cbrt: np.ufunc
|
||||
chdtr: np.ufunc
|
||||
chdtrc: np.ufunc
|
||||
chdtri: np.ufunc
|
||||
chdtriv: np.ufunc
|
||||
chndtr: np.ufunc
|
||||
chndtridf: np.ufunc
|
||||
chndtrinc: np.ufunc
|
||||
chndtrix: np.ufunc
|
||||
cosdg: np.ufunc
|
||||
cosm1: np.ufunc
|
||||
cotdg: np.ufunc
|
||||
dawsn: np.ufunc
|
||||
ellipe: np.ufunc
|
||||
ellipeinc: np.ufunc
|
||||
ellipj: np.ufunc
|
||||
ellipk: np.ufunc
|
||||
ellipkinc: np.ufunc
|
||||
ellipkm1: np.ufunc
|
||||
elliprc: np.ufunc
|
||||
elliprd: np.ufunc
|
||||
elliprf: np.ufunc
|
||||
elliprg: np.ufunc
|
||||
elliprj: np.ufunc
|
||||
entr: np.ufunc
|
||||
erf: np.ufunc
|
||||
erfc: np.ufunc
|
||||
erfcinv: np.ufunc
|
||||
erfcx: np.ufunc
|
||||
erfi: np.ufunc
|
||||
erfinv: np.ufunc
|
||||
eval_chebyc: np.ufunc
|
||||
eval_chebys: np.ufunc
|
||||
eval_chebyt: np.ufunc
|
||||
eval_chebyu: np.ufunc
|
||||
eval_gegenbauer: np.ufunc
|
||||
eval_genlaguerre: np.ufunc
|
||||
eval_hermite: np.ufunc
|
||||
eval_hermitenorm: np.ufunc
|
||||
eval_jacobi: np.ufunc
|
||||
eval_laguerre: np.ufunc
|
||||
eval_legendre: np.ufunc
|
||||
eval_sh_chebyt: np.ufunc
|
||||
eval_sh_chebyu: np.ufunc
|
||||
eval_sh_jacobi: np.ufunc
|
||||
eval_sh_legendre: np.ufunc
|
||||
exp10: np.ufunc
|
||||
exp1: np.ufunc
|
||||
exp2: np.ufunc
|
||||
expi: np.ufunc
|
||||
expit: np.ufunc
|
||||
expm1: np.ufunc
|
||||
expn: np.ufunc
|
||||
exprel: np.ufunc
|
||||
fdtr: np.ufunc
|
||||
fdtrc: np.ufunc
|
||||
fdtri: np.ufunc
|
||||
fdtridfd: np.ufunc
|
||||
fresnel: np.ufunc
|
||||
gamma: np.ufunc
|
||||
gammainc: np.ufunc
|
||||
gammaincc: np.ufunc
|
||||
gammainccinv: np.ufunc
|
||||
gammaincinv: np.ufunc
|
||||
gammaln: np.ufunc
|
||||
gammasgn: np.ufunc
|
||||
gdtr: np.ufunc
|
||||
gdtrc: np.ufunc
|
||||
gdtria: np.ufunc
|
||||
gdtrib: np.ufunc
|
||||
gdtrix: np.ufunc
|
||||
hankel1: np.ufunc
|
||||
hankel1e: np.ufunc
|
||||
hankel2: np.ufunc
|
||||
hankel2e: np.ufunc
|
||||
huber: np.ufunc
|
||||
hyp0f1: np.ufunc
|
||||
hyp1f1: np.ufunc
|
||||
hyp2f1: np.ufunc
|
||||
hyperu: np.ufunc
|
||||
i0: np.ufunc
|
||||
i0e: np.ufunc
|
||||
i1: np.ufunc
|
||||
i1e: np.ufunc
|
||||
inv_boxcox1p: np.ufunc
|
||||
inv_boxcox: np.ufunc
|
||||
it2i0k0: np.ufunc
|
||||
it2j0y0: np.ufunc
|
||||
it2struve0: np.ufunc
|
||||
itairy: np.ufunc
|
||||
iti0k0: np.ufunc
|
||||
itj0y0: np.ufunc
|
||||
itmodstruve0: np.ufunc
|
||||
itstruve0: np.ufunc
|
||||
iv: np.ufunc
|
||||
ive: np.ufunc
|
||||
j0: np.ufunc
|
||||
j1: np.ufunc
|
||||
jn: np.ufunc
|
||||
jv: np.ufunc
|
||||
jve: np.ufunc
|
||||
k0: np.ufunc
|
||||
k0e: np.ufunc
|
||||
k1: np.ufunc
|
||||
k1e: np.ufunc
|
||||
kei: np.ufunc
|
||||
keip: np.ufunc
|
||||
kelvin: np.ufunc
|
||||
ker: np.ufunc
|
||||
kerp: np.ufunc
|
||||
kl_div: np.ufunc
|
||||
kn: np.ufunc
|
||||
kolmogi: np.ufunc
|
||||
kolmogorov: np.ufunc
|
||||
kv: np.ufunc
|
||||
kve: np.ufunc
|
||||
log1p: np.ufunc
|
||||
log_expit: np.ufunc
|
||||
log_ndtr: np.ufunc
|
||||
log_wright_bessel: np.ufunc
|
||||
loggamma: np.ufunc
|
||||
logit: np.ufunc
|
||||
lpmv: np.ufunc
|
||||
mathieu_a: np.ufunc
|
||||
mathieu_b: np.ufunc
|
||||
mathieu_cem: np.ufunc
|
||||
mathieu_modcem1: np.ufunc
|
||||
mathieu_modcem2: np.ufunc
|
||||
mathieu_modsem1: np.ufunc
|
||||
mathieu_modsem2: np.ufunc
|
||||
mathieu_sem: np.ufunc
|
||||
modfresnelm: np.ufunc
|
||||
modfresnelp: np.ufunc
|
||||
modstruve: np.ufunc
|
||||
nbdtr: np.ufunc
|
||||
nbdtrc: np.ufunc
|
||||
nbdtri: np.ufunc
|
||||
nbdtrik: np.ufunc
|
||||
nbdtrin: np.ufunc
|
||||
ncfdtr: np.ufunc
|
||||
ncfdtri: np.ufunc
|
||||
ncfdtridfd: np.ufunc
|
||||
ncfdtridfn: np.ufunc
|
||||
ncfdtrinc: np.ufunc
|
||||
nctdtr: np.ufunc
|
||||
nctdtridf: np.ufunc
|
||||
nctdtrinc: np.ufunc
|
||||
nctdtrit: np.ufunc
|
||||
ndtr: np.ufunc
|
||||
ndtri: np.ufunc
|
||||
ndtri_exp: np.ufunc
|
||||
nrdtrimn: np.ufunc
|
||||
nrdtrisd: np.ufunc
|
||||
obl_ang1: np.ufunc
|
||||
obl_ang1_cv: np.ufunc
|
||||
obl_cv: np.ufunc
|
||||
obl_rad1: np.ufunc
|
||||
obl_rad1_cv: np.ufunc
|
||||
obl_rad2: np.ufunc
|
||||
obl_rad2_cv: np.ufunc
|
||||
owens_t: np.ufunc
|
||||
pbdv: np.ufunc
|
||||
pbvv: np.ufunc
|
||||
pbwa: np.ufunc
|
||||
pdtr: np.ufunc
|
||||
pdtrc: np.ufunc
|
||||
pdtri: np.ufunc
|
||||
pdtrik: np.ufunc
|
||||
poch: np.ufunc
|
||||
powm1: np.ufunc
|
||||
pro_ang1: np.ufunc
|
||||
pro_ang1_cv: np.ufunc
|
||||
pro_cv: np.ufunc
|
||||
pro_rad1: np.ufunc
|
||||
pro_rad1_cv: np.ufunc
|
||||
pro_rad2: np.ufunc
|
||||
pro_rad2_cv: np.ufunc
|
||||
pseudo_huber: np.ufunc
|
||||
psi: np.ufunc
|
||||
radian: np.ufunc
|
||||
rel_entr: np.ufunc
|
||||
rgamma: np.ufunc
|
||||
round: np.ufunc
|
||||
shichi: np.ufunc
|
||||
sici: np.ufunc
|
||||
sindg: np.ufunc
|
||||
smirnov: np.ufunc
|
||||
smirnovi: np.ufunc
|
||||
spence: np.ufunc
|
||||
sph_harm: np.ufunc
|
||||
stdtr: np.ufunc
|
||||
stdtridf: np.ufunc
|
||||
stdtrit: np.ufunc
|
||||
struve: np.ufunc
|
||||
tandg: np.ufunc
|
||||
tklmbda: np.ufunc
|
||||
voigt_profile: np.ufunc
|
||||
wofz: np.ufunc
|
||||
wright_bessel: np.ufunc
|
||||
wrightomega: np.ufunc
|
||||
xlog1py: np.ufunc
|
||||
xlogy: np.ufunc
|
||||
y0: np.ufunc
|
||||
y1: np.ufunc
|
||||
yn: np.ufunc
|
||||
yv: np.ufunc
|
||||
yve: np.ufunc
|
||||
zetac: np.ufunc
|
||||
|
||||
13173
venv/lib/python3.13/site-packages/scipy/special/_ufuncs.pyx
Normal file
13173
venv/lib/python3.13/site-packages/scipy/special/_ufuncs.pyx
Normal file
File diff suppressed because it is too large
Load diff
Binary file not shown.
142
venv/lib/python3.13/site-packages/scipy/special/_ufuncs_cxx.pxd
Normal file
142
venv/lib/python3.13/site-packages/scipy/special/_ufuncs_cxx.pxd
Normal file
|
|
@ -0,0 +1,142 @@
|
|||
from . cimport sf_error
|
||||
cdef void _set_action(sf_error.sf_error_t, sf_error.sf_action_t) noexcept nogil
|
||||
cdef void *_export_beta_pdf_float
|
||||
cdef void *_export_beta_pdf_double
|
||||
cdef void *_export_beta_ppf_float
|
||||
cdef void *_export_beta_ppf_double
|
||||
cdef void *_export_binom_cdf_float
|
||||
cdef void *_export_binom_cdf_double
|
||||
cdef void *_export_binom_isf_float
|
||||
cdef void *_export_binom_isf_double
|
||||
cdef void *_export_binom_pmf_float
|
||||
cdef void *_export_binom_pmf_double
|
||||
cdef void *_export_binom_ppf_float
|
||||
cdef void *_export_binom_ppf_double
|
||||
cdef void *_export_binom_sf_float
|
||||
cdef void *_export_binom_sf_double
|
||||
cdef void *_export_cauchy_isf_float
|
||||
cdef void *_export_cauchy_isf_double
|
||||
cdef void *_export_cauchy_ppf_float
|
||||
cdef void *_export_cauchy_ppf_double
|
||||
cdef void *_export_hypergeom_cdf_float
|
||||
cdef void *_export_hypergeom_cdf_double
|
||||
cdef void *_export_hypergeom_mean_float
|
||||
cdef void *_export_hypergeom_mean_double
|
||||
cdef void *_export_hypergeom_pmf_float
|
||||
cdef void *_export_hypergeom_pmf_double
|
||||
cdef void *_export_hypergeom_sf_float
|
||||
cdef void *_export_hypergeom_sf_double
|
||||
cdef void *_export_hypergeom_skewness_float
|
||||
cdef void *_export_hypergeom_skewness_double
|
||||
cdef void *_export_hypergeom_variance_float
|
||||
cdef void *_export_hypergeom_variance_double
|
||||
cdef void *_export_invgauss_isf_float
|
||||
cdef void *_export_invgauss_isf_double
|
||||
cdef void *_export_invgauss_ppf_float
|
||||
cdef void *_export_invgauss_ppf_double
|
||||
cdef void *_export_landau_cdf_float
|
||||
cdef void *_export_landau_cdf_double
|
||||
cdef void *_export_landau_isf_float
|
||||
cdef void *_export_landau_isf_double
|
||||
cdef void *_export_landau_pdf_float
|
||||
cdef void *_export_landau_pdf_double
|
||||
cdef void *_export_landau_ppf_float
|
||||
cdef void *_export_landau_ppf_double
|
||||
cdef void *_export_landau_sf_float
|
||||
cdef void *_export_landau_sf_double
|
||||
cdef void *_export_nbinom_cdf_float
|
||||
cdef void *_export_nbinom_cdf_double
|
||||
cdef void *_export_nbinom_isf_float
|
||||
cdef void *_export_nbinom_isf_double
|
||||
cdef void *_export_nbinom_kurtosis_excess_float
|
||||
cdef void *_export_nbinom_kurtosis_excess_double
|
||||
cdef void *_export_nbinom_mean_float
|
||||
cdef void *_export_nbinom_mean_double
|
||||
cdef void *_export_nbinom_pmf_float
|
||||
cdef void *_export_nbinom_pmf_double
|
||||
cdef void *_export_nbinom_ppf_float
|
||||
cdef void *_export_nbinom_ppf_double
|
||||
cdef void *_export_nbinom_sf_float
|
||||
cdef void *_export_nbinom_sf_double
|
||||
cdef void *_export_nbinom_skewness_float
|
||||
cdef void *_export_nbinom_skewness_double
|
||||
cdef void *_export_nbinom_variance_float
|
||||
cdef void *_export_nbinom_variance_double
|
||||
cdef void *_export_ncf_isf_float
|
||||
cdef void *_export_ncf_isf_double
|
||||
cdef void *_export_ncf_kurtosis_excess_float
|
||||
cdef void *_export_ncf_kurtosis_excess_double
|
||||
cdef void *_export_ncf_mean_float
|
||||
cdef void *_export_ncf_mean_double
|
||||
cdef void *_export_ncf_pdf_float
|
||||
cdef void *_export_ncf_pdf_double
|
||||
cdef void *_export_ncf_sf_float
|
||||
cdef void *_export_ncf_sf_double
|
||||
cdef void *_export_ncf_skewness_float
|
||||
cdef void *_export_ncf_skewness_double
|
||||
cdef void *_export_ncf_variance_float
|
||||
cdef void *_export_ncf_variance_double
|
||||
cdef void *_export_nct_isf_float
|
||||
cdef void *_export_nct_isf_double
|
||||
cdef void *_export_nct_kurtosis_excess_float
|
||||
cdef void *_export_nct_kurtosis_excess_double
|
||||
cdef void *_export_nct_mean_float
|
||||
cdef void *_export_nct_mean_double
|
||||
cdef void *_export_nct_pdf_float
|
||||
cdef void *_export_nct_pdf_double
|
||||
cdef void *_export_nct_sf_float
|
||||
cdef void *_export_nct_sf_double
|
||||
cdef void *_export_nct_skewness_float
|
||||
cdef void *_export_nct_skewness_double
|
||||
cdef void *_export_nct_variance_float
|
||||
cdef void *_export_nct_variance_double
|
||||
cdef void *_export_ncx2_cdf_float
|
||||
cdef void *_export_ncx2_cdf_double
|
||||
cdef void *_export_ncx2_isf_float
|
||||
cdef void *_export_ncx2_isf_double
|
||||
cdef void *_export_ncx2_pdf_float
|
||||
cdef void *_export_ncx2_pdf_double
|
||||
cdef void *_export_ncx2_ppf_float
|
||||
cdef void *_export_ncx2_ppf_double
|
||||
cdef void *_export_ncx2_sf_float
|
||||
cdef void *_export_ncx2_sf_double
|
||||
cdef void *_export_skewnorm_cdf_float
|
||||
cdef void *_export_skewnorm_cdf_double
|
||||
cdef void *_export_skewnorm_isf_float
|
||||
cdef void *_export_skewnorm_isf_double
|
||||
cdef void *_export_skewnorm_ppf_float
|
||||
cdef void *_export_skewnorm_ppf_double
|
||||
cdef void *_export__stirling2_inexact
|
||||
cdef void *_export_ibeta_float
|
||||
cdef void *_export_ibeta_double
|
||||
cdef void *_export_ibetac_float
|
||||
cdef void *_export_ibetac_double
|
||||
cdef void *_export_ibetac_inv_float
|
||||
cdef void *_export_ibetac_inv_double
|
||||
cdef void *_export_ibeta_inv_float
|
||||
cdef void *_export_ibeta_inv_double
|
||||
cdef void *_export_fellint_RC
|
||||
cdef void *_export_cellint_RC
|
||||
cdef void *_export_fellint_RD
|
||||
cdef void *_export_cellint_RD
|
||||
cdef void *_export_fellint_RF
|
||||
cdef void *_export_cellint_RF
|
||||
cdef void *_export_fellint_RG
|
||||
cdef void *_export_cellint_RG
|
||||
cdef void *_export_fellint_RJ
|
||||
cdef void *_export_cellint_RJ
|
||||
cdef void *_export_erfinv_float
|
||||
cdef void *_export_erfinv_double
|
||||
cdef void *_export_hyp1f1_double
|
||||
cdef void *_export_ncf_cdf_float
|
||||
cdef void *_export_ncf_cdf_double
|
||||
cdef void *_export_ncf_ppf_float
|
||||
cdef void *_export_ncf_ppf_double
|
||||
cdef void *_export_nct_cdf_float
|
||||
cdef void *_export_nct_cdf_double
|
||||
cdef void *_export_nct_ppf_float
|
||||
cdef void *_export_nct_ppf_double
|
||||
cdef void *_export_powm1_float
|
||||
cdef void *_export_powm1_double
|
||||
cdef void *_export_wrightomega
|
||||
cdef void *_export_wrightomega_real
|
||||
427
venv/lib/python3.13/site-packages/scipy/special/_ufuncs_cxx.pyx
Normal file
427
venv/lib/python3.13/site-packages/scipy/special/_ufuncs_cxx.pyx
Normal file
|
|
@ -0,0 +1,427 @@
|
|||
# This file is automatically generated by _generate_pyx.py.
|
||||
# Do not edit manually!
|
||||
|
||||
from libc.math cimport NAN
|
||||
|
||||
include "_ufuncs_extra_code_common.pxi"
|
||||
|
||||
cdef extern from r"_ufuncs_cxx_defs.h":
|
||||
cdef float _func_beta_pdf_float "beta_pdf_float"(float, float, float) noexcept nogil
|
||||
cdef void *_export_beta_pdf_float = <void*>_func_beta_pdf_float
|
||||
cdef extern from r"_ufuncs_cxx_defs.h":
|
||||
cdef double _func_beta_pdf_double "beta_pdf_double"(double, double, double) noexcept nogil
|
||||
cdef void *_export_beta_pdf_double = <void*>_func_beta_pdf_double
|
||||
cdef extern from r"_ufuncs_cxx_defs.h":
|
||||
cdef float _func_beta_ppf_float "beta_ppf_float"(float, float, float) noexcept nogil
|
||||
cdef void *_export_beta_ppf_float = <void*>_func_beta_ppf_float
|
||||
cdef extern from r"_ufuncs_cxx_defs.h":
|
||||
cdef double _func_beta_ppf_double "beta_ppf_double"(double, double, double) noexcept nogil
|
||||
cdef void *_export_beta_ppf_double = <void*>_func_beta_ppf_double
|
||||
cdef extern from r"_ufuncs_cxx_defs.h":
|
||||
cdef float _func_binom_cdf_float "binom_cdf_float"(float, float, float) noexcept nogil
|
||||
cdef void *_export_binom_cdf_float = <void*>_func_binom_cdf_float
|
||||
cdef extern from r"_ufuncs_cxx_defs.h":
|
||||
cdef double _func_binom_cdf_double "binom_cdf_double"(double, double, double) noexcept nogil
|
||||
cdef void *_export_binom_cdf_double = <void*>_func_binom_cdf_double
|
||||
cdef extern from r"_ufuncs_cxx_defs.h":
|
||||
cdef float _func_binom_isf_float "binom_isf_float"(float, float, float) noexcept nogil
|
||||
cdef void *_export_binom_isf_float = <void*>_func_binom_isf_float
|
||||
cdef extern from r"_ufuncs_cxx_defs.h":
|
||||
cdef double _func_binom_isf_double "binom_isf_double"(double, double, double) noexcept nogil
|
||||
cdef void *_export_binom_isf_double = <void*>_func_binom_isf_double
|
||||
cdef extern from r"_ufuncs_cxx_defs.h":
|
||||
cdef float _func_binom_pmf_float "binom_pmf_float"(float, float, float) noexcept nogil
|
||||
cdef void *_export_binom_pmf_float = <void*>_func_binom_pmf_float
|
||||
cdef extern from r"_ufuncs_cxx_defs.h":
|
||||
cdef double _func_binom_pmf_double "binom_pmf_double"(double, double, double) noexcept nogil
|
||||
cdef void *_export_binom_pmf_double = <void*>_func_binom_pmf_double
|
||||
cdef extern from r"_ufuncs_cxx_defs.h":
|
||||
cdef float _func_binom_ppf_float "binom_ppf_float"(float, float, float) noexcept nogil
|
||||
cdef void *_export_binom_ppf_float = <void*>_func_binom_ppf_float
|
||||
cdef extern from r"_ufuncs_cxx_defs.h":
|
||||
cdef double _func_binom_ppf_double "binom_ppf_double"(double, double, double) noexcept nogil
|
||||
cdef void *_export_binom_ppf_double = <void*>_func_binom_ppf_double
|
||||
cdef extern from r"_ufuncs_cxx_defs.h":
|
||||
cdef float _func_binom_sf_float "binom_sf_float"(float, float, float) noexcept nogil
|
||||
cdef void *_export_binom_sf_float = <void*>_func_binom_sf_float
|
||||
cdef extern from r"_ufuncs_cxx_defs.h":
|
||||
cdef double _func_binom_sf_double "binom_sf_double"(double, double, double) noexcept nogil
|
||||
cdef void *_export_binom_sf_double = <void*>_func_binom_sf_double
|
||||
cdef extern from r"_ufuncs_cxx_defs.h":
|
||||
cdef float _func_cauchy_isf_float "cauchy_isf_float"(float, float, float) noexcept nogil
|
||||
cdef void *_export_cauchy_isf_float = <void*>_func_cauchy_isf_float
|
||||
cdef extern from r"_ufuncs_cxx_defs.h":
|
||||
cdef double _func_cauchy_isf_double "cauchy_isf_double"(double, double, double) noexcept nogil
|
||||
cdef void *_export_cauchy_isf_double = <void*>_func_cauchy_isf_double
|
||||
cdef extern from r"_ufuncs_cxx_defs.h":
|
||||
cdef float _func_cauchy_ppf_float "cauchy_ppf_float"(float, float, float) noexcept nogil
|
||||
cdef void *_export_cauchy_ppf_float = <void*>_func_cauchy_ppf_float
|
||||
cdef extern from r"_ufuncs_cxx_defs.h":
|
||||
cdef double _func_cauchy_ppf_double "cauchy_ppf_double"(double, double, double) noexcept nogil
|
||||
cdef void *_export_cauchy_ppf_double = <void*>_func_cauchy_ppf_double
|
||||
cdef extern from r"_ufuncs_cxx_defs.h":
|
||||
cdef float _func_hypergeom_cdf_float "hypergeom_cdf_float"(float, float, float, float) noexcept nogil
|
||||
cdef void *_export_hypergeom_cdf_float = <void*>_func_hypergeom_cdf_float
|
||||
cdef extern from r"_ufuncs_cxx_defs.h":
|
||||
cdef double _func_hypergeom_cdf_double "hypergeom_cdf_double"(double, double, double, double) noexcept nogil
|
||||
cdef void *_export_hypergeom_cdf_double = <void*>_func_hypergeom_cdf_double
|
||||
cdef extern from r"_ufuncs_cxx_defs.h":
|
||||
cdef float _func_hypergeom_mean_float "hypergeom_mean_float"(float, float, float) noexcept nogil
|
||||
cdef void *_export_hypergeom_mean_float = <void*>_func_hypergeom_mean_float
|
||||
cdef extern from r"_ufuncs_cxx_defs.h":
|
||||
cdef double _func_hypergeom_mean_double "hypergeom_mean_double"(double, double, double) noexcept nogil
|
||||
cdef void *_export_hypergeom_mean_double = <void*>_func_hypergeom_mean_double
|
||||
cdef extern from r"_ufuncs_cxx_defs.h":
|
||||
cdef float _func_hypergeom_pmf_float "hypergeom_pmf_float"(float, float, float, float) noexcept nogil
|
||||
cdef void *_export_hypergeom_pmf_float = <void*>_func_hypergeom_pmf_float
|
||||
cdef extern from r"_ufuncs_cxx_defs.h":
|
||||
cdef double _func_hypergeom_pmf_double "hypergeom_pmf_double"(double, double, double, double) noexcept nogil
|
||||
cdef void *_export_hypergeom_pmf_double = <void*>_func_hypergeom_pmf_double
|
||||
cdef extern from r"_ufuncs_cxx_defs.h":
|
||||
cdef float _func_hypergeom_sf_float "hypergeom_sf_float"(float, float, float, float) noexcept nogil
|
||||
cdef void *_export_hypergeom_sf_float = <void*>_func_hypergeom_sf_float
|
||||
cdef extern from r"_ufuncs_cxx_defs.h":
|
||||
cdef double _func_hypergeom_sf_double "hypergeom_sf_double"(double, double, double, double) noexcept nogil
|
||||
cdef void *_export_hypergeom_sf_double = <void*>_func_hypergeom_sf_double
|
||||
cdef extern from r"_ufuncs_cxx_defs.h":
|
||||
cdef float _func_hypergeom_skewness_float "hypergeom_skewness_float"(float, float, float) noexcept nogil
|
||||
cdef void *_export_hypergeom_skewness_float = <void*>_func_hypergeom_skewness_float
|
||||
cdef extern from r"_ufuncs_cxx_defs.h":
|
||||
cdef double _func_hypergeom_skewness_double "hypergeom_skewness_double"(double, double, double) noexcept nogil
|
||||
cdef void *_export_hypergeom_skewness_double = <void*>_func_hypergeom_skewness_double
|
||||
cdef extern from r"_ufuncs_cxx_defs.h":
|
||||
cdef float _func_hypergeom_variance_float "hypergeom_variance_float"(float, float, float) noexcept nogil
|
||||
cdef void *_export_hypergeom_variance_float = <void*>_func_hypergeom_variance_float
|
||||
cdef extern from r"_ufuncs_cxx_defs.h":
|
||||
cdef double _func_hypergeom_variance_double "hypergeom_variance_double"(double, double, double) noexcept nogil
|
||||
cdef void *_export_hypergeom_variance_double = <void*>_func_hypergeom_variance_double
|
||||
cdef extern from r"_ufuncs_cxx_defs.h":
|
||||
cdef float _func_invgauss_isf_float "invgauss_isf_float"(float, float, float) noexcept nogil
|
||||
cdef void *_export_invgauss_isf_float = <void*>_func_invgauss_isf_float
|
||||
cdef extern from r"_ufuncs_cxx_defs.h":
|
||||
cdef double _func_invgauss_isf_double "invgauss_isf_double"(double, double, double) noexcept nogil
|
||||
cdef void *_export_invgauss_isf_double = <void*>_func_invgauss_isf_double
|
||||
cdef extern from r"_ufuncs_cxx_defs.h":
|
||||
cdef float _func_invgauss_ppf_float "invgauss_ppf_float"(float, float, float) noexcept nogil
|
||||
cdef void *_export_invgauss_ppf_float = <void*>_func_invgauss_ppf_float
|
||||
cdef extern from r"_ufuncs_cxx_defs.h":
|
||||
cdef double _func_invgauss_ppf_double "invgauss_ppf_double"(double, double, double) noexcept nogil
|
||||
cdef void *_export_invgauss_ppf_double = <void*>_func_invgauss_ppf_double
|
||||
cdef extern from r"_ufuncs_cxx_defs.h":
|
||||
cdef float _func_landau_cdf_float "landau_cdf_float"(float, float, float) noexcept nogil
|
||||
cdef void *_export_landau_cdf_float = <void*>_func_landau_cdf_float
|
||||
cdef extern from r"_ufuncs_cxx_defs.h":
|
||||
cdef double _func_landau_cdf_double "landau_cdf_double"(double, double, double) noexcept nogil
|
||||
cdef void *_export_landau_cdf_double = <void*>_func_landau_cdf_double
|
||||
cdef extern from r"_ufuncs_cxx_defs.h":
|
||||
cdef float _func_landau_isf_float "landau_isf_float"(float, float, float) noexcept nogil
|
||||
cdef void *_export_landau_isf_float = <void*>_func_landau_isf_float
|
||||
cdef extern from r"_ufuncs_cxx_defs.h":
|
||||
cdef double _func_landau_isf_double "landau_isf_double"(double, double, double) noexcept nogil
|
||||
cdef void *_export_landau_isf_double = <void*>_func_landau_isf_double
|
||||
cdef extern from r"_ufuncs_cxx_defs.h":
|
||||
cdef float _func_landau_pdf_float "landau_pdf_float"(float, float, float) noexcept nogil
|
||||
cdef void *_export_landau_pdf_float = <void*>_func_landau_pdf_float
|
||||
cdef extern from r"_ufuncs_cxx_defs.h":
|
||||
cdef double _func_landau_pdf_double "landau_pdf_double"(double, double, double) noexcept nogil
|
||||
cdef void *_export_landau_pdf_double = <void*>_func_landau_pdf_double
|
||||
cdef extern from r"_ufuncs_cxx_defs.h":
|
||||
cdef float _func_landau_ppf_float "landau_ppf_float"(float, float, float) noexcept nogil
|
||||
cdef void *_export_landau_ppf_float = <void*>_func_landau_ppf_float
|
||||
cdef extern from r"_ufuncs_cxx_defs.h":
|
||||
cdef double _func_landau_ppf_double "landau_ppf_double"(double, double, double) noexcept nogil
|
||||
cdef void *_export_landau_ppf_double = <void*>_func_landau_ppf_double
|
||||
cdef extern from r"_ufuncs_cxx_defs.h":
|
||||
cdef float _func_landau_sf_float "landau_sf_float"(float, float, float) noexcept nogil
|
||||
cdef void *_export_landau_sf_float = <void*>_func_landau_sf_float
|
||||
cdef extern from r"_ufuncs_cxx_defs.h":
|
||||
cdef double _func_landau_sf_double "landau_sf_double"(double, double, double) noexcept nogil
|
||||
cdef void *_export_landau_sf_double = <void*>_func_landau_sf_double
|
||||
cdef extern from r"_ufuncs_cxx_defs.h":
|
||||
cdef float _func_nbinom_cdf_float "nbinom_cdf_float"(float, float, float) noexcept nogil
|
||||
cdef void *_export_nbinom_cdf_float = <void*>_func_nbinom_cdf_float
|
||||
cdef extern from r"_ufuncs_cxx_defs.h":
|
||||
cdef double _func_nbinom_cdf_double "nbinom_cdf_double"(double, double, double) noexcept nogil
|
||||
cdef void *_export_nbinom_cdf_double = <void*>_func_nbinom_cdf_double
|
||||
cdef extern from r"_ufuncs_cxx_defs.h":
|
||||
cdef float _func_nbinom_isf_float "nbinom_isf_float"(float, float, float) noexcept nogil
|
||||
cdef void *_export_nbinom_isf_float = <void*>_func_nbinom_isf_float
|
||||
cdef extern from r"_ufuncs_cxx_defs.h":
|
||||
cdef double _func_nbinom_isf_double "nbinom_isf_double"(double, double, double) noexcept nogil
|
||||
cdef void *_export_nbinom_isf_double = <void*>_func_nbinom_isf_double
|
||||
cdef extern from r"_ufuncs_cxx_defs.h":
|
||||
cdef float _func_nbinom_kurtosis_excess_float "nbinom_kurtosis_excess_float"(float, float) noexcept nogil
|
||||
cdef void *_export_nbinom_kurtosis_excess_float = <void*>_func_nbinom_kurtosis_excess_float
|
||||
cdef extern from r"_ufuncs_cxx_defs.h":
|
||||
cdef double _func_nbinom_kurtosis_excess_double "nbinom_kurtosis_excess_double"(double, double) noexcept nogil
|
||||
cdef void *_export_nbinom_kurtosis_excess_double = <void*>_func_nbinom_kurtosis_excess_double
|
||||
cdef extern from r"_ufuncs_cxx_defs.h":
|
||||
cdef float _func_nbinom_mean_float "nbinom_mean_float"(float, float) noexcept nogil
|
||||
cdef void *_export_nbinom_mean_float = <void*>_func_nbinom_mean_float
|
||||
cdef extern from r"_ufuncs_cxx_defs.h":
|
||||
cdef double _func_nbinom_mean_double "nbinom_mean_double"(double, double) noexcept nogil
|
||||
cdef void *_export_nbinom_mean_double = <void*>_func_nbinom_mean_double
|
||||
cdef extern from r"_ufuncs_cxx_defs.h":
|
||||
cdef float _func_nbinom_pmf_float "nbinom_pmf_float"(float, float, float) noexcept nogil
|
||||
cdef void *_export_nbinom_pmf_float = <void*>_func_nbinom_pmf_float
|
||||
cdef extern from r"_ufuncs_cxx_defs.h":
|
||||
cdef double _func_nbinom_pmf_double "nbinom_pmf_double"(double, double, double) noexcept nogil
|
||||
cdef void *_export_nbinom_pmf_double = <void*>_func_nbinom_pmf_double
|
||||
cdef extern from r"_ufuncs_cxx_defs.h":
|
||||
cdef float _func_nbinom_ppf_float "nbinom_ppf_float"(float, float, float) noexcept nogil
|
||||
cdef void *_export_nbinom_ppf_float = <void*>_func_nbinom_ppf_float
|
||||
cdef extern from r"_ufuncs_cxx_defs.h":
|
||||
cdef double _func_nbinom_ppf_double "nbinom_ppf_double"(double, double, double) noexcept nogil
|
||||
cdef void *_export_nbinom_ppf_double = <void*>_func_nbinom_ppf_double
|
||||
cdef extern from r"_ufuncs_cxx_defs.h":
|
||||
cdef float _func_nbinom_sf_float "nbinom_sf_float"(float, float, float) noexcept nogil
|
||||
cdef void *_export_nbinom_sf_float = <void*>_func_nbinom_sf_float
|
||||
cdef extern from r"_ufuncs_cxx_defs.h":
|
||||
cdef double _func_nbinom_sf_double "nbinom_sf_double"(double, double, double) noexcept nogil
|
||||
cdef void *_export_nbinom_sf_double = <void*>_func_nbinom_sf_double
|
||||
cdef extern from r"_ufuncs_cxx_defs.h":
|
||||
cdef float _func_nbinom_skewness_float "nbinom_skewness_float"(float, float) noexcept nogil
|
||||
cdef void *_export_nbinom_skewness_float = <void*>_func_nbinom_skewness_float
|
||||
cdef extern from r"_ufuncs_cxx_defs.h":
|
||||
cdef double _func_nbinom_skewness_double "nbinom_skewness_double"(double, double) noexcept nogil
|
||||
cdef void *_export_nbinom_skewness_double = <void*>_func_nbinom_skewness_double
|
||||
cdef extern from r"_ufuncs_cxx_defs.h":
|
||||
cdef float _func_nbinom_variance_float "nbinom_variance_float"(float, float) noexcept nogil
|
||||
cdef void *_export_nbinom_variance_float = <void*>_func_nbinom_variance_float
|
||||
cdef extern from r"_ufuncs_cxx_defs.h":
|
||||
cdef double _func_nbinom_variance_double "nbinom_variance_double"(double, double) noexcept nogil
|
||||
cdef void *_export_nbinom_variance_double = <void*>_func_nbinom_variance_double
|
||||
cdef extern from r"_ufuncs_cxx_defs.h":
|
||||
cdef float _func_ncf_isf_float "ncf_isf_float"(float, float, float, float) noexcept nogil
|
||||
cdef void *_export_ncf_isf_float = <void*>_func_ncf_isf_float
|
||||
cdef extern from r"_ufuncs_cxx_defs.h":
|
||||
cdef double _func_ncf_isf_double "ncf_isf_double"(double, double, double, double) noexcept nogil
|
||||
cdef void *_export_ncf_isf_double = <void*>_func_ncf_isf_double
|
||||
cdef extern from r"_ufuncs_cxx_defs.h":
|
||||
cdef float _func_ncf_kurtosis_excess_float "ncf_kurtosis_excess_float"(float, float, float) noexcept nogil
|
||||
cdef void *_export_ncf_kurtosis_excess_float = <void*>_func_ncf_kurtosis_excess_float
|
||||
cdef extern from r"_ufuncs_cxx_defs.h":
|
||||
cdef double _func_ncf_kurtosis_excess_double "ncf_kurtosis_excess_double"(double, double, double) noexcept nogil
|
||||
cdef void *_export_ncf_kurtosis_excess_double = <void*>_func_ncf_kurtosis_excess_double
|
||||
cdef extern from r"_ufuncs_cxx_defs.h":
|
||||
cdef float _func_ncf_mean_float "ncf_mean_float"(float, float, float) noexcept nogil
|
||||
cdef void *_export_ncf_mean_float = <void*>_func_ncf_mean_float
|
||||
cdef extern from r"_ufuncs_cxx_defs.h":
|
||||
cdef double _func_ncf_mean_double "ncf_mean_double"(double, double, double) noexcept nogil
|
||||
cdef void *_export_ncf_mean_double = <void*>_func_ncf_mean_double
|
||||
cdef extern from r"_ufuncs_cxx_defs.h":
|
||||
cdef float _func_ncf_pdf_float "ncf_pdf_float"(float, float, float, float) noexcept nogil
|
||||
cdef void *_export_ncf_pdf_float = <void*>_func_ncf_pdf_float
|
||||
cdef extern from r"_ufuncs_cxx_defs.h":
|
||||
cdef double _func_ncf_pdf_double "ncf_pdf_double"(double, double, double, double) noexcept nogil
|
||||
cdef void *_export_ncf_pdf_double = <void*>_func_ncf_pdf_double
|
||||
cdef extern from r"_ufuncs_cxx_defs.h":
|
||||
cdef float _func_ncf_sf_float "ncf_sf_float"(float, float, float, float) noexcept nogil
|
||||
cdef void *_export_ncf_sf_float = <void*>_func_ncf_sf_float
|
||||
cdef extern from r"_ufuncs_cxx_defs.h":
|
||||
cdef double _func_ncf_sf_double "ncf_sf_double"(double, double, double, double) noexcept nogil
|
||||
cdef void *_export_ncf_sf_double = <void*>_func_ncf_sf_double
|
||||
cdef extern from r"_ufuncs_cxx_defs.h":
|
||||
cdef float _func_ncf_skewness_float "ncf_skewness_float"(float, float, float) noexcept nogil
|
||||
cdef void *_export_ncf_skewness_float = <void*>_func_ncf_skewness_float
|
||||
cdef extern from r"_ufuncs_cxx_defs.h":
|
||||
cdef double _func_ncf_skewness_double "ncf_skewness_double"(double, double, double) noexcept nogil
|
||||
cdef void *_export_ncf_skewness_double = <void*>_func_ncf_skewness_double
|
||||
cdef extern from r"_ufuncs_cxx_defs.h":
|
||||
cdef float _func_ncf_variance_float "ncf_variance_float"(float, float, float) noexcept nogil
|
||||
cdef void *_export_ncf_variance_float = <void*>_func_ncf_variance_float
|
||||
cdef extern from r"_ufuncs_cxx_defs.h":
|
||||
cdef double _func_ncf_variance_double "ncf_variance_double"(double, double, double) noexcept nogil
|
||||
cdef void *_export_ncf_variance_double = <void*>_func_ncf_variance_double
|
||||
cdef extern from r"_ufuncs_cxx_defs.h":
|
||||
cdef float _func_nct_isf_float "nct_isf_float"(float, float, float) noexcept nogil
|
||||
cdef void *_export_nct_isf_float = <void*>_func_nct_isf_float
|
||||
cdef extern from r"_ufuncs_cxx_defs.h":
|
||||
cdef double _func_nct_isf_double "nct_isf_double"(double, double, double) noexcept nogil
|
||||
cdef void *_export_nct_isf_double = <void*>_func_nct_isf_double
|
||||
cdef extern from r"_ufuncs_cxx_defs.h":
|
||||
cdef float _func_nct_kurtosis_excess_float "nct_kurtosis_excess_float"(float, float) noexcept nogil
|
||||
cdef void *_export_nct_kurtosis_excess_float = <void*>_func_nct_kurtosis_excess_float
|
||||
cdef extern from r"_ufuncs_cxx_defs.h":
|
||||
cdef double _func_nct_kurtosis_excess_double "nct_kurtosis_excess_double"(double, double) noexcept nogil
|
||||
cdef void *_export_nct_kurtosis_excess_double = <void*>_func_nct_kurtosis_excess_double
|
||||
cdef extern from r"_ufuncs_cxx_defs.h":
|
||||
cdef float _func_nct_mean_float "nct_mean_float"(float, float) noexcept nogil
|
||||
cdef void *_export_nct_mean_float = <void*>_func_nct_mean_float
|
||||
cdef extern from r"_ufuncs_cxx_defs.h":
|
||||
cdef double _func_nct_mean_double "nct_mean_double"(double, double) noexcept nogil
|
||||
cdef void *_export_nct_mean_double = <void*>_func_nct_mean_double
|
||||
cdef extern from r"_ufuncs_cxx_defs.h":
|
||||
cdef float _func_nct_pdf_float "nct_pdf_float"(float, float, float) noexcept nogil
|
||||
cdef void *_export_nct_pdf_float = <void*>_func_nct_pdf_float
|
||||
cdef extern from r"_ufuncs_cxx_defs.h":
|
||||
cdef double _func_nct_pdf_double "nct_pdf_double"(double, double, double) noexcept nogil
|
||||
cdef void *_export_nct_pdf_double = <void*>_func_nct_pdf_double
|
||||
cdef extern from r"_ufuncs_cxx_defs.h":
|
||||
cdef float _func_nct_sf_float "nct_sf_float"(float, float, float) noexcept nogil
|
||||
cdef void *_export_nct_sf_float = <void*>_func_nct_sf_float
|
||||
cdef extern from r"_ufuncs_cxx_defs.h":
|
||||
cdef double _func_nct_sf_double "nct_sf_double"(double, double, double) noexcept nogil
|
||||
cdef void *_export_nct_sf_double = <void*>_func_nct_sf_double
|
||||
cdef extern from r"_ufuncs_cxx_defs.h":
|
||||
cdef float _func_nct_skewness_float "nct_skewness_float"(float, float) noexcept nogil
|
||||
cdef void *_export_nct_skewness_float = <void*>_func_nct_skewness_float
|
||||
cdef extern from r"_ufuncs_cxx_defs.h":
|
||||
cdef double _func_nct_skewness_double "nct_skewness_double"(double, double) noexcept nogil
|
||||
cdef void *_export_nct_skewness_double = <void*>_func_nct_skewness_double
|
||||
cdef extern from r"_ufuncs_cxx_defs.h":
|
||||
cdef float _func_nct_variance_float "nct_variance_float"(float, float) noexcept nogil
|
||||
cdef void *_export_nct_variance_float = <void*>_func_nct_variance_float
|
||||
cdef extern from r"_ufuncs_cxx_defs.h":
|
||||
cdef double _func_nct_variance_double "nct_variance_double"(double, double) noexcept nogil
|
||||
cdef void *_export_nct_variance_double = <void*>_func_nct_variance_double
|
||||
cdef extern from r"_ufuncs_cxx_defs.h":
|
||||
cdef float _func_ncx2_cdf_float "ncx2_cdf_float"(float, float, float) noexcept nogil
|
||||
cdef void *_export_ncx2_cdf_float = <void*>_func_ncx2_cdf_float
|
||||
cdef extern from r"_ufuncs_cxx_defs.h":
|
||||
cdef double _func_ncx2_cdf_double "ncx2_cdf_double"(double, double, double) noexcept nogil
|
||||
cdef void *_export_ncx2_cdf_double = <void*>_func_ncx2_cdf_double
|
||||
cdef extern from r"_ufuncs_cxx_defs.h":
|
||||
cdef float _func_ncx2_isf_float "ncx2_isf_float"(float, float, float) noexcept nogil
|
||||
cdef void *_export_ncx2_isf_float = <void*>_func_ncx2_isf_float
|
||||
cdef extern from r"_ufuncs_cxx_defs.h":
|
||||
cdef double _func_ncx2_isf_double "ncx2_isf_double"(double, double, double) noexcept nogil
|
||||
cdef void *_export_ncx2_isf_double = <void*>_func_ncx2_isf_double
|
||||
cdef extern from r"_ufuncs_cxx_defs.h":
|
||||
cdef float _func_ncx2_pdf_float "ncx2_pdf_float"(float, float, float) noexcept nogil
|
||||
cdef void *_export_ncx2_pdf_float = <void*>_func_ncx2_pdf_float
|
||||
cdef extern from r"_ufuncs_cxx_defs.h":
|
||||
cdef double _func_ncx2_pdf_double "ncx2_pdf_double"(double, double, double) noexcept nogil
|
||||
cdef void *_export_ncx2_pdf_double = <void*>_func_ncx2_pdf_double
|
||||
cdef extern from r"_ufuncs_cxx_defs.h":
|
||||
cdef float _func_ncx2_ppf_float "ncx2_ppf_float"(float, float, float) noexcept nogil
|
||||
cdef void *_export_ncx2_ppf_float = <void*>_func_ncx2_ppf_float
|
||||
cdef extern from r"_ufuncs_cxx_defs.h":
|
||||
cdef double _func_ncx2_ppf_double "ncx2_ppf_double"(double, double, double) noexcept nogil
|
||||
cdef void *_export_ncx2_ppf_double = <void*>_func_ncx2_ppf_double
|
||||
cdef extern from r"_ufuncs_cxx_defs.h":
|
||||
cdef float _func_ncx2_sf_float "ncx2_sf_float"(float, float, float) noexcept nogil
|
||||
cdef void *_export_ncx2_sf_float = <void*>_func_ncx2_sf_float
|
||||
cdef extern from r"_ufuncs_cxx_defs.h":
|
||||
cdef double _func_ncx2_sf_double "ncx2_sf_double"(double, double, double) noexcept nogil
|
||||
cdef void *_export_ncx2_sf_double = <void*>_func_ncx2_sf_double
|
||||
cdef extern from r"_ufuncs_cxx_defs.h":
|
||||
cdef float _func_skewnorm_cdf_float "skewnorm_cdf_float"(float, float, float, float) noexcept nogil
|
||||
cdef void *_export_skewnorm_cdf_float = <void*>_func_skewnorm_cdf_float
|
||||
cdef extern from r"_ufuncs_cxx_defs.h":
|
||||
cdef double _func_skewnorm_cdf_double "skewnorm_cdf_double"(double, double, double, double) noexcept nogil
|
||||
cdef void *_export_skewnorm_cdf_double = <void*>_func_skewnorm_cdf_double
|
||||
cdef extern from r"_ufuncs_cxx_defs.h":
|
||||
cdef float _func_skewnorm_isf_float "skewnorm_isf_float"(float, float, float, float) noexcept nogil
|
||||
cdef void *_export_skewnorm_isf_float = <void*>_func_skewnorm_isf_float
|
||||
cdef extern from r"_ufuncs_cxx_defs.h":
|
||||
cdef double _func_skewnorm_isf_double "skewnorm_isf_double"(double, double, double, double) noexcept nogil
|
||||
cdef void *_export_skewnorm_isf_double = <void*>_func_skewnorm_isf_double
|
||||
cdef extern from r"_ufuncs_cxx_defs.h":
|
||||
cdef float _func_skewnorm_ppf_float "skewnorm_ppf_float"(float, float, float, float) noexcept nogil
|
||||
cdef void *_export_skewnorm_ppf_float = <void*>_func_skewnorm_ppf_float
|
||||
cdef extern from r"_ufuncs_cxx_defs.h":
|
||||
cdef double _func_skewnorm_ppf_double "skewnorm_ppf_double"(double, double, double, double) noexcept nogil
|
||||
cdef void *_export_skewnorm_ppf_double = <void*>_func_skewnorm_ppf_double
|
||||
cdef extern from r"_ufuncs_cxx_defs.h":
|
||||
cdef double _func__stirling2_inexact "_stirling2_inexact"(double, double) noexcept nogil
|
||||
cdef void *_export__stirling2_inexact = <void*>_func__stirling2_inexact
|
||||
cdef extern from r"_ufuncs_cxx_defs.h":
|
||||
cdef float _func_ibeta_float "ibeta_float"(float, float, float) noexcept nogil
|
||||
cdef void *_export_ibeta_float = <void*>_func_ibeta_float
|
||||
cdef extern from r"_ufuncs_cxx_defs.h":
|
||||
cdef double _func_ibeta_double "ibeta_double"(double, double, double) noexcept nogil
|
||||
cdef void *_export_ibeta_double = <void*>_func_ibeta_double
|
||||
cdef extern from r"_ufuncs_cxx_defs.h":
|
||||
cdef float _func_ibetac_float "ibetac_float"(float, float, float) noexcept nogil
|
||||
cdef void *_export_ibetac_float = <void*>_func_ibetac_float
|
||||
cdef extern from r"_ufuncs_cxx_defs.h":
|
||||
cdef double _func_ibetac_double "ibetac_double"(double, double, double) noexcept nogil
|
||||
cdef void *_export_ibetac_double = <void*>_func_ibetac_double
|
||||
cdef extern from r"_ufuncs_cxx_defs.h":
|
||||
cdef float _func_ibetac_inv_float "ibetac_inv_float"(float, float, float) noexcept nogil
|
||||
cdef void *_export_ibetac_inv_float = <void*>_func_ibetac_inv_float
|
||||
cdef extern from r"_ufuncs_cxx_defs.h":
|
||||
cdef double _func_ibetac_inv_double "ibetac_inv_double"(double, double, double) noexcept nogil
|
||||
cdef void *_export_ibetac_inv_double = <void*>_func_ibetac_inv_double
|
||||
cdef extern from r"_ufuncs_cxx_defs.h":
|
||||
cdef float _func_ibeta_inv_float "ibeta_inv_float"(float, float, float) noexcept nogil
|
||||
cdef void *_export_ibeta_inv_float = <void*>_func_ibeta_inv_float
|
||||
cdef extern from r"_ufuncs_cxx_defs.h":
|
||||
cdef double _func_ibeta_inv_double "ibeta_inv_double"(double, double, double) noexcept nogil
|
||||
cdef void *_export_ibeta_inv_double = <void*>_func_ibeta_inv_double
|
||||
cdef extern from r"_ufuncs_cxx_defs.h":
|
||||
cdef double _func_fellint_RC "fellint_RC"(double, double) noexcept nogil
|
||||
cdef void *_export_fellint_RC = <void*>_func_fellint_RC
|
||||
cdef extern from r"_ufuncs_cxx_defs.h":
|
||||
cdef double complex _func_cellint_RC "cellint_RC"(double complex, double complex) noexcept nogil
|
||||
cdef void *_export_cellint_RC = <void*>_func_cellint_RC
|
||||
cdef extern from r"_ufuncs_cxx_defs.h":
|
||||
cdef double _func_fellint_RD "fellint_RD"(double, double, double) noexcept nogil
|
||||
cdef void *_export_fellint_RD = <void*>_func_fellint_RD
|
||||
cdef extern from r"_ufuncs_cxx_defs.h":
|
||||
cdef double complex _func_cellint_RD "cellint_RD"(double complex, double complex, double complex) noexcept nogil
|
||||
cdef void *_export_cellint_RD = <void*>_func_cellint_RD
|
||||
cdef extern from r"_ufuncs_cxx_defs.h":
|
||||
cdef double _func_fellint_RF "fellint_RF"(double, double, double) noexcept nogil
|
||||
cdef void *_export_fellint_RF = <void*>_func_fellint_RF
|
||||
cdef extern from r"_ufuncs_cxx_defs.h":
|
||||
cdef double complex _func_cellint_RF "cellint_RF"(double complex, double complex, double complex) noexcept nogil
|
||||
cdef void *_export_cellint_RF = <void*>_func_cellint_RF
|
||||
cdef extern from r"_ufuncs_cxx_defs.h":
|
||||
cdef double _func_fellint_RG "fellint_RG"(double, double, double) noexcept nogil
|
||||
cdef void *_export_fellint_RG = <void*>_func_fellint_RG
|
||||
cdef extern from r"_ufuncs_cxx_defs.h":
|
||||
cdef double complex _func_cellint_RG "cellint_RG"(double complex, double complex, double complex) noexcept nogil
|
||||
cdef void *_export_cellint_RG = <void*>_func_cellint_RG
|
||||
cdef extern from r"_ufuncs_cxx_defs.h":
|
||||
cdef double _func_fellint_RJ "fellint_RJ"(double, double, double, double) noexcept nogil
|
||||
cdef void *_export_fellint_RJ = <void*>_func_fellint_RJ
|
||||
cdef extern from r"_ufuncs_cxx_defs.h":
|
||||
cdef double complex _func_cellint_RJ "cellint_RJ"(double complex, double complex, double complex, double complex) noexcept nogil
|
||||
cdef void *_export_cellint_RJ = <void*>_func_cellint_RJ
|
||||
cdef extern from r"_ufuncs_cxx_defs.h":
|
||||
cdef float _func_erfinv_float "erfinv_float"(float) noexcept nogil
|
||||
cdef void *_export_erfinv_float = <void*>_func_erfinv_float
|
||||
cdef extern from r"_ufuncs_cxx_defs.h":
|
||||
cdef double _func_erfinv_double "erfinv_double"(double) noexcept nogil
|
||||
cdef void *_export_erfinv_double = <void*>_func_erfinv_double
|
||||
cdef extern from r"_ufuncs_cxx_defs.h":
|
||||
cdef double _func_hyp1f1_double "hyp1f1_double"(double, double, double) noexcept nogil
|
||||
cdef void *_export_hyp1f1_double = <void*>_func_hyp1f1_double
|
||||
cdef extern from r"_ufuncs_cxx_defs.h":
|
||||
cdef float _func_ncf_cdf_float "ncf_cdf_float"(float, float, float, float) noexcept nogil
|
||||
cdef void *_export_ncf_cdf_float = <void*>_func_ncf_cdf_float
|
||||
cdef extern from r"_ufuncs_cxx_defs.h":
|
||||
cdef double _func_ncf_cdf_double "ncf_cdf_double"(double, double, double, double) noexcept nogil
|
||||
cdef void *_export_ncf_cdf_double = <void*>_func_ncf_cdf_double
|
||||
cdef extern from r"_ufuncs_cxx_defs.h":
|
||||
cdef float _func_ncf_ppf_float "ncf_ppf_float"(float, float, float, float) noexcept nogil
|
||||
cdef void *_export_ncf_ppf_float = <void*>_func_ncf_ppf_float
|
||||
cdef extern from r"_ufuncs_cxx_defs.h":
|
||||
cdef double _func_ncf_ppf_double "ncf_ppf_double"(double, double, double, double) noexcept nogil
|
||||
cdef void *_export_ncf_ppf_double = <void*>_func_ncf_ppf_double
|
||||
cdef extern from r"_ufuncs_cxx_defs.h":
|
||||
cdef float _func_nct_cdf_float "nct_cdf_float"(float, float, float) noexcept nogil
|
||||
cdef void *_export_nct_cdf_float = <void*>_func_nct_cdf_float
|
||||
cdef extern from r"_ufuncs_cxx_defs.h":
|
||||
cdef double _func_nct_cdf_double "nct_cdf_double"(double, double, double) noexcept nogil
|
||||
cdef void *_export_nct_cdf_double = <void*>_func_nct_cdf_double
|
||||
cdef extern from r"_ufuncs_cxx_defs.h":
|
||||
cdef float _func_nct_ppf_float "nct_ppf_float"(float, float, float) noexcept nogil
|
||||
cdef void *_export_nct_ppf_float = <void*>_func_nct_ppf_float
|
||||
cdef extern from r"_ufuncs_cxx_defs.h":
|
||||
cdef double _func_nct_ppf_double "nct_ppf_double"(double, double, double) noexcept nogil
|
||||
cdef void *_export_nct_ppf_double = <void*>_func_nct_ppf_double
|
||||
cdef extern from r"_ufuncs_cxx_defs.h":
|
||||
cdef float _func_powm1_float "powm1_float"(float, float) noexcept nogil
|
||||
cdef void *_export_powm1_float = <void*>_func_powm1_float
|
||||
cdef extern from r"_ufuncs_cxx_defs.h":
|
||||
cdef double _func_powm1_double "powm1_double"(double, double) noexcept nogil
|
||||
cdef void *_export_powm1_double = <void*>_func_powm1_double
|
||||
cdef extern from r"_ufuncs_cxx_defs.h":
|
||||
cdef double complex _func_wrightomega "wrightomega"(double complex) noexcept nogil
|
||||
cdef void *_export_wrightomega = <void*>_func_wrightomega
|
||||
cdef extern from r"_ufuncs_cxx_defs.h":
|
||||
cdef double _func_wrightomega_real "wrightomega_real"(double) noexcept nogil
|
||||
cdef void *_export_wrightomega_real = <void*>_func_wrightomega_real
|
||||
|
|
@ -0,0 +1,147 @@
|
|||
#ifndef UFUNCS_PROTO_H
|
||||
#define UFUNCS_PROTO_H 1
|
||||
#include "boost_special_functions.h"
|
||||
npy_float beta_pdf_float(npy_float, npy_float, npy_float);
|
||||
npy_double beta_pdf_double(npy_double, npy_double, npy_double);
|
||||
npy_float beta_ppf_float(npy_float, npy_float, npy_float);
|
||||
npy_double beta_ppf_double(npy_double, npy_double, npy_double);
|
||||
npy_float binom_cdf_float(npy_float, npy_float, npy_float);
|
||||
npy_double binom_cdf_double(npy_double, npy_double, npy_double);
|
||||
npy_float binom_isf_float(npy_float, npy_float, npy_float);
|
||||
npy_double binom_isf_double(npy_double, npy_double, npy_double);
|
||||
npy_float binom_pmf_float(npy_float, npy_float, npy_float);
|
||||
npy_double binom_pmf_double(npy_double, npy_double, npy_double);
|
||||
npy_float binom_ppf_float(npy_float, npy_float, npy_float);
|
||||
npy_double binom_ppf_double(npy_double, npy_double, npy_double);
|
||||
npy_float binom_sf_float(npy_float, npy_float, npy_float);
|
||||
npy_double binom_sf_double(npy_double, npy_double, npy_double);
|
||||
npy_float cauchy_isf_float(npy_float, npy_float, npy_float);
|
||||
npy_double cauchy_isf_double(npy_double, npy_double, npy_double);
|
||||
npy_float cauchy_ppf_float(npy_float, npy_float, npy_float);
|
||||
npy_double cauchy_ppf_double(npy_double, npy_double, npy_double);
|
||||
npy_float hypergeom_cdf_float(npy_float, npy_float, npy_float, npy_float);
|
||||
npy_double hypergeom_cdf_double(npy_double, npy_double, npy_double, npy_double);
|
||||
npy_float hypergeom_mean_float(npy_float, npy_float, npy_float);
|
||||
npy_double hypergeom_mean_double(npy_double, npy_double, npy_double);
|
||||
npy_float hypergeom_pmf_float(npy_float, npy_float, npy_float, npy_float);
|
||||
npy_double hypergeom_pmf_double(npy_double, npy_double, npy_double, npy_double);
|
||||
npy_float hypergeom_sf_float(npy_float, npy_float, npy_float, npy_float);
|
||||
npy_double hypergeom_sf_double(npy_double, npy_double, npy_double, npy_double);
|
||||
npy_float hypergeom_skewness_float(npy_float, npy_float, npy_float);
|
||||
npy_double hypergeom_skewness_double(npy_double, npy_double, npy_double);
|
||||
npy_float hypergeom_variance_float(npy_float, npy_float, npy_float);
|
||||
npy_double hypergeom_variance_double(npy_double, npy_double, npy_double);
|
||||
npy_float invgauss_isf_float(npy_float, npy_float, npy_float);
|
||||
npy_double invgauss_isf_double(npy_double, npy_double, npy_double);
|
||||
npy_float invgauss_ppf_float(npy_float, npy_float, npy_float);
|
||||
npy_double invgauss_ppf_double(npy_double, npy_double, npy_double);
|
||||
npy_float landau_cdf_float(npy_float, npy_float, npy_float);
|
||||
npy_double landau_cdf_double(npy_double, npy_double, npy_double);
|
||||
npy_float landau_isf_float(npy_float, npy_float, npy_float);
|
||||
npy_double landau_isf_double(npy_double, npy_double, npy_double);
|
||||
npy_float landau_pdf_float(npy_float, npy_float, npy_float);
|
||||
npy_double landau_pdf_double(npy_double, npy_double, npy_double);
|
||||
npy_float landau_ppf_float(npy_float, npy_float, npy_float);
|
||||
npy_double landau_ppf_double(npy_double, npy_double, npy_double);
|
||||
npy_float landau_sf_float(npy_float, npy_float, npy_float);
|
||||
npy_double landau_sf_double(npy_double, npy_double, npy_double);
|
||||
npy_float nbinom_cdf_float(npy_float, npy_float, npy_float);
|
||||
npy_double nbinom_cdf_double(npy_double, npy_double, npy_double);
|
||||
npy_float nbinom_isf_float(npy_float, npy_float, npy_float);
|
||||
npy_double nbinom_isf_double(npy_double, npy_double, npy_double);
|
||||
npy_float nbinom_kurtosis_excess_float(npy_float, npy_float);
|
||||
npy_double nbinom_kurtosis_excess_double(npy_double, npy_double);
|
||||
npy_float nbinom_mean_float(npy_float, npy_float);
|
||||
npy_double nbinom_mean_double(npy_double, npy_double);
|
||||
npy_float nbinom_pmf_float(npy_float, npy_float, npy_float);
|
||||
npy_double nbinom_pmf_double(npy_double, npy_double, npy_double);
|
||||
npy_float nbinom_ppf_float(npy_float, npy_float, npy_float);
|
||||
npy_double nbinom_ppf_double(npy_double, npy_double, npy_double);
|
||||
npy_float nbinom_sf_float(npy_float, npy_float, npy_float);
|
||||
npy_double nbinom_sf_double(npy_double, npy_double, npy_double);
|
||||
npy_float nbinom_skewness_float(npy_float, npy_float);
|
||||
npy_double nbinom_skewness_double(npy_double, npy_double);
|
||||
npy_float nbinom_variance_float(npy_float, npy_float);
|
||||
npy_double nbinom_variance_double(npy_double, npy_double);
|
||||
npy_float ncf_isf_float(npy_float, npy_float, npy_float, npy_float);
|
||||
npy_double ncf_isf_double(npy_double, npy_double, npy_double, npy_double);
|
||||
npy_float ncf_kurtosis_excess_float(npy_float, npy_float, npy_float);
|
||||
npy_double ncf_kurtosis_excess_double(npy_double, npy_double, npy_double);
|
||||
npy_float ncf_mean_float(npy_float, npy_float, npy_float);
|
||||
npy_double ncf_mean_double(npy_double, npy_double, npy_double);
|
||||
npy_float ncf_pdf_float(npy_float, npy_float, npy_float, npy_float);
|
||||
npy_double ncf_pdf_double(npy_double, npy_double, npy_double, npy_double);
|
||||
npy_float ncf_sf_float(npy_float, npy_float, npy_float, npy_float);
|
||||
npy_double ncf_sf_double(npy_double, npy_double, npy_double, npy_double);
|
||||
npy_float ncf_skewness_float(npy_float, npy_float, npy_float);
|
||||
npy_double ncf_skewness_double(npy_double, npy_double, npy_double);
|
||||
npy_float ncf_variance_float(npy_float, npy_float, npy_float);
|
||||
npy_double ncf_variance_double(npy_double, npy_double, npy_double);
|
||||
npy_float nct_isf_float(npy_float, npy_float, npy_float);
|
||||
npy_double nct_isf_double(npy_double, npy_double, npy_double);
|
||||
npy_float nct_kurtosis_excess_float(npy_float, npy_float);
|
||||
npy_double nct_kurtosis_excess_double(npy_double, npy_double);
|
||||
npy_float nct_mean_float(npy_float, npy_float);
|
||||
npy_double nct_mean_double(npy_double, npy_double);
|
||||
npy_float nct_pdf_float(npy_float, npy_float, npy_float);
|
||||
npy_double nct_pdf_double(npy_double, npy_double, npy_double);
|
||||
npy_float nct_sf_float(npy_float, npy_float, npy_float);
|
||||
npy_double nct_sf_double(npy_double, npy_double, npy_double);
|
||||
npy_float nct_skewness_float(npy_float, npy_float);
|
||||
npy_double nct_skewness_double(npy_double, npy_double);
|
||||
npy_float nct_variance_float(npy_float, npy_float);
|
||||
npy_double nct_variance_double(npy_double, npy_double);
|
||||
npy_float ncx2_cdf_float(npy_float, npy_float, npy_float);
|
||||
npy_double ncx2_cdf_double(npy_double, npy_double, npy_double);
|
||||
npy_float ncx2_isf_float(npy_float, npy_float, npy_float);
|
||||
npy_double ncx2_isf_double(npy_double, npy_double, npy_double);
|
||||
npy_float ncx2_pdf_float(npy_float, npy_float, npy_float);
|
||||
npy_double ncx2_pdf_double(npy_double, npy_double, npy_double);
|
||||
npy_float ncx2_ppf_float(npy_float, npy_float, npy_float);
|
||||
npy_double ncx2_ppf_double(npy_double, npy_double, npy_double);
|
||||
npy_float ncx2_sf_float(npy_float, npy_float, npy_float);
|
||||
npy_double ncx2_sf_double(npy_double, npy_double, npy_double);
|
||||
npy_float skewnorm_cdf_float(npy_float, npy_float, npy_float, npy_float);
|
||||
npy_double skewnorm_cdf_double(npy_double, npy_double, npy_double, npy_double);
|
||||
npy_float skewnorm_isf_float(npy_float, npy_float, npy_float, npy_float);
|
||||
npy_double skewnorm_isf_double(npy_double, npy_double, npy_double, npy_double);
|
||||
npy_float skewnorm_ppf_float(npy_float, npy_float, npy_float, npy_float);
|
||||
npy_double skewnorm_ppf_double(npy_double, npy_double, npy_double, npy_double);
|
||||
#include "stirling2.h"
|
||||
npy_double _stirling2_inexact(npy_double, npy_double);
|
||||
npy_float ibeta_float(npy_float, npy_float, npy_float);
|
||||
npy_double ibeta_double(npy_double, npy_double, npy_double);
|
||||
npy_float ibetac_float(npy_float, npy_float, npy_float);
|
||||
npy_double ibetac_double(npy_double, npy_double, npy_double);
|
||||
npy_float ibetac_inv_float(npy_float, npy_float, npy_float);
|
||||
npy_double ibetac_inv_double(npy_double, npy_double, npy_double);
|
||||
npy_float ibeta_inv_float(npy_float, npy_float, npy_float);
|
||||
npy_double ibeta_inv_double(npy_double, npy_double, npy_double);
|
||||
#include "ellint_carlson_wrap.hh"
|
||||
npy_double fellint_RC(npy_double, npy_double);
|
||||
npy_cdouble cellint_RC(npy_cdouble, npy_cdouble);
|
||||
npy_double fellint_RD(npy_double, npy_double, npy_double);
|
||||
npy_cdouble cellint_RD(npy_cdouble, npy_cdouble, npy_cdouble);
|
||||
npy_double fellint_RF(npy_double, npy_double, npy_double);
|
||||
npy_cdouble cellint_RF(npy_cdouble, npy_cdouble, npy_cdouble);
|
||||
npy_double fellint_RG(npy_double, npy_double, npy_double);
|
||||
npy_cdouble cellint_RG(npy_cdouble, npy_cdouble, npy_cdouble);
|
||||
npy_double fellint_RJ(npy_double, npy_double, npy_double, npy_double);
|
||||
npy_cdouble cellint_RJ(npy_cdouble, npy_cdouble, npy_cdouble, npy_cdouble);
|
||||
npy_float erfinv_float(npy_float);
|
||||
npy_double erfinv_double(npy_double);
|
||||
npy_double hyp1f1_double(npy_double, npy_double, npy_double);
|
||||
npy_float ncf_cdf_float(npy_float, npy_float, npy_float, npy_float);
|
||||
npy_double ncf_cdf_double(npy_double, npy_double, npy_double, npy_double);
|
||||
npy_float ncf_ppf_float(npy_float, npy_float, npy_float, npy_float);
|
||||
npy_double ncf_ppf_double(npy_double, npy_double, npy_double, npy_double);
|
||||
npy_float nct_cdf_float(npy_float, npy_float, npy_float);
|
||||
npy_double nct_cdf_double(npy_double, npy_double, npy_double);
|
||||
npy_float nct_ppf_float(npy_float, npy_float, npy_float);
|
||||
npy_double nct_ppf_double(npy_double, npy_double, npy_double);
|
||||
npy_float powm1_float(npy_float, npy_float);
|
||||
npy_double powm1_double(npy_double, npy_double);
|
||||
#include "_wright.h"
|
||||
npy_cdouble wrightomega(npy_cdouble);
|
||||
npy_double wrightomega_real(npy_double);
|
||||
#endif
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
#ifndef UFUNCS_PROTO_H
|
||||
#define UFUNCS_PROTO_H 1
|
||||
#include "_cosine.h"
|
||||
npy_double cosine_cdf(npy_double);
|
||||
npy_double cosine_invcdf(npy_double);
|
||||
#include "xsf_wrappers.h"
|
||||
npy_double cephes_igam_fac(npy_double, npy_double);
|
||||
npy_double xsf_kolmogc(npy_double);
|
||||
npy_double xsf_kolmogci(npy_double);
|
||||
npy_double xsf_kolmogp(npy_double);
|
||||
npy_double cephes_lanczos_sum_expg_scaled(npy_double);
|
||||
npy_double cephes_lgam1p(npy_double);
|
||||
npy_double cephes_smirnovc_wrap(npy_intp, npy_double);
|
||||
npy_double cephes_smirnovci_wrap(npy_intp, npy_double);
|
||||
npy_double cephes_smirnovp_wrap(npy_intp, npy_double);
|
||||
npy_double cephes__struve_asymp_large_z(npy_double, npy_double, npy_intp, npy_double *);
|
||||
npy_double cephes__struve_bessel_series(npy_double, npy_double, npy_intp, npy_double *);
|
||||
npy_double cephes__struve_power_series(npy_double, npy_double, npy_intp, npy_double *);
|
||||
npy_double cephes_bdtr_wrap(npy_double, npy_intp, npy_double);
|
||||
npy_double cephes_bdtrc_wrap(npy_double, npy_intp, npy_double);
|
||||
npy_double cephes_bdtri_wrap(npy_double, npy_intp, npy_double);
|
||||
npy_double xsf_chdtr(npy_double, npy_double);
|
||||
npy_double xsf_chdtrc(npy_double, npy_double);
|
||||
npy_double xsf_chdtri(npy_double, npy_double);
|
||||
npy_double cephes_erfcinv(npy_double);
|
||||
npy_double cephes_expn_wrap(npy_intp, npy_double);
|
||||
npy_double xsf_fdtr(npy_double, npy_double, npy_double);
|
||||
npy_double xsf_fdtrc(npy_double, npy_double, npy_double);
|
||||
npy_double xsf_fdtri(npy_double, npy_double, npy_double);
|
||||
npy_double xsf_gdtr(npy_double, npy_double, npy_double);
|
||||
npy_double xsf_gdtrc(npy_double, npy_double, npy_double);
|
||||
npy_double xsf_gdtrib(npy_double, npy_double, npy_double);
|
||||
npy_cdouble chyp1f1_wrap(npy_double, npy_double, npy_cdouble);
|
||||
npy_double special_cyl_bessel_k_int(npy_intp, npy_double);
|
||||
npy_double xsf_kolmogi(npy_double);
|
||||
npy_double xsf_kolmogorov(npy_double);
|
||||
npy_double pmv_wrap(npy_double, npy_double, npy_double);
|
||||
npy_double cephes_nbdtr_wrap(npy_intp, npy_intp, npy_double);
|
||||
npy_double cephes_nbdtrc_wrap(npy_intp, npy_intp, npy_double);
|
||||
npy_double cephes_nbdtri_wrap(npy_intp, npy_intp, npy_double);
|
||||
npy_double xsf_ndtri(npy_double);
|
||||
npy_double xsf_owens_t(npy_double, npy_double);
|
||||
npy_double xsf_pdtr(npy_double, npy_double);
|
||||
npy_double xsf_pdtrc(npy_double, npy_double);
|
||||
npy_double cephes_pdtri_wrap(npy_intp, npy_double);
|
||||
npy_double cephes_poch(npy_double, npy_double);
|
||||
npy_double cephes_round(npy_double);
|
||||
npy_int xsf_cshichi(npy_cdouble, npy_cdouble *, npy_cdouble *);
|
||||
npy_int xsf_shichi(npy_double, npy_double *, npy_double *);
|
||||
npy_int xsf_csici(npy_cdouble, npy_cdouble *, npy_cdouble *);
|
||||
npy_int xsf_sici(npy_double, npy_double *, npy_double *);
|
||||
npy_double cephes_smirnov_wrap(npy_intp, npy_double);
|
||||
npy_double cephes_smirnovi_wrap(npy_intp, npy_double);
|
||||
npy_double cephes_spence(npy_double);
|
||||
npy_double xsf_tukeylambdacdf(npy_double, npy_double);
|
||||
npy_double cephes_yn_wrap(npy_intp, npy_double);
|
||||
#endif
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
# This file is not meant for public use and will be removed in SciPy v2.0.0.
|
||||
|
||||
from scipy._lib.deprecation import _sub_module_deprecation
|
||||
|
||||
__all__: list[str] = []
|
||||
|
||||
|
||||
def __dir__():
|
||||
return __all__
|
||||
|
||||
|
||||
def __getattr__(name):
|
||||
return _sub_module_deprecation(sub_package="special", module="add_newdocs",
|
||||
private_modules=["_add_newdocs"], all=__all__,
|
||||
attribute=name)
|
||||
87
venv/lib/python3.13/site-packages/scipy/special/basic.py
Normal file
87
venv/lib/python3.13/site-packages/scipy/special/basic.py
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
# This file is not meant for public use and will be removed in SciPy v2.0.0.
|
||||
# Use the `scipy.special` namespace for importing the functions
|
||||
# included below.
|
||||
|
||||
from scipy._lib.deprecation import _sub_module_deprecation
|
||||
|
||||
|
||||
__all__ = [ # noqa: F822
|
||||
'ai_zeros',
|
||||
'assoc_laguerre',
|
||||
'bei_zeros',
|
||||
'beip_zeros',
|
||||
'ber_zeros',
|
||||
'bernoulli',
|
||||
'berp_zeros',
|
||||
'bi_zeros',
|
||||
'clpmn',
|
||||
'comb',
|
||||
'digamma',
|
||||
'diric',
|
||||
'erf_zeros',
|
||||
'euler',
|
||||
'factorial',
|
||||
'factorial2',
|
||||
'factorialk',
|
||||
'fresnel_zeros',
|
||||
'fresnelc_zeros',
|
||||
'fresnels_zeros',
|
||||
'gamma',
|
||||
'h1vp',
|
||||
'h2vp',
|
||||
'hankel1',
|
||||
'hankel2',
|
||||
'iv',
|
||||
'ivp',
|
||||
'jn_zeros',
|
||||
'jnjnp_zeros',
|
||||
'jnp_zeros',
|
||||
'jnyn_zeros',
|
||||
'jv',
|
||||
'jvp',
|
||||
'kei_zeros',
|
||||
'keip_zeros',
|
||||
'kelvin_zeros',
|
||||
'ker_zeros',
|
||||
'kerp_zeros',
|
||||
'kv',
|
||||
'kvp',
|
||||
'lmbda',
|
||||
'lpmn',
|
||||
'lpn',
|
||||
'lqmn',
|
||||
'lqn',
|
||||
'mathieu_a',
|
||||
'mathieu_b',
|
||||
'mathieu_even_coef',
|
||||
'mathieu_odd_coef',
|
||||
'obl_cv_seq',
|
||||
'pbdn_seq',
|
||||
'pbdv_seq',
|
||||
'pbvv_seq',
|
||||
'perm',
|
||||
'polygamma',
|
||||
'pro_cv_seq',
|
||||
'psi',
|
||||
'riccati_jn',
|
||||
'riccati_yn',
|
||||
'sinc',
|
||||
'y0_zeros',
|
||||
'y1_zeros',
|
||||
'y1p_zeros',
|
||||
'yn_zeros',
|
||||
'ynp_zeros',
|
||||
'yv',
|
||||
'yvp',
|
||||
'zeta'
|
||||
]
|
||||
|
||||
|
||||
def __dir__():
|
||||
return __all__
|
||||
|
||||
|
||||
def __getattr__(name):
|
||||
return _sub_module_deprecation(sub_package="special", module="basic",
|
||||
private_modules=["_basic", "_ufuncs"], all=__all__,
|
||||
attribute=name)
|
||||
Binary file not shown.
|
|
@ -0,0 +1,259 @@
|
|||
|
||||
ctypedef fused number_t:
|
||||
double complex
|
||||
double
|
||||
|
||||
cpdef number_t spherical_jn(Py_ssize_t n, number_t z, bint derivative=*) noexcept nogil
|
||||
cpdef number_t spherical_yn(Py_ssize_t n, number_t z, bint derivative=*) noexcept nogil
|
||||
cpdef number_t spherical_in(Py_ssize_t n, number_t z, bint derivative=*) noexcept nogil
|
||||
cpdef number_t spherical_kn(Py_ssize_t n, number_t z, bint derivative=*) noexcept nogil
|
||||
|
||||
ctypedef fused Dd_number_t:
|
||||
double complex
|
||||
double
|
||||
|
||||
ctypedef fused df_number_t:
|
||||
double
|
||||
float
|
||||
|
||||
ctypedef fused dfg_number_t:
|
||||
double
|
||||
float
|
||||
long double
|
||||
|
||||
ctypedef fused dlp_number_t:
|
||||
double
|
||||
long
|
||||
Py_ssize_t
|
||||
|
||||
cpdef double voigt_profile(double x0, double x1, double x2) noexcept nogil
|
||||
cpdef double agm(double x0, double x1) noexcept nogil
|
||||
cdef void airy(Dd_number_t x0, Dd_number_t *y0, Dd_number_t *y1, Dd_number_t *y2, Dd_number_t *y3) noexcept nogil
|
||||
cdef void airye(Dd_number_t x0, Dd_number_t *y0, Dd_number_t *y1, Dd_number_t *y2, Dd_number_t *y3) noexcept nogil
|
||||
cpdef double bdtr(double x0, dlp_number_t x1, double x2) noexcept nogil
|
||||
cpdef double bdtrc(double x0, dlp_number_t x1, double x2) noexcept nogil
|
||||
cpdef double bdtri(double x0, dlp_number_t x1, double x2) noexcept nogil
|
||||
cpdef double bdtrik(double x0, double x1, double x2) noexcept nogil
|
||||
cpdef double bdtrin(double x0, double x1, double x2) noexcept nogil
|
||||
cpdef double bei(double x0) noexcept nogil
|
||||
cpdef double beip(double x0) noexcept nogil
|
||||
cpdef double ber(double x0) noexcept nogil
|
||||
cpdef double berp(double x0) noexcept nogil
|
||||
cpdef double besselpoly(double x0, double x1, double x2) noexcept nogil
|
||||
cpdef double beta(double x0, double x1) noexcept nogil
|
||||
cpdef df_number_t betainc(df_number_t x0, df_number_t x1, df_number_t x2) noexcept nogil
|
||||
cpdef df_number_t betaincc(df_number_t x0, df_number_t x1, df_number_t x2) noexcept nogil
|
||||
cpdef df_number_t betaincinv(df_number_t x0, df_number_t x1, df_number_t x2) noexcept nogil
|
||||
cpdef df_number_t betainccinv(df_number_t x0, df_number_t x1, df_number_t x2) noexcept nogil
|
||||
cpdef double betaln(double x0, double x1) noexcept nogil
|
||||
cpdef double binom(double x0, double x1) noexcept nogil
|
||||
cpdef double boxcox(double x0, double x1) noexcept nogil
|
||||
cpdef double boxcox1p(double x0, double x1) noexcept nogil
|
||||
cpdef double btdtria(double x0, double x1, double x2) noexcept nogil
|
||||
cpdef double btdtrib(double x0, double x1, double x2) noexcept nogil
|
||||
cpdef double cbrt(double x0) noexcept nogil
|
||||
cpdef double chdtr(double x0, double x1) noexcept nogil
|
||||
cpdef double chdtrc(double x0, double x1) noexcept nogil
|
||||
cpdef double chdtri(double x0, double x1) noexcept nogil
|
||||
cpdef double chdtriv(double x0, double x1) noexcept nogil
|
||||
cpdef double chndtr(double x0, double x1, double x2) noexcept nogil
|
||||
cpdef double chndtridf(double x0, double x1, double x2) noexcept nogil
|
||||
cpdef double chndtrinc(double x0, double x1, double x2) noexcept nogil
|
||||
cpdef double chndtrix(double x0, double x1, double x2) noexcept nogil
|
||||
cpdef double cosdg(double x0) noexcept nogil
|
||||
cpdef double cosm1(double x0) noexcept nogil
|
||||
cpdef double cotdg(double x0) noexcept nogil
|
||||
cpdef Dd_number_t dawsn(Dd_number_t x0) noexcept nogil
|
||||
cpdef double ellipe(double x0) noexcept nogil
|
||||
cpdef double ellipeinc(double x0, double x1) noexcept nogil
|
||||
cdef void ellipj(double x0, double x1, double *y0, double *y1, double *y2, double *y3) noexcept nogil
|
||||
cpdef double ellipkinc(double x0, double x1) noexcept nogil
|
||||
cpdef double ellipkm1(double x0) noexcept nogil
|
||||
cpdef double ellipk(double x0) noexcept nogil
|
||||
cpdef Dd_number_t elliprc(Dd_number_t x0, Dd_number_t x1) noexcept nogil
|
||||
cpdef Dd_number_t elliprd(Dd_number_t x0, Dd_number_t x1, Dd_number_t x2) noexcept nogil
|
||||
cpdef Dd_number_t elliprf(Dd_number_t x0, Dd_number_t x1, Dd_number_t x2) noexcept nogil
|
||||
cpdef Dd_number_t elliprg(Dd_number_t x0, Dd_number_t x1, Dd_number_t x2) noexcept nogil
|
||||
cpdef Dd_number_t elliprj(Dd_number_t x0, Dd_number_t x1, Dd_number_t x2, Dd_number_t x3) noexcept nogil
|
||||
cpdef double entr(double x0) noexcept nogil
|
||||
cpdef Dd_number_t erf(Dd_number_t x0) noexcept nogil
|
||||
cpdef Dd_number_t erfc(Dd_number_t x0) noexcept nogil
|
||||
cpdef Dd_number_t erfcx(Dd_number_t x0) noexcept nogil
|
||||
cpdef Dd_number_t erfi(Dd_number_t x0) noexcept nogil
|
||||
cpdef df_number_t erfinv(df_number_t x0) noexcept nogil
|
||||
cpdef double erfcinv(double x0) noexcept nogil
|
||||
cpdef Dd_number_t eval_chebyc(dlp_number_t x0, Dd_number_t x1) noexcept nogil
|
||||
cpdef Dd_number_t eval_chebys(dlp_number_t x0, Dd_number_t x1) noexcept nogil
|
||||
cpdef Dd_number_t eval_chebyt(dlp_number_t x0, Dd_number_t x1) noexcept nogil
|
||||
cpdef Dd_number_t eval_chebyu(dlp_number_t x0, Dd_number_t x1) noexcept nogil
|
||||
cpdef Dd_number_t eval_gegenbauer(dlp_number_t x0, double x1, Dd_number_t x2) noexcept nogil
|
||||
cpdef Dd_number_t eval_genlaguerre(dlp_number_t x0, double x1, Dd_number_t x2) noexcept nogil
|
||||
cpdef double eval_hermite(Py_ssize_t x0, double x1) noexcept nogil
|
||||
cpdef double eval_hermitenorm(Py_ssize_t x0, double x1) noexcept nogil
|
||||
cpdef Dd_number_t eval_jacobi(dlp_number_t x0, double x1, double x2, Dd_number_t x3) noexcept nogil
|
||||
cpdef Dd_number_t eval_laguerre(dlp_number_t x0, Dd_number_t x1) noexcept nogil
|
||||
cpdef Dd_number_t eval_legendre(dlp_number_t x0, Dd_number_t x1) noexcept nogil
|
||||
cpdef Dd_number_t eval_sh_chebyt(dlp_number_t x0, Dd_number_t x1) noexcept nogil
|
||||
cpdef Dd_number_t eval_sh_chebyu(dlp_number_t x0, Dd_number_t x1) noexcept nogil
|
||||
cpdef Dd_number_t eval_sh_jacobi(dlp_number_t x0, double x1, double x2, Dd_number_t x3) noexcept nogil
|
||||
cpdef Dd_number_t eval_sh_legendre(dlp_number_t x0, Dd_number_t x1) noexcept nogil
|
||||
cpdef Dd_number_t exp1(Dd_number_t x0) noexcept nogil
|
||||
cpdef double exp10(double x0) noexcept nogil
|
||||
cpdef double exp2(double x0) noexcept nogil
|
||||
cpdef Dd_number_t expi(Dd_number_t x0) noexcept nogil
|
||||
cpdef dfg_number_t expit(dfg_number_t x0) noexcept nogil
|
||||
cpdef Dd_number_t expm1(Dd_number_t x0) noexcept nogil
|
||||
cpdef double expn(dlp_number_t x0, double x1) noexcept nogil
|
||||
cpdef double exprel(double x0) noexcept nogil
|
||||
cpdef double fdtr(double x0, double x1, double x2) noexcept nogil
|
||||
cpdef double fdtrc(double x0, double x1, double x2) noexcept nogil
|
||||
cpdef double fdtri(double x0, double x1, double x2) noexcept nogil
|
||||
cpdef double fdtridfd(double x0, double x1, double x2) noexcept nogil
|
||||
cdef void fresnel(Dd_number_t x0, Dd_number_t *y0, Dd_number_t *y1) noexcept nogil
|
||||
cpdef Dd_number_t gamma(Dd_number_t x0) noexcept nogil
|
||||
cpdef double gammainc(double x0, double x1) noexcept nogil
|
||||
cpdef double gammaincc(double x0, double x1) noexcept nogil
|
||||
cpdef double gammainccinv(double x0, double x1) noexcept nogil
|
||||
cpdef double gammaincinv(double x0, double x1) noexcept nogil
|
||||
cpdef double gammaln(double x0) noexcept nogil
|
||||
cpdef double gammasgn(double x0) noexcept nogil
|
||||
cpdef double gdtr(double x0, double x1, double x2) noexcept nogil
|
||||
cpdef double gdtrc(double x0, double x1, double x2) noexcept nogil
|
||||
cpdef double gdtria(double x0, double x1, double x2) noexcept nogil
|
||||
cpdef double gdtrib(double x0, double x1, double x2) noexcept nogil
|
||||
cpdef double gdtrix(double x0, double x1, double x2) noexcept nogil
|
||||
cpdef double complex hankel1(double x0, double complex x1) noexcept nogil
|
||||
cpdef double complex hankel1e(double x0, double complex x1) noexcept nogil
|
||||
cpdef double complex hankel2(double x0, double complex x1) noexcept nogil
|
||||
cpdef double complex hankel2e(double x0, double complex x1) noexcept nogil
|
||||
cpdef double huber(double x0, double x1) noexcept nogil
|
||||
cpdef Dd_number_t hyp0f1(double x0, Dd_number_t x1) noexcept nogil
|
||||
cpdef Dd_number_t hyp1f1(double x0, double x1, Dd_number_t x2) noexcept nogil
|
||||
cpdef Dd_number_t hyp2f1(double x0, double x1, double x2, Dd_number_t x3) noexcept nogil
|
||||
cpdef double hyperu(double x0, double x1, double x2) noexcept nogil
|
||||
cpdef double i0(double x0) noexcept nogil
|
||||
cpdef double i0e(double x0) noexcept nogil
|
||||
cpdef double i1(double x0) noexcept nogil
|
||||
cpdef double i1e(double x0) noexcept nogil
|
||||
cpdef double inv_boxcox(double x0, double x1) noexcept nogil
|
||||
cpdef double inv_boxcox1p(double x0, double x1) noexcept nogil
|
||||
cdef void it2i0k0(double x0, double *y0, double *y1) noexcept nogil
|
||||
cdef void it2j0y0(double x0, double *y0, double *y1) noexcept nogil
|
||||
cpdef double it2struve0(double x0) noexcept nogil
|
||||
cdef void itairy(double x0, double *y0, double *y1, double *y2, double *y3) noexcept nogil
|
||||
cdef void iti0k0(double x0, double *y0, double *y1) noexcept nogil
|
||||
cdef void itj0y0(double x0, double *y0, double *y1) noexcept nogil
|
||||
cpdef double itmodstruve0(double x0) noexcept nogil
|
||||
cpdef double itstruve0(double x0) noexcept nogil
|
||||
cpdef Dd_number_t iv(double x0, Dd_number_t x1) noexcept nogil
|
||||
cpdef Dd_number_t ive(double x0, Dd_number_t x1) noexcept nogil
|
||||
cpdef double j0(double x0) noexcept nogil
|
||||
cpdef double j1(double x0) noexcept nogil
|
||||
cpdef Dd_number_t jv(double x0, Dd_number_t x1) noexcept nogil
|
||||
cpdef Dd_number_t jve(double x0, Dd_number_t x1) noexcept nogil
|
||||
cpdef double k0(double x0) noexcept nogil
|
||||
cpdef double k0e(double x0) noexcept nogil
|
||||
cpdef double k1(double x0) noexcept nogil
|
||||
cpdef double k1e(double x0) noexcept nogil
|
||||
cpdef double kei(double x0) noexcept nogil
|
||||
cpdef double keip(double x0) noexcept nogil
|
||||
cdef void kelvin(double x0, double complex *y0, double complex *y1, double complex *y2, double complex *y3) noexcept nogil
|
||||
cpdef double ker(double x0) noexcept nogil
|
||||
cpdef double kerp(double x0) noexcept nogil
|
||||
cpdef double kl_div(double x0, double x1) noexcept nogil
|
||||
cpdef double kn(dlp_number_t x0, double x1) noexcept nogil
|
||||
cpdef double kolmogi(double x0) noexcept nogil
|
||||
cpdef double kolmogorov(double x0) noexcept nogil
|
||||
cpdef Dd_number_t kv(double x0, Dd_number_t x1) noexcept nogil
|
||||
cpdef Dd_number_t kve(double x0, Dd_number_t x1) noexcept nogil
|
||||
cpdef Dd_number_t log1p(Dd_number_t x0) noexcept nogil
|
||||
cpdef dfg_number_t log_expit(dfg_number_t x0) noexcept nogil
|
||||
cpdef Dd_number_t log_ndtr(Dd_number_t x0) noexcept nogil
|
||||
cpdef Dd_number_t loggamma(Dd_number_t x0) noexcept nogil
|
||||
cpdef dfg_number_t logit(dfg_number_t x0) noexcept nogil
|
||||
cpdef double lpmv(double x0, double x1, double x2) noexcept nogil
|
||||
cpdef double mathieu_a(double x0, double x1) noexcept nogil
|
||||
cpdef double mathieu_b(double x0, double x1) noexcept nogil
|
||||
cdef void mathieu_cem(double x0, double x1, double x2, double *y0, double *y1) noexcept nogil
|
||||
cdef void mathieu_modcem1(double x0, double x1, double x2, double *y0, double *y1) noexcept nogil
|
||||
cdef void mathieu_modcem2(double x0, double x1, double x2, double *y0, double *y1) noexcept nogil
|
||||
cdef void mathieu_modsem1(double x0, double x1, double x2, double *y0, double *y1) noexcept nogil
|
||||
cdef void mathieu_modsem2(double x0, double x1, double x2, double *y0, double *y1) noexcept nogil
|
||||
cdef void mathieu_sem(double x0, double x1, double x2, double *y0, double *y1) noexcept nogil
|
||||
cdef void modfresnelm(double x0, double complex *y0, double complex *y1) noexcept nogil
|
||||
cdef void modfresnelp(double x0, double complex *y0, double complex *y1) noexcept nogil
|
||||
cpdef double modstruve(double x0, double x1) noexcept nogil
|
||||
cpdef double nbdtr(dlp_number_t x0, dlp_number_t x1, double x2) noexcept nogil
|
||||
cpdef double nbdtrc(dlp_number_t x0, dlp_number_t x1, double x2) noexcept nogil
|
||||
cpdef double nbdtri(dlp_number_t x0, dlp_number_t x1, double x2) noexcept nogil
|
||||
cpdef double nbdtrik(double x0, double x1, double x2) noexcept nogil
|
||||
cpdef double nbdtrin(double x0, double x1, double x2) noexcept nogil
|
||||
cpdef df_number_t ncfdtr(df_number_t x0, df_number_t x1, df_number_t x2, df_number_t x3) noexcept nogil
|
||||
cpdef df_number_t ncfdtri(df_number_t x0, df_number_t x1, df_number_t x2, df_number_t x3) noexcept nogil
|
||||
cpdef double ncfdtridfd(double x0, double x1, double x2, double x3) noexcept nogil
|
||||
cpdef double ncfdtridfn(double x0, double x1, double x2, double x3) noexcept nogil
|
||||
cpdef double ncfdtrinc(double x0, double x1, double x2, double x3) noexcept nogil
|
||||
cpdef df_number_t nctdtr(df_number_t x0, df_number_t x1, df_number_t x2) noexcept nogil
|
||||
cpdef double nctdtridf(double x0, double x1, double x2) noexcept nogil
|
||||
cpdef double nctdtrinc(double x0, double x1, double x2) noexcept nogil
|
||||
cpdef df_number_t nctdtrit(df_number_t x0, df_number_t x1, df_number_t x2) noexcept nogil
|
||||
cpdef Dd_number_t ndtr(Dd_number_t x0) noexcept nogil
|
||||
cpdef double ndtri(double x0) noexcept nogil
|
||||
cpdef double nrdtrimn(double x0, double x1, double x2) noexcept nogil
|
||||
cpdef double nrdtrisd(double x0, double x1, double x2) noexcept nogil
|
||||
cdef void obl_ang1(double x0, double x1, double x2, double x3, double *y0, double *y1) noexcept nogil
|
||||
cdef void obl_ang1_cv(double x0, double x1, double x2, double x3, double x4, double *y0, double *y1) noexcept nogil
|
||||
cpdef double obl_cv(double x0, double x1, double x2) noexcept nogil
|
||||
cdef void obl_rad1(double x0, double x1, double x2, double x3, double *y0, double *y1) noexcept nogil
|
||||
cdef void obl_rad1_cv(double x0, double x1, double x2, double x3, double x4, double *y0, double *y1) noexcept nogil
|
||||
cdef void obl_rad2(double x0, double x1, double x2, double x3, double *y0, double *y1) noexcept nogil
|
||||
cdef void obl_rad2_cv(double x0, double x1, double x2, double x3, double x4, double *y0, double *y1) noexcept nogil
|
||||
cpdef double owens_t(double x0, double x1) noexcept nogil
|
||||
cdef void pbdv(double x0, double x1, double *y0, double *y1) noexcept nogil
|
||||
cdef void pbvv(double x0, double x1, double *y0, double *y1) noexcept nogil
|
||||
cdef void pbwa(double x0, double x1, double *y0, double *y1) noexcept nogil
|
||||
cpdef double pdtr(double x0, double x1) noexcept nogil
|
||||
cpdef double pdtrc(double x0, double x1) noexcept nogil
|
||||
cpdef double pdtri(dlp_number_t x0, double x1) noexcept nogil
|
||||
cpdef double pdtrik(double x0, double x1) noexcept nogil
|
||||
cpdef double poch(double x0, double x1) noexcept nogil
|
||||
cpdef df_number_t powm1(df_number_t x0, df_number_t x1) noexcept nogil
|
||||
cdef void pro_ang1(double x0, double x1, double x2, double x3, double *y0, double *y1) noexcept nogil
|
||||
cdef void pro_ang1_cv(double x0, double x1, double x2, double x3, double x4, double *y0, double *y1) noexcept nogil
|
||||
cpdef double pro_cv(double x0, double x1, double x2) noexcept nogil
|
||||
cdef void pro_rad1(double x0, double x1, double x2, double x3, double *y0, double *y1) noexcept nogil
|
||||
cdef void pro_rad1_cv(double x0, double x1, double x2, double x3, double x4, double *y0, double *y1) noexcept nogil
|
||||
cdef void pro_rad2(double x0, double x1, double x2, double x3, double *y0, double *y1) noexcept nogil
|
||||
cdef void pro_rad2_cv(double x0, double x1, double x2, double x3, double x4, double *y0, double *y1) noexcept nogil
|
||||
cpdef double pseudo_huber(double x0, double x1) noexcept nogil
|
||||
cpdef Dd_number_t psi(Dd_number_t x0) noexcept nogil
|
||||
cpdef double radian(double x0, double x1, double x2) noexcept nogil
|
||||
cpdef double rel_entr(double x0, double x1) noexcept nogil
|
||||
cpdef Dd_number_t rgamma(Dd_number_t x0) noexcept nogil
|
||||
cpdef double round(double x0) noexcept nogil
|
||||
cdef void shichi(Dd_number_t x0, Dd_number_t *y0, Dd_number_t *y1) noexcept nogil
|
||||
cdef void sici(Dd_number_t x0, Dd_number_t *y0, Dd_number_t *y1) noexcept nogil
|
||||
cpdef double sindg(double x0) noexcept nogil
|
||||
cpdef double smirnov(dlp_number_t x0, double x1) noexcept nogil
|
||||
cpdef double smirnovi(dlp_number_t x0, double x1) noexcept nogil
|
||||
cpdef Dd_number_t spence(Dd_number_t x0) noexcept nogil
|
||||
cpdef double complex sph_harm(dlp_number_t x0, dlp_number_t x1, double x2, double x3) noexcept nogil
|
||||
cpdef double stdtr(double x0, double x1) noexcept nogil
|
||||
cpdef double stdtridf(double x0, double x1) noexcept nogil
|
||||
cpdef double stdtrit(double x0, double x1) noexcept nogil
|
||||
cpdef double struve(double x0, double x1) noexcept nogil
|
||||
cpdef double tandg(double x0) noexcept nogil
|
||||
cpdef double tklmbda(double x0, double x1) noexcept nogil
|
||||
cpdef double complex wofz(double complex x0) noexcept nogil
|
||||
cpdef Dd_number_t wrightomega(Dd_number_t x0) noexcept nogil
|
||||
cpdef Dd_number_t xlog1py(Dd_number_t x0, Dd_number_t x1) noexcept nogil
|
||||
cpdef Dd_number_t xlogy(Dd_number_t x0, Dd_number_t x1) noexcept nogil
|
||||
cpdef double y0(double x0) noexcept nogil
|
||||
cpdef double y1(double x0) noexcept nogil
|
||||
cpdef double yn(dlp_number_t x0, double x1) noexcept nogil
|
||||
cpdef Dd_number_t yv(double x0, Dd_number_t x1) noexcept nogil
|
||||
cpdef Dd_number_t yve(double x0, Dd_number_t x1) noexcept nogil
|
||||
cpdef double zetac(double x0) noexcept nogil
|
||||
cpdef double wright_bessel(double x0, double x1, double x2) noexcept nogil
|
||||
cpdef double log_wright_bessel(double x0, double x1, double x2) noexcept nogil
|
||||
cpdef double ndtri_exp(double x0) noexcept nogil
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
from typing import Any
|
||||
|
||||
def __getattr__(name) -> Any: ...
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
# This file is not meant for public use and will be removed in SciPy v2.0.0.
|
||||
# Use the `scipy.special` namespace for importing the functions
|
||||
# included below.
|
||||
|
||||
from scipy._lib.deprecation import _sub_module_deprecation
|
||||
|
||||
|
||||
_polyfuns = ['legendre', 'chebyt', 'chebyu', 'chebyc', 'chebys',
|
||||
'jacobi', 'laguerre', 'genlaguerre', 'hermite',
|
||||
'hermitenorm', 'gegenbauer', 'sh_legendre', 'sh_chebyt',
|
||||
'sh_chebyu', 'sh_jacobi']
|
||||
|
||||
# Correspondence between new and old names of root functions
|
||||
_rootfuns_map = {'roots_legendre': 'p_roots',
|
||||
'roots_chebyt': 't_roots',
|
||||
'roots_chebyu': 'u_roots',
|
||||
'roots_chebyc': 'c_roots',
|
||||
'roots_chebys': 's_roots',
|
||||
'roots_jacobi': 'j_roots',
|
||||
'roots_laguerre': 'l_roots',
|
||||
'roots_genlaguerre': 'la_roots',
|
||||
'roots_hermite': 'h_roots',
|
||||
'roots_hermitenorm': 'he_roots',
|
||||
'roots_gegenbauer': 'cg_roots',
|
||||
'roots_sh_legendre': 'ps_roots',
|
||||
'roots_sh_chebyt': 'ts_roots',
|
||||
'roots_sh_chebyu': 'us_roots',
|
||||
'roots_sh_jacobi': 'js_roots'}
|
||||
|
||||
|
||||
__all__ = _polyfuns + list(_rootfuns_map.keys()) + [ # noqa: F822
|
||||
'airy', 'p_roots', 't_roots', 'u_roots', 'c_roots', 's_roots',
|
||||
'j_roots', 'l_roots', 'la_roots', 'h_roots', 'he_roots', 'cg_roots',
|
||||
'ps_roots', 'ts_roots', 'us_roots', 'js_roots'
|
||||
]
|
||||
|
||||
|
||||
def __dir__():
|
||||
return __all__
|
||||
|
||||
|
||||
def __getattr__(name):
|
||||
return _sub_module_deprecation(sub_package="special", module="orthogonal",
|
||||
private_modules=["_orthogonal"], all=__all__,
|
||||
attribute=name)
|
||||
20
venv/lib/python3.13/site-packages/scipy/special/sf_error.py
Normal file
20
venv/lib/python3.13/site-packages/scipy/special/sf_error.py
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
# This file is not meant for public use and will be removed in SciPy v2.0.0.
|
||||
# Use the `scipy.special` namespace for importing the functions
|
||||
# included below.
|
||||
|
||||
from scipy._lib.deprecation import _sub_module_deprecation
|
||||
|
||||
__all__ = [ # noqa: F822
|
||||
'SpecialFunctionWarning',
|
||||
'SpecialFunctionError'
|
||||
]
|
||||
|
||||
|
||||
def __dir__():
|
||||
return __all__
|
||||
|
||||
|
||||
def __getattr__(name):
|
||||
return _sub_module_deprecation(sub_package="special", module="sf_error",
|
||||
private_modules=["_sf_error"], all=__all__,
|
||||
attribute=name)
|
||||
24
venv/lib/python3.13/site-packages/scipy/special/specfun.py
Normal file
24
venv/lib/python3.13/site-packages/scipy/special/specfun.py
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
# This file is not meant for public use and will be removed in SciPy v2.0.0.
|
||||
# Use the `scipy.special` namespace for importing the functions
|
||||
# included below.
|
||||
|
||||
from scipy._lib.deprecation import _sub_module_deprecation
|
||||
|
||||
# ruff: noqa: F822
|
||||
__all__ = [
|
||||
'clpmn',
|
||||
'lpmn',
|
||||
'lpn',
|
||||
'lqmn',
|
||||
'pbdv'
|
||||
]
|
||||
|
||||
|
||||
def __dir__():
|
||||
return __all__
|
||||
|
||||
|
||||
def __getattr__(name):
|
||||
return _sub_module_deprecation(sub_package="special", module="specfun",
|
||||
private_modules=["_basic", "_specfun"], all=__all__,
|
||||
attribute=name)
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
# This file is not meant for public use and will be removed in SciPy v2.0.0.
|
||||
# Use the `scipy.special` namespace for importing the functions
|
||||
# included below.
|
||||
|
||||
from scipy._lib.deprecation import _sub_module_deprecation
|
||||
|
||||
__all__ = ['multigammaln'] # noqa: F822
|
||||
|
||||
|
||||
def __dir__():
|
||||
return __all__
|
||||
|
||||
|
||||
def __getattr__(name):
|
||||
return _sub_module_deprecation(sub_package="special", module="spfun_stats",
|
||||
private_modules=["_spfun_stats"], all=__all__,
|
||||
attribute=name)
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue