o
    8VaM                     @   s  d 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	 h dZ
d	d
hZh dZddiZi ddddddddddddddddddddddddddddddddddd d!d"d"d#d$d%d&d'd(d)d*d+Zd,d-d,d.Zd/d0 Zd1d2 ZG d3d4 d4e	ZG d5d6 d6eZejD ]
Zeed7e e qeD ]
Zeed7e e qd8d9 Zd: Zd;d< e D Zeefi d=d>d?d@dAdBdCZd,d-dDdEdFdGdHdIdJZdKdL ZG dMdN dNeZ e jD ]
Zee d7e e qeD ]
Zee d7e e qG dOdP dPeZ!dQS )Rzy
Python code printers

This module contains python code printers for plain python as well as NumPy & SciPy enabled code.
    )defaultdict)chain)S   )
precedence)CodePrinter>   asifinisoranddefdelfornottryNoneelifelsefrompasswithbreakclassraisewhileyieldassertexceptglobalimportlambdareturnfinallycontinueexecprint>   TrueFalsenonlocalZAbsabsZacosZacoshZasinZasinhZatanZatan2ZatanhZceilingZceilZcosZcoshZerfZerfcexpZexpm1Z	factorialZfloorZgammahypotZlgammaloglog10log1plog2sinsinhsqrttantanh)r-   loggammar.   Zlnr/   r0   r1   r2   r3   ZSqrtr5   r6   eZpi)Exp1PiEc                    s8    j |jj }dj |dt fdd|jdS )Nz{name}({args}), c                    
     | S N_printargself 7/usr/lib/python3/dist-packages/sympy/printing/pycode.py<lambda>D      
 z#_print_known_func.<locals>.<lambda>)nameargs)known_functions	__class____name__format_module_formatjoinmaprJ   rD   exprZknownrE   rC   rF   _print_known_funcA   s   rT   c                 C   s   | j |jj }| |S r>   )known_constantsrL   rM   rO   rR   rE   rE   rF   _print_known_constG   s   
rV   c                	       s  e Zd ZdZdZeeZdZ	dZ
eee dd e D Zdd e D Zd	d
ddZeeji ddddddZdQ fdd	Zdd ZdRd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$ fd0d1Z%d2d3 Z&d4d5 Z'd6d7 Z(d8d9 Z)d:d; Z*d<d=  Z+ Z, Z- Z. Z/ Z0 Z1Z2d>d? Z3d@dA Z4dBdC Z5dDdE Z6dFdG Z7dHdI Z8dJdK Z9dLdM Z:dSdOdPZ;  Z<S )TAbstractPythonCodePrinterZ_pythoncodePythonNz    c                 C      g | ]
\}}|d | fqS zmath.rE   .0kvrE   rE   rF   
<listcomp>T       z$AbstractPythonCodePrinter.<listcomp>c                 C      i | ]	\}}|d | qS rZ   rE   r[   rE   rE   rF   
<dictcomp>V       z$AbstractPythonCodePrinter.<dictcomp>r   r   r   )r   r   r      TFpython3)user_functionsZ	precisionZinlinefully_qualified_modulesZcontractstandardc                    s   t  | | jd }|d u rdd l}d|jj}|dvr%td||| _t	t
| _t| jfi |p5i di | _t| jfi |pEi di | _d S )Nrh   r   zpython{})python2re   z!Unrecognized python standard : {}rf   Zuser_constants)super__init__	_settingssysrN   version_infomajor
ValueErrorrh   r   setmodule_importsdict_kfgetrK   _kcrU   )rD   settingsZstdrm   rL   rE   rF   rk   b   s   


z"AbstractPythonCodePrinter.__init__c                 C   s   d||f S Nz%s = %srE   )rD   rI   valuerE   rE   rF   _declare_number_constv   s   z/AbstractPythonCodePrinter._declare_number_constc                 C   sl   | d}|rt|dkr| jd|d d  |d  | jd r%|S | dd  dd  dd S )N.r   rg   (r   [)splitlenrr   rP   addrl   )rD   ZfqnregisterpartsrE   rE   rF   rO   y   s   
"
"z(AbstractPythonCodePrinter._module_formatc                 C   s   |S r>   rE   )rD   linesrE   rE   rF   _format_code      z&AbstractPythonCodePrinter._format_codec                 C   
   d |S )Nz{}rN   rD   Z
codestringrE   rE   rF   _get_statement      
z(AbstractPythonCodePrinter._get_statementc                 C   r   )Nz  # {}r   )rD   textrE   rE   rF   _get_comment   r   z&AbstractPythonCodePrinter._get_commentc                 C   sH   t |dkr| |d S d| || ||dd | |d f S )z
        This method expands a fold on binary operations.

        ``functools.reduce`` is an example of a folded operation.

        For example, the expression

        `A + B + C + D`

        is folded into

        `((A + B) + C) + D`
        r   r   
%s(%s, %s)Nr}   )r   r@   rO   _expand_fold_binary_op)rD   oprJ   rE   rE   rF   r      s   z0AbstractPythonCodePrinter._expand_fold_binary_opc                 C   sZ   t |dkr| |d S t |}|d }d| || |d| | ||d f S )z
        This method expands a reductin on binary operations.

        Notice: this is NOT the same as ``functools.reduce``.

        For example, the expression

        `A + B + C + D`

        is reduced into:

        `(A + B) + (C + D)`
        r   r      r   N)r   r@   rO   _expand_reduce_binary_op)rD   r   rJ   NZNhalfrE   rE   rF   r      s   z2AbstractPythonCodePrinter._expand_reduce_binary_opc                 C   s   |   }d}d}dd |D }g }|D ]%}g }	t|D ]}
||v r)|	||  n|	| |d7 }q||	 qi }g }g }|D ]3}
|
D ]*}||vrTt|}|||< n|| }||7 }||v rj||vri|| qE|| qE|d7 }qA|d d }|||fS )N r   c                 S   s    i | ]}|D ]}|t |qqS rE   )min)r\   ijrE   rE   rF   rb           z@AbstractPythonCodePrinter._get_einsum_string.<locals>.<dictcomp>r   ,r}   )Z _get_letter_generator_for_einsumrangeappendnext)rD   ZsubranksZcontraction_indicesZlettersZcontraction_stringZcounterdindicesZrank_argZlindicesr   mappingZletters_freeZletters_dumr   lrE   rE   rF   _get_einsum_string   s>   





z,AbstractPythonCodePrinter._get_einsum_stringc                 C      dS )Nzfloat('nan')rE   rD   rS   rE   rE   rF   
_print_NaN   r   z$AbstractPythonCodePrinter._print_NaNc                 C   r   )Nzfloat('inf')rE   r   rE   rE   rF   _print_Infinity   r   z)AbstractPythonCodePrinter._print_Infinityc                 C   r   )Nzfloat('-inf')rE   r   rE   rE   rF   _print_NegativeInfinity   r   z1AbstractPythonCodePrinter._print_NegativeInfinityc                 C   
   |  |S r>   )r   r   rE   rE   rF   _print_ComplexInfinity   r   z0AbstractPythonCodePrinter._print_ComplexInfinityc                    s$   t | djt fdd|j S )Nz{} % {}c                    s    |  S r>   )parenthesize)xPRECrD   rE   rF   rG      s    z6AbstractPythonCodePrinter._print_Mod.<locals>.<lambda>)r   rN   rQ   rJ   r   rE   r   rF   
_print_Mod      z$AbstractPythonCodePrinter._print_Modc                 C   s   g }d}|j D ]9}|j}|j}|dkr|d |d || | |d |d || | |d |d7 }q|d d }|d dkrY|d d	 }|d n|d
 d|S )Nr   r~   )z if z else r   r}   r(   z else None)r   )rJ   rS   condr   r@   rP   )rD   rS   resultr   rB   r8   crE   rE   rF   _print_Piecewise   s(   








z*AbstractPythonCodePrinter._print_Piecewisec                    sR   ddddddd}|j |v r#| |j}| |j}dj|j ||d	S t |S )
z.Relational printer for Equality and UnequalityZequalZ	not_equalZlessZ
less_equalZgreaterZgreater_equal)z==z!=<z<=>z>=z({lhs} {op} {rhs}))r   lhsrhs)Zrel_opr@   r   r   rN   rj   _print_Relational)rD   rS   r   r   r   rx   rE   rF   r     s   
z+AbstractPythonCodePrinter._print_Relationalc                 C   s   ddl m} | ||S )Nr   )	Piecewise)Z$sympy.functions.elementary.piecewiser   r@   Zrewrite)rD   rS   r   rE   rE   rF   
_print_ITE  s   z$AbstractPythonCodePrinter._print_ITEc                    s0    fdd|j D }dj |jd|dS )Nc                 3   s8    | ]\}}}d j  | | |dV  qdS )zfor {i} in range({a}, {b}+1))r   abN)rN   r@   )r\   r   r   r   rC   rE   rF   	<genexpr>  s    
z7AbstractPythonCodePrinter._print_Sum.<locals>.<genexpr>z"(builtins.sum({function} {loops})) )functionloops)limitsrN   r@   r   rP   )rD   rS   r   rE   rC   rF   
_print_Sum  s   

z$AbstractPythonCodePrinter._print_Sumc                 C   r   )NZ1jrE   r   rE   rE   rF   _print_ImaginaryUnit%  r   z.AbstractPythonCodePrinter._print_ImaginaryUnitc                 C   s$   |j \}}dj| || |dS )Nz(1 if {a} == {b} else 0))r   r   )rJ   rN   r@   )rD   rS   r   r   rE   rE   rF   _print_KroneckerDelta(  s
   
z/AbstractPythonCodePrinter._print_KroneckerDeltac                 C   s,   |j j}| j||}d|| | f S )N%s(%s))rL   rM   rK   ru   r@   tolist)rD   rS   rI   funcrE   rE   rF   _print_MatrixBase0  s   z+AbstractPythonCodePrinter._print_MatrixBasec                 C   r   r>   )r   r   rE   rE   rF   rG   =  rH   z"AbstractPythonCodePrinter.<lambda>c                    s   d  fdd|dD S )N
c                    s   g | ]} j | qS rE   )tab)r\   linerC   rE   rF   r_   @      z@AbstractPythonCodePrinter._indent_codestring.<locals>.<listcomp>)rP   r   r   rE   rC   rF   _indent_codestring?  s   z,AbstractPythonCodePrinter._indent_codestringc                    sN   d t fdd|j}dj |jd  fdd|jD  |dS )	Nr   c                    r=   r>   r?   rA   rC   rE   rF   rG   C  rH   zEAbstractPythonCodePrinter._print_FunctionDefinition.<locals>.<lambda>z def {name}({parameters}):
{body}r<   c                    s   g | ]}  |jqS rE   )r@   symbol)r\   varrC   rE   rF   r_   F  s    zGAbstractPythonCodePrinter._print_FunctionDefinition.<locals>.<listcomp>)rI   
parametersbody)rP   rQ   r   rN   r@   rI   r   r   )rD   fdr   rE   rC   rF   _print_FunctionDefinitionB  s   
z3AbstractPythonCodePrinter._print_FunctionDefinitionc                    s6   d t fdd|j}dj |j |dS )Nr   c                    r=   r>   r?   rA   rC   rE   rF   rG   K  rH   z8AbstractPythonCodePrinter._print_While.<locals>.<lambda>zwhile {cond}:
{body})r   r   )rP   rQ   r   rN   r@   Z	conditionr   )rD   Zwhlr   rE   rC   rF   _print_WhileJ  s
   
z&AbstractPythonCodePrinter._print_Whilec                 C   s    d|  |jj|  |jjf S ry   )r@   variabler   rz   )rD   ZdeclrE   rE   rF   _print_DeclarationQ  s   z,AbstractPythonCodePrinter._print_Declarationc                 C   s   |j \}d| | S )Nz	return %s)rJ   r@   )rD   retrB   rE   rE   rF   _print_ReturnW  s   z'AbstractPythonCodePrinter._print_Returnc                    sp   d t fdd|j}|jd krd |j|}|jd kr+|d |j 7 } jdkr4d| S d| S )	Nr<   c                    r=   r>   r?   rA   rC   rE   rF   rG   \  rH   z8AbstractPythonCodePrinter._print_Print.<locals>.<lambda>z	{} % ({})z	, file=%sri   zprint %sz	print(%s))rP   rQ   
print_argsformat_stringrN   r@   filerh   )rD   Zprntr   rE   rC   rF   _print_Print[  s   


z&AbstractPythonCodePrinter._print_Printc                 C   s<   t |jdkr| dS t |jdkr| dS | |jS )Nstdoutz
sys.stdoutstderrz
sys.stderr)strrI   rO   r@   )rD   ZstrmrE   rE   rF   _print_Streamg  s
   

z'AbstractPythonCodePrinter._print_Streamc                 C   r   )Nr   rE   )rD   rB   rE   rE   rF   _print_NoneTokeno  r   z*AbstractPythonCodePrinter._print_NoneToken	math.sqrtc           
      C   s   t |}|jtjkr|s| |}| |j}dj||dS |jrC|j tju rC|sC| |}| tj	}| |j}dj|||dS | j
|j|dd}| j
|j|dd}	d||	S )a(  Printing helper function for ``Pow``

        Notes
        =====

        This only preprocesses the ``sqrt`` as math formatter

        Examples
        ========

        >>> from sympy.functions import sqrt
        >>> from sympy.printing.pycode import PythonCodePrinter
        >>> from sympy.abc import x

        Python code printer automatically looks up ``math.sqrt``.

        >>> printer = PythonCodePrinter({'standard':'python3'})
        >>> printer._hprint_Pow(sqrt(x), rational=True)
        'x**(1/2)'
        >>> printer._hprint_Pow(sqrt(x), rational=False)
        'math.sqrt(x)'
        >>> printer._hprint_Pow(1/sqrt(x), rational=True)
        'x**(-1/2)'
        >>> printer._hprint_Pow(1/sqrt(x), rational=False)
        '1/math.sqrt(x)'

        Using sqrt from numpy or mpmath

        >>> printer._hprint_Pow(sqrt(x), sqrt='numpy.sqrt')
        'numpy.sqrt(x)'
        >>> printer._hprint_Pow(sqrt(x), sqrt='mpmath.sqrt')
        'mpmath.sqrt(x)'

        See Also
        ========

        sympy.printing.str.StrPrinter._print_Pow
        z{func}({arg}))r   rB   z{num}/{func}({arg}))numr   rB   F)strictz{}**{})r   r,   r   ZHalfrO   r@   baserN   Zis_commutativeZOner   )
rD   rS   rationalr4   r   r   rB   r   Zbase_strZexp_strrE   rE   rF   _hprint_Powr  s    '

z%AbstractPythonCodePrinter._hprint_Powr>   )T)Fr   )=rM   
__module____qualname__printmethodlanguage_kw_py2and3union_kw_only_py3Zreserved_wordsmodulesr   rs   r   _known_functionsitems_known_functions_mathrt   _known_constants_mathrv   
_operatorsr   Z_default_settingsrk   r{   rO   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   Z_print_SparseMatrixZ_print_MutableSparseMatrixZ_print_ImmutableSparseMatrixZ_print_MatrixZ_print_DenseMatrixZ_print_MutableDenseMatrixZ_print_ImmutableMatrixZ_print_ImmutableDenseMatrixr   r   r   r   r   r   r   r   r   __classcell__rE   rE   rx   rF   rW   L   s    



#rW   c                   @   s^   e Zd Zdd Zdd Zdd Zddd	Zd
d Zdd Zdd Z	e
jZe
jZe
jZe
jZdS )PythonCodePrinterc                 C   s    dj | d| |jd dS )Nz"(0.0 if {e} == 0 else {f}(1, {e}))zmath.copysignr   )fr8   rN   rO   r@   rJ   rD   r8   rE   rE   rF   _print_sign  s   zPythonCodePrinter._print_signc                 C   s$   t |}| jd | |jd | S )Nr   r   )r   r   r   rJ   )rD   rS   r   rE   rE   rF   
_print_Not  r   zPythonCodePrinter._print_Notc                    s<   |j d }|j dd  }dt|d fdd|D S )Nr   r   z{}[{}]r<   c                    s   g | ]}  |qS rE   r?   )r\   ZindrC   rE   rF   r_     r   z4PythonCodePrinter._print_Indexed.<locals>.<listcomp>)rJ   rN   r   rP   )rD   rS   r   indexrE   rC   rF   _print_Indexed  s   
$z PythonCodePrinter._print_IndexedFc                 C   s   | j ||dS )N)r   r   rD   rS   r   rE   rE   rF   
_print_Pow  s   zPythonCodePrinter._print_Powc                 C   s*   | j dkrd|j|jS d|j|jS )Nri   z{}./{}.z{}/{})rh   rN   pqr   rE   rE   rF   _print_Rational  s   
z!PythonCodePrinter._print_Rationalc                 C   r   r>   r  r   rE   rE   rF   _print_Half  r   zPythonCodePrinter._print_Halfc                 C   s"   ddl m} | ||jd dS )Nr   )Modr   )Zsympyr  r   rJ   )rD   rS   r  rE   rE   rF   _print_frac  s   zPythonCodePrinter._print_fracNF)rM   r   r   r   r   r   r  r  r  r	  r   Z_print_not_supported_print_lowergamma_print_uppergammaZ_print_fresnelcZ_print_fresnelsrE   rE   rE   rF   r     s    

r   z	_print_%sc                 K   s   t || S )a   Converts an expr to a string of Python code

    Parameters
    ==========

    expr : Expr
        A SymPy expression.
    fully_qualified_modules : bool
        Whether or not to write out full module names of functions
        (``math.sin`` vs. ``sin``). default: ``True``.
    standard : str or None, optional
        If 'python2', Python 2 sematics will be used.
        If 'python3', Python 3 sematics will be used.
        If None, the standard will be automatically detected.
        Default is 'python3'. And this parameter may be removed in the
        future.

    Examples
    ========

    >>> from sympy import tan, Symbol
    >>> from sympy.printing.pycode import pycode
    >>> pycode(tan(Symbol('x')) + 1)
    'math.tan(x) + 1'

    )r   Zdoprint)rS   rw   rE   rE   rF   pycode  s   r  z
log1p log2c                 C   s    g | ]\}}|t vr||fqS rE   )_not_in_mpmathr[   rE   rE   rF   r_     r   r_   betafracfresnelcfresnelssignr7   )r  r  r  r  r  r7   ZphiZeulercatalannaninfZninf)r9   r:   ZGoldenRatioZ
EulerGammaZCatalanZNaNZInfinityZNegativeInfinityc                 C   sT   g }g }| j D ]}t|dkr|\}}}ntd|| |||f q||fS )z helper function for _print_Integral that
        - accepts an Integral expression
        - returns a tuple of
           - a list variables of integration
           - a list of tuples of the upper and lower limits of integration
       z%Only definite integrals are supported)r   r   NotImplementedErrorr   )Zintegral_exprintegration_varsr   Zintegration_rangeZintegration_varZlower_limitZupper_limitrE   rE   rF   _unpack_integral_limits  s   

r  c                   @   s   e Zd ZdZdZdZeee	 dd e
	 D Zdd e	 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dZdd ZdS )MpmathPrinterzH
    Lambda printer for mpmath which maintains precision for floats
    Z_mpmathcodezPython with mpmathc                 C   rY   zmpmath.rE   r[   rE   rE   rF   r_   )  r`   zMpmathPrinter.<listcomp>c                 C   ra   r  rE   r[   rE   rE   rF   rb   +  rc   zMpmathPrinter.<dictcomp>c                 C   s(   t ttt|j}dj| d|dS )Nz{func}({args})
mpmath.mpf)r   rJ   )r   tuplerQ   intZ_mpf_rN   rO   )rD   r8   rJ   rE   rE   rF   _print_Float-  s   zMpmathPrinter._print_Floatc                 C   s&   dj | d| |j| |jdS )Nz{func}({p})/{func}({q})r  )r   r  r  )rN   rO   r@   r  r  r   rE   rE   rF   r  7  s
   

zMpmathPrinter._print_Rationalc                 C   r   r>   r  r   rE   rE   rF   r  >  r   zMpmathPrinter._print_Halfc                 C   s4   d | d| |jd | |jd | dS )Nz{}({}, {}, {})mpmath.gammaincr   r   z
mpmath.infr   r   rE   rE   rF   r  A  s   zMpmathPrinter._print_uppergammac                 C   s,   d | d| |jd | |jd S )Nz{}({}, 0, {})r!  r   r   r   r   rE   rE   rF   r  H  s
   zMpmathPrinter._print_lowergammac                 C      d | d| |jd S )Nz{0}({1})/{0}(2)
mpmath.logr   r   r   rE   rE   rF   _print_log2N     zMpmathPrinter._print_log2c                 C   r"  )Nz{}({}+1)r#  r   r   r   rE   rE   rF   _print_log1pR  r%  zMpmathPrinter._print_log1pFc                 C      | j ||ddS )Nzmpmath.sqrtr   r4   r   r  rE   rE   rF   r  V     zMpmathPrinter._print_Powc              
      sP   t |\}}d ddt j| |jd d fdd|D S )Nz{}(lambda {}: {}, {})zmpmath.quadr<   r   c                 3   s$    | ]}d t t j| V  qdS )z(%s, %s)N)r  rQ   r@   )r\   r   rC   rE   rF   r   `  s   " z0MpmathPrinter._print_Integral.<locals>.<genexpr>)r  rN   rO   rP   rQ   r@   rJ   )rD   r8   r  r   rE   rC   rF   _print_IntegralY  s   zMpmathPrinter._print_IntegralNr
  )rM   r   r   __doc__r   r   rs   r   r   r   _known_functions_mpmathrt   _known_constants_mpmathrv   r   r  r  r  r  r$  r&  r  r*  rE   rE   rE   rF   r    s$    

r  c                   @   s"   e Zd ZdZdd ZdddZdS )	SymPyPrinterzPython with SymPyc                    sH   |j jpd}d ||rdnd |j j dt fdd|jf S )Nr   r   r|   r<   c                    r=   r>   r?   rA   rC   rE   rF   rG   q  rH   z.SymPyPrinter._print_Function.<locals>.<lambda>)r   r   rO   rM   rP   rQ   rJ   )rD   rS   modrE   rC   rF   _print_Functionn  s   zSymPyPrinter._print_FunctionFc                 C   r'  )Nz
sympy.sqrtr(  r   r  rE   rE   rF   r  s  r)  zSymPyPrinter._print_PowNr
  )rM   r   r   r   r0  r  rE   rE   rE   rF   r.  j  s    r.  N)"r+  collectionsr   	itertoolsr   Z
sympy.corer   r   Zcodeprinterr   r   Z_kw_only_py2r   r   r   r   rT   rV   rW   r   rt   r]   setattrr  r   r  r   Z
_in_mpmathrs   r,  r-  r  r  r.  rE   rE   rE   rF   <module>   s    	
!	  c
$
	
D