o
    èEbÚÇ  ã                
   @   sê  d Z dZdZdZdZdZdZddlZddlZddl	Z	ddl
Z
ddlZddlZdd	lmZ ddlZe	j e	j e¡¡Zed
ƒZddddddddddœ	Zddddddddddœ	Zdddd d!d"d#d$d%œZd&d'gd(gd)d*gd)gd)d*gd(d+gd*gd)gd)d*gd,œ	Zd-d.„ Zd/d0„ Zeg d1¢ƒZd2d2d2d2d2d2d3d3d%œZd4d5„ Z d6d7„ Z!d8d9„ Z"d:d;„ Z#d<d=„ Z$d>d?„ Z%d@dA„ Z&G dBdC„ dCƒZ'G dDdE„ dEe'ƒZ(G dFdG„ dGe'ƒZ)dHdI„ Z*dJdK„ Z+dLdM„ Z,dNe-dOee( fdPdQ„Z.dRdS„ Z/dTdU„ Z0dVdW„ Z1e2dXkróe1ƒ  dS dS )YaC	  
python _generate_pyx.py

Generate Ufunc definition source files for scipy.special. Produces
files '_ufuncs.c' and '_ufuncs_cxx.c' by first producing Cython.

This will generate both calls to PyUFunc_FromFuncAndData and the
required ufunc inner loops.

The functions signatures are contained in 'functions.json', the syntax
for a function signature is

    <function>:       <name> ':' <input> '*' <output>
                        '->' <retval> '*' <ignored_retval>
    <input>:          <typecode>*
    <output>:         <typecode>*
    <retval>:         <typecode>?
    <ignored_retval>: <typecode>?
    <headers>:        <header_name> [',' <header_name>]*

The input parameter types are denoted by single character type
codes, according to

   'f': 'float'
   'd': 'double'
   'g': 'long double'
   'F': 'float complex'
   'D': 'double complex'
   'G': 'long double complex'
   'i': 'int'
   'l': 'long'
   'v': 'void'

If multiple kernel functions are given for a single ufunc, the one
which is used is determined by the standard ufunc mechanism. Kernel
functions that are listed first are also matched first against the
ufunc input types, so functions listed earlier take precedence.

In addition, versions with casted variables, such as d->f,D->F and
i->d are automatically generated.

There should be either a single header that contains all of the kernel
functions listed, or there should be one header for each kernel
function. Cython pxd files are allowed in addition to .h files.

Cython functions may use fused types, but the names in the list
should be the specialized ones, such as 'somefunc[float]'.

Function coming from C++ should have ``++`` appended to the name of
the header.

Floating-point exceptions inside these Ufuncs are converted to
special function errors --- which are separately controlled by the
user, and off by default, as they are usually not especially useful
for the user.


The C++ module
--------------
In addition to ``_ufuncs`` module, a second module ``_ufuncs_cxx`` is
generated. This module only exports function pointers that are to be
used when constructing some of the ufuncs in ``_ufuncs``. The function
pointers are exported via Cython's standard mechanism.

This mainly avoids build issues --- Python distutils has no way to
figure out what to do if you want to link both C++ and Fortran code in
the same shared library.

z}# This file is automatically generated by _generate_pyx.py.
# Do not edit manually!

include "_ufuncs_extra_code_common.pxi"
z!include "_ufuncs_extra_code.pxi"
z#
# Aliases
#
jn = jv
a±  # This file is automatically generated by _generate_pyx.py.
# Do not edit manually!

ctypedef fused number_t:
    double complex
    double

cpdef number_t spherical_jn(long n, number_t z, bint derivative=*) nogil
cpdef number_t spherical_yn(long n, number_t z, bint derivative=*) nogil
cpdef number_t spherical_in(long n, number_t z, bint derivative=*) nogil
cpdef number_t spherical_kn(long n, number_t z, bint derivative=*) nogil
at	  # This file is automatically generated by _generate_pyx.py.
# Do not edit manually!
"""
.. highlight:: cython

Cython API for special functions
================================

Scalar, typed versions of many of the functions in ``scipy.special``
can be accessed directly from Cython; the complete list is given
below. Functions are overloaded using Cython fused types so their
names match their Python counterpart. The module follows the following
conventions:

- If a function's Python counterpart returns multiple values, then the
  function returns its outputs via pointers in the final arguments.
- If a function's Python counterpart returns a single value, then the
  function's output is returned directly.

The module is usable from Cython via::

    cimport scipy.special.cython_special

Error handling
--------------

Functions can indicate an error by returning ``nan``; however they
cannot emit warnings like their counterparts in ``scipy.special``.

Available functions
-------------------

FUNCLIST

Custom functions
----------------

Some functions in ``scipy.special`` which are not ufuncs have custom
Cython wrappers.

Spherical Bessel functions
~~~~~~~~~~~~~~~~~~~~~~~~~~

The optional ``derivative`` boolean argument is replaced with an
optional Cython ``bint``, leading to the following signatures.

- :py:func:`~scipy.special.spherical_jn`::

        double complex spherical_jn(long, double complex)
        double complex spherical_jn(long, double complex, bint)
        double spherical_jn(long, double)
        double spherical_jn(long, double, bint)

- :py:func:`~scipy.special.spherical_yn`::

        double complex spherical_yn(long, double complex)
        double complex spherical_yn(long, double complex, bint)
        double spherical_yn(long, double)
        double spherical_yn(long, double, bint)

- :py:func:`~scipy.special.spherical_in`::

        double complex spherical_in(long, double complex)
        double complex spherical_in(long, double complex, bint)
        double spherical_in(long, double)
        double spherical_in(long, double, bint)

- :py:func:`~scipy.special.spherical_kn`::

        double complex spherical_kn(long, double complex)
        double complex spherical_kn(long, double complex, bint)
        double spherical_kn(long, double)
        double spherical_kn(long, double, bint)

"""

include "_cython_special.pxi"
include "_cython_special_custom.pxi"
a+  # This file is automatically generated by _generate_pyx.py.
# Do not edit manually!

from typing import Any, Dict

import numpy as np

__all__ = [
    'geterr',
    'seterr',
    'errstate',
    {ALL}
]

def geterr() -> Dict[str, str]: ...
def seterr(**kwargs: str) -> Dict[str, str]: ...

class errstate:
    def __init__(self, **kargs: str) -> None: ...
    def __enter__(self) -> None: ...
    def __exit__(
        self,
        exc_type: Any,  # Unused
        exc_value: Any,  # Unused
        traceback: Any,  # Unused
    ) -> None: ...

{STUBS}

é    N)ÚListZ_add_newdocsÚfloatZdoublezlong doublezfloat complexúdouble complexzlong double complexÚintZlongZvoid)	ÚfÚdÚgÚFÚDÚGÚiÚlÚvZ	npy_floatZ
npy_doubleZnpy_longdoubleZ
npy_cfloatZnpy_cdoubleZnpy_clongdoubleZnpy_intZnpy_longZ	NPY_FLOATZ
NPY_DOUBLEZNPY_LONGDOUBLEZ
NPY_CFLOATZNPY_CDOUBLEZNPY_CLONGDOUBLEZNPY_INTZNPY_LONG)r   r   r   r	   r
   r   r   r   zd*ddddzD*DDDDÚddr   r
   ÚdD)	ZairyZbetaZerfZexprelZgammaZjvZloggammaZlogitZpsic                 C   s   |   dd¡S )Nú Ú_)Úreplace)Úarg© r   ú=/usr/lib/python3/dist-packages/scipy/special/_generate_pyx.pyÚ
underscore   s   r   c                 C   s   dd„ | D ƒS )Nc                 S   ó   g | ]}d   |¡‘qS )ZilfdgFDG)Úindex©Ú.0Úxr   r   r   Ú
<listcomp>%  ó    zcast_order.<locals>.<listcomp>r   )Úcr   r   r   Ú
cast_order$  s   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   )r   r   )r   r   )r   r   )r   r   )r   r   )r   r   )r   r   )r   r   ZNPY_NANZ
0xbad0bad0c                 C   sÒ  t | ƒt |ƒkrtdƒ‚t |ƒt |ƒkr&|dkr"t |ƒd t |ƒks&tdƒ‚d|| |||f }d| }|d7 }|d7 }|d	7 }tt |ƒƒD ]
}|d
||f 7 }qEtt |ƒƒD ]}|d||t |ƒ f 7 }qVg }g }	g }
tt | ƒƒD ]}| t| |  ¡ |	 dt| |  t||  |f ¡ qqt |ƒd t |ƒkrªd}|
 |¡ |dt| f 7 }nd}t|ƒD ]'\}}|dt| || f 7 }| dt|  ¡ |	 d||  ¡ |
 |¡ q°|d7 }t |ƒd t |ƒkréd}nd}d|t| d |¡d |	¡f }g }tt | ƒƒD ](}|| | | ftv r*dt| |  t||  |t||  |f }| |¡ q|r^|dd |¡ 7 }|d| 7 }|d7 }|d7 }t|
ƒD ]\}}|d|t| t| f 7 }qJn||7 }tt	||
ƒƒD ]O\}\}}||ftv r©|d|t| |f 7 }|dt| |t| |f 7 }|d7 }|d 7 }|d!t| |t| t| f 7 }qi|d"t| |t| |f 7 }qitt |ƒƒD ]}|d#||f 7 }q¿tt |ƒƒD ]}|d$||t |ƒ f 7 }qÑ|d%7 }||fS )&a¡  
    Generate a UFunc loop function that calls a function given as its
    data parameter with the specified input and output arguments and
    return value.

    This function can be passed to PyUFunc_FromFuncAndData.

    Parameters
    ----------
    func_inputs, func_outputs, func_retval : str
        Signature of the function to call, given as type codes of the
        input, output and return value arguments. These 1-character
        codes are given according to the CY_TYPES and TYPE_NAMES
        lists above.

        The corresponding C function signature to be called is:

            retval func(intype1 iv1, intype2 iv2, ..., outtype1 *ov1, ...);

        If len(ufunc_outputs) == len(func_outputs)+1, the return value
        is treated as the first output argument. Otherwise, the return
        value is ignored.

    ufunc_inputs, ufunc_outputs : str
        Ufunc input and output signature.

        This does not have to exactly match the function signature,
        as long as the type casts work out on the C level.

    Returns
    -------
    loop_name
        Name of the generated loop function.
    loop_body
        Generated C code for the loop.

    z2Function and ufunc have different number of inputsr   é   z-Function retval and ufunc outputs don't matchzloop_%s_%s_%s_As_%s_%szTcdef void %s(char **args, np.npy_intp *dims, np.npy_intp *steps, void *data) nogil:
z$    cdef np.npy_intp i, n = dims[0]
z(    cdef void *func = (<void**>data)[0]
z4    cdef char *func_name = <char*>(<void**>data)[1]
z    cdef char *ip%d = args[%d]
z    cdef char *op%d = args[%d]
z<%s>(<%s*>ip%d)[0]z    cdef %s ov0
r   z    cdef %s ov%d
z%s *z&ov%dz    for i in range(n):
zov0 = Ú z&        %s(<%s(*)(%s) nogil>func)(%s)
ú, z$<%s>(<%s*>ip%d)[0] == (<%s*>ip%d)[0]z        if %s:
ú and ú    z        else:
zQ            sf_error.error(func_name, sf_error.DOMAIN, "invalid input argument")
z            ov%d = <%s>%s
z        if ov%d == <%s>ov%d:
z'            (<%s *>op%d)[0] = <%s>ov%d
zI            sf_error.error(func_name, sf_error.DOMAIN, "invalid output")
z%            (<%s *>op%d)[0] = <%s>%s
z#        (<%s *>op%d)[0] = <%s>ov%d
z        ip%d += steps[%d]
z        op%d += steps[%d]
z"    sf_error.check_fpe(func_name)
)
ÚlenÚ
ValueErrorÚrangeÚappendÚCY_TYPESÚ	enumerateÚjoinÚDANGEROUS_DOWNCASTÚ	NAN_VALUEÚzip)Zfunc_inputsZfunc_outputsZfunc_retvalZufunc_inputsZufunc_outputsÚnameÚbodyÚjZftypesZfvarsZouttypecodesZ	func_joffÚouttypeZrvZfuncallZinput_checksZchkZfouttyper   r   r   Úgenerate_loop@  sª   'ÿÿ
ÿ

þ
ÿþ
€ÿÿÿÿÿr4   c                 C   sN   dd„ | D ƒ}| d }d| d g}|D ]	}|  d| ¡ qd |¡}||fS )z¦
    Generate name of and cython code for a fused type.

    Parameters
    ----------
    typecodes : str
        Valid inputs to CY_TYPES (i.e. f, d, g, ...).

    c                 S   ó   g | ]}t | ‘qS r   ©r*   r   r   r   r   r   Ï  ó    z'generate_fused_type.<locals>.<listcomp>Z	_number_tzctypedef fused ú:r%   Ú
)r)   r,   )ÚcodesZcytypesr0   ZdeclarationZcytyper   r   r   Úgenerate_fused_typeÅ  s   

r;   c                 C   s˜  d}g g g }}}|  d¡}t|ƒdkr|d }|d }n|d }d}g g }	}
t|ƒD ]\}}d |¡}|	 |¡ |
 d t| |¡¡ q-d d	 |
¡¡}| |¡ | |d
 ¡ g }t|ƒD ] \}}d |¡}| d |¡¡ d t| |¡}| || ¡ qa| |d ¡ | d| d ¡ d | |d¡}d | |d¡}d || ¡}d || | ¡}| |d|  d	 |	¡¡}| || d	 |	| ¡¡}||fS )Nr%   Ú*r!   r   r"   úx{}ú{} {}zdef {{}}(int N, {}):r#   z
cdef int núy{}ú&{}ú
cdef {} {}zfor n in range(N):é   ú{}({})z_bench_{}_{}_{}ÚpyÚcyr9   z_ufuncs.)Úsplitr&   r+   Úformatr)   r*   r,   )r0   r:   ÚtabÚtopZmiddleÚendÚtmpÚincodesÚoutcodesZinargsZinargs_and_typesÚnÚcoder   ÚlineZoutargsZpyfuncZcyfuncZ
pytemplateZ
cytemplateÚpybenchÚcybenchr   r   r   Úgenerate_benchØ  s>   






rS   c                 C   sº   d}d  | ¡g}|D ]B}| d¡\}}| d¡}dd„ |d D ƒ}t|ƒdkr5d	d„ |d D ƒ}| |¡ t| }	d
  |	| d |¡¡}
| d| |
 ¡ q
d  |d ¡|d< d |¡}|S )Nr%   z!- :py:func:`~scipy.special.{}`::
z->r<   c                 S   r5   r   r6   r   r   r   r   r     r7   z generate_doc.<locals>.<listcomp>r   r!   c                 S   s   g | ]	}t | › d ‘qS ©z *r6   r   r   r   r   r     s    z	{} {}({})r#   rB   z{}
éÿÿÿÿr9   )rG   rF   r&   Úextendr*   r,   r)   )r0   ÚspecsrH   ÚdocÚspecrL   rM   ÚintypesÚtypesr3   rP   r   r   r   Úgenerate_docÿ  s   


r\   c                 C   ó   d  | ¡}|S )z0Cast a Cython double complex to a NumPy cdouble.z1_complexstuff.npy_cdouble_from_double_complex({})©rG   ©ÚvarÚresr   r   r   Únpy_cdouble_from_double_complex  ó   
rb   c                 C   r]   )z0Cast a NumPy cdouble to a Cython double complex.z1_complexstuff.double_complex_from_npy_cdouble({})r^   r_   r   r   r   Údouble_complex_from_npy_cdouble  rc   rd   c           	      c   sz    dg}d| v sd| v s|dd„ |D ƒ }|D ]#\}}| }|}t ||ƒD ]\}}| ||¡}| ||¡}q$||fV  qdS )a.  
    Generate variants of UFunc signatures, by changing variable types,
    within the limitation that the corresponding C types casts still
    work out.

    This does not generate all possibilities, just the ones required
    for the ufunc to work properly with the most common data types.

    Parameters
    ----------
    inputs, outputs : str
        UFunc input and output signature strings

    Yields
    ------
    new_input, new_output : str
        Modified input and output strings.
        Also the original input/output pair is yielded.

    )r   r   r   r   c                 S   s    g | ]\}}|d  |d f‘qS )r   ZfFr   )r   ÚaÚbr   r   r   r   ?  s     z!iter_variants.<locals>.<listcomp>N)r/   r   )	ÚinputsÚoutputsÚmapsÚsrcÚdstZ
new_inputsZnew_outputsre   rf   r   r   r   Úiter_variants  s   €þúrl   c                   @   s8   e Zd ZdZdd„ Zdd„ Zddd„Z			
ddd„ZdS )ÚFuncz.
    Base class for Ufunc and FusedFunc.

    c              	   C   s`   || _ g | _i | _| ¡ D ] }||  ¡ D ]\}}|  |¡\}}}| j |||||f¡ qqd S ©N)r0   Ú
signaturesÚfunction_name_overridesÚkeysÚitemsÚ_parse_signaturer)   )Úselfr0   ro   ÚheaderÚsigÚinargÚoutargÚretr   r   r   Ú__init__P  s   þÿzFunc.__init__c                 C   s”   t  d|¡}|r)dd„ | ¡ D ƒ\}}}| d¡dkr$td | j|¡ƒ‚|||fS t  d|¡}|rAdd„ | ¡ D ƒ\}}|d	|fS td | j|¡ƒ‚)
Nz?\s*([fdgFDGil]*)\s*\*\s*([fdgFDGil]*)\s*->\s*([*fdgFDGil]*)\s*$c                 S   ó   g | ]}|  ¡ ‘qS r   ©Ústripr   r   r   r   r   ]  r7   z)Func._parse_signature.<locals>.<listcomp>r<   r!   z{}: Invalid signature: {}z)\s*([fdgFDGil]*)\s*->\s*([fdgFDGil]?)\s*$c                 S   r{   r   r|   r   r   r   r   r   c  r7   r"   )ÚreÚmatchÚgroupsÚcountr'   rG   r0   )rt   rv   Úmrw   rx   ry   r   r   r   rs   Z  s   

zFunc._parse_signatureFc                 C   s¸   g }| j D ]T\}}}}}| dd¡}dd„ |D ƒdd„ |D ƒ }dd„ |D ƒdd„ |D ƒ }	dt| d	 |¡f }
| d
¡rE|rE|
d }ndt| d	 |	¡f }| ||
||f¡ q|S )Nr<   r"   c                 S   r5   r   ©ÚC_TYPESr   r   r   r   r   k  r7   z'Func.get_prototypes.<locals>.<listcomp>c                 S   ó   g | ]}t | d  ‘qS rT   rƒ   r   r   r   r   r   l  ó    c                 S   r5   r   r6   r   r   r   r   r   m  r7   c                 S   r…   rT   r6   r   r   r   r   r   n  r†   z
%s (*)(%s)r#   ÚhZnogilz%s (*)(%s) nogil)ro   r   r„   r,   Úendswithr*   r)   )rt   Únptypes_for_hZ
prototypesÚ	func_namerw   rx   ry   ru   Zc_argsZcy_argsÚc_protoÚcy_protor   r   r   Úget_prototypesg  s   ÿÿ
zFunc.get_prototypesÚ_func_Tc                 C   sj   |r|| j v r| j | }d}t d|¡}|r| ¡ \}}n|d}}|r/d||| dd¡f S d||f S )Nr"   z^(.*?)(\[.*\])$z%s%s%sr   r   z%s%s)rp   r~   r   r€   r   )rt   Úc_nameÚspecializedÚprefixÚoverrider‚   Zc_base_nameZ
fused_partr   r   r   Úcython_func_namew  s   

zFunc.cython_func_nameN)F)FrŽ   T)Ú__name__Ú
__module__Ú__qualname__Ú__doc__rz   rs   r   r“   r   r   r   r   rm   K  s    

ÿrm   c                       s0   e Zd ZdZ‡ fdd„Zdd„ Zdd„ Z‡  ZS )ÚUfunca  
    Ufunc signature, restricted format suitable for special functions.

    Parameters
    ----------
    name
        Name of the ufunc to create
    signature
        String of form 'func: fff*ff->f, func2: ddd->*i' describing
        the C-level functions and types of their input arguments
        and return values.

        The syntax is 'function_name: inputparams*outputparams->output_retval*ignored_retval'

    Attributes
    ----------
    name : str
        Python name for the Ufunc
    signatures : list of (func_name, inarg_spec, outarg_spec, ret_spec, header_name)
        List of parsed signatures
    doc : str
        Docstring, obtained from add_newdocs
    function_name_overrides : dict of str->str
        Overrides for the function names in signatures

    c                    sF   t ƒ  ||¡ t |¡| _| jd u rtd| ƒ‚t | j¡ ¡ | _d S )NzNo docstring for ufunc %r)	Úsuperrz   Úadd_newdocsÚgetrX   r'   ÚtextwrapÚdedentr}   )rt   r0   ro   ©Ú	__class__r   r   rz   ¥  s
   
zUfunc.__init__c           
   	      s  d ‰d ‰t ƒ ‰g ‰‡ ‡‡‡‡‡fdd„}ˆjD ]6\}}}}}t dd|¡| }| dd¡}ˆd u r9t|ƒ‰t|ƒ‰tt||ƒƒd \}	}||||||	|ƒ qˆjD ])\}}}}}t dd|¡| }| dd¡}t||ƒD ]\}	}||||||	|ƒ qlqQˆjdd„ d	 ˆˆˆfS )
Nc           	         sš   |ˆv rd S ˆ  |¡ | ||f}d|v rtdˆj|f ƒ‚t|ƒˆks)t|ƒˆkr4tdˆj|ˆˆf ƒ‚t|||||ƒ\}}|ˆ |< ˆ | |||f¡ d S )Nr   z%s: void signature %rz6%s: signature %r does not have %d/%d input/output args)Úaddr'   r0   r&   r4   r)   )	rŠ   rw   rx   ry   ÚinpÚoutprv   Ú	loop_nameZloop©Ú	all_loopsÚ	inarg_numÚ
outarg_numÚseenrt   Úvariantsr   r   Úadd_variant³  s   

þz4Ufunc._get_signatures_and_loops.<locals>.add_variantú\*.*r"   r<   r   c                 S   s   t | d ƒS )NrB   )r    )r   r   r   r   Ú<lambda>Ù  s    z1Ufunc._get_signatures_and_loops.<locals>.<lambda>©Úkey)	Úsetro   r~   Úsubr   r&   Úlistrl   Úsort)
rt   r¥   rª   rŠ   rw   rx   ry   ru   r¢   r¡   r   r¤   r   Ú_get_signatures_and_loops¬  s*   ÿ
zUfunc._get_signatures_and_loopsc              	   C   sæ  d}|   |¡\}}}g }g }g }|D ](\}	}
}}|D ]	}| t| ¡ q|D ]	}| t| ¡ q&| |
¡ | |	¡ q|d| jt|ƒf 7 }|d| jdt|ƒ f 7 }|d| jt|ƒf 7 }|d| jt|ƒf 7 }|d| j| j dd	¡ d
d¡ dd¡f 7 }t|ƒD ]\}}|d| j||f 7 }qƒt|ƒD ]\}}|d| j||f 7 }q–t|ƒD ]\}}|d| j|| j|ddf 7 }|d| j|| jf 7 }q©t|ƒD ]\}}|d| j|| j|f 7 }qÌ|dt|ƒ||  ||f  d| j¡7 }|S )Nr"   z2cdef np.PyUFuncGenericFunction ufunc_%s_loops[%d]
zcdef void *ufunc_%s_ptr[%d]
rB   zcdef void *ufunc_%s_data[%d]
zcdef char ufunc_%s_types[%d]
z&cdef char *ufunc_%s_doc = (
    "%s")
ú\z\\ú"z\"r9   z	\n"
    "z3ufunc_%s_loops[%d] = <np.PyUFuncGenericFunction>%s
zufunc_%s_types[%d] = <char>%s
zufunc_%s_ptr[2*%d] = <void*>%s
T©r   z,ufunc_%s_ptr[2*%d+1] = <void*>(<char*>"%s")
z(ufunc_%s_data[%d] = &ufunc_%s_ptr[2*%d]
zo@ = np.PyUFunc_FromFuncAndData(ufunc_@_loops, ufunc_@_data, ufunc_@_types, %d, %d, %d, 0, "@", ufunc_@_doc, 0)
ú@)	r³   r)   Ú
TYPE_NAMESr0   r&   rX   r   r+   r“   )rt   r¥   Útoplevelr©   r¦   r§   ZloopsZfuncsr[   rŠ   r£   rg   rh   r   r2   ÚfunctionÚtypeÚfuncr   r   r   ÚgenerateÝ  sZ   
ÿ
þ
ÿ

ÿ
ÿÿþ
üzUfunc.generate)r”   r•   r–   r—   rz   r³   r½   Ú__classcell__r   r   rž   r   r˜   Š  s
    1r˜   c                       s   e Zd ZdZ‡ fdd„Zdd„ Zdd„ Zdd	„ Zd
d„ Zdd„ Z	dd„ Z
dd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Z‡  ZS ) Ú	FusedFuncz_
    Generate code for a fused-type special function that can be
    cimported in Cython.

    c                    s‚   t ƒ  ||¡ d| j | _|  ¡ \| _| _tƒ | _|  	| j¡\| _
}| j |¡ |  	| j¡\| _}| j |¡ |  ¡ \| _| _d S )Nz(See the documentation for scipy.special.)r™   rz   r0   rX   Ú
_get_codesrL   rM   r¯   Úfused_typesÚ
_get_typesrZ   ÚupdateÚouttypesÚ	_get_varsÚinvarsÚoutvars)rt   r0   ro   Zinfused_typesZoutfused_typesrž   r   r   rz     s   zFusedFunc.__init__c                    s  d\}}g g }}| j D ]1\}}}}}t dd|¡| }	|d u r(t|ƒ}t|	ƒ}tt||	ƒƒd \}
}	| |
¡ | |	¡ qg }t|ƒD ]‰ t‡ fdd„|D ƒƒ}| 	¡  | d 
|¡¡ qDg }t|ƒD ]‰ t‡ fdd„|D ƒƒ}| 	¡  | d 
|¡¡ qdt|ƒt|ƒfS )N)NNr«   r"   r   c                    ó   g | ]}|ˆ  ‘qS r   r   r   ©rN   r   r   r   .  r7   z(FusedFunc._get_codes.<locals>.<listcomp>c                    rÈ   r   r   r   rÉ   r   r   r   3  r7   )ro   r~   r°   r&   r±   rl   r)   r(   Úuniquer²   r,   Útuple)rt   r¦   r§   Zall_inpZall_outpr   rw   rx   ry   r¢   r¡   rL   r:   rM   r   rÉ   r   rÀ      s*   

zFusedFunc._get_codesc                 C   s`   g }t ƒ }|D ]$}t|ƒdkr| t| |f¡ qt|ƒ\}}| |¡ | ||f¡ q||fS )Nr!   )r¯   r&   r)   r*   r;   r    )rt   r:   Z	all_typesrÁ   rO   Ú
fused_typeÚdecr   r   r   rÂ   9  s   
zFusedFunc._get_typesc                 C   s8   dd„ t t| jƒƒD ƒ}dd„ t t| jƒƒD ƒ}||fS )Nc                 S   r   )r=   r^   ©r   rN   r   r   r   r   H  r   z'FusedFunc._get_vars.<locals>.<listcomp>c                 S   r   )r?   r^   rÎ   r   r   r   r   I  r   )r(   r&   rZ   rÄ   )rt   rÆ   rÇ   r   r   r   rÅ   G  s   zFusedFunc._get_varsc           
      C   sœ   g }t ƒ }t||ƒD ]$\\}}}t|ƒdkrq
||vr.| |› dtt| ƒ› ¡ | |¡ q
|r@|dkr@d |d |¡¡}	|	S |rJ|dkrJd}	|	S d}	|	S )z_Generate an if/elif/else clause that selects a specialization of
        fused types.

        r!   z is Úelsez{} {}:r$   úelse:N)	r¯   r/   r&   r)   r   r*   r    rG   r,   )
rt   r[   r:   ÚadverbZclausesr¨   ÚtypZtypcoderO   rP   r   r   r   Ú_get_conditionalL  s"   
€üÿzFusedFunc._get_conditionalc                 C   sB   g }t |ƒD ]\}}| j| }|r|dkrt|ƒ}| |¡ q|S )zxGenerate pure input variables to a specialization,
        i.e., variables that aren't used to return a value.

        r   )r+   rÆ   rb   r)   )rt   rZ   r   Z
incallvarsrN   Úintyper`   r   r   r   Ú_get_incallvarsa  s   
zFusedFunc._get_incallvarsc                 C   s²   g g g }}}t | jƒt |ƒ }| j|d… }tt||ƒƒD ]4\}\}	}
|rK|
dkrKd |¡}| |¡ | d |¡¡ t|ƒ}| d |	|¡¡ q| d |	¡¡ q|||fS )zoGenerate output variables to a specialization,
        i.e., pointers that are used to return values.

        Nr   ztmp{}r@   ú
{}[0] = {}z{})r&   rÇ   r+   r/   rG   r)   rd   )rt   rÄ   r   ÚoutcallvarsÚtmpvarsÚcastsÚstartrÇ   rN   r`   r3   rK   Ztmpcastr   r   r   Ú_get_outcallvarsn  s   


zFusedFunc._get_outcallvarsc                    s¬  d‰ g ˆ d g}}t ƒ }t| j| j| jƒD ]1\}}}t|ƒdkr3d |t| ¡}| dˆ  | ¡ q|}|\}	}
|	|vrG| |¡ | 	|	¡ q|sL|S t
dd„ |D ƒƒ}dd„ |D ƒ}t |¡d }ttj|Ž ƒD ]i\}}g g }}t|ƒD ]/\}}|| }| tt| ƒ¡ t| jƒD ]\}}| j| |kr¥d |t| ¡}| |¡ qqw|d	kr®d
}n	||krµd}nd}|  |||¡}| dˆ  | ¡ | ‡ fdd„|D ƒ¡ qj|S )znSet all variables to nan for specializations of fused types for
        which don't have signatures.

        r%   rÐ   r!   rÖ   rB   c                 S   s   g | ]\}}|‘qS r   r   )r   Z_unusedr:   r   r   r   r   ›  r7   z+FusedFunc._get_nan_decs.<locals>.<listcomp>c                 S   s   g | ]}t |ƒ‘qS r   )r&   r   r   r   r   r     r7   r   ÚifrÏ   Úelifc                    s   g | ]}d ˆ  | ‘qS )é   r   r   ©rH   r   r   r   °  r†   )r¯   r/   rÇ   rÄ   rM   r&   rG   r.   r)   r    rË   ÚnumpyZprodr+   Ú	itertoolsÚproductr   r*   rÓ   rV   )rt   rÁ   Úlinesr¨   Úoutvarr3   rO   rP   rÌ   r0   r   Z	all_codesZcodelensÚlastr‚   r:   Zfused_codesZdecsrN   ÚnnrÑ   Úcondr   rß   r   Ú_get_nan_decsƒ  sP   
ÿ

€

€ýzFusedFunc._get_nan_decsc                    s*   d‰ t |ƒ}| ¡  ‡ fdd„|D ƒ}|S )zQGenerate the declarations of any necessary temporary
        variables.

        r%   c                    s   g | ]	}ˆ d   |¡ ‘qS )zcdef npy_cdouble {}r^   )r   Ztmpvarrß   r   r   r   »  s    ÿz+FusedFunc._get_tmp_decs.<locals>.<listcomp>)r±   r²   )rt   Úall_tmpvarsrØ   Ztmpdecsr   rß   r   Ú_get_tmp_decs³  s   
ÿzFusedFunc._get_tmp_decsc                 C   sú   d}g g }}t | j| jƒD ]\\}}}| d ||¡¡ qd | jd |¡¡}| |¡ t | j| jƒD ]\\}}}	d ||	¡}| || ¡ q4dd„ | jD ƒ}
d | jd | j¡d |
¡¡}| || ¡ d	 d | j¡¡}| || ¡ d
 |¡}|S )zaGenerate a Python wrapper for functions which pass their
        arguments as pointers.

        r%   r>   zdef _{}_pywrap({}):r#   rA   c                 S   s   g | ]}d |› ‘qS )ú&r   r   r   r   r   r   Í  r   z.FusedFunc._get_python_wrap.<locals>.<listcomp>z
{}({}, {})ú	return {}r9   )	r/   rZ   rÆ   r)   rG   r0   r,   rÄ   rÇ   )rt   rH   r1   ÚcallvarsrÔ   r   ÚinvarrP   r3   rä   Zaddr_outvarsr   r   r   Ú_get_python_wrap¿  s$   

ÿ
zFusedFunc._get_python_wrapc              
   C   s(  d}|\}}}}}|  dd¡}|  dd¡}|  dd¡}| d¡r#d}	nd}	| d¡r-d}
nd}
dd	„ |D ƒ}d
d	„ |D ƒ}t dd|¡}|sHd}t| }|
r`d |¡}d |d || ¡|¡}n| j|dd}|dkrnd}nd}|  | j	||¡}|r„|| g}d| }ng }|}||||||||	||f
S )z4Generate code common to all the _generate_* methods.r%   r   r   r‡   TFú++c                 S   r5   r   r6   r   r   r   r   r   è  r7   z)FusedFunc._get_common.<locals>.<listcomp>c                 S   r5   r   r6   r   r   r   r   r   é  r7   r«   r"   r   z$scipy.special._ufuncs_cxx._export_{}z(<{}(*)({}) nogil>{})r#   r¶   r   rÜ   rÝ   rB   )
r   rˆ   r~   r°   r*   rG   r,   r“   rÓ   rZ   )rt   Úsignumrv   rH   rŠ   rL   rM   Úretcoderu   r   ZcpprZ   rÄ   ÚrettyperÑ   rç   rã   Úspr   r   r   Ú_get_commonÖ  sF   


ÿ

ÿzFusedFunc._get_commonc                 C   s  d}g g }}t | jƒD ]I\}}|  ||¡\
}}}}	}
}}}}}| |¡ |  |
|¡}d |d |¡¡}|r>|dkr>t|ƒ}|d |¡ }| |¡ d ||	¡}| |¡ qt	|ƒdkrÁ| |d ¡ | j
d	 \}}t	|ƒd }t	|ƒdkr‡d t| ¡}| d
| | ¡ n:t |ƒD ]5\}}|d	kr–d}n	||krd}nd}|  | j
||¡}| d
| | ¡ d t| ¡}| d| | ¡ q‹g g }}t | jƒD ]\}\}}| d || j| ¡¡ qË| j
d	 \}}d || jd |¡¡}| |d ¡ | |d | j¡ ¡ d || ¡}|||fS )Nr%   rC   r#   r   rì   ú{}->{}r!   rÐ   r   rB   rÜ   rÏ   rÝ   rÞ   r>   úcpdef {} {}({}) nogilr8   ú"""{}"""r9   )r+   ro   rõ   rV   rÕ   rG   r,   rd   r)   r&   rÄ   r.   rÓ   rZ   rÆ   r0   rX   )rt   rH   rW   r1   rñ   rv   rŠ   rL   rM   rò   rZ   rÄ   ró   r   rã   rô   rí   ÚcallrP   r3   rå   rN   rO   rÑ   rç   ÚheadrÔ   r   rÍ   rj   r   r   r   Ú$_generate_from_return_and_no_outargs  sR   

ÿ



z.FusedFunc._generate_from_return_and_no_outargsc                    sŠ  d}t ƒ }g g }}t| jƒD ]k\}}|  ||¡\
}}}	}
}}}}}‰ | |¡ |  ||¡}|  ||¡\}}}| |¡ | |¡ d |d 	|¡¡}| 
ˆ | ¡ | ‡ fdd„|D ƒ¡ t|	ƒdkrod ||	¡}| 
|¡ qd ||	¡}| 
|¡ qt|ƒdkrŠ|  ¡ }| |¡ t| jƒdkr d	 | jd
 ¡}| 
|| ¡ g g }}t| j| jƒD ]\}\}}| 
d ||¡¡ q¬t| jƒdkrÚt| j| jƒD ]\}\}}| 
d ||¡¡ qÊt| jƒdkrô| jd
 \}}d || jd 	|¡¡}n
d | jd 	|¡¡}| 
|d ¡ | 
|d | j¡ ¡ t| jƒdkr1| jd
 }| jd
 \}}d ||¡}| 
|| ¡ | |  |¡¡ d 	|| ¡}|||fS )Nr%   rC   r#   c                    ó   g | ]}ˆ | ‘qS r   r   r   ©rô   r   r   r   K  r7   zBFusedFunc._generate_from_outargs_and_no_return.<locals>.<listcomp>r!   rö   ú{}*{}->vzreturn {}[0]r   r>   ú{} *{}r÷   úcdef void {}({}) nogilr8   rø   rA   r9   )r¯   r+   ro   rõ   rV   rÕ   rÛ   rÃ   rG   r,   r)   r&   rè   rÇ   r/   rÆ   rZ   rÄ   r0   rX   rê   )rt   rH   ré   rW   r1   rñ   rv   rŠ   rL   rM   rò   rZ   rÄ   ró   r   rã   rí   r×   rØ   rÙ   rù   rP   rú   rî   rÔ   r   rä   r3   rÍ   rj   r   rý   r   Ú$_generate_from_outargs_and_no_return:  s\   

ÿ






z.FusedFunc._generate_from_outargs_and_no_returnc                    sà  d}t ƒ }g g }}t| jƒD ]n\}}|  ||¡\
}}}	}
}}}}}‰ | |¡ |  ||¡}|  ||¡\}}}| |¡ | |¡ d |d 	|¡¡}|rT|dkrTt
|ƒ}d | jd |¡}| ˆ | ¡ | ‡ fdd„|D ƒ¡ d	 ||	|
 ¡}| |¡ qt|ƒd
kr|  ¡ }| |¡ g g }}t| j| jƒD ]\}\}}| d ||¡¡ q™t| j| jƒD ]\}\}}| d ||¡¡ q°d | jd 	|¡¡}| |d ¡ | |d | j¡ ¡ | |  |¡¡ d 	|| ¡}|||fS )Nr%   rC   r#   r   rÖ   r   c                    rü   r   r   r   rý   r   r   r   †  r7   z?FusedFunc._generate_from_outargs_and_return.<locals>.<listcomp>rþ   r!   r>   rÿ   r   r8   rø   r9   )r¯   r+   ro   rõ   rV   rÕ   rÛ   rÃ   rG   r,   rd   rÇ   r)   r&   rè   r/   rÆ   rZ   rÄ   r0   rX   rê   )rt   rH   ré   rW   r1   rñ   rv   rŠ   rL   rM   rò   rZ   rÄ   ró   r   rã   rí   r×   rØ   rÙ   rù   rú   rî   rÔ   r   rä   r3   rÍ   rj   r   rý   r   Ú!_generate_from_outargs_and_returns  sD   

ÿ





z+FusedFunc._generate_from_outargs_and_returnc                 C   sÊ   | j d \}}}}}t dd|¡}|sd}t|ƒdkr'|dkr'|  ¡ \}}}n(t|ƒdkr9|dkr9|  ¡ \}}}nt|ƒdkrK|dkrK|  ¡ \}}}ntdƒ‚t| jƒdkr[|  	¡ }nd }|||| j
|fS )Nr   r«   r"   r   zInvalid signaturer!   )ro   r~   r°   r&   rû   r  r  r'   rÇ   rï   rÁ   )rt   r   rM   rò   rÍ   rj   rW   Úwrapr   r   r   r½   œ  s   
zFusedFunc.generate)r”   r•   r–   r—   rz   rÀ   rÂ   rÅ   rÓ   rÕ   rÛ   rè   rê   rï   rõ   rû   r  r  r½   r¾   r   r   rž   r   r¿     s"    0139)r¿   c              	   C   sü   g }g }|  dd¡  dd¡  dd¡}| d¡rL| d|dd… | j|d	d
|  |¡f ¡ d| }	| d|  d|	¡ ¡ | d|	|	| j|ddf ¡ n-d|  |¡|f }
| d| ¡ | d|  d|
¡ ¡ | d| ¡ | d|  d|¡ ¡ |||fS )zÑ
    Construct a Cython declaration of a function coming either from a
    pxd or a header file. Do sufficient tricks to enable compile-time
    type checking against the signature expected by the ufunc.

    ú[r   ú]r   ú.pxdzfrom .%s cimport %s as %sNéüÿÿÿr"   )r‘   z_proto_%s_tzctypedef %sz(*)zcdef %s *%s_var = &%sTr¶   z%s "%s"zcdef extern from "%s":z    cdef %sz#include "%s"z%s;)r   rˆ   r)   r“   )Úufuncr   r‹   rŒ   ru   Úproto_h_filenameÚdefsÚdefs_hÚvar_nameZ
proto_nameÚnew_namer   r   r   Úget_declaration³  s&   
þ
ÿ
r  c                 C   s2  | d }| d }|d }|d }|d }d}g }	g }
i }g }ddg}g }|j dd„ d	 |D ]p}| ¡ }|D ]\\}}}}| d
¡r||d d… }t||||||ƒ\}}}| |¡ | |¡ | d||j|dddf ¡ | d|f ¡ d| |j|< q6t||||||ƒ\}}}|	 |¡ |
 |¡ q6| |¡}||d 7 }q.d 	t
| ¡ ƒ|	 |g ¡}dd„ |D ƒg d¢ }d d 	|¡¡}t|dƒ&}| t¡ | t¡ | |¡ | d¡ | |¡ | t¡ W d   ƒ n1 sîw   Y  t|
ƒ}
t|dƒ}| d¡ | d 	|
¡¡ | d¡ W d   ƒ n	1 sw   Y  t|ƒ}t|dƒ}| d¡ | d 	|¡¡ | d¡ W d   ƒ n	1 sFw   Y  t|dƒ}| t¡ | d¡ | d 	|¡¡ | d¡ W d   ƒ n	1 ssw   Y  t|dƒ}| d 	|¡¡ W d   ƒ d S 1 s’w   Y  d S )Nú.pyxú_defs.hr  r"   zfrom . cimport sf_errorzFcdef void _set_action(sf_error.sf_error_t, sf_error.sf_action_t) nogilc                 S   s   | j S rn   )r0   )Úur   r   r   r¬   í  s    z!generate_ufuncs.<locals>.<lambda>r­   rð   éþÿÿÿz!cdef void *_export_%s = <void*>%sTF)r   r’   zcdef void *_export_%sz"scipy.special._ufuncs_cxx._export_r9   c                 S   s$   g | ]}|j  d ¡sd |j ¡‘qS )r   z'{}')r0   Ú
startswithrG   )r   r  r   r   r   r     s
    þ
ÿz#generate_ufuncs.<locals>.<listcomp>)z'geterr'z'seterr'z
'errstate'ú'jn'z__all__ = [{}]r#   Úwz0#ifndef UFUNCS_PROTO_H
#define UFUNCS_PROTO_H 1
z
#endif
z
# distutils: language = c++
)r²   r   rˆ   r  rV   r)   r“   rp   r½   r,   ÚsortedÚvaluesrG   ÚopenÚwriteÚUFUNCS_EXTRA_CODE_COMMONÚUFUNCS_EXTRA_CODEÚUFUNCS_EXTRA_CODE_BOTTOMrÊ   )Z	fn_prefixZcxx_fn_prefixÚufuncsÚfilenamer	  Zcxx_proto_h_filenameZcxx_pyx_filenameZcxx_pxd_filenamer¹   r
  r  r¥   Zcxx_defsZcxx_pxd_defsZ
cxx_defs_hr  Úcfuncsr   r‹   rŒ   ru   Ú	item_defsZitem_defs_hr  r   ÚtZ
all_ufuncsÚ
module_allr   r   r   r   Úgenerate_ufuncsÖ  s”   þ


ÿ

ÿ
ÿ

þüÿ




ú
ý
ý

ü$ÿr#  c              	   C   s6  | d }| d }|d }g }g }g }t ƒ }	g }
g }|D ]s}|j d¡r$q| ¡ \}}}}}| |¡ | |¡ |r>| |¡ |	 |¡ |jdd}|D ]\}}}}| d¡rWqKt||||||ƒ\}}}| 	|¡ qK|
 t
|j|ƒ¡ |jtv rŽt|j D ]}t|j|ƒ\}}| 	||g¡ q|qt|	ƒ}	|	 ¡  t|dƒ'}| t¡ | d	¡ | d
 |	¡¡ | d
¡ | d	 |¡¡ W d   ƒ n1 sÆw   Y  t|dƒ@}t}| dd	 |
¡¡}| |¡ | d	¡ | d	 |¡¡ | d
¡ | d
 |¡¡ | d
¡ | d
 |¡¡ W d   ƒ d S 1 sw   Y  d S )Nr  r  r  r   T)r‰   rð   r  r9   z

ZFUNCLIST)r¯   r0   r  r½   r)   rÃ   r   rˆ   r  rV   r\   ÚCYTHON_SPECIAL_BENCHFUNCSrS   r±   r²   r  r  ÚCYTHON_SPECIAL_PXDr,   ÚCYTHON_SPECIAL_PYXr   )ÚmodnameZufunc_fn_prefixÚfused_funcsZpxdfileZpyxfiler	  ZsourcesZdeclarationsZ	bench_auxrÁ   rX   r
  r¼   rÍ   rj   rW   Zfunc_fused_typesr  r  r   r‹   rŒ   ru   r   r   r:   rQ   rR   r   r   r   r   Úgenerate_fused_funcs7  sj   





þ
€


û



$÷r)  Úmodule_namer  c                 C   sÈ   g g }}|D ]}|  |j› d¡ |j d¡s"|  d|j› d¡ q|  d¡ |  d¡ | ¡  | ¡  tjd |¡d |¡d}| › d	}t|d
ƒ}| |¡ W d   ƒ d S 1 s]w   Y  d S )Nz
: np.ufuncr   ú'r  zjn: np.ufuncz,
    r9   )ZALLÚSTUBSz.pyir  )	r)   r0   r  r²   r,  rG   r,   r  r  )r*  r  Zstubsr"  r  ÚcontentsZ
stubs_filer   r   r   r   Úgenerate_ufuncs_type_stubs}  s$   
€

þ
"ÿr.  c                 C   s6   t ƒ }g }| D ]}||v rq| |¡ | |¡ q|S )zb
    Return a list without repeated entries (first occurrence is kept),
    preserving order.
    )r¯   r    r)   )Zlstr¨   Znew_lstÚitemr   r   r   rÊ   “  s   
rÊ   c                    s$   ddl m‰  t‡ ‡fdd„|D ƒƒS )Nr   )Únewerc                 3   s0    | ]}ˆD ]}t j |¡oˆ ||ƒV  qqd S rn   )ÚosÚpathÚexists)r   rk   rj   ©r0  Ú	src_filesr   r   Ú	<genexpr>¤  s   € ÿ ÿzall_newer.<locals>.<genexpr>)Zdistutils.dep_utilr0  Úall)r5  Ú	dst_filesr   r4  r   Ú	all_newer¢  s   ÿr9  c                  C   s0  t jtpd ¡ d} |  ¡ \}}t|ƒdkr|  d¡ tj 	t
¡}tj t
¡tj tj |d¡¡tj tj |d¡¡f}d}t t¡ t||ƒrNtdƒ d S g g }}tdƒ}t |¡}	W d   ƒ n1 sgw   Y  |	 ¡ D ]\}
}| t|
|ƒ¡ | t|
|ƒ¡ qptd	d
|ƒ td	|ƒ tdd	|ƒ d S )Nr"   )Úusager   zinvalid number of argumentszfunctions.jsonz_add_newdocs.py)z_ufuncs.pyxz_ufuncs_defs.hz_ufuncs_cxx.pyxz_ufuncs_cxx.pxdz_ufuncs_cxx_defs.hz_ufuncs.pyizcython_special.pyxzcython_special.pxdz4scipy/special/_generate_pyx.py: all files up-to-dateZ_ufuncsZ_ufuncs_cxxZcython_special)ÚoptparseZOptionParserr—   r}   Ú
parse_argsr&   Úerrorr1  r2  ÚdirnameÚ__file__Úabspathr,   ÚchdirÚBASE_DIRr9  Úprintr  ÚjsonÚloadrr   r)   r˜   r¿   r#  r.  r)  )ÚpÚoptionsÚargsÚpwdr5  r8  r  r(  ÚdataZ	functionsr   rv   r   r   r   Úmain¨  s0   

þ
	


ÿ
rK  Ú__main__)3r—   r  r  r  r%  r&  r,  rá   rD  r1  r;  r~   rœ   Útypingr   rà   r2  r@  r>  r?  rB  Ú
__import__rš   r*   r„   r¸   r$  r   r    r¯   r-   r.   r4   r;   rS   r\   rb   rd   rl   rm   r˜   r¿   r  r#  r)  Ústrr.  rÊ   r9  rK  r”   r   r   r   r   Ú<module>   sº    JQ%÷÷ø÷ø '.?    (#aF$
ÿ