
    uki                      d dl mZ d dlmZ d dlZd dlmZmZ d dlZ	d dl
mZ d dl
mZ d dl
mZ d dl
mZ d d	l
mZ d d
l
mZ d dl
mZ d dl
mZ d dl
mZ d dlmZmZmZ d dlmZmZmZ d dlmZ d dlm Z! d dlm"Z# d dl$m%Z%m&Z& d dl'm(Z) d dl*m+Z, d dl-m.Z.m/Z/ d dl0m1Z2 d dl0m3Z4 ddZ5edd       Z6ddZ7ddZ+dddZ8ddZ9ddZ:dd Z;dd!Z<dd"Z=dd#Z>dd$Z?dd%Z@ej                  dd&       ZBeBj                  d'        dd(ZDe)j                  ZEej                  dd)       ZFd* ZGeFj                  eG       ej                  dd+       ZId, ZJeIj                  eJ       ej                  d-        ZKd. ZLeKj                  eL       dd/ZMdd0ZN	 	 	 	 	 	 dd1ZO	 	 	 	 	 	 dd2ZP e	j                  g d3      ZRej                  ddd4       ZSddd5ZTeSj                   eeeT             dd6ZU e	j                  d7e	j                        ZW e	j                  d8e	j                        ZY e	j                  d9e	j                        ZZ e	j                  d:e	j                        Z[dd;Z\dd<Z]dd=Z^dd>Z_ eej                  d?@      dddA       Z`dB Zae`j                  ea       dC ZbdD ZcddEZd e	j                   e	j                  dFe	j                  z              ZhdG ZiddHZjddIZkddJZlddKZmdL ZndMdNddQZo edOdPgR      dMdNddS       Zp	 	 	 	 	 	 	 	 ddTZq edFU      	 	 	 	 	 	 ddV       Zr edWU      	 	 	 	 	 	 ddX       ZsddYZtddZZu ed[U      	 	 	 	 	 	 	 	 	 	 dd\       Zv	 	 d	 	 	 	 	 	 	 	 	 	 	 dd]Zw	 d	 	 	 	 	 	 	 	 	 dd^Zxdd_Zydd`ZzddaZ{ddbZ|ddcZ}dd Z~de Zdf ZddgZddhZej                  eddi              Zej                  edj               Zej                  eddk              ZddlZddmZddnZej                  edo               ZddpZddqZddrZ eej                  ds@      e#jD                  eddt                     Zej                  edu               ZddvZddwZddxZddyZddzZdd{Zej                  dd|       Zd} Zd~ Zej                  d d        d Zd Zee#jD                  d               Zee#jD                  d               Zed        Zej                  ee#jD                  dd                     Zej                  d d d        d Zd Zd Zd Zee#jD                  d               Zee#jD                  d               Zee#jD                  d               Zed        Zej                  ee#jD                  dd                     Zej                  d d d d        dd	 	 	 ddZ1dd	 	 	 ddZ3y)    )annotations)partialN)castAny)api_util)config)core)custom_derivatives)deprecations)dispatch)dtypes)lax)numpy)isposinfisneginfsinc)jitjvpvmap)_const)einsum)	vectorize)promote_args_inexactpromote_dtypes_inexact)special)betaln)Array	ArrayLike)softmax)log_softmaxc                H    t        d|       \  } t        j                  |       S )aL  Natural log of the absolute value of the gamma function.

  JAX implementation of :obj:`scipy.special.gammaln`.

  .. math::

     \mathrm{gammaln}(x) = \log(|\Gamma(x)|)

  Where :math:`\Gamma` is the :func:`~jax.scipy.special.gamma` function.

  Args:
    x: arraylike, real valued.

  Returns:
    array containing the values of the log-gamma function

  See Also:
    - :func:`jax.scipy.special.gammaln`: the natural log of the gamma function
    - :func:`jax.scipy.special.gammasgn`: the sign of the gamma function

  Notes:
    ``gammaln`` does not support complex-valued inputs.
  gammaln)r   r   lgammaxs    Q/home/cdr/jupyterlab/.venv/lib/python3.12/site-packages/jax/_src/scipy/special.pyr"   r"   ,   s     0 Iq)"!	A    c                   t        d|       \  } t        j                  | j                  t        j
                        rt        d      | j                  j                  }t        j                  |       }| dk  }t        j                  || |k(  z  t        j                  |       z  ||dz  dk7  z  | dk(  t        j                  |       z  z  g |t        j                         |d      g |d            S )a  Sign of the gamma function.

  JAX implementation of :obj:`scipy.special.gammasgn`.

  .. math::

    \mathrm{gammasgn}(x) = \begin{cases}
      +1 & \Gamma(x) > 0 \\
      -1 & \Gamma(x) < 0
    \end{cases}

  Where :math:`\Gamma` is the :func:`~jax.scipy.special.gamma` function.
  Because :math:`\Gamma(x)` is never zero, no condition is required for this case.

  * if :math:`x = -\infty`, NaN is returned.
  * if :math:`x = \pm 0`, :math:`\pm 1` is returned.
  * if :math:`x` is a negative integer, NaN is returned. The sign of gamma
    at a negative integer depends on from which side the pole is approached.
  * if :math:`x = \infty`, :math:`1` is returned.
  * if :math:`x` is NaN, NaN is returned.

  Args:
    x: arraylike, real valued.

  Returns:
    array containing the sign of the gamma function

  See Also:
    - :func:`jax.scipy.special.gamma`: the gamma function
    - :func:`jax.scipy.special.gammaln`: the natural log of the gamma function
  gammasgnz0gammasgn does not support complex-valued inputs.r                  ?)r   r   
issubdtypedtypenpcomplexfloating
ValueErrortyper   floorjnpselectisnansignbitnan)r%   typfloor_x
x_negatives       r&   r)   r)   H   s    B J*"!qww 2 23
G
HH	#IIaL'1u*	AL!SYYq\1GaK1$%16S[[^*CDF[#d)H	
 r'   c                    t        d|       \  } t        |       t        j                  t        j                  |             z  S )a  The gamma function.

  JAX implementation of :obj:`scipy.special.gamma`.

  The gamma function is defined for :math:`\Re(z)>0` as

  .. math::

     \mathrm{gamma}(z) = \Gamma(z) = \int_0^\infty t^{z-1}e^{-t}\mathrm{d}t

  and is extended by analytic continuation to arbitrary complex values `z`.
  For positive integers `n`, the gamma function is related to the
  :func:`~jax.scipy.special.factorial` function via the following identity:

  .. math::

     \Gamma(n) = (n - 1)!

  * if :math:`z = -\infty`, NaN is returned.
  * if :math:`x = \pm 0`, :math:`\pm \infty` is returned.
  * if :math:`x` is a negative integer, NaN is returned. The sign of gamma
    at a negative integer depends on from which side the pole is approached.
  * if :math:`x = \infty`, :math:`\infty` is returned.
  * if :math:`x` is NaN, NaN is returned.

  Args:
    x: arraylike, real valued.

  Returns:
    array containing the values of the gamma function

  See Also:
    - :func:`jax.scipy.special.factorial`: the factorial function.
    - :func:`jax.scipy.special.gammaln`: the natural log of the gamma function
    - :func:`jax.scipy.special.gammasgn`: the sign of the gamma function

  Notes:
    Unlike the scipy version, JAX's ``gamma`` does not support complex-valued
    inputs.
  gamma)r   r)   r   expr#   r$   s    r&   r=   r=   v   s3    R GQ'"!	!swwszz!}-	--r'   c                :    t        d| |      \  } }t        | |      S )a  Natural log of the absolute value of the beta function

  JAX implementation of :obj:`scipy.special.betaln`.

  .. math::

     \mathrm{betaln}(a, b) = \log B(a, b)

  where :math:`B` is the :func:`~jax.scipy.special.beta` function.

  Args:
    a: arraylike, real-valued.  Parameter *a* of the beta distribution.
    b: arraylike, real-valued.  Parameter *b* of the beta distribution.

  Returns:
    array containing the values of the log-beta function

  See Also:
    :func:`jax.scipy.special.beta`
  r   )r   _betaln_impl)abs     r&   r   r      s#    * 
h1	-$!Q	a	r'   c           
         |rt        d      t        d|       \  } t        j                  | dk  dt	        j
                  t	        j                  | dz                     S )a  Factorial function

  JAX implementation of :obj:`scipy.special.factorial`

  .. math::

     \mathrm{factorial}(n) = n! = \prod_{k=1}^n k

  Args:
    n: arraylike, values for which factorial will be computed elementwise
    exact: bool, only ``exact=False`` is supported.

  Returns:
    array containing values of the factorial.

  Notes:
    This computes the float-valued factorial via the :func:`~jax.scipy.special.gamma`
    function. JAX does not support exact factorials, because it is not particularly
    useful: above ``n=20``, the exact result cannot be represented by 64-bit integers,
    which are the largest integers available to JAX.

  See Also:
    :func:`jax.scipy.special.gamma`
  zfactorial with exact=True	factorialr      )NotImplementedErrorr   r4   wherer   r>   r#   )nexacts     r&   rD   rD      sN    2 
9
::K+"!	1q5!SWWSZZA%67	88r'   c                $   t        d| |      \  } }t        j                  | j                  t        j
                        rt        d      t        |       t        |      z  t        | |z         z  }|t        j                  t        | |            z  S )a!  The beta function

  JAX implementation of :obj:`scipy.special.beta`.

  .. math::

     \mathrm{beta}(a, b) = B(a, b) = \frac{\Gamma(a)\Gamma(b)}{\Gamma(a + b)}

  where :math:`\Gamma` is the :func:`~jax.scipy.special.gamma` function.

  Args:
    a: arraylike, real-valued. Parameter *a* of the beta distribution.
    b: arraylike, real-valued. Parameter *b* of the beta distribution.

  Returns:
    array containing the values of the beta function.

  See Also:
    - :func:`jax.scipy.special.gamma`
    - :func:`jax.scipy.special.betaln`
  betaz,beta does not support complex-valued inputs.)r   r   r-   r.   r/   r0   r1   r)   r   r>   r   )rA   rB   signs      r&   rK   rK      su    , 
fa	+$!Qqww 2 23
C
DD	!x{	"Xa!e_	4$	q!%	%%r'   c                    t        d| ||      \  } }}t        j                  |j                  t        j
                        rt        d      t        j                  | ||      S )a  The regularized incomplete beta function.

  JAX implementation of :obj:`scipy.special.betainc`.

  .. math::

     \mathrm{betainc}(a, b, x) = \frac{1}{B(a, b)}\int_0^x t^{a-1}(1-t)^{b-1}\mathrm{d}t

  where :math:`B(a, b)` is the :func:`~jax.scipy.special.beta` function.

  Args:
    a: arraylike, real-valued. Parameter *a* of the beta distribution.
    b: arraylike, real-valued. Parameter *b* of the beta distribution.
    x: arraylike, real-valued. Upper limit of the integration.

  Returns:
    array containing values of the betainc function

  See Also:
    - :func:`jax.scipy.special.beta`
    - :func:`jax.scipy.special.betaln`
  betaincz/betainc does not support complex-valued inputs.)	r   r   r-   r.   r/   r0   r1   r   rN   rA   rB   r%   s      r&   rN   rN      sS    . !Aq!4'!Qqww 2 23
F
GG	Q1	r'   c                H    t        d|       \  } t        j                  |       S )a  The digamma function

  JAX implementation of :obj:`scipy.special.digamma`.

  .. math::

     \mathrm{digamma}(z) = \psi(z) = \frac{\mathrm{d}}{\mathrm{d}z}\log \Gamma(z)

  where :math:`\Gamma(z)` is the :func:`~jax.scipy.special.gamma` function.

  Args:
    x: arraylike, real-valued.

  Returns:
    array containing values of the digamma function.

  Notes:
    The JAX version of `digamma` accepts real-valued inputs.

  See also:
    - :func:`jax.scipy.special.gamma`
    - :func:`jax.scipy.special.polygamma`
  digamma)r   r   rQ   r$   s    r&   rQ   rQ     s     0 Iq)"!	Qr'   c                N    t        d| |      \  } }t        j                  | |      S )a\  The regularized lower incomplete gamma function.

  JAX implementation of :obj:`scipy.special.gammainc`.

  .. math::

     \mathrm{gammainc}(x; a) = \frac{1}{\Gamma(a)}\int_0^x t^{a-1}e^{-t}\mathrm{d}t

  where :math:`\Gamma(a)` is the :func:`~jax.scipy.special.gamma` function.

  Args:
    a: arraylike, real-valued. Positive shape parameter of the gamma distribution.
    x: arraylike, real-valued. Non-negative upper limit of integration

  Returns:
    array containing values of the gammainc function.

  See Also:
    - :func:`jax.scipy.special.gamma`
    - :func:`jax.scipy.special.gammaincc`
  gammainc)r   r   igammarA   r%   s     r&   rS   rS   1  s'    , 
j!Q	/$!Q	Aq	r'   c                N    t        d| |      \  } }t        j                  | |      S )ac  The regularized upper incomplete gamma function.

  JAX implementation of :obj:`scipy.special.gammaincc`.

  .. math::

     \mathrm{gammaincc}(x; a) = \frac{1}{\Gamma(a)}\int_x^\infty t^{a-1}e^{-t}\mathrm{d}t

  where :math:`\Gamma(a)` is the :func:`~jax.scipy.special.gamma` function.

  Args:
    a: arraylike, real-valued. Positive shape parameter of the gamma distribution.
    x: arraylike, real-valued. Non-negative lower limit of integration

  Returns:
    array containing values of the gammaincc function.

  See Also:
    - :func:`jax.scipy.special.gamma`
    - :func:`jax.scipy.special.gammainc`
  	gammaincc)r   r   igammacrU   s     r&   rW   rW   K  s'    , 
k1a	0$!Q	Q	r'   c                H    t        d|       \  } t        j                  |       S )a  The error function

  JAX implementation of :obj:`scipy.special.erf`.

  .. math::

     \mathrm{erf}(x) = \frac{2}{\sqrt\pi} \int_{0}^x e^{-t^2} \mathrm{d}t

  Args:
    x: arraylike, real-valued.

  Returns:
    array containing values of the error function.

  Notes:
     The JAX version only supports real-valued inputs.

  See also:
    - :func:`jax.scipy.special.erfc`
    - :func:`jax.scipy.special.erfinv`
  erf)r   r   rZ   r$   s    r&   rZ   rZ   e  s     , E1%"!	r'   c                H    t        d|       \  } t        j                  |       S )a7  The complement of the error function

  JAX implementation of :obj:`scipy.special.erfc`.

  .. math::

     \mathrm{erfc}(x) = \frac{2}{\sqrt\pi} \int_{x}^\infty e^{-t^2} \mathrm{d}t

  This is the complement of the error function :func:`~jax.scipy.special.erf`,
  ``erfc(x) = 1 - erf(x)``.

  Args:
    x: arraylike, real-valued.

  Returns:
    array containing values of the complement of the error function.

  Notes:
     The JAX version only supports real-valued inputs.

  See also:
    - :func:`jax.scipy.special.erf`
    - :func:`jax.scipy.special.erfinv`
  erfc)r   r   r\   r$   s    r&   r\   r\     s     2 FA&"!	!r'   c                H    t        d|       \  } t        j                  |       S )a  The inverse of the error function

  JAX implementation of :obj:`scipy.special.erfinv`.

  Returns the inverse of :func:`~jax.scipy.special.erf`.

  Args:
    x: arraylike, real-valued.

  Returns:
    array containing values of the inverse error function.

  Notes:
     The JAX version only supports real-valued inputs.

  See also:
    - :func:`jax.scipy.special.erf`
    - :func:`jax.scipy.special.erfc`
  erfinv)r   r   erf_invr$   s    r&   r^   r^     s     ( Ha("!	Qr'   c                    t        d|       \  } t        j                  t        j                  | t        j                  t        | d      |                   S )zThe logit function

  JAX implementation of :obj:`scipy.special.logit`.

  .. math::

     \mathrm{logit}(p) = \log\frac{p}{1 - p}

  Args:
    x: arraylike, real-valued.

  Returns:
    array containing values of the logit function.
  logitrE   )r   r   logdivsub
_lax_constr$   s    r&   ra   ra     s>      GQ'"!	CGGJq!$4a89	::r'   c                    t        j                  | t        j                  |t        j                  t	        |d      |                  S NrE   )r   rc   mulrd   re   )gansr%   s      r&   <lambda>rk     s.    cggaCGGJq!4Da,H!IJ r'   c                H    t        d|       \  } t        j                  |       S )a   The logistic sigmoid (expit) function

  JAX implementation of :obj:`scipy.special.expit`.

  .. math::

     \mathrm{expit}(x) = \frac{1}{1 + e^{-x}}

  Args:
    x: arraylike, real-valued.

  Returns:
    array containing values of the expit function.
  expit)r   r   logisticr$   s    r&   rm   rm     s      GQ'"!	ar'   c           	         t        d| |      \  } }| dk7  }t        j                  |t        j                  | t        j
                  |            t        j                  |             S )a  Compute x*log(y), returning 0 for x=0.

  JAX implementation of :obj:`scipy.special.xlogy`.

  This is defined to return zero when :math:`(x, y) = (0, 0)`, with a custom
  derivative rule so that automatic differentiation is well-defined at this point.

  Args:
    x: arraylike, real-valued.
    y: arraylike, real-valued.

  Returns:
    array containing xlogy values.

  See also:
    :func:`jax.scipy.special.xlog1py`
  xlogy        )r   r4   rG   r   rh   rb   
zeros_liker%   yx_oks      r&   rp   rp     sN    ( 
gq!	,$!Q	
b$	4CGGAJ/1B	CCr'   c                    | \  }}|\  }}t        ||      }||t        j                  |      z  ||z  |z  z   j                  |j                        fS N)rp   r   rb   astyper.   primalstangentsr%   rt   x_doty_dotresults          r&   
_xlogy_jvpr     sS    &1a.5%A;&	%#''!*$uqy1}4<<V\\J	JJr'   c           	         t        d| |      \  } }| dk7  }t        j                  |t        j                  | t        j
                  |            t        j                  |             S )a  Compute x*log(1 + y), returning 0 for x=0.

  JAX implementation of :obj:`scipy.special.xlog1py`.

  This is defined to return 0 when :math:`(x, y) = (0, -1)`, with a custom
  derivative rule so that automatic differentiation is well-defined at this point.

  Args:
    x: arraylike, real-valued.
    y: arraylike, real-valued.

  Returns:
    array containing xlog1py values.

  See also:
    :func:`jax.scipy.special.xlogy`
  xlog1pyrq   )r   r4   rG   r   rh   log1prr   rs   s      r&   r   r      sN    ( 
iA	.$!Q	
b$	4CIIaL13>>!3D	EEr'   c                    | \  }}|\  }}t        ||      }||t        j                  |      z  ||z  d|z   z  z   j                  |j                        fS rg   )r   r   r   rx   r.   ry   s          r&   _xlog1py_jvpr     sX    &1a.5%1a=&	%#))A,&a!e)<<DDV\\R	RRr'   c                    t        | |       S )z/Compute x log(x) with well-defined derivatives.)rp   r$   s    r&   _xlogxr     s     
q!r'   c                ^    | \  }|\  }t        |      |t        j                  |      dz   z  fS rg   )r   r   rb   rz   r{   r%   r|   s       r&   
_xlogx_jvpr   $  s0    "!&%
)Ucggaj1n-
--r'   c           	     x   t        d|       \  } t        j                  | j                  t        j
                        rt        d      t        j                  t        j                  | t        | d            t        j                  | t        j                         t        j                  t        |                   S )a  The entropy function

  JAX implementation of :obj:`scipy.special.entr`.

  .. math::

     \mathrm{entr}(x) = \begin{cases}
       -x\log(x) & x > 0 \\
       0 & x = 0\\
       -\infty & \mathrm{otherwise}
     \end{cases}

  Args:
    x: arraylike, real-valued.

  Returns:
    array containing entropy values.

  See also:
    - :func:`jax.scipy.special.kl_div`
    - :func:`jax.scipy.special.rel_entr`
  entrz,entr does not support complex-valued inputs.r   )r   r   r-   r.   r/   r0   r1   r   r5   ltre   	full_likeinfnegr   r$   s    r&   r   r   +  s    . FA&"!qww 2 23
C
DD	CFF1jA./MM!bffW-GGF1I&
( (r'   c                   t        j                  t        |d      }t        d| |      \  } }t	        j
                  t	        j
                  t	        j
                  t        | d      |      t	        j                  |t        | d                  t	        j                  t        | t        j                                    }t	        j                  t        j                  ||j                        t        | d            }t        j                  t!        t        j"                  | d      t        j"                  |t%        t'        | j(                                    z
        d      }||z   S )	a-  The natural log of the multivariate gamma function.

  JAX implementation of :func:`scipy.special.multigammaln`.

  .. math::

     \mathrm{multigammaln}(a, d) = \log\Gamma_d(a)

  where

  .. math::

     \Gamma_d(a) = \pi^{d(d-1)/4}\prod_{i=1}^d\Gamma(a-(i-1)/2)

  and :math:`\Gamma(x)` is the :func:`~jax.scipy.special.gamma` function.

  Args:
    a: arraylike, real-valued.
    d: int, the dimension of the integration space.

  Returns:
    array containing values of the log-multigamma function.

  See also:
    - :func:`jax.scipy.special.gamma`
  zd argument of multigammalnmultigammalng      ?rE   r.   r*   axis)r	   concrete_or_errorintr   r   rh   re   rd   rb   r/   pirc   r4   aranger.   sumr"   expand_dimstuplerangendim)rA   dd_constantrB   ress         r&   r   r   J  s    6 S!%AB!
~q!
4%!RWWSWWSWWZ4%8"= WWRAq)9:<WWZ255124( 
ggcjj"((+Z1-=>!3eAFFm0DEF G	# 
xr'   c                    t        d| |      \  } }t        j                  | j                  t        j
                        rt        d      t        | |      | z
  |z   S )a  The Kullback-Leibler divergence.

  JAX implementation of :obj:`scipy.special.kl_div`.

  .. math::

     \mathrm{kl\_div}(p, q) = \begin{cases}
       p\log(p/q)-p+q & p>0,q>0\\
       q & p=0,q\ge 0\\
       \infty & \mathrm{otherwise}
    \end{cases}

  Args:
    p: arraylike, real-valued.
    q: arraylike, real-valued.

  Returns:
    array of KL-divergence values

  See also:
    - :func:`jax.scipy.special.entr`
    - :func:`jax.scipy.special.rel_entr`
  kl_divz.kl_div does not support complex-valued inputs.)r   r   r-   r.   r/   r0   r1   rel_entr)pqs     r&   r   r   r  sR    6 
h1	-$!Qqww 2 23
E
FF	!Q!	a	r'   c           	        t        d| |      \  } }t        j                  | j                  t        j
                        rt        d      t        | d      }t        j                  t        j                  | |      t        j                  ||            }t        j                  t        j                  | |      t        j                  ||            }t        j                  || d      }t        j                  ||d      }t        j                  t!        |      t#        ||            }t        j                  ||t        j                  ||t        j$                              }|S )a  The relative entropy function.

  JAX implementation of :obj:`scipy.special.rel_entr`.

  .. math::

     \mathrm{rel\_entr}(p, q) = \begin{cases}
       p\log(p/q) & p>0,q>0\\
       0 & p=0,q\ge 0\\
       \infty & \mathrm{otherwise}
    \end{cases}

  Args:
    p: arraylike, real-valued.
    q: arraylike, real-valued.

  Returns:
    array of relative entropy values.

  See also:
    - :func:`jax.scipy.special.entr`
    - :func:`jax.scipy.special.kl_div`
  r   z0rel_entr does not support complex-valued inputs.rq   rE   )r   r   r-   r.   r/   r0   r1   re   r   bitwise_andgteqger4   rG   rd   r   rp   r   )	r   r   zeroboth_gt_zero_maskone_zero_masksafe_psafe_qlog_valr~   s	            r&   r   r     s    6 
j!Q	/$!Qqww 2 23
G
HH	As	$oocffQosvvaG//#&&D/366!T?C-99&1-&99&1-&GGF6NE&&$9:'99#))M4"H& 
-r'   )   i0i v  i i gS`3l    KE gPqwg+cQ{Bg1oXU0gީ~#'Cg2HUgopyL.DgiTg"WDg.,c                h    |t        d      t        d| |      \  } }t        j                  | |      S )aT  The Hurwitz zeta function.

  JAX implementation of :func:`scipy.special.zeta`. JAX does not implement
  the Riemann zeta function (i.e. ``q = None``).

  .. math::

     \zeta(x, q) = \sum_{n=0}^\infty \frac{1}{(n + q)^x}

  Args:
    x: arraylike, real-valued
    q: arraylike, real-valued

  Returns:
    array of zeta function values
  [Riemann zeta function not implemented; pass q != None to compute the Hurwitz Zeta function.zeta)rF   r   r   r   )r%   r   s     r&   r   r     s=    $ Y
ce e	fa	+$!Q	!Qr'   c                    |t        d      t        d| |      \  }}t        j                  |      j                  }t        j                  |d      t        j                  |d      }}t        j                  |      t        j                  k(  r |d      n |d      x}}|t        t              k  sJ t        j                  t        j                  ||j                        t        t        |j                                    }	t        j                  ||	z   | z  d      }
t        j                   ||z    |d      |z
  z  | |d      z
        }||z   | z  }t        j                  t        j                  d|z  |j                        t        t        |j                                    }||z   ||z   z  }t        j"                  |d      d	d d df   }t        j$                  |t'        j(                  |      j*                  
      }t        j                  t        j,                  t        d |j.                  d    |      t        t        |j                                    }||z  }| |d      |j                  d      z   z  }|
|z   |z   S )Nr   r   r         r   rE   r*   .)max      ?)rF   r   r   r.   r2   r4   r   r/   float32len_BERNOULLI_COEFSr   r   r   r   r   rc   cumprodclipr   finfor   arrayshape)r%   r   srA   r.   s_a_NMkSIT0ms_over_aT1coefsTs                     r&   _zeta_series_expansionr     s   Y
ce e 
fa	+$!Q
))A,

%??1b!3??1b#9b"iilbjj0%(eBi?!a	
c"#	##	#	oobii15qvv3GH!	ggrAv2#or"!	ggq1u%(Q,'U1X6!	A1"}"	oobiiAQWW5uU166]7KL!1fa (
{{8R cc*"
xxU+//0"
.."2=BHHRL"AOuQVV}-/%	Ez"E#J#$!	
Qr'   c                r   t        j                  t        j                  |       t        j
                        s"t        dt        j                  |        d      t        d| |      \  }}t        j                  |j                  t        j                        rt        d      t        j                  ||      S )aa  The polygamma function.

  JAX implementation of :func:`scipy.special.polygamma`.

  .. math::

     \mathrm{polygamma}(n, x) = \psi^{(n)}(x) = \frac{\mathrm{d}^{n+1}}{\mathrm{d}x^{n+1}} \log \Gamma(x)

  where :math:`\psi` is the :func:`~jax.scipy.special.digamma` function and
  :math:`\Gamma` is the :func:`~jax.scipy.special.gamma` function.

  Args:
    n: arraylike, integer-valued. The order of the derivative.
    x: arraylike, real-valued. The value at which to evaluate the function.

  Returns:
    array

  See also:
    - :func:`jax.scipy.special.gamma`
    - :func:`jax.scipy.special.digamma`
  z=Argument `n` to polygamma must be of integer type. Got dtype .	polygammaz1polygamma does not support complex-valued inputs.)
r   r-   r   r.   r/   integerr1   r   r0   r   )rH   r%   n_arrx_arrs       r&   r   r     s    . 
		399Q<	4

G		RS~UVW  &k1a8,%u{{B$6$67
H
II	ue	$$r'   iir      c                    t        j                  |       } t        j                  |       }|t        j
                  t        j                  fvrt        dj                  |            t        |       S )ac  Normal distribution function.

  JAX implementation of :obj:`scipy.special.ndtr`.

  Returns the area under the Gaussian probability density function, integrated
  from minus infinity to x:

  .. math::
    \begin{align}
    \mathrm{ndtr}(x) =&
      \ \frac{1}{\sqrt{2 \pi}}\int_{-\infty}^{x} e^{-\frac{1}{2}t^2} dt \\
    =&\ \frac{1}{2} (1 + \mathrm{erf}(\frac{x}{\sqrt{2}})) \\
    =&\ \frac{1}{2} \mathrm{erfc}(\frac{x}{\sqrt{2}})
    \end{align}

  Args:
    x: An array of type `float32`, `float64`.

  Returns:
    An array with `dtype=x.dtype`.

  Raises:
    TypeError: if `x` is not floating-type.
  ?x.dtype={} is not supported, see docstring for supported types.)
r4   asarrayr   r.   r/   r   float64	TypeErrorformat_ndtrr%   r.   s     r&   ndtrr   |  sW    2 
kk!n!
))A,%
2::rzz**
I	  
q/r'   c                   t        j                  |       j                  } |d      t        j                  d|      z  }| |z  }t        j
                  |      }t        j                  t        j                  ||       |d      t        j                  |      z   t        j                  t        j                  | |d             |d      t        j                  |      z
  t        j                  |                  } |d      |z  S )zImplements ndtr core logic.r          @r   r,   rq   )r   r.   r2   r/   sqrtabsr5   r   rZ   r   r\   )r%   r.   half_sqrt_2wzrt   s         r&   r   r     s    
))A,

%c
RWWRu55++o!	ggaj!	jj;'Bi#''!*,jj59!5&+Bi#((1+&=&)hhqk34!
 
sar'   c                    t        j                  |       }|t        j                  t        j                  fvrt        dj                  |            t        |       S )a  The inverse of the CDF of the Normal distribution function.

  JAX implementation of :obj:`scipy.special.ndtri`.

  Returns `x` such that the area under the PDF from :math:`-\infty` to `x` is equal
  to `p`.

  A piece-wise rational approximation is done for the function.
  This is based on the implementation in netlib.

  Args:
    p: an array of type `float32`, `float64`.

  Returns:
    an array with `dtype=p.dtype`.

  Raises:
    TypeError: if `p` is not floating-type.
  r   )r   r.   r/   r   r   r   r   _ndtri)r   r.   s     r&   ndtrir     sK    ( ))A,%
2::rzz**
I	  
r'   c                    t        j                  |       j                  }t        j                  |       }t        j
                  g d|      }t        j
                  g d|      }t        j
                  g d|      }t        j
                  g d|      }t        j
                  g d|      }t        j
                  g d|      }t        j                  |  |t        j                  d             kD   |d	      | z
  |       }	t        j                  |	 |d
      k(  t        j                  | |d            |	      }
|
 |d      z
  }t        j                  |      }|||z  t        j                  ||      t        j                  ||      z  z  z   }| |t        j                  dt        j                  z               z  }t        j                   |d      t        j                  |
      z        }|t        j                  |      |z  z
  }t        j                  |d|z        t        j                  |d|z        z  |z  }t        j                  |d|z        t        j                  |d|z        z  |z  }||z
  }||z
  }t        j                  |
 |t        j                  d            kD  |t        j                  | |d      k\  ||            }t        j                  |  |d	t        j                  d      z
        kD  ||       }t!        j"                  d      5  t        j                  | |t        j$                              }t        j                  |  |d
      k(  | t        j                  |  |d	      k(  ||            }ddd       t'        |t(        j*                        s	 t-        j.                  d|g       |S |S # 1 sw Y   ?xY w# t0        j2                  $ r}t5        d|j6                   d      dd}~ww xY w)zImplements ndtri core logic.)g-^OMgX@gVLg;+@g~r   )	r,   gt ҕE?g@gԁ5U@g_6V.lgSi@gٷaTgcu/@gͿ)	gێ<8@gyՒm?@gBהL@gN
F@g>F^-@glz9~@gwDgAcglL)	r,   g;Z/@go)F@gF"D@gE؇.@g <	@g23¿gmENg}yN)	gtՓ	@gx'1@g+@gT?gQ&^E?gM5iPV?g3?g4"L)L>gX0:>)	r,   g(V@g8ҪMp@g b*G?g<_?gǶ'|?g)e+5?gC>g=kv)=>g       r,   rq   r   r   rE          @FNr   zinvalid value (z) encountered in ndtri.)r   r.   r2   r/   r   r   r4   rG   expm1fullsquarepolyvalr   r   rb   r>   r   
debug_infsr   
isinstancer	   Tracerr   check_specialr   InternalFloatingPointErrorFloatingPointErrorty)r   r.   r   p0q0p1q1p2q2maybe_complement_psanitized_mcpr   wwx_for_big_pr   
first_termsecond_term_small_psecond_term_otherwisex_for_small_px_otherwiser%   infinityes                          r&   r   r     s   
))A,

%
((1+%
 
xx , 49	:"
 
xx , 49:" 
xx - 5:;" 
xx - 5:;" 
xx , 49:" 
xx , 49:" yyUBHHSM>%:!:E"IM1M ))E"I%	hhueCj!- eCj !
zz!}"AFckk"b1CKKB4GGHH+%RUU
+,,,+
 
hhuSzCGGM223!3771:>!*BA.RQ1GG!K++b!a%03;;r1q53IIAM22-22+	iibffSk 22		!uSz/=+FH! 
iiE"rvvc{*++Q3! MxxuRVV}-H			U3Z(CIIa5:ox$K	MAM 
At{{	#EWqc* 
((M M .. EADD6!8
9;@DEEs%   'A*O4O OP.PP)rE   )nondiff_argnumsc                   t        |t              st        d      |dk  rt        d      |dkD  rt        d      t	        j
                  |       }t        j                  |      }|t        j                  k(  rt        }t        }nB|t        j                  k(  rt        }t        }n"t        dt        j                  |       d      t	        j                  t        j                   ||      t#        |        t	        j                  t        j                   ||      t        j$                  t#        t        j&                  ||                  t)        t        j*                  ||      |                  S )a  Log Normal distribution function.

  JAX implementation of :obj:`scipy.special.log_ndtr`.

  For details of the Normal distribution function see `ndtr`.

  This function calculates :math:`\log(\mathrm{ndtr}(x))` by either calling
  :math:`\log(\mathrm{ndtr}(x))` or using an asymptotic series. Specifically:

  - For `x > upper_segment`, use the approximation `-ndtr(-x)` based on
    :math:`\log(1-x) \approx -x, x \ll 1`.
  - For `lower_segment < x <= upper_segment`, use the existing `ndtr` technique
    and take a log.
  - For `x <= lower_segment`, we use the series approximation of `erf` to compute
    the log CDF directly.

  The `lower_segment` is set based on the precision of the input:

  .. math::
    \begin{align}
    \mathit{lower\_segment} =&
      \ \begin{cases}
        -20 &  x.\mathrm{dtype}=\mathit{float64} \\
        -10 &  x.\mathrm{dtype}=\mathit{float32} \\
        \end{cases} \\
    \mathit{upper\_segment} =&
      \ \begin{cases}
        8&  x.\mathrm{dtype}=\mathit{float64} \\
        5&  x.\mathrm{dtype}=\mathit{float32} \\
        \end{cases}
    \end{align}


  When `x < lower_segment`, the `ndtr` asymptotic series approximation is:

  .. math::
    \begin{align}
     \mathrm{ndtr}(x) =&\  \mathit{scale} * (1 + \mathit{sum}) + R_N \\
     \mathit{scale}   =&\  \frac{e^{-0.5 x^2}}{-x \sqrt{2 \pi}} \\
     \mathit{sum}     =&\  \sum_{n=1}^N {-1}^n (2n-1)!! / (x^2)^n \\
     R_N     =&\  O(e^{-0.5 x^2} (2N+1)!! / |x|^{2N+3})
    \end{align}

  where :math:`(2n-1)!! = (2n-1) (2n-3) (2n-5) ...  (3) (1)` is a
  `double-factorial
  <https://en.wikipedia.org/wiki/Double_factorial>`_ operator.


  Args:
    x: an array of type `float32`, `float64`.
    series_order: Positive Python integer. Maximum depth to
      evaluate the asymptotic expansion. This is the `N` above.

  Returns:
    an array with `dtype=x.dtype`.

  Raises:
    TypeError: if `x.dtype` is not handled.
    TypeError: if `series_order` is a not Python `integer.`
    ValueError:  if `series_order` is not in `[0, 30]`.
  z&series_order must be a Python integer.r   z"series_order must be non-negative.   zseries_order must be <= 30.x.dtype=z is not supported.)r   r   r   r1   r4   r   r   r.   r/   r   _LOGNDTR_FLOAT64_LOWER_LOGNDTR_FLOAT64_UPPERr   _LOGNDTR_FLOAT32_LOWER_LOGNDTR_FLOAT32_UPPERrG   r   r   rb   r   _log_ndtr_lowermin)r%   series_orderr   r.   lower_segmentupper_segments         r&   log_ndtrr  .  s!   ~ 
L#	&
<
==A
9
::B
2
33
++a.%
))E
%
bjj 6M 6M

*M*M
hrxx//AB
CC  
	ffUM"eV}n	iium,wwuSWWUM%BCD&swwum'D'356
7 7r'   c           
         ||c\  }\  }t        ||       }t        j                  |t        j                  t        j                  t        |      |                  }||fS )N)r  )r  r   rh   r>   rd   _norm_logpdf)r  rz   r{   r%   trj   t_outs          r&   _log_ndtr_jvpr    sO    *$1.#
''!SWWSWW\!_c:;
<%	er'   c                T   t        j                  |       j                  }t        j                  |       } |d       |z  t        j                  |        z
   |dt        j                  dt
        j                  z        z        z
  }|t        j                  t        | |            z   S )zGAsymptotic expansion version of `Log[cdf(x)]`, appropriate for `x<<-1`.r   r   )r   r.   r2   r   rb   r/   r   _log_ndtr_asymptotic_series)r%   r  r.   x_2	log_scales        r&   r  r    s}    
))A,

%

1#SzkC#''1"+-cBFF2:<N6N0OO)	SWW8LIJ	JJr'   c                   t        j                  |       j                  }|dk  rt        j                  d|      S t        j
                  |       }t        j                  |       }t        j                  |       }|}t        d|dz         D ]?  }t        j                  t        d|z  dz
        |      |z  }|dz  r||z  }n||z  }||z  }A  |d      |z   |z
  S )z2Calculates the asymptotic series used in log_ndtr.r   rE   r*   r,   )
r   r.   r2   r/   r   r   r4   rr   r   _double_factorial)	r%   r  r.   r   even_sumodd_sumx_2nrH   rt   s	            r&   r  r    s    
))A,

%Q88Au

1#^^A(NN1'	$L1$% a
"1q519-u5<A1ulg!mhCKD 
rX		''r'   c                V    t        j                  t        j                  | dd            S )z;The double factorial function for small Python integer `n`.rE   )r/   prodr   rH   s    r&   r#  r#    s    	1a$	%%r'   r*   c                    t        | d      }t        | t              }t        j                  t        j                  |t        j
                  |             |      S )N      )re   _norm_logpdf_constantr   rd   rh   r   )r%   neg_halflog_normalizers      r&   r  r    s?    4 (a!67.	3::a=1>	BBr'   c                H    t        d|       \  } t        j                  |       S )a  Exponentially scaled modified bessel function of zeroth order.

  JAX implementation of :obj:`scipy.special.i0e`.

  .. math::

     \mathrm{i0e}(x) = e^{-|x|} I_0(x)

  where :math:`I_0(x)` is the modified Bessel function :func:`~jax.scipy.special.i0`.

  Args:
    x: array, real-valued

  Returns:
    array of bessel function values.

  See also:
    - :func:`jax.scipy.special.i0`
    - :func:`jax.scipy.special.i1`
    - :func:`jax.scipy.special.i1e`
  i0e)r   r   
bessel_i0er$   s    r&   r1  r1    !    , E1%"!		r'   c                    t        d|       \  } t        j                  t        j                  t        j                  |             t        j
                  |             S )a  Modified bessel function of zeroth order.

  JAX implementation of :obj:`scipy.special.i0`.

  .. math::

     \mathrm{i0}(x) = I_0(x) = \sum_{k=0}^\infty \frac{(x^2/4)^k}{(k!)^2}

  Args:
    x: array, real-valued

  Returns:
    array of bessel function values.

  See also:
    - :func:`jax.scipy.special.i0e`
    - :func:`jax.scipy.special.i1`
    - :func:`jax.scipy.special.i1e`
  i0)r   r   rh   r>   r   r2  r$   s    r&   r5  r5    =    ( D!$"!	$cnnQ&7	88r'   c                H    t        d|       \  } t        j                  |       S )a  Exponentially scaled modified bessel function of first order.

  JAX implementation of :obj:`scipy.special.i1e`.

  .. math::

     \mathrm{i1e}(x) = e^{-|x|} I_1(x)

  where :math:`I_1(x)` is the modified Bessel function :func:`~jax.scipy.special.i1`.

  Args:
    x: array, real-valued

  Returns:
    array of bessel function values

  See also:
    - :func:`jax.scipy.special.i0`
    - :func:`jax.scipy.special.i0e`
    - :func:`jax.scipy.special.i1`
  i1e)r   r   
bessel_i1er$   s    r&   r8  r8    r3  r'   c                    t        d|       \  } t        j                  t        j                  t        j                  |             t        j
                  |             S )a  Modified bessel function of first order.

  JAX implementation of :obj:`scipy.special.i1`.

  .. math::

     \mathrm{i1}(x) = I_1(x) = \frac{1}{2}x\sum_{k=0}^\infty\frac{(x^2/4)^k}{k!(k+1)!}

  Args:
    x: array, real-valued

  Returns:
    array of bessel function values

  See also:
    - :func:`jax.scipy.special.i0`
    - :func:`jax.scipy.special.i0e`
    - :func:`jax.scipy.special.i1e`
  i1)r   r   rh   r>   r   r9  r$   s    r&   r;  r;    r6  r'   c                    | \  }}}}d|dz   z  |z  |z  |z
  }d }d }t        j                  t        j                  |d      dk(  ||||f      }|}|}||||f|fS )Nr   r,   c                    | \  }}|d|z  z   S )Nr    )ubsfs      r&   true_fn_update_bsz3_bessel_jn_scan_body_fun.<locals>.true_fn_update_bs-  s    EBa<r'   c                    | \  }}|S rw   r>  )r?  r@  _s      r&   false_fn_update_bsz4_bessel_jn_scan_body_fun.<locals>.false_fn_update_bs1  s    EBIr'   r*   r   )operand)r   condr4   mod)	carryr   f0f1r@  r   rA  rB  rE  s	            r&   _bessel_jn_scan_body_funrL  )  s    -"b"a	QWoQ#! xx1"$5"RG5" 
""
b"a!	r'   2   )n_itervrN  c          	     6   t        | d      }t        | d      }t        | d      }t        | d      }t        j                  t        |||| ft        j                  t        j
                  |       |dz         d      \  \  }}}}}|d   }|d |dz    }|||z
  z  }|S )Nrq   gؗҜ<rE   T)rA  initxsreverser   )re   r   scanrL  iotar.   )	r   rO  rN  rJ  rK  rA  r@  rD  j_valss	            r&   
_bessel_jnrW  =  s    !S"!U"C!!S"(( BA	#))A,q	)49-1aQ Qi!$1Q3<&R!V&	-r'   )static_argnamesc                  t        j                  |       } t        |       \  } t        j                  |       }t        j                  |t              rt        d      t        j                  t        j                  |d      }t        j                  t        |d      }t        t        ||      }t!        | j"                        D ]  }t%        |      } t        j&                   ||       dd      S )a  Bessel function of the first kind of integer order and real argument.

  Reference:
  Shanjie Zhang and Jian-Ming Jin. Computation of special functions.
  Wiley-Interscience, 1996.

  Args:
    z: The sampling point(s) at which the Bessel function of the first kind are
      computed.
    v: The order (int) of the Bessel function.
    n_iter: The number of iterations required for updating the function
      values. As a rule of thumb, `n_iter` is the smallest nonnegative integer
      that satisfies the condition
      `int(0.5 * log10(6.28 + n_iter) - n_iter *  log10(1.36 + abs(z) / n_iter)) > 20`.
      Details in `BJNDD` (https://people.sc.fsu.edu/~jburkardt/f77_src/special_functions/special_functions.f)

  Returns:
    An array of shape `(v+1, *z.shape)` containing the values of the Bessel
    function of orders 0, 1, ..., v. The return type matches the type of `z`.

  Raises:
    TypeError if `v` is not integer.
    ValueError if elements of array `z` are not float.
  zcomplex input not supported.zArgument v of bessel_jn.zArgument n_iter of bessel_jn.)rO  rN  r   r   )r4   r   r   r   r.   r   r-   complexr1   r	   r   operatorindexr   r   rW  r   r   r   moveaxis)r   rO  rN  z_dtypebessel_jn_funrD  s         r&   	bessel_jnr`  N  s    4 
kk!n!a "!IIaL'w(
3
44
X^^Q0JK!!!#v/NO&*&9-= (a'M(	mA&A	..r'   c                   t        j                  t        j                  | dz   |      t        j                  | dz   |      d      \  }}|rf||z  }||z  }d|z  }|dz
  |dz
  z  }t        j                  d|z  dz
  ||z
  z        }	t        j                  |dz   ||z
  z  |dz
  ||z
  z  z        }
nd|z  dz
  ||z
  z  }	||z   dz
  ||z
  z  }
t        j                  | dz   d      }t        j                  | dz   d	      }t        j
                  | dz   | dz   f|      }|j                  |   j                  |	|         }|j                  |   j                  |
|         }t         j                  d
| dz   d
| dz   d
| dz   f   \  }}}||z   |z
  dk(  j                  |      }t        j                  d||      }t        j                  d||      }||fS )a  Generates a mask for recurrence relation on the remaining entries.

  The remaining entries are with respect to the diagonal and offdiagonal
  entries.

  Args:
    l_max: see `gen_normalized_legendre`.
    is_normalized: True if the recurrence mask is used by normalized associated
      Legendre functions.

  Returns:
    Arrays representing the mask used by the recurrence relations.
  rE   r   ijindexingr   r,         @      @r*   Nr   zjk,ijk->ijk)r4   meshgridr   r   triu_indiceszerosatsetogridrx   
jnp_einsumr   )l_maxis_normalizedr.   m_matl_matc0c1c2c3d0d1d0_mask_indicesd1_mask_indicesd_zerosd0_maskd1_maskijr   mask
d0_mask_3d
d1_mask_3ds                         r&   _gen_recurrence_maskr  w  s   $ JJuqy&JJuqy&,% 	B	B	uB
#+%#+	&B	38c>b2g.	/B	BHb)rCxBG.DE	FB
+
	.B
%-#
%%-	0B$$UQY2/$$UQY2/IIuqy%!),E:'JJ'++B,?@'JJ'++B,?@' IIjuqyj*519*juqyj89'!Q
a%!)q.	 	 	'$  >*  >*
j	!!r'   )static_argnumsc           	     	   | j                   \  }}}t        j                  | d      ddd|ddf   }t        j                  |d      d|dz   ddddf   }t        j                  |d      d|ddddf   }|rt        d      |dkD  r{t        j                  d|dz
  |j
                        }	| dd|dz
  ddf   }
d	|	dz   |	z  z  }t        j                  d
||
      }|j                  dd|ddf   j                  |      }|dkD  rt        j                  d|dz
  |j
                        }	| dd|dz
  ddf   }d|	dz   |	dz   z  |	z  |	dz
  z  z  }t        j                  d
||      }|j                  dd|ddf   j                  |      }t        j                  t        j                  ||j
                        t        j                  ||j
                        d      \  }}t        j                  ||f|j
                        }t        j                  |d|      }t        j                  |f|j
                        }d|dz
  z  }|j                  |   j                  ||         }|j                  dddf   j                  |      }||z   }||dz
  z  |dz
  z  }|j                  |   j                  ||         }|j                  dddf   j                  |      }t        j                  d||      t        j                  d||      z   }d|dz   z  }|j                  |   j                  ||         }||z  |dz   z  }|j                  |   j                  ||         }t        j                  d||      t        j                  d||      z   }|||z
  dz   z  dz  }|j                  |   j                  ||         } t        j                  d| |      d|z  z
  }!|dkD  rt        j                  || j
                        }	t        j                  d
|	dz   |	z  | dddddf         }"|dkD  r|"| dddddf   z
  }"t        j                  ddt        j                  d||z  z
        z  |"      }#|!j                  dddddf   j                  |#      }!|!j                  ddddf   j                  d      }!|!S )a  Generates derivatives of associated Legendre functions of the first kind.

  Args:
    p: The 3D array containing the values of associated Legendre functions; the
      dimensions are in the sequence of order (m), degree (l), and evaluation
      points.
    x: A vector of type `float32` or `float64` containing the sampled points.
    is_normalized: True if the associated Legendre functions are normalized.
  Returns:
    The 3D array representing the derivatives of associated Legendre functions
    of the first kind.
  )r   r   )rE   r   r  N)r   r*   r  r  r*   ))r*   r   r  r  z9Negative orders for normalization is not implemented yet.rE   r   r+   i,ij->ijr,   r      rb  rc  r,  r   ij,ijk->ijkr   zj,ij->ij)r   r4   padrF   r   r.   rm  r   rj  rk  rg  ri  rh  r   )$r   r%   ro  num_mnum_lnum_xp_m_lm1	p_mp2_lm1	p_mm2_lm1l_vecp_p1coeffupdate_p_p1p_p2update_p_p2rp  rq  coeff_zerosupper_0_indiceszero_veca0	a0_maskedb0rr  	c0_maskedp_mm1_lrv  	d0_maskede0	e0_maskedp_mp1_lrJ  	f0_maskedp_derivativeg0p_derivative_m0s$                                       r&   _gen_derivativesr    s   " % GGA/0FUFA>' ggg78519a9JK) ggg78%AF) 
CE E qyjjEAIQWW5eq!EAI+q !duqyE)*e%%j%>k,,q!E'1}-11+>iqyjjEAIQWW5eq!EAI+q !deaiEAI.6%!)DEe%%j%>k,,q!E'1}-11+>iJJuAGG$JJuAGG$,%
 		5%.8+$$UAu5/YYxqww/(us{"nn_-11"_2EF)ll1a4 $$X.)u}"	R#X"s(#"nn_-11"_2EF)ll1a4 $$X.) }iA}iCD' us{"nn_-11"_2EF)	Bw"s("nn_-11"_2EF) }iC}iAB' 
UU]S !C'"nn_-11"_2EF)""=)WEgU, QYJJuAGG,E			:	U':AaAgJ	GBqy1a7b ''
C#((1q1u9:M4MrRO??1a7+//@L??1a7+//2L	r'   r  c           	        t        j                  | dz   | dz   j                  d   fj                        }t        j                  d| dz   j                        }t        j                  | j                        }|rsdt        j
                  t        j                        z  }t        j                  dt        j
                  dd|z  z         z        }t        j
                  d|z  dz         }n%d}t        j                  dd|z  z
        }d|z  dz   }|j                  d	   j                  |      }t        j                  t        j                  t        j
                  dz  z
        | j                  d   f      d
      }	|t        j                  d||	      z  }
t        j                  | dz         }|j                  |d   dd |d   dd f   j                  |
      }t        j                  dt        j                  d|      |t        j                  |                }|d   d|  |d   d|  dz   f}|j                  |   j                  |      }t        | |j                        \  fd}|j!                  t#        j$                  |            }| dkD  rt'        j(                  d| dz   ||      }|S )u
  Computes associated Legendre functions (ALFs) of the first kind.

  The ALFs of the first kind are used in spherical harmonics. The spherical
  harmonic of degree `l` and order `m` can be written as
  `Y_l^m(θ, φ) = N_l^m * P_l^m(cos(θ)) * exp(i m φ)`, where `N_l^m` is the
  normalization factor and θ and φ are the colatitude and longitude,
  respectively. `N_l^m` is chosen in the way that the spherical harmonics form
  a set of orthonormal basis functions of L^2(S^2). For the computational
  efficiency of spherical harmonics transform, the normalization factor is
  used in the computation of the ALFs. In addition, normalizing `P_l^m`
  avoids overflow/underflow and achieves better numerical stability. Three
  recurrence relations are used in the computation.

  Args:
    l_max: The maximum degree of the associated Legendre function. Both the
      degrees and orders are `[0, 1, 2, ..., l_max]`.
    x: A vector of type `float32`, `float64` containing the sampled points in
      spherical coordinates, at which the ALFs are computed; `x` is essentially
      `cos(θ)`. For the numerical integration used by the spherical harmonics
      transforms, `x` contains the quadrature points in the interval of
      `[-1, 1]`. There are several approaches to provide the quadrature points:
      Gauss-Legendre method (`scipy.special.roots_legendre`), Gauss-Chebyshev
      method (`scipy.special.roots_chebyu`), and Driscoll & Healy
      method (Driscoll, James R., and Dennis M. Healy. "Computing Fourier
      transforms and convolutions on the 2-sphere." Advances in applied
      mathematics 15, no. 2 (1994): 202-250.). The Gauss-Legendre quadrature
      points are nearly equal-spaced along θ and provide exact discrete
      orthogonality, (P^m)^T W P_m = I, where `T` represents the transpose
      operation, `W` is a diagonal matrix containing the quadrature weights,
      and `I` is the identity matrix. The Gauss-Chebyshev points are equally
      spaced, which only provide approximate discrete orthogonality. The
      Driscoll & Healy quadrature points are equally spaced and provide the
      exact discrete orthogonality. The number of sampling points is required to
      be twice as the number of frequency points (modes) in the Driscoll & Healy
      approach, which enables FFT and achieves a fast spherical harmonics
      transform.
    is_normalized: True if the associated Legendre functions are normalized.
      With normalization, `N_l^m` is applied such that the spherical harmonics
      form a set of orthonormal basis functions of L^2(S^2).

  Returns:
    The 3D array of shape `(l_max + 1, l_max + 1, len(x))` containing the values
    of the ALFs at `x`; the dimensions in the sequence of order, degree, and
    evaluation points.
  rE   r   r   r   r   r,   r   rf  r  r   r  Nz	ij,ij->ijzi,j->ij)ro  r.   c                   |    }|    }t        j                  d|t        j                  dt        j                  |dd                  t        j                  d|t        j                  |dd            z
  }||z   }|S )Nr  z
ijk,k->ijkrE   )shiftr   r*   )rm  r   r4   roll)r}  p_valcoeff_0coeff_1hr  r  r%   s        r&   body_funz*_gen_associated_legendre.<locals>.body_fun]  s    mGmG			=%%$chhuAA&FK
L 
		='388EQR3S	T	
UA
 AIELr'   r*   )lowerupperr  init_val)r4   ri  r   r.   r   r   r/   r   r   rj  rk  broadcast_torm  r   diag_indicesr  rx   r   result_typer   	fori_loop)rn  r%   ro  r   a_idxb_idxinitial_valuef_af_brt   p_diagr  	p_offdiagoffdiag_indicesr  r  r  s    `             @@r&   _gen_associated_legendrer  
  sw   b 
iiEAIqwwqz2!''B!
**Q	
1%
**U!''
*%"SXXbee_4M
++b388C#+$566
7C
((3;$
%CM
++cC%K'
(C
+
Cdd6l}%! 
kk	sxxa!e,uaggaj.AB! :,,Za@@&!!%!),,ddLOABa!456::6B! #**9c1=3++E235) "!_Ve,l1ofu.E.IJ/dd?	*! 0=9*j	 hhv!!!Q
34!
QYAU1Wx!LA	
(r'   c                   t        j                  |      }|t        j                  t        j                  fvrt        dj                  |            |j                  dk7  rt        d      t        j                  t        | d      } t        j                  t        |d      }| |k7  rt        d      |}d}t        |||      }t        |||      }||fS )aH  The associated Legendre functions (ALFs) of the first kind.

  Args:
    m: The maximum order of the associated Legendre functions.
    n: The maximum degree of the associated Legendre function, often called
      `l` in describing ALFs. Both the degrees and orders are
      `[0, 1, 2, ..., l_max]`, where `l_max` denotes the maximum degree.
    z: A vector of type `float32` or `float64` containing the sampling
      points at which the ALFs are computed.

  Returns:
    A 2-tuple of 3D arrays of shape `(l_max + 1, l_max + 1, len(z))` containing
    the values and derivatives of the associated Legendre functions of the
    first kind. The return type matches the type of `z`.

  Raises:
    TypeError if elements of array `z` are not in (float32, float64).
    ValueError if array `z` is not 1D.
    NotImplementedError if `m!=n`.
  ?z.dtype={} is not supported, see docstring for supported types.rE   z must be a 1D array.Argument m of lpmn.Argument n of lpmn.,Computations for m!=n are not yet supported.F)r   r.   r/   r   r   r   r   r   r1   r	   r   r   rF   r  r  )r   rH   r   r.   rn  ro  p_valsp_derivativess           r&   lpmnr  p  s    * ))A,%
2::rzz**
I	  VVq[
,
--
S!%:;!
S!%:;!!V
L
MM
%-#E1m<&"61m<-
-	  r'   c                   t        j                  |      }|t        j                  t        j                  fvrt        dj                  |            |j                  dk7  rt        d      t        j                  t        | d      } t        j                  t        |d      }| |k7  rt        d      |}t        |||      S )u}  The associated Legendre functions (ALFs) of the first kind.

  Unlike `lpmn`, this function only computes the values of ALFs.
  The ALFs of the first kind can be used in spherical harmonics. The
  spherical harmonic of degree `l` and order `m` can be written as
  :math:`Y_l^m(\theta, \phi) = N_l^m * P_l^m(\cos \theta) * \exp(i m \phi)`,
  where :math:`N_l^m` is the normalization factor and θ and φ are the
  colatitude and longitude, respectively. :math:`N_l^m` is chosen in the
  way that the spherical harmonics form a set of orthonormal basis function
  of :math:`L^2(S^2)`. Normalizing :math:`P_l^m` avoids overflow/underflow
  and achieves better numerical stability.

  Args:
    m: The maximum order of the associated Legendre functions.
    n: The maximum degree of the associated Legendre function, often called
      `l` in describing ALFs. Both the degrees and orders are
      `[0, 1, 2, ..., l_max]`, where `l_max` denotes the maximum degree.
    z: A vector of type `float32` or `float64` containing the sampling
      points at which the ALFs are computed.
    is_normalized: True if the associated Legendre functions are normalized.
      With normalization, :math:`N_l^m` is applied such that the spherical
      harmonics form a set of orthonormal basis functions of :math:`L^2(S^2)`.

  Returns:
    A 3D array of shape `(l_max + 1, l_max + 1, len(z))` containing
    the values of the associated Legendre functions of the first kind. The
    return type matches the type of `z`.

  Raises:
    TypeError if elements of array `z` are not in (float32, float64).
    ValueError if array `z` is not 1D.
    NotImplementedError if `m!=n`.
  r  rE   r  r  r  r  )r   r.   r/   r   r   r   r   r   r1   r	   r   r   rF   r  )r   rH   r   ro  r.   rn  s         r&   lpmn_valuesr    s    D ))A,%
2::rzz**
I	  VVq[
,
--
S!%:;!
S!%:;!!V
L
MM
%	!%M	::r'   )   c                h   t        j                  |      }t        ||d      }|j                  t	        |      | t        j
                  t        |             f   j                  d      }t	        |      |z  }t        j                  t        j                  |      t        j                  |            }	t        j                  |t        j                  |	      z  |t        j                  |	      z        }
t        j                  |dk  dt	        |      z  t        j                  |
      z  |
      }
|
S )z!Computes the spherical harmonics.Tr   )moder   r+   )r4   cosr  rj  r   r   r   getr   rZ  sinrealimagrG   	conjugate)rH   r   thetaphin_maxcos_colatitudelegendrelegendre_valanglevandermonde	harmonicss              r&   	_sph_harmr    s     775>.%e^TB(SVQ

3q6(::;??V?L,
a&3,%CGGENCGGEN;+kk,+)>>&+)>>@) iiAAy)AA!#) 
r'   c                    |t        d      t        j                  |      rt        j                  |g      }|t	        j
                  |       }t        j                  t        |d      }t        | ||||      S )a0  Computes the spherical harmonics.

  The JAX version has one extra argument `n_max`, the maximum value in `n`.

  The spherical harmonic of degree `n` and order `m` can be written as
  :math:`Y_n^m(\theta, \phi) = N_n^m * P_n^m(\cos \theta) * \exp(i m \phi)`,
  where :math:`N_n^m = \sqrt{\frac{\left(2n+1\right) \left(n-m\right)!}
  {4 \pi \left(n+m\right)!}}` is the normalization factor and :math:`\theta` and
  :math:`\phi` are the colatitude and longitude, respectively. :math:`N_n^m` is
  chosen in the way that the spherical harmonics form a set of orthonormal basis
  functions of :math:`L^2(S^2)`.

  Args:
    n: The degree of the harmonic; must have `n >= 0`. The standard notation for
      degree in descriptions of spherical harmonics is `l (lower case L)`. We
      use `n` here to be consistent with `scipy.special.sph_harm_y`. Return
      values for `n < 0` are undefined.
    m: The order of the harmonic; must have `|m| <= n`. Return values for
      `|m| > n` are undefined.
    theta: The polar (colatitudinal) coordinate; must be in [0, pi].
    phi: The azimuthal (longitudinal) coordinate; must be in [0, 2*pi].
    diff_n: Unsupported by JAX.
    n_max: The maximum degree `max(n)`. If the supplied `n_max` is not the true
      maximum value of `n`, the results are clipped to `n_max`. For example,
      `sph_harm(m=jnp.array([2]), n=jnp.array([10]), theta, phi, n_max=6)`
      actually returns
      `sph_harm(m=jnp.array([2]), n=jnp.array([6]), theta, phi, n_max=6)`
  Returns:
    A 1D array containing the spherical harmonics at (m, n, theta, phi).
  zGThe 'diff_n' argument to jax.scipy.special.sph_harm_y is not supported.zThe `n_max` argument of `jnp.scipy.special.sph_harm` must be statically specified to use `sph_harm` within JAX transformations.)
rF   r4   isscalarr   r/   r   r	   r   r   r  )rH   r   r  r  diff_nr  s         r&   
sph_harm_yr    s~    H 
QS S 	\\%IIugE
]FF1IE

 
 	5 NO% 
1aU	++r'   c                R    t        j                  ddd       t        || |||      S )a  Computes the spherical harmonics.

  Note:
    This function is deprecated, and :func:`~jax.scipy.special.sph_harm_y`
    should be used instead, noting that the order of ``m`` and ``n`` are
    reversed, and definitions of ``theta`` and ``phi`` are swapped.

  The JAX version has one extra argument `n_max`, the maximum value in `n`.

  The spherical harmonic of degree `n` and order `m` can be written as
  :math:`Y_n^m(\theta, \phi) = N_n^m * P_n^m(\cos \phi) * \exp(i m \theta)`,
  where :math:`N_n^m = \sqrt{\frac{\left(2n+1\right) \left(n-m\right)!}
  {4 \pi \left(n+m\right)!}}` is the normalization factor and :math:`\phi` and
  :math:`\theta` are the colatitude and longitude, respectively. :math:`N_n^m` is
  chosen in the way that the spherical harmonics form a set of orthonormal basis
  functions of :math:`L^2(S^2)`.

  Args:
    m: The order of the harmonic; must have `|m| <= n`. Return values for
      `|m| > n` are undefined.
    n: The degree of the harmonic; must have `n >= 0`. The standard notation for
      degree in descriptions of spherical harmonics is `l (lower case L)`. We
      use `n` here to be consistent with `scipy.special.sph_harm`. Return
      values for `n < 0` are undefined.
    theta: The azimuthal (longitudinal) coordinate; must be in [0, 2*pi].
    phi: The polar (colatitudinal) coordinate; must be in [0, pi].
    n_max: The maximum degree `max(n)`. If the supplied `n_max` is not the true
      maximum value of `n`, the results are clipped to `n_max`. For example,
      `sph_harm(m=jnp.array([2]), n=jnp.array([10]), theta, phi, n_max=6)`
      actually returns
      `sph_harm(m=jnp.array([2]), n=jnp.array([6]), theta, phi, n_max=6)`
  Returns:
    A 1D array containing the spherical harmonics at (m, n, theta, phi).
  zjax-scipy-special-sph-harmzjax.scipy.special.sph_harm is deprecated. Please use jax.scipy.special.sph_harm_y instead, noting that the order of `m` and `n` are reversed, and definitions of `theta` and `phi` are swapped.r*   )
stacklevel)r  )r   warnr  )r   rH   r  r  r  s        r&   sph_harmr  !  s6    R "M  
Aq#uE	22r'   c                @   t        j                  g d| j                        }t        j                  g d| j                        }t        j                  ||       t        j                  ||       z  }| |z  t         j
                  z   t        j                  |       z   S )N)gfgrG(Pk@g`χPg>x@gN	P(9煘)3M8Ar   )r,   gX$@JgEv@g_'g鏱9Ag-C&r  )r/   r   r.   r4   r   euler_gammarb   )r%   ABrA  s       r&   _expint1r  Z  s~    hh  77! 	hh  77! 
kk!Q#++a++!	
Q	#''!*	,,r'   c                    t        |d      }||z  }t        j                  | |      t        j                  ||      z  }||z  |z   }t        j                  |      |z  |z  S Nr,   )re   r4   r   r>   )r  r  r%   oner   rA  s         r&   _eval_expint_kr  q  s[    1c#	Ag!	kk!Q#++a++!!eck!	a!	r'   c                    t        j                  g d| j                        }t        j                  g d| j                        }t        |||       S )N)g`V,1K?gN{Xg+qg gmZ@g0$N8ܿg=S?g`PYg,n߁?r   )r,   gA?gE]l?gIUW?gScjw?gY)R:r?gSS&?gٹ?r/   r   r.   r  r%   r  r  s      r&   _expint2r  z  sM    hh 	 77	! 	hh 	 77	! 
1a	  r'   c                    t        j                  g d| j                        }t        j                  g d| j                        }t        |||       S )N)g󲛯g/Sg!J?gwh]Lпga*\?g*reQgL?gr>r   )	r,   giy?gT]j?g\?gw.?gTp1L?gxV>?gТӾgv[>r  r  s      r&   _expint3r    M    hh 	 77	! 	hh 
 77
! 
1a	  r'   c                    t        j                  g d| j                        }t        j                  g d| j                        }t        |||       S )N)
gܞH  gn&G?gDϿg(Kȗ?go /?g}$4
gJԼǾ>gGW󇘾g3uO>g^]h8>r   )
r,   g$>:TJjͿgD;J?g`0
gO. uf?gTzb+g٨%L>gR*
흾gBw6,M>gl\[">r  r  s      r&   _expint4r    sM    hh  77! 	hh  77! 
1a	  r'   c                    t        j                  g d| j                        }t        j                  g d| j                        }t        |||       S )N)gvϿg5F9¿g	?%=?gg V?g4gP/CU.>g/fr   )	r,   g9\pg\!ѿgE{H"Ѹ?gOVfgiCkX?g.G/g[Y>gZ<fr  r  s      r&   _expint5r    r  r'   c                    t        j                  g d| j                        }t        j                  g d| j                        }t        |||       S )N)g
?g[Og}?g$ D!g[X?g(tr   )r,   g9	gNe?g}8gНNfY?g⏩tr  r  s      r&   _expint6r    sM    hh  77! 	hh  77! 
1a	  r'   c                    t        j                  g d| j                        }t        j                  g d| j                        }t        |||       S )N)	gi|Ng.;<8+	?gJΨL˿gҵ b!?gp3ig\&?gw}ϙپg	l Y>g2r   )
r,   gW[8gwM+?gC68ѿgJ? ?g+kg=x(?gMd~yھg|e[gã>g/r  r  s      r&   _expint7r    sM    hh 
 77
! 	hh  77! 
1a	  r'   c                6   t         } || d      | k  |  || d      k  z  gt        dd      D cg c]$  } || d|z        | k  |  || d|dz   z        k  z  & c}z   }t        j                  | |t        t
        t        t        t        t        t        g      S c c}w )Nr   r*   rE      )re   r   r4   	piecewiser  r  r  r  r  r  r  )r%   _cr}  condss       r&   	_expi_posr    s    "q!HqLQ"Q(]+
,>CAqk09:R16]Q11aAEl 3340 % 
	x8XxJ
 0s   )Bc                    t        |         S rw   )exp1r$   s    r&   	_expi_negr  !  s    
r(r'   c                    t        d|       \  }t        j                  |j                  t        j
                        rt        d      t        j                  ||dk  gt        t        g      S )aH  Exponential integral function.

  JAX implementation of :obj:`scipy.special.expi`

  .. math::

     \mathrm{expi}(x) = \int_{-\infty}^x \frac{e^t}{t} \mathrm{d}t

  Args:
    x: arraylike, real-valued

  Returns:
    array of expi values

  See also:
    - :func:`jax.scipy.special.expn`
    - :func:`jax.scipy.special.exp1`
  expiz,expi does not support complex-valued inputs.r   )r   r   r-   r.   r/   r0   r1   r4   r  r  r  )r%   r   s     r&   r
  r
  %  sV    *  *&%u{{B$6$67
C
DD	uuqykIy+A	BBr'   c                ^    | \  }|\  }t        |      t        j                  |      |z  |z  fS rw   )r
  r4   r>   r   s       r&   expi_jvpr  ?  s2     
$1(5	a#''!*q.5(	((r'   c                J   t        d|       \  } t        j                  | j                  t        j
                        rt        d| j                   d      t        j                  |       }t        |      \  }}t        |      \  }}t        |      \  }}|dk  }|dkD  |dk  z  }	t        j                  ||	g||g|      }
t        j                  ||	g||g|      }t        j                  |       |
z  }
t        j                  t        |       t        j                   |      }|
|fS )uS  Sine and cosine integrals.

  JAX implementation of :obj:`scipy.special.sici`.

  .. math::

    \mathrm{Si}(x) = \int_0^x \frac{\sin t}{t} \, dt

  .. math::

    \mathrm{Ci}(x) = \gamma + \ln(x) + \int_0^x \frac{\cos t - 1}{t} \, dt

  where :math:`\gamma` is the Euler–Mascheroni constant.

  Args:
    x: array-like, real-valued input.

  Returns:
    A tuple of two arrays, each with the same shape as `x`:
      - The first array contains the sine integral values `Si(x)`.
      - The second array contains the cosine integral values `Ci(x)`.

  See also:
    - :func:`jax.numpy.sinc`
  siciz4Argument `x` to sici must be real-valued. Got dtype r   r  g    eA)r   r   r-   r.   r/   r0   r1   r4   r   _sici_series_sici_asympt_sici_approxr5   rL   rG   r   r8   )r%   x_abs	si_series	ci_seriessi_asympci_asymp	si_approx	ci_approxcond1cond2sicis               r&   r  r  G  s   : FA&"!qww 2 23
<QWWIQG  ''!*%%e,)Y%e,(X&u-)Y
1*%19#
&%
zz5%.9h"7C"
zz5%.9h"7C"
xx{R"
yy!bffb)"	R-r'   c                4   t         j                  dz  t        j                  |       | z  z
  }t        j                  |       | z  }t        j
                  t        |       t         j                  dz  |      }t        j
                  t        |       d|      }||fS )Nr*   rq   )r/   r   r4   r  r  rG   r   )r%   r  r  s      r&   r  r  |  sn    
	SWWQZ!^#"
wwqzA~"
yy!beeai,"
yy!c2&"	R-r'   c                    d }d }t        j                  | dk(  d ||             }t        j                  | dk(  t        j                    ||             }||fS )Nc                    t        j                  g d| j                        }t        j                  g d| j                        }| | z  }| t        j                  ||      z  t        j                  ||      z  S )N)gN]׽g+h>g'`vg&>-P?g6)p+r,   r   )go7=gk6#h>g
g>g(?gҌ[?r,   )r/   r   r.   r4   r   )r%   SNSDr  s       r&   r  z_sici_series.<locals>.si_series  sm    	  
 ()ww
0B 
 !
 )*
1B 	
AAB""ckk"a&888r'   c                F   t        j                  g d| j                        }t        j                  g d| j                        }| | z  }t         j                  t	        j
                  |       z   |t	        j                  ||      z  t	        j                  ||      z  z   S )N)g<D=g.kMgef\r$>g'`s?g2E%?r+   r   )g#q=gjh{/Z*>g)/ث>g,b4?gP,
?re  )r/   r   r.   r  r4   rb   r   )r%   CNCDr  s       r&   r  z_sici_series.<locals>.ci_series  s    	 !
 )*
1B 
  
 ()ww
0B 	
AA>>CGGAJ&S[[Q-?)?#++bRSBT)TTTr'   r   rq   )r4   rG   r/   r   )r%   r  r  r  r  s        r&   r  r    s`    9"U" yyFaL" yyFVVGaL" 
R-r'   c                   t        j                  |       }t        j                  |       }d| | z  z  }t        j                  g d| j
                        }t        j                  g d| j
                        }t        j                  g d| j
                        }t        j                  g d| j
                        }t        j                  g d| j
                        }t        j                  g d| j
                        }	t        j                  g d	| j
                        }
t        j                  g d
| j
                        }t        j                  ||      | t        j                  ||      z  z  }|t        j                  ||      z  t        j                  ||      z  }t        j                  ||      | t        j                  |	|      z  z  }|t        j                  |
|      z  t        j                  ||      z  }| dk  }t        j                  |||      }t        j                  |||      }t        j                  dz  ||z  z
  ||z  z
  }||z  ||z  z
  }||fS )Nr,   )gz@g"f@g qt?g y`?gc~{?gu4?g%@5[k>r   )rE   gwvT @gml;@g׹f?gv!r?g-x;|?gG?gEڸkk>)g[/]2L?gyVj?g)fk?gVS')?g1rv?gf;%?g Q=>gFF@>)rE   g	M?gjAuMR?g-#ʽP?gwL~y?g0zU&?gt.ʢ >g&ZMVF@>)	g/]&-?gHNj?g0?gyŇ?g&	}6?g̲d>g	bR/a>g^B/=z.=Q;=)	r,   gr[?gF*?g[	?go㫨7?g2{>g
f1FHa>g@.=r&  )	gʆ2P?guٖt%?g׮?g"Yb"\?ghK?g=K>g΢;wF>gd]=cEI<)
r,   g7M?gy8?g^W%?g^qHy-_?g9"Y1Q?g>goq<&>g|X=r'  r   r*   )	r4   r  r  r/   r   r.   r   rG   r   )r%   r   cr   FN4FD4GN4GD4FN8FD8GN8GD8f4g4f8g8r  rA  ri   r  r  s                        r&   r  r    s   	ggaj!	ggaj!	QUm! 	  77	# 	 	 77		# 	 	 77		# 	 	 77		# 	 
 77
	# 	 
 77
	# 	 
 77
	# 	  77	# {{3a#++c1"556"3;;sAS!!44"
{{3a#++c1"556"3;;sAS!!44"	
S$	iib"!	iib"!
	QUQU""1uq1u}"	R-r'   c                    | |c\  }\  }t        |      }t        |t        j                  z        }t	        j
                  |      |z  }||z  ||z  f}||fS rw   )r  r   r/   r   r4   r  )rz   r{   r   r  
primal_outsin_termcos_termtangent_outs           r&   sici_jvpr:  $	  s[     *$1Aw*!bee)_(WWQZ!^(Ax!|,+	[	  r'   c                  
 t         t        j                  | j                        j                  
 | d       | d      t
        j                   t        j                  |       z
  }t        j                   |d      |fd|      }t        j                  | |d      k(  z   |      }t        | |  |z
  t        j                  | |d      k(  |z
  z        t
        j                        }fd}
fd}t        j                  |||      }|}| |d      z
  }	|d   |	z  |z  t        j                  t!        |            z  |d	   z
  S )
Nrq   r,   rE   c                    || z  z   S rw   r>  )r}  psir  s     r&   rk   z_expn1.<locals>.<lambda>9	  s    #a- r'   )r%   r   xkykpkrj   r  c           	     .   | dxx   z  cc<   | dxx   | d   | d   z  z  cc<   | dxx   z  cc<   | dxx   t        j                  | d   k7  | d   | d   z        z  cc<   t        j                  | d   k7  t        | d   | d   z              | d<   | S )Nr>  r?  r   r@  rj   r  r4   rG   r   )r   r  r   s    r&   bodyz_expn1.<locals>.bodyE	  s    dGsNGdGqv$GdGsNGeH		!D'T/1T7QtW+<dCCHYYqx4'QtWqx-?)@#FAcFHr'   c                :    | d    | d   d      kD  | d   kD  z  S )Nr%   rq   r  r>  r   MACHEPr  s    r&   rG  z_expn1.<locals>.condM	  s)    cFR#_$3&99r'   r   rj   )re   r   r   r.   epsr/   r  r4   rb   r   r  rG   dictr   
while_loopr>   r"   )r%   rH   r=  n1rQ  rC  rG  r   r  rrF  r  r  r   s             @@@@r&   _expn1rL  1	  s2   "<< $$&	As$
1c
#	#''!*$#bAh#?E#
yybAhc	1-"	b

Qw		!r!Qx-scBh'78ff
$: 
nnT4&!!"Q(l!	
31s	SWWWQZ0	01U8	;;r'   c                  	
 t          | d      t        j                  | j                        j                   | d      
 | d      	t         d      	| 	| z   	| z   z   | t        j                        
| 	      }	
fd}fd}t        j                  |||      }|d   t        j                  |        z  S )	Ng      Crq   r,   rE   )	r   pkm2qkm2pkm1qkm1rj   r  rK  r%   c           	        | d   }| dxx    | d   d      z  cc<   | d   }| |d      z   |d      k(  }t        j                  ||      }t        j                  || |d      z
   |d      z  z   | |d      z        }| d   |z  | d   |z  z   }| d   |z  | d   |z  z   }|k7  }t        j                  |||z  | d	         x| d	<   }	t        j                  |t        | d
   |	z
  |	z              | d<   t        j                  ||	| d
         | d
<   | d   | d<   || d<   | d   | d<   || d<   t        |      kD  }
dD ]4  }dD ]-  }|dz   |z   }t        j                  |
| |   z  | |         | |<   / 6 | S )Nr%   r   rE   r*   rP  rN  rQ  rO  rK  rj   r  pq12kmrB  )r   r%   r   oddr?  r>  r@  qknzrK  is_bigr   r}  keyBIGr  rH   r  r   s                 r&   rC  z_expn2.<locals>.bodyj	  s   	#AcFb3mF	#A
bAh,"Q(
"C	3Q	B	3QAq\R1X55q2a8|	DB	
6R!F)b.	(B	
6R!F)b.	(B	tB2rBw#//AcFQYYr3%112C8AcFyyQ%)AeH&	AfIAfI&	AfIAfIWs]F 9 9!$hl61S6C<38#99 Hr'   c                :    | d    | d   d      kD  | d   kD  z  S )Nr%   r   r   r  r>  rE  s    r&   rG  z_expn2.<locals>.cond	  s)    cFR#]"qv77r'   rj   )re   r   r   r.   rG  rH  r/   r   r   rI  r4   r>   )r%   rH   rQ  rC  rG  r   r[  rF  r  r  r   s    `    @@@@@r&   _expn2r]  V	  s    "
1$%#<< $$&	As$
1c
#	Ah		
		
Qq1uBFFm


$ 08 
nnT4&!	
5CGGQBK	r'   c                   t         } || d      }| |z   }|||z  z  }|}||z   || d      | z  | z   || d      |z  | z  z
  ||z  z   z  }|||| || d      | z  z
  z  z   z  }|||z   z  }||z   t        j                  |        z  |z  S )Nr,   r  r   r*   )re   r4   r>   )r%   rH   r  r  r>  r?  r  rj   s           r&   _expn3r_  	  s    "
1c
#1u"
b2g"!
Q"Q(Q,"R1X\A%55A=>#
cAR1X\)**+#
cAg#
)swwr{	"R	''r'   )r   c           	        t        d| |      \  } }t        j                  |j                  t        j
                        rt        d      t        } ||d      } ||d      }|  || d      k  ||k  z  ||k(  |  || d      k  z  ||k(  |  || d      k\  z  |  || d      k(  ||k\  z  |  || d      k\  ||kD  g}t        j                  |  || d      k(  | | z   |       }t        j                  t        j                  ||z  t        j                  |       |z  t        t        t        g}t        j                   ||||       }|S )a  Generalized exponential integral function.

  JAX implementation of :obj:`scipy.special.expn`.

  .. math::

     \mathrm{expn}(x) = E_n(x) = x^{n-1}\int_x^\infty\frac{e^{-t}}{t^n}\mathrm{d}t

  Args:
    n: arraylike, real-valued
    x: arraylike, real-valued

  Returns:
    array of expn values

  See also:
    - :func:`jax.scipy.special.expi`
    - :func:`jax.scipy.special.exp1`
  expnz,expn does not support complex-valued inputs.r   rE   r*   i  r*  )r   r   r-   r.   r/   r0   r1   re   r4   rG   r8   r   r>   r_  r]  rL  r  )	rH   r%   r  r   r  r  rJ  valsrets	            r&   ra  ra  	  s>   . 
fa	+$!Qqww 2 23
C
DD"	Aq$
1a#Aq\a$h$Y1r!Qx< $Y11a=!"Q(]qDy!"Q+W% yybAhAq)"FFFF"HGGQBK!O



$ 	a*#	*r'   c                    ||c\  }\  }t        | |      t        j                  t        j                  |      t        t        j                  | t        | d            |            fS rg   )ra  r   rh   r   rd   re   )rH   rz   r{   r%   r|   s        r&   expn_jvpre  	  sW     H.$1	aSWWGGENDJq!$45q9 
 r'   c                    t        d|       \  } t        j                  | j                  t        j
                        rt        d      t        t        t        d|             S )aW  Exponential integral function.

  JAX implementation of :obj:`scipy.special.exp1`

  .. math::

     \mathrm{exp1}(x) = E_1(x) = x^{n-1}\int_x^\infty\frac{e^{-t}}{t}\mathrm{d}t


  Args:
    x: arraylike, real-valued

  Returns:
    array of exp1 values

  See also:
    - :func:`jax.scipy.special.expi`
    - :func:`jax.scipy.special.expn`
  r  z,exp1 does not support complex-valued inputs.rE   )
r   r   r-   r.   r/   r0   r1   r   r   ra  r$   s    r&   r  r  	  sK    ( FA&"!qww 2 23
C
DD	eT!QZ	  r'   c                    t        j                  g d| j                        }t        j                  g d| j                        }|  t        j                  ||       z  t        j                  ||       z  S )N)g
b?g4ھcD}?gh\Qa!?gdn&?gj[!&@g'4z#@g#+wa
@r,   r   )grF?g! #ך?g?4B?g)m?gN@goR7c!@g#+wa@r,   )r4   r   r.   r   )r   r  r  s      r&   _spence_polyrh  	  sf    	ii  77$! 
ii  ''#! ckk!Q	#++a"3	33r'   c                   | dkD  }t        j                  | |gd d g      } | dkD  }| dk  }||z  }t        j                  | ||gd d d g      }t        |      }t        j                  d	z  d
z  t        j
                  |       t        j
                  d| z
        z  z
  |z
  }t        j                  |||      }dt        j
                  |       d	z  z  |z
  }t        j                  |||      S )Nr   c                    d| z  S r  r>  r$   s    r&   rk   z_spence_calc.<locals>.<lambda>
  s
    sQw r'   c                    | S rw   r>  r$   s    r&   rk   z_spence_calc.<locals>.<lambda>
  s    ! r'   g      ?r   c                    d| z  dz
  S r  r>  r$   s    r&   rk   z_spence_calc.<locals>.<lambda>
  s    sQw} r'   c                    |  S rw   r>  r$   s    r&   rk   z_spence_calc.<locals>.<lambda>
  s     r'   c                    | dz
  S r  r>  r$   s    r&   rk   z_spence_calc.<locals>.<lambda>
  s
    C r'   r*   g      @r,   r,  )r4   r  rh  r/   r   rb   rG   )r%   x2_bool	x1_5_boolx_5_boolr   rt   
y_flag_one
y_flag_twos           r&   _spence_calcrt  
  s    G'	mmAy&46! #g)W(i'	mmA),"')*! 1o!uuzC#''!*swwsQw/?"??!C*	ii*a(!cggajAo%)*	7J	**r'   c                    t        j                  | | dk  | dk(  | dk(  gt        j                  dt        j                  dz  dz  t
        g      S )Nrq   r,   r   r*   r  )r4   r  r/   r8   r   rt  r$   s    r&   _spencerv  
  sI    	qCc184255A:><@
B Br'   c                    t        j                  |       } t        j                  |       }|t        j
                  t        j                  fvrt        d| d      t        |       S )a?  Spence's function, also known as the dilogarithm for real values.

  JAX implementation of :obj:`scipy.special.spence`.

  It is defined to be:

  .. math::
    \mathrm{spence}(x) = \begin{equation}
    \int_1^x \frac{\log(t)}{1 - t}dt
    \end{equation}

  Unlike the SciPy implementation, this is only defined for positive
  real values of `z`. For negative values, `NaN` is returned.

  Args:
    z: An array of type `float32`, `float64`.

  Returns:
    An array with `dtype=z.dtype`.
    computed values of Spence's function.

  Raises:
    TypeError: if elements of array `z` are not in (float32, float64).

  Notes:
  There is a different convention which defines Spence's function by the
  integral:

  .. math::
    \begin{equation}
    -\int_0^z \frac{\log(1 - t)}{t}dt
    \end{equation}

  This is our spence(1 - z).
  r  z5 is not supported, see docstring for supported types.)	r4   r   r   r.   r/   r   r   r   rv  r   s     r&   spencerx  !
  sZ    H 
kk!n!
))A,%
2::rzz**
LMO O	r'   c                   t        j                  t        j                  | d      } | dk  rt	        d      t        j                  g d      }| dk  r|d| dz    S t        j                  | dz         j                  dd j                  |      }t        j                  d| dz   d	|j                  
      }dt        j                  d	z  z  t        j                  |dz
   |z  dz  t        j                  d	z  z        z  }t        j                  d	d|j                  
      }t        j                  |dddf   |dddf    z  d      }|j                  ddd	   j                  |d|z   z        S )a^  Generate the first N Bernoulli numbers.

  JAX implementation of :func:`scipy.special.bernoulli`.

  Args:
    n: integer, the number of Bernoulli terms to generate.

  Returns:
    Array containing the first ``n`` Bernoulli numbers.

  Notes:
    ``bernoulli`` generates numbers using the :math:`B_n^-` convention,
    such that :math:`B_1=-1/2`.
  zArgument n of bernoullir   z!n must be a non-negative integer.)rE   r,  gUUUUUU?r  NrE   r  r*   r   r,   rM  r   )r	   r   r[  r\  r1   r4   r   ri  rj  rk  r   r.   r/   r   r   r   )rH   b3bnr   r   r   r   s          r&   	bernoullir|  M
  s8     X^^Q0IJ!U
8
99
yy "Ufq1u:
yyQ2A""2&"	jjAE1BHH-!
RUUaZ3;;Qx!|a'7"%%1*'DEE"	jjBbhh'!
wwqDzaaj[(q1"	qt!tq2v	''r'   c                6   t        d| |      \  } }t        j                  | j                  t        j
                        rt        d      t        j                  |dk(  t        j                  d| j                        t        | |z         t        |       z        S )a  The Pochammer symbol.

  JAX implementation of :obj:`scipy.special.poch`.

  .. math::

     \mathrm{poch}(z, m) = (z)_m = \frac{\Gamma(z + m)}{\Gamma(z)}

  where :math:`\Gamma(z)` is the :func:`~jax.scipy.special.gamma` function.

  Args:
    z: arraylike, real-valued
    m: arraylike, real-valued

  Returns:
    array of Pochammer values.

  Notes:
    The JAX version supports only real-valued inputs.
  pochz0jnp.poch does not support complex-valued inputs.rq   rE   r   )r   r   r-   r.   r/   r0   r1   r4   rG   r   r=   r   r   s     r&   r~  r~  k
  ss    , 
fa	+$!Qqww 2 23
G
HH	17CIIaqww7q1ua9P	QQr'   c                P    t        | |z         t        |       z
  t        | |      z  S )zT
  Defined in :
  https://functions.wolfram.com/GammaBetaErf/Pochhammer/20/01/01/
  rQ   r~  r  s     r&   _poch_z_derivativer  
  s&     !a%.71:
%a	33r'   c                8    t        | |z         t        | |      z  S )zT
  Defined in :
  https://functions.wolfram.com/GammaBetaErf/Pochhammer/20/01/02/
  r  r  s     r&   _poch_m_derivativer  
  s     
Q$q!*	$$r'   c                     t        ||      | z  S rw   )r  )z_dotr6  r   r   s       r&   rk   rk   
  s    #5a#;e#C r'   c                     t        ||      | z  S rw   )r  )m_dotr6  r   r   s       r&   rk   rk   
  s    "4Q":U"B r'   c                     t        j                  j                        j                   fd}fd}dd z  z  f}t	        j
                  |||      d   S )z
  Compute the 1F1 hypergeometric function using the taylor expansion
  See Eq. 3.2 and associated method (a) from PEARSON, OLVER & PORTER 2014
  https://doi.org/10.48550/arXiv.1407.7786
  c                \    | \  }}}||z  }||z   |z   z  z  |dz   z  z  }|dz  }|||fS rg   r>  stateserier   termrA   rB   r%   s       r&   rC  z_hyp1f1_serie.<locals>.body
  sQ    NE1d	TMEQUq1u!QU++DFA!T>r'   c                x    | \  }}}|dk  t        j                  |      t        j                  |      z  kD  z  S N   r   r   r  r  r   r  	precisions       r&   rG  z_hyp1f1_serie.<locals>.cond
  7    NE1dG6BCCr'   rE   r   r   r   r.   rG  r   rI  rA   rB   r%   rC  rG  rQ  r  s   ```   @r&   _hyp1f1_serier  
  sU     ll177#'')D
 
Aq1uqy$	dD	)!	,,r'   c                <    t        j                  j                        j                   fd}fd}dd z
  d z
  z  z  f}t	        j
                  |||      d   }t              t               z  t	        j                        z   z
  z  z  |z  S )z
  Compute the 1F1 hypergeometric function using asymptotic expansion
  See Eq. 3.8 and simplification for real inputs from PEARSON, OLVER & PORTER 2014
  https://doi.org/10.48550/arXiv.1407.7786
  c                h    | \  }}}||z  }|z
  |z   dz
  |z   z  |dz   z  z  z  }|dz  }|||fS rg   r>  r  s       r&   rC  z _hyp1f1_asymptotic.<locals>.body
  sY    NE1d	TMEQUQY1q519%Q/!33DFA!T>r'   c                x    | \  }}}|dk  t        j                  |      t        j                  |      z  kD  z  S r  r  r  s       r&   rG  z _hyp1f1_asymptotic.<locals>.cond
  r  r'   rE   r   )r   r   r.   rG  r   rI  r=   r>   )rA   rB   r%   rC  rG  rQ  r  r  s   ```    @r&   _hyp1f1_asymptoticr  
  s     ll177#'')D
 
AA!a% 1$	$$
..tT
*1
-%	qE!H	swwqz	)A!a%L	85	@@r'   c                     t        j                  j                        j                   fd}fd}dd z  z  f}t	        j
                  |||      d   S )zv
  Define it as a serie using :
  https://functions.wolfram.com/HypergeometricFunctions/Hypergeometric1F1/20/01/01/
  c                    | \  }}}||t        |z         t              z
  z  z  }||z   |z   z  z  |dz   z  z  }|dz  }|||fS rg   rQ   r  s       r&   rC  z"_hyp1f1_a_derivative.<locals>.body
  sh    NE1d	TWQU^gaj011EQUq1u!QU++DFA!T>r'   c                x    | \  }}}|dk  t        j                  |      t        j                  |      z  kD  z  S r  r  r  s       r&   rG  z"_hyp1f1_a_derivative.<locals>.cond
  r  r'   r   rE   r  r  s   ```   @r&   _hyp1f1_a_derivativer  
  U     ll177#'')D
 
Aq1uqy$	dD	)!	,,r'   c                     t        j                  j                        j                   fd}fd}dd z  z  f}t	        j
                  |||      d   S )zv
  Define it as a serie using :
  https://functions.wolfram.com/HypergeometricFunctions/Hypergeometric1F1/20/01/02/
  c                    | \  }}}||t              t        |z         z
  z  z  }||z   |z   z  z  |dz   z  z  }|dz  }|||fS rg   r  r  s       r&   rC  z"_hyp1f1_b_derivative.<locals>.body
  sh    NE1d	TWQZ'!a%.011EQUq1u!QU++DFA!T>r'   c                x    | \  }}}|dk  t        j                  |      t        j                  |      z  kD  z  S r  r  r  s       r&   rG  z"_hyp1f1_b_derivative.<locals>.cond  r  r'   r   rE   r  r  s   ```   @r&   _hyp1f1_b_derivativer  
  r  r'   c                4    | |z  t        | dz   |dz   |      z  S )zv
  Define it as a serie using :
  https://functions.wolfram.com/HypergeometricFunctions/Hypergeometric1F1/20/01/04/
  rE   )hyp1f1rO   s      r&   _hyp1f1_x_derivativer    s$     
QAq1ua(	((r'   c           
     D   t        d| ||      \  } }}t        j                  |j                  t        j
                        rt        d      t        j                  t        j                  |      dk  t        t        | ||      }| dk(  dz  | |k(  | dk7  z  dz  z   |dk(  | dk7  z  dz  z   }t        j                  ||t        j                  d|j                        t        j                  |      t        j                  t        j                   |j                              S )	a  The 1F1 hypergeometric function.

  JAX implementation of :obj:`scipy.special.hyp1f1`.

  .. math::

     \mathrm{hyp1f1}(a, b, x) = {}_1F_1(x;a, b) = \sum_{k=0}^\infty \frac{(a)_k}{(b)_kk!}x^k

  where :math:`(\cdot)_k` is the Pochammer symbol (refer to :func:`~jax.scipy.special.poch`).

  The JAX version only accepts positive and real inputs. Values of ``a``, ``b``,
  and ``x``, leading to high values of 1F1 may lead to erroneous results;
  consider enabling double precision in this case. The convention for
  ``a = b = 0`` is ``1``, unlike in scipy's implementation.

  Args:
    a: arraylike, real-valued
    b: arraylike, real-valued
    x: arraylike, real-valued

  Returns:
    array of 1F1 values.
  r  z.hyp1f1 does not support complex-valued inputs.d   r   rE   r*   r  r   )r   r   r-   r.   r/   r0   r1   r   rG  r   r  r  select_nr4   r   r>   r   )rA   rB   r%   r~   r\  s        r&   r  r    s    < !1a3'!Qqww 2 23
E
FF88CGGAJ$m5GAqQ&6Q,16a1f-2
2qAv!q&6IQ5N
N%	eii1ggajiiagg6	
8 8r'   c                "    t        |||      | z  S rw   )r  )a_dotr6  rA   rB   r%   s        r&   rk   rk   G      %9!Q%BU%J r'   c                "    t        |||      | z  S rw   )r  )b_dotr6  rA   rB   r%   s        r&   rk   rk   H  r  r'   c                "    t        |||      | z  S rw   )r  )r|   r6  rA   rB   r%   s        r&   rk   rk   I  r  r'   c                >    t        j                  j                        j                  dz  }t	        j
                        }t	        j                   k  t	        j                  t	        j                  |z
        |k  t	        j                  t	        j                  dz  dk(  t	        j                  dk  kD                                } }t	        j                  |        t	        j                  ||      t	        j                           fd}t	        j                  dj                        t	        j                  dj                        f}	t        j                  t	        j                  d j                         dz   ||	      d   S )z
  The Taylor series representation of the 2F1 hypergeometric function
  terminates when either a or b is a non-positive integer. See Eq. 4.1 and
  Taylor Series Method (a) from PEARSON, OLVER & PORTER 2014
  https://doi.org/10.48550/arXiv.1407.7786
  rM  rE   r   c                h    |\  }}|| z
  dz    | z   dz
  z  | z   dz
  z  | z  z  z  }||z  }||fS rg   r>  )r}  r  r  r  rA   rB   r(  r%   s       r&   rC  z_hyp2f1_terminal.<locals>.bodyn  sW    KE4a!eaiLAEAI&!a%!)4q81<<D	TME$;r'   r   )r   r   r.   rG  r4   roundlogical_andr   logical_notrG   r   r   r  )
rA   rB   r(  r%   rG  ibr  orig_arC  rQ  s
   ````      r&   _hyp2f1_terminalr  M  sA    	QWW!!B&#
yy|"	!e	ooB#
//EQJOO1f!e	

$ &	iia!	iifa !	ggaj! ))AQWW
%syy!'''B	C$	syy!''21u
 
   r'   c                p    t        j                  j                        j                   fd}fd}t	        j
                  dj                        t	        j
                  dj                        t	        j
                  dj                        f}t        j                  |||      d   S )z
  Compute the 2F1 hypergeometric function using the Taylor expansion.
  See Eq. 4.1 from PEARSON, OLVER & PORTER 2014
  https://doi.org/10.48550/arXiv.1407.7786
  c                t    | \  }}}||z  }||z   dz
  |z   dz
  z  |z   dz
  z  |z  z  z  }|dz  }|||fS rg   r>  r  r  r   r  rA   rB   r(  r%   s       r&   rC  z_hyp2f1_serie.<locals>.body  sb    NE1d	TMEQUQY1q519%Q3a7!;;DFA!T>r'   c                x    | \  }}}|dk  t        j                  |      t        j                  |      z  kD  z  S r  r  )r  r  r   r  rtols       r&   rG  z_hyp2f1_serie.<locals>.cond  s7    NE1dGswwu~(==>>r'   r   r   rE   )r   r   r.   rG  r4   r   r   rI  )rA   rB   r(  r%   rC  rG  rQ  r  s   ````   @r&   _hyp2f1_serier  ~  s     
agg		"	"$?
 ))AQWW
%
))AQWW
%
))AQWW
%
'$ 
dD	)!	,,r'   c                `   t        j                  |j                        j                  dz  }|| z
  |z
  }t	        j
                  |       }t	        j
                  |      }t	        j
                  |      }t	        j                  | dk  t	        j                  | |z
        |k        }	t	        j                  |dk  t	        j                  ||z
        |k        }
t	        j                  |	|
      }t	        j                  |      }t	        j                  t	        j                  |dkD  |      t	        j                  t	        j                  ||z
        |k\  dd      t	        j                  |dd            }t        j                  |t        | |||      t        | |||      t        | |||            S )a$  
  Check for recurrence relations along with whether or not the series
  terminates. True recursion is not possible; however, the recurrence
  relation may still be approximated.
  See 4.6.1. Recurrence Relations from PEARSON, OLVER & PORTER 2014
  https://doi.org/10.48550/arXiv.1407.7786
  rM  r   g?rE   r*   )r   r   r.   rG  r4   r  r  r   
logical_orr  rG   r   r  r  _hyp2f1_digamma_transformr  )rA   rB   r(  r%   rG  r   iar  id	neg_int_a	neg_int_bneg_int_a_or_bnot_neg_int_a_or_br\  s                 r&   _hyp2f1_terminal_or_serier    sN    	QWW!!B&#!eai!
yy|"
yy|"
yy|"ooa1fcgga"fo&;<)ooa1fcgga"fo&;<)>>)Y7.~6
))COOAG-?@		#''!b&/S(!Q/		.!Q')% 
e#Aq!Q//1a;&q!Q2
4 4r'   c                    t        j                  j                        j                   z
  z
  }dz
  t	        j
                  |      t	        j                  dk\  ||       t	        j                  dk\  |t	        j                  d|j                              t	        j                  dk\  t	        j                  d|j                        |      t	        j                  dk\         j                  d      t	        j                        }t        d      t        dz         z   t         z         z
  t        z         z
  |z
  }|t        dz         z  } z   z   z  z  t        dz         z  }fd}d }	 |||t	        j                  dj                        t	        j                  dj                        |f}
t        j                  ||	|
      \  }}}}}}}}}}} f
d	}t	        j                  dk(  |t              z  t               t              z  z   ||            S )
zi
  Digamma transformation of the 2F1 hypergeometric function.
  See AMS55 #15.3.10, #15.3.11, #15.3.12
  rE   r   r   int32r,   r   c                    | \  }}}}}}}}}}}t        j                  |dk  t        j                  |      t        j                  |      z  k\        S r  )r4   r  r   )r  rD  r   r  rt   r  s        r&   rG  z'_hyp2f1_digamma_transform.<locals>.cond  sT    &+#Aq!Q1aAq!??#g	ggajD3771:%% r'   c                4   | \  }}}}}}}}}	}
}t        d|
z         t        d|
z   |z         z   t        ||
z   |z         z
  t        ||
z   |z         z
  |z
  }||z  }||z  }||	||
z   |z   z  |
dz   z  z  }|||
z   |z   |
dz   |z   z  z  }|
dz  }
|||||||||	|
|fS r  r  )r  rA   axrB   rw  r
  r   r   rK  r   r  rt   s               r&   rC  z'_hyp2f1_digamma_transform.<locals>.body  s    (-%Ar1b!Q1aAa737Q;//'!a%"*2EE
!a%"*
	 "	#A	AAFAa!ebj	QW	%%A!a%"*S1	%%AHAb!RAq!Q1,,r'   c                f  
 t        j                  dj                        }t        j                  dj                        }t        j                  dj                        }d }	|||f}t        j                  d||      d   }t        
      }|t              |z  t        z         t        	z         z  z  z  }| |t        z         t        	z         z  z  z  } t        j                  dz  dk7  |  |       } z  }t        j                  dkD  | |z  |z   | ||z  z         S )NrE   r   r   c                    |\  }}}}}}}}	d|z
  |z   }
||||z   |z   z  ||z   |z   z  |
z  z  }|dz  }||z  }|	|z  }	||||||||	fS r  r>  )r}  r  rA   rB   d2r
  r   r   r  y1rK  s              r&   for_bodyz@_hyp2f1_digamma_transform.<locals>.compute_sum.<locals>.for_body  s    !&aB1aB
'A+a1A
q1urz*Q..a3ha1faAgb2q!Q2%%r'   r   )r4   r   r.   r   r  r=   rG   )rt   r  r  r   r  r  r   rA   ardrB   r(  rw  r  r
  rdr   r%   s          r&   compute_sumz._hyp2f1_digamma_transform.<locals>.compute_sum  s   	1AGG	$B		!177#A		!177#A	& !RAq!R'H	q#x	22	6BaA%(Q,%B-%B-7
88BeAFmeAFm+	,,A		37q.1"a(A	RA99R!VQURZR!V44r'   )r   r   r.   rG  r4   r  rG   r   rx   rb   rQ   r=   r   rI  )rA   rB   r(  r%   r   r  rt   r   rG  rC  rQ  rD  r   rK  r  r  rw  r  r
  r  r  r   s   ````           @@@@@@@r&   r  r    s   
 
agg		"	"$!eai!!e!
yy|"	iiaQB!
yyq!SYYq89"
yyq#))AQWW5q9"		"'2s#**73#
wwqz"clWS1W%%B7'!b&/IBN!uQW~!2v!b&Aa#g.!- RB1a1AGG!<a
))AQWW
%q
*$$'NN4t$D!!Q1aAq!Q5 58 
!GaLE!HuQx'(N
 r'   c                     t        j                  j                        j                   fd}fd}dd z  z  z  f}t	        j
                  |||      d   S )zv
  Define it as a serie using :
  https://functions.wolfram.com/HypergeometricFunctions/Hypergeometric2F1/20/01/01/
  c                    | \  }}}||t        |z         t              z
  z  z  }||z   |z   z  |z   z  |dz   z  z  z  }|dz  }|||fS rg   r  r  s       r&   rC  z"_hyp2f1_a_derivative.<locals>.body  q    NE1d	TWQU^gaj011EQUq1uQ'1q51A55DFA!T>r'   c                x    | \  }}}|dk  t        j                  |      t        j                  |      z  kD  z  S r  r  r  s       r&   rG  z"_hyp2f1_a_derivative.<locals>.cond  r  r'   r   rE   r  rA   rB   r(  r%   rC  rG  rQ  r  s   ````   @r&   _hyp2f1_a_derivativer    Z     ll177#'')D
 
Aq1uqy1}	$	dD	)!	,,r'   c                     t        j                  j                        j                   fd}fd}dd z  z  z  f}t	        j
                  |||      d   S )zv
  Define it as a serie using :
  https://functions.wolfram.com/HypergeometricFunctions/Hypergeometric2F1/20/01/02/
  c                    | \  }}}||t        |z         t              z
  z  z  }||z   |z   z  |z   z  |dz   z  z  z  }|dz  }|||fS rg   r  r  s       r&   rC  z"_hyp2f1_b_derivative.<locals>.body3  r  r'   c                x    | \  }}}|dk  t        j                  |      t        j                  |      z  kD  z  S r  r  r  s       r&   rG  z"_hyp2f1_b_derivative.<locals>.cond;  r  r'   r   rE   r  r  s   ````   @r&   _hyp2f1_b_derivativer  )  r  r'   c                     t        j                  j                        j                   fd}fd}dd z  z  z  f}t	        j
                  |||      d   S )zv
  Define it as a serie using :
  https://functions.wolfram.com/HypergeometricFunctions/Hypergeometric2F1/20/01/03/
  c                    | \  }}}||t              t        |z         z
  z  z  }||z   |z   z  |z   z  |dz   z  z  z  }|dz  }|||fS rg   r  r  s       r&   rC  z"_hyp2f1_c_derivative.<locals>.bodyO  sq    NE1d	TWQZ'!a%.011EQUq1uQ'1q51A55DFA!T>r'   c                x    | \  }}}|dk  t        j                  |      t        j                  |      z  kD  z  S r  r  r  s       r&   rG  z"_hyp2f1_c_derivative.<locals>.condW  r  r'   r   rE   r  r  s   ````   @r&   _hyp2f1_c_derivativer  E  r  r'   c                B    | |z  |z  t        | dz   |dz   |dz   |      z  S )z
  Define the derivative with regard to ``x`` :
  https://functions.wolfram.com/HypergeometricFunctions/Hypergeometric2F1/20/01/05/
  rE   )hyp2f1)rA   rB   r(  r%   s       r&   _hyp2f1_x_derivativer  a  s.     
QVAE1q5!a%3	33r'   c           !     @   t        d| |||      \  } }}}t        j                  |j                        j                  dz  }|| z
  |z
  }d|z
  }|| z
  }||z
  }t        j                  |      }	t        j                  |      }
t        j                  |      }t        j                  |dk  t        j                  ||
z
        |k        }t        j                  |dk  t        j                  ||z
        |k        }t        j                  ||      }t        j                  t        j                  |dk(  t        j                  t        j                  | dk(  |dk(        |dk7              dt        j                  t        j                  |dk(  t        j                  |dk  |dz  dk(              dt        j                  t        j                  |dk  t        j                  t        j                  t        j                  ||	z
        |k\  |dk                    dt        j                  t        j                  |dk  |dk(        dt        j                  t        j                  |dk  ||k(        dt        j                  t        j                  |dk  | |k(        dt        j                  |dkD  dt        j                  |dk(  d	d
                                                }t        j                  |t        j                  d|j                        t        j                  t        j                   |j                        ||z  t#        ||||      z  ||  z  || z  t%        |      t%        |      z  t%        |      t%        |      z  z  t#        | |||            S )a  The 2F1 hypergeometric function.

  JAX implementation of :obj:`scipy.special.hyp2f1`.

  .. math::

     \mathrm{hyp2f1}(a, b, c, x) = {}_2F_1(a; b; c; x) = \sum_{k=0}^\infty \frac{(a)_k(b)_k}{(c)_k}\frac{x^k}{k!}

  where :math:`(\cdot)_k` is the Pochammer symbol.

  The JAX version only accepts positive and real inputs. Values of
  ``a``, ``b``, ``c``, and ``x`` leading to high values of 2F1 may
  lead to erroneous results; consider enabling double precision in this case.

  Args:
    a: arraylike, real-valued
    b: arraylike, real-valued
    c: arraylike, real-valued
    x: arraylike, real-valued

  Returns:
    array of 2F1 values.
  r  rM  rE   r   r   r*   r  r  r   r  r   )r   r   r   r.   rG  r4   r  r  r   r  rG   r  r   r  r   r/   r   r  r=   )rA   rB   r(  r%   rG  r   r   cacbr  icaicb
neg_int_ca
neg_int_cbneg_int_ca_or_cbr\  s                   r&   r  r  k  s   8 $HaAq9*!Q1QWW!!B&#!eai!!e!1u"1u"
yy|"		"#		"#rQwS(9C(?@*rQwS(9C(?@*^^J
;
))CNN163??3>>!q&RSWXRX;Y[\`a[a+bcefIIcnnQ!VS__QUAEQJ-OPRSiiRQTQXQXYZ]_Y_Q`dgQgijmninAo1pqst		#//!q&!q&91))COOAE16:AIIcooa!eQ!V<aiiAq		!q&!Q/1234567% 
eii1iiagg61f8RAFFQBiQBiAhq)U2Yr-BC/1a;
= =r'   c                $    t        ||||      | z  S rw   )r  )r  r6  rA   rB   r(  r%   s         r&   rk   rk         (<Q1a(H5(P r'   c                $    t        ||||      | z  S rw   )r  )r  r6  rA   rB   r(  r%   s         r&   rk   rk     r  r'   c                $    t        ||||      | z  S rw   )r  )c_dotr6  rA   rB   r(  r%   s         r&   rk   rk     r  r'   c                $    t        ||||      | z  S rw   )r  )r|   r6  rA   rB   r(  r%   s         r&   rk   rk     r  r'   r   c                  t        | |      S )a  Softmax function.

  JAX implementation of :func:`scipy.special.softmax`.

  Computes the function which rescales elements to the range :math:`[0, 1]`
  such that the elements along :code:`axis` sum to :math:`1`.

  .. math ::
    \mathrm{softmax}(x) = \frac{\exp(x_i)}{\sum_j \exp(x_j)}

  Args:
    x : input array
    axis: the axis or axes along which the softmax should be computed. The
      softmax output summed across these dimensions should sum to :math:`1`.
      ``None`` means all axes.

  Returns:
    An array of the same shape as ``x``.

  Note:
    If any input values are ``+inf``, the result will be all ``NaN``: this
    reflects the fact that ``inf / inf`` is not well-defined in the context of
    floating-point math.

  See also:
    :func:`log_softmax`
  r   )
nn_softmaxr%   r   s     r&   r   r     s    @ 
AD	!!r'   c                  t        | |      S )a  Log-Softmax function.

  JAX implementation of :func:`scipy.special.log_softmax`

  Computes the logarithm of the :code:`softmax` function, which rescales
  elements to the range :math:`[-\infty, 0)`.

  .. math ::
    \mathrm{log\_softmax}(x)_i = \log \left( \frac{\exp(x_i)}{\sum_j \exp(x_j)}
    \right)

  Args:
    x : input array
    axis: the axis or axes along which the :code:`log_softmax` should be
      computed. ``None`` means all axes.

  Returns:
    An array of the same shape as ``x``

  Note:
    If any input values are ``+inf``, the result will be all ``NaN``: this
    reflects the fact that ``inf / inf`` is not well-defined in the context of
    floating-point math.

  See also:
    :func:`softmax`
  r   )nn_log_softmaxr  s     r&   r    r      s    @ 
	%%r'   )r%   r   returnr   )rA   r   rB   r   r  r   )F)rH   r   rI   boolr  r   )rA   r   rB   r   r%   r   r  r   )rA   r   r%   r   r  r   )r%   r   rt   r   r  r   )rA   r   r   r   r  r   )r   r   r   r   r  r   rw   )r%   r   r   zArrayLike | Noner  r   )rH   r   r%   r   r  r   )r   r   r  r   )r  )r%   r   r  r   r  r   )rH   r   r  z
np.ndarray)r   r   rO  r   rN  r   r  r   )rn  r   ro  r  r.   r   r  tuple[Array, Array])r   r   r%   r   ro  r  r  r   )rn  r   r%   r   ro  r  r  r   )r   r   rH   r   r   r   r  r  )
r   r   rH   r   r   r   ro  r  r  r   )rH   r   r   r   r  r   r  r   r  r   r  r   )NN)rH   r   r   r   r  r   r  r   r  
int | Noner  r   r  r   )r   r   rH   r   r  r   r  r   r  r   r  r   )r%   r   r  r   )r  r   r  r   r%   r   r  r   )r%   r   r  r  )r%   r   )r%   r   rH   r   r  r   )r   r   r  r   )rH   r   r  r   )r   r   r   r   r  r   )
rA   r   rB   r   r(  r   r%   r   r  r   )r%   r   r   zint | tuple[int, ...] | Noner  r   )
__future__r   	functoolsr   r[  typingr   r   r   r/   jax._srcr   r   r	   r
   r   r   r   r   r4   jax._src.numpy.ufuncsr   r   r   jax._src.apir   r   r   jax._src.lax.laxr   re   jax._src.numpyr   rm  r   jnp_vectorizejax._src.numpy.utilr   r   jax._src.opsr   ops_special!jax._src.third_party.scipy.betalnr   r@   jax._src.typingr   r   jax._src.nn.functionsr   r  r    r  r"   r)   r=   rD   rK   rN   rQ   rS   rW   rZ   r\   r^   
custom_jvpra   defjvpsrm   	logsumexprp   r   defjvpr   r   r   r   r   r   r   r   r   r   r   r   r   r   r  r   r  r  r  r   r   r   r   r  r  r  r  r#  rb   r   r   r-  r  r1  r5  r8  r;  rL  rW  r`  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r
  r  r  r  r  r  r:  rL  r]  r_  ra  re  r  rh  rt  rv  rx  r|  r~  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r>  r'   r&   <module>r     s   #        ' !    ! : : ' ' 1 / 5 L / D , 7 ?8 * *Z*.Z29>&::8444:0 ; ;" JL& !!	 D D.K
 Z  F F.S
 |  . j (>%P     B((( (X 288   (  4: GC/0 1%F "#rzz2 !#rzz2  "!RZZ0 !!RZZ0 D8cL 			&	&=e7 >e7N
 	 K(&&
 wrwwq255y12 C49049.( 57 " c8_%35 %/ &%/P1"1"#1",/1"1"h Q[[$([-2[ [| Fb %b,0b5:b bJ)!X3;n D  	 #	 : %)#'1,1,1, 1, "	1,
 !1,
 -21,p "&	030303 03 	03 +0	03r-.!2!4!:!4!*!8
 C  C0 )  ) 1  1f0djX !  !"<J0 f
( 			&	&=-   >-`   !640+,B)X(< R R84% CB-6A8 -  -4 -  -4 ) ) '8   '8T JJJ. b-:4>Pf -  -4 -  -4 -  -4 4 4 9=   9=x PPPP	 26 " / " 	 "L 6: & 3 & 	 &r'   