U
    HvfR2                     @   s   d Z ddlmZmZ ddlZddlmZ ddlm	Z	m
Z
 ddlmZ zLddlZddlmZmZmZmZmZmZmZmZmZmZmZ ddlmZ W n ek
r   Y nX d	d
 Zdd Zdd Zdd Zdd Zdd Z dd Z!e"dkre!  dS )zPrecompute coefficients of several series expansions
of Wright's generalized Bessel function Phi(a, b, x).

See https://dlmf.nist.gov/10.46.E1 with rho=a, beta=b, z=x.
    )ArgumentParserRawTextHelpFormatterN)quad)minimize_scalar	curve_fit)time)
EulerGammaRationalSSum	factorialgamma	gammasimppi	polygammasymbolszeta)hornerc                  C   s`  d} t d\}}}}g }g }g }t|| t| t|| |  |dtjf}t|t| | }td| d D ]}	|	||	
|d  }
|

td|dtdd }|d|	 9 }|||	 t|	  |t| |t|
|   qrd}|d	7 }td
ddg|||gD ]@\}}tt|D ](}|d| d| dt||  7 }q.q|S )zATylor series expansion of Phi(a, b, x) in a=0 up to order 5.
       a b x kr      c                  W   s   dS Nr    argsr   r   K/tmp/pip-unpacked-wheel-96ln3f52/scipy/special/_precompute/wright_bessel.py<lambda>&       z series_small_a.<locals>.<lambda>z=Tylor series expansion of Phi(a, b, x) in a=0 up to order 5.
zAPhi(a, b, x) = exp(x)/gamma(b) * sum(A[i] * X[i] * B[i], i=0..5)
AXB
[] = )r   r   r   r   r
   Infinitysympyexprangediffsubssimplifydoitr   replaceappendr   ziplenstr)orderabxkr   r    r!   
expressionntermx_partsnamecir   r   r   series_small_a   s.    . *r?   c                 C   sB   t d}d|  t td| t| | |d   |d|d f S )zSymbolic expansion of digamma(z) in z=0 to order n.

    See https://dlmf.nist.gov/5.7.E4 and with https://dlmf.nist.gov/5.5.E2
    r6   r   r      )r   r   r&   Z	summationr   )zr8   r6   r   r   r   	dg_series7   s    
,rB   c                 C   s   t t|||  || S )z8Symbolic expansion of polygamma(k, z) in z=0 to order n.)r&   r)   rB   )r6   rA   r8   r   r   r   	pg_seriesA   s    rC   c                     sz  dt d\} }}t d\}}}t|t|td|i}g }g }g }	g  tt| t|| t| t| |   |dt	j
f }
tdd D ]މ|
| | d  }|tddtdd }|d	 9 }|| t }dkrD|tfd
d}|jdd  d tdddtd  }||  t  |t| |	| qt|	d |     tt D ]} | t|   |< qd}|d7 }|d7 }|d7 }|d7 }|d7 }|d7 }tddg||gD ]D\}}tt|D ],}|d| d| d7 }|t|| 7 }qqtt D ]b}|d| d7 }|t | 7 }|d| d7 }|t | |t|t|tdid7 }qZ|d7 }|d7 }|d7 }t fd d!td D }||	d |  }|d"|t	dk 7 }|d#7 }t fd$d!td D }||	d |  }|d"|t	dk 7 }|S )%a  Tylor series expansion of Phi(a, b, x) in a=0 and b=0 up to order 5.

    Be aware of cancellation of poles in b=0 of digamma(b)/Gamma(b) and
    polygamma functions.

    digamma(b)/Gamma(b) = -1 - 2*M_EG*b + O(b^2)
    digamma(b)^2/Gamma(b) = 1/b + 3*M_EG + b*(-5/12*PI^2+7/2*M_EG^2) + O(b^2)
    polygamma(1, b)/Gamma(b) = 1/b + M_EG + b*(1/12*PI^2 + 1/2*M_EG^2) + O(b^2)
    and so on.
    r   r   zM_PI M_EG M_Z3   r   r   c                  W   s   dS r   r   r   r   r   r   r   e   r   z(series_small_a_small_b.<locals>.<lambda>r   c                    s   t | |d   S )Nr   )rC   )r6   r5   )r8   r2   r   r   r   m   r   )r8   r@   zDTylor series expansion of Phi(a, b, x) in a=0 and b=0 up to order 5.z9
Phi(a, b, x) = exp(x) * sum(A[i] * X[i] * B[i], i=0..5)
z	B[0] = 1
z&B[i] = sum(C[k+i-1] * b**k/k!, k=0..)
z

M_PI = piz
M_EG = EulerGammaz
M_Z3 = zeta(3)r   r    r"   r#   r$   z
# C[z
C[   z/

Test if B[i] does have the assumed structure.z#
C[i] are derived from B[1] allone.z:
Test B[2] == C[1] + b*C[2] + b^2/2*C[3] + b^3/6*C[4] + ..c                    s(   g | ] }| t |  |d    qS )r   r   .0r6   Cr4   r   r   
<listcomp>   s     z*series_small_a_small_b.<locals>.<listcomp>z
test successful = z-
Test B[3] == C[2] + b*C[3] + b^2/2*C[4] + ..c                    s(   g | ] }| t |  |d    qS )r@   rG   rH   rJ   r   r   rL      s     )r   r   r   r   r   r&   r'   r   r   r
   r%   r(   r)   r*   r+   r,   r   r-   ZseriesZremoveOr.   r   Polycoeffsreverser0   r/   r1   Zevalfsum)r3   r5   r6   ZM_PIZM_EGZM_Z3Zc_subsr   r    r!   r7   r9   r:   Zpg_partr>   r;   r<   r=   testr   )rK   r4   r8   r2   r   series_small_a_small_bF   s~    , 
 
"  rR   c               	      s  d} G  fdddt j G  fdddt j}td\}}}|d||}d}|d	7 }|d
7 }|d7 }|d7 }|d7 }|d7 }|d7 }td| d D ]}|||||d| |    }dd t | D }	t |	}	||	  |t j	}|
|d |i}|d| d|	 d| d7 }|d| dt| d7 }qddl}
|
d}|d|}|
d}|d|}|dd}|d d!}|
d"}|d#|}|S )$a  Asymptotic expansion for large x.

    Phi(a, b, x) ~ Z^(1/2-b) * exp((1+a)/a * Z) * sum_k (-1)^k * C_k / Z^k
    Z = (a*x)^(1/(1+a))

    Wright (1935) lists the coefficients C_0 and C_1 (he calls them a_0 and
    a_1). With slightly different notation, Paris (2017) lists coefficients
    c_k up to order k=3.
    Paris (2017) uses ZP = (1+a)/a * Z  (ZP = Z of Paris) and
    C_k = C_0 * (-a/(1+a))^k * c_k
       c                       s$   e Zd ZdZdZe fddZdS )zasymptotic_series.<locals>.gzHelper function g according to Wright (1935)

        g(n, rho, v) = (1 + (rho+2)/3 * v + (rho+2)*(rho+3)/(2*3) * v^2 + ...)

        Note: Wright (1935) uses square root of above definition.
        rD   c                    sr   |dkst dn\|dkrdS  |d ||tt|d | t|d  ttd| td  ||   S d S )Nr   zmust have n >= 0r   r@   rD   )
ValueErrorr   r   )clsr8   rhovgr   r   eval   s    
z!asymptotic_series.<locals>.g.evalN__name__
__module____qualname____doc__nargsclassmethodrZ   r   rX   r   r   rY      s   rY   c                       s$   e Zd ZdZdZe fddZdS )z!asymptotic_series.<locals>.coef_CzCalculate coefficients C_m for integer m.

        C_m is the coefficient of v^(2*m) in the Taylor expansion in v=0 of
        Gamma(m+1/2)/(2*pi) * (2/(rho+1))^(m+1/2) * (1-v)^(-b)
            * g(rho, v)^(-m-1/2)
        rD   c                    s   |dkst dtd}d| |   d| ||| tdd   }||d| |dtd|  }|t|tdd dt  d|d  |tdd    }|S )Nr   zmust have m >= 0rW   r   r@   )rT   r   r	   r)   r*   r   r   r   )rU   mrV   betarW   r7   resrX   r   r   rZ      s    .$z&asymptotic_series.<locals>.coef_C.evalNr[   r   rX   r   r   coef_C   s   re   z	xa b xap1r   z!Asymptotic expansion for large x
z.Phi(a, b, x) = Z**(1/2-b) * exp((1+a)/a * Z) 
z3               * sum((-1)**k * C[k]/Z**k, k=0..6)

zZ      = pow(a * x, 1/(1+a))
zA[k]   = pow(a, k)
zB[k]   = pow(b, k)
zAp1[k] = pow(1+a, k)

z#C[0] = 1./sqrt(2. * M_PI * Ap1[1])
r   c                 S   s   g | ]}|  qS r   )denominatorrI   r5   r   r   r   rL      s     z%asymptotic_series.<locals>.<listcomp>zC[z] = C[0] / (z * Ap1[z])
z] *= z

Nzxa\*\*(\d+)zA[\1]z
b\*\*(\d+)zB[\1]xap1zAp1[1]xar3   z	(\d{10,})z\1.)r&   ZFunctionr   r(   r+   rM   rN   ZlcmZcollectfactorZxreplacer1   recompilesubr-   )r2   re   ri   r4   rh   ZC0r;   r>   exprrj   rk   Zre_aZre_bZ	re_digitsr   rX   r   asymptotic_series   s>     



ro   c                     sF  dd d0fdd	 ddd	d
ddddddg
dddddgdddddddddddddgt \     g } tjD ]0| t fddddd did!j qt | } | d"}d#d$ }t	t
|||d% d&d'd }d(}|d)7 }|d*7 }|d+7 }|d,7 }|d-d.d/ |D 7 }|S )1a  Fit optimal choice of epsilon for integral representation.

    The integrand of
        int_0^pi P(eps, a, b, x, phi) * dphi
    can exhibit oscillatory behaviour. It stems from the cosine of P and can be
    minimized by minimizing the arc length of the argument
        f(phi) = eps * sin(phi) - x * eps^(-a) * sin(a * phi) + (1 - b) * phi
    of cos(f(phi)).
    We minimize the arc length in eps for a grid of values (a, b, x) and fit a
    parametric function to it.
    c                 S   sB   t d|  | }| t | || | t ||   d | S )zDerivative of f w.r.t. phi.g      ?r   )nppowercos)epsr3   r4   r5   phiZeps_ar   r   r   fp  s    z$optimal_epsilon_integral.<locals>.fp{Gz?d   c                    s(   t  fdddtj|ddd S )zCompute Arc length of f.

        Note that the arg length of a function f fro t0 to t1 is given by
            int_t0^t1 sqrt(1 + f'(t)^2) dt
        c              	      s   t d | d  S )Nr   r@   )rp   sqrt)rt   )r3   r4   rs   ru   r5   r   r   r     r   z=optimal_epsilon_integral.<locals>.arclength.<locals>.<lambda>r   rw   )epsrellimit)r   rp   r   )rs   r3   r4   r5   ry   rz   )ru   )r3   r4   rs   r5   r   	arclength	  s      z+optimal_epsilon_integral.<locals>.arclengthMbP?g?g      ?g?r   r@      r      rS   r      
   g      ?   2      i  g     @@g     @g     @c                    s    |    S Nr   )rs   )r{   data_adata_bdata_xr>   r   r   r     s   z*optimal_epsilon_integral.<locals>.<lambda>)r|   i  ZBoundedZxatol)Zboundsmethodoptions)r3   r4   r5   rs   c           
   
   S   sx   | d }| d }| d }	|| t d|  t |dd|  t |	  |t | |   |dt ||     S )z#Compute parametric function to fit.r3   r4   r5   g      r   )rp   r'   log)
dataZA0A1A2ZA3ZA4ZA5r3   r4   r5   r   r   r   func*  s    0z&optimal_epsilon_integral.<locals>.funcrs   Ztrf)r   z7Fit optimal eps for integrand P via minimal arc length
zwith parametric function:
zBoptimal_eps = (A0 * b * exp(-a/2) + exp(A1 + 1 / (1 + a) * log(x)
z=              - A2 * exp(-A3 * a) + A4 / (1 + exp(A5 * a)))

z Fitted parameters A0 to A5 are:
z, c                 S   s   g | ]}d  |qS )z{:.5g})formatrg   r   r   r   rL   :  s     z,optimal_epsilon_integral.<locals>.<listcomp>)rv   rw   )rp   Zmeshgridflattenr(   sizer.   r   r5   arraylistr   join)Zbest_epsZdfr   Zfunc_paramsr;   r   )r{   r   r   r   ru   r>   r   optimal_epsilon_integral   sB    
 
	r   c                  C   s   t  } tttd}|jdtddddgdd | }d	d
 dd
 dd
 dd
 d}||jdd
   t	d
t  |  d  d S )N)descriptionformatter_classactionr   r@   rD   r}   zchose what expansion to precompute
1 : Series for small a
2 : Series for small a and small b
3 : Asymptotic series for large x
    This may take some time (>4h).
4 : Fit optimal eps for integral representation.)typechoiceshelpc                   S   s
   t t S r   )printr?   r   r   r   r   r   L  r   zmain.<locals>.<lambda>c                   S   s
   t t S r   )r   rR   r   r   r   r   r   M  r   c                   S   s
   t t S r   )r   ro   r   r   r   r   r   N  r   c                   S   s
   t t S r   )r   r   r   r   r   r   r   O  r   )r   r@   rD   r}   c                   S   s   t dS )NzInvalid input.)r   r   r   r   r   r   Q  r   z
{:.1f} minutes elapsed.
<   )r   r   r_   r   add_argumentint
parse_argsgetr   r   r   )t0parserr   switchr   r   r   main>  s    r   __main__)#r_   argparser   r   Znumpyrp   Zscipy.integrater   Zscipy.optimizer   r   r   r&   r   r	   r
   r   r   r   r   r   r   r   r   Zsympy.polys.polyfuncsr   ImportErrorr?   rB   rC   rR   ro   r   r   r\   r   r   r   r   <module>   s(   4"
YYF