o
    8Vad                     @   s   d dl mZmZmZmZ d dlmZ d dlmZm	Z	m
Z
mZ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 d dlmZ d d	lmZ d d
lmZ G dd dZG dd deZG dd deZ dddZ!dd Z"dddZ#dd Z$d ddZ%dS )!    )AnyDictSetTuplewraps)AddExprMulPowSsympifyFloat)Basic)default_sort_key)Lambda)_keep_coeff)Symbol)
StrPrinter)
precedencec                   @   s    e Zd ZdZdd Zdd ZdS )requiresz: Decorator for registering requirements on print methods. c                 K   s
   || _ d S N)_req)selfkwargs r   </usr/lib/python3/dist-packages/sympy/printing/codeprinter.py__init__      
zrequires.__init__c                    s    fdd}t  |S )Nc                    s:   j  D ]\}}t| || q | g|R i |S r   )r   itemsgetattrupdate)Zself_argsr   kvmethodr   r   r   _method_wrapper   s   z*requires.__call__.<locals>._method_wrapperr   )r   r&   r'   r   r%   r   __call__   s   zrequires.__call__N)__name__
__module____qualname____doc__r   r(   r   r   r   r   r      s    r   c                   @   s   e Zd ZdZdS )AssignmentErrorzA
    Raised if an assignment variable for a loop is missing.
    N)r)   r*   r+   r,   r   r   r   r   r-      s    r-   c                       s  e Zd ZdZddddZdddd	d
dddZddddZdZ fdd	ZdZddZdZd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d0d1 Zd2d3 Zd4d5 Zd6d7 Zd8d9 Z fd:d;Zd<d= ZeZdZd>d? Z d@dA Z!dBdC Z"dDdE Z#dFdG Z$dHdI Z%dJdK Z&dLdM Z'dNdO Z(dPdQ Z)dRdS Z*dTdU Z+dVdW Z,dXdY Z-e-Z.e-Z/e-Z0e-Z1e-Z2e-Z3e-Z4e-Z5e-Z6e-Z7e-Z8e-Z9e-Z:e-Z;e-Z<e-Z=e-Z>e-Z?e-Z@e-ZAe-ZBe-ZCe-ZD  ZES )[CodePrinterz6
    The base class for code-printing subclasses.
    z&&z||!)andornotNautoF_T)orderZ	full_precerror_on_reservedreserved_word_suffixhumaninlineallow_unknown_functionsZerfZliZgamma)Zerf2ZLiZbetac                    s(   t  j|d t| dst | _d S d S )N)settingsreserved_words)superr   hasattrsetr<   )r   r;   	__class__r   r   r   @   s   
zCodePrinter.__init__c           	         s:  ddl m ddlmm   fdd||}t _t _|	 }j
d r{g }jrW|dj tjtdD ]}|t|j qItjtdD ]\}}||| q^|| }|}d	|}n|}fd
djD }|jd	|f}t _t _|S )a  
        Print the expression as code.

        Parameters
        ----------
        expr : Expression
            The expression to be printed.

        assign_to : Symbol, string, MatrixSymbol, list of strings or Symbols (optional)
            If provided, the printed code will set the expression to a variable or multiple variables
            with the name or names given in ``assign_to``.
        r   MatrixSymbol)	CodeBlock
Assignmentc                    s   |d u rt | S t|ttfr1t| t|kr#tdt| t|fddt| |D  S t|trH| j	rC|g| j
R  }nt|}nt|tsZtdtjt| || S )Nz;Failed to assign an expression of length {} to {} variablesc                    s   g | ]	\}} ||qS r   r   ).0lhsrhs)_handle_assign_tor   r   
<listcomp>\   s    zBCodePrinter.doprint.<locals>._handle_assign_to.<locals>.<listcomp>z%{} cannot assign to object of type {})r   
isinstancelisttuplelen
ValueErrorformatzipstrZ	is_Matrixshaper   r   	TypeErrortyper)   )expr	assign_torE   rD   rC   rI   r   r   r   rI   V   s   



z.CodePrinter.doprint.<locals>._handle_assign_tor8   zNot supported in {}:key
c                    s   h | ]\}}|  |fqS r   _print)rF   r#   r$   r   r   r   	<setcomp>   s    z&CodePrinter.doprint.<locals>.<setcomp>)"sympy.matrices.expressions.matexprrC   sympy.codegen.astrD   rE   r?   _not_supported_number_symbolsr]   
splitlines	_settingsappend_get_commentrP   languagesortedrR   rU   r)   _declare_number_const_format_codejoin)	r   rV   rW   linesZ
frontlinesnamevalueresultZnum_symsr   rX   r   doprintF   s4   




zCodePrinter.doprintc              	   C   s  | j ddrddlm} | ||}||}ng }d |fi}| |\}}d |v r5t| t|d   }nt| d}| 	|}	g }
||	krb|

| |d urX| d|	|f }|
| |

| |D ]n}t|tr| ||}| |\}}|| D ]U}||v rdd || D dd || D kstd	|d u rtd
||rtd|

| |

| d|	t| || f }|
| | |

| |

| q|qdd|
S )NcontractTr   )get_contraction_structure%s = %sc                 S   s   g | ]}t | qS r   )rL   keysrF   fr   r   r   rJ          z.CodePrinter._doprint_loops.<locals>.<listcomp>c                 S   s   g | ]}d gqS r   r   rv   r   r   r   rJ      s    z0FIXME: no support for contractions in factor yetz"need assignment variable for loopszZFIXME: lhs present in rhs,                                this is undefined in CodePrinterr[   )re   getsympy.tensorrs   _get_expression_indices_get_loop_opening_endingr   rq   r   r]   extend_get_statementrf   rK   rM   _sort_optimizedNotImplementedErrorr-   hasrO   rl   )r   rV   rW   rs   indicesZdummiesZopenloopZ	closelooptextZlhs_printedrm   dZ
openloop_dZcloseloop_dZtermr   r   r   _doprint_loops   s^   











zCodePrinter._doprint_loopsc                 C   sP   ddl m} ||\}}||\}}|r|s|}||kr"td| | ||S )Nr   )get_indicesz2lhs indices must match non-dummy rhs indices in %s)rz   r   rO   r   )r   rV   rW   r   ZrindsZjunkZlindsr   r   r   r{      s   z#CodePrinter._get_expression_indicesc           	   
      s   ddl m} |s
g S i  |D ]}d |< q||}|D ]"}t|jD ]\}}z |  | |7  < W q# ty=   Y q#w qt| fdddS )Nr   )Indexedc                    s    |  S r   r   )xZscore_tabler   r   <lambda>   s    z-CodePrinter._sort_optimized.<locals>.<lambda>rY   )sympy.tensor.indexedr   Zatoms	enumerater   _rate_index_positionKeyErrorri   )	r   r   rV   r   iZarraysZarrpZindr   r   r   r      s    

zCodePrinter._sort_optimizedc                 C      t d)zfunction to calculate score based on position among indices

        This method is used to sort loops in an optimized order, see
        CodePrinter._sort_optimized()
        =This function must be implemented by subclass of CodePrinter.r   )r   r   r   r   r   r      s   z CodePrinter._rate_index_positionc                 C   r   )z1Formats a codestring with the proper line ending.r   r   )r   Z
codestringr   r   r   r~        zCodePrinter._get_statementc                 C   r   )z#Formats a text string as a comment.r   r   )r   r   r   r   r   rg     r   zCodePrinter._get_commentc                 C   r   )z3Declare a numeric constant at the top of a functionr   r   )r   rn   ro   r   r   r   rj     r   z!CodePrinter._declare_number_constc                 C   r   )z~Take in a list of lines of code, and format them accordingly.

        This may include indenting, wrapping long lines, etc...r   r   )r   rm   r   r   r   rk     s   zCodePrinter._format_codec                 C   r   )zOReturns a tuple (open_lines, close_lines) containing lists
        of codelinesr   r   )r   r   r   r   r   r|     s   z$CodePrinter._get_loop_opening_endingc                 C   s&   |j drd|j  S d|j |jf S )NZDummy_r4   z%s_%d)rn   
startswithZdummy_indexr   rV   r   r   r   _print_Dummy  s   
zCodePrinter._print_Dummyc                    s   d  fdd|jD S )Nr[   c                    s   g | ]}  |qS r   r\   )rF   r   r^   r   r   rJ   %  s    z0CodePrinter._print_CodeBlock.<locals>.<listcomp>)rl   r"   r   r   r^   r   _print_CodeBlock$  s   zCodePrinter._print_CodeBlockc                 C   s   t |S r   )rR   r   stringr   r   r   _print_String'  s   zCodePrinter._print_Stringc                 C   s
   d|j  S )Nz"%s")r   )r   argr   r   r   _print_QuotedString*  r   zCodePrinter._print_QuotedStringc                 C   s   |  t|S r   )rg   rR   r   r   r   r   _print_Comment-  s   zCodePrinter._print_Commentc                 C   s@  ddl m} ddlm} ddlm} ddlm} |j}|j	}t
|j	|rIg }g }	|jD ]\}
}||||
 |	| q+|t||	 }| |S t
||rvg }| |D ]\}}||||f |||f }| |}|| qUd|S | jddr||s||r| ||S | |}| |}| d	||f S )
Nr   )rE   )	PiecewiserB   )IndexedBaser[   rr   Frt   )ra   rE   Z$sympy.functions.elementary.piecewiser   r`   rC   r   r   rG   rH   rK   r"   rf   rQ   r]   Z_traverse_matrix_indicesrl   re   ry   r   r   r~   )r   rV   rE   r   rC   r   rG   rH   ZexpressionsZ
conditionsecZtemprm   r   jZcode0lhs_coderhs_coder   r   r   _print_Assignment0  s8   





zCodePrinter._print_Assignmentc                    s>     |j}  |j} djt fdd||j|g S )Nz{} {} {}c                    
     | S r   r\   r   r^   r   r   r   Y     
 z8CodePrinter._print_AugmentedAssignment.<locals>.<lambda>)r]   rG   rH   r~   rP   mapop)r   rV   r   r   r   r^   r   _print_AugmentedAssignmentU  s   
z&CodePrinter._print_AugmentedAssignmentc                    s$   d|j dt fdd|jf S )N%s(%s), c                    r   r   r\   r   r^   r   r   r   _  r   z1CodePrinter._print_FunctionCall.<locals>.<lambda>)rn   rl   r   Zfunction_argsr   r   r^   r   _print_FunctionCall\  s   zCodePrinter._print_FunctionCallc                 C   s   |  |jS r   )r]   symbolr   r   r   r   _print_Variableb  s   zCodePrinter._print_Variablec                 C   s   |j \}| | |S r   )r"   r~   r]   )r   rV   r   r   r   r   _print_Statemente  s   zCodePrinter._print_Statementc                    sD   t  |}|| jv r | jd rd}t|||| jd  S |S )Nr6   zVThis expression includes the symbol "{}" which is a reserved keyword in this language.r7   )r=   _print_Symbolr<   re   rO   rP   )r   rV   rn   msgr@   r   r   r   i  s   

zCodePrinter._print_Symbolc              	      sB  |j j jv rN j|j j }d }t|tr|}n|D ]\}}||j r% nq|d urLz| fdd|jD  W S  tyK   d| |jdf  Y S w d S t|drbt|j	t
rb |j	|j S |j j jv r j|j j  jv r | j|j j S |jr jddrd |j dt j|jf S  |S )Nc                    s   g | ]}  |d qS )r   parenthesize)rF   itemr^   r   r   rJ     rx   z/CodePrinter._print_Function.<locals>.<listcomp>r   r   _imp_r:   F)funcr)   Zknown_functionsrK   rR   r"   rT   Z	stringifyr>   r   r   r]   _rewriteable_functionsZrewriteZis_Functionre   ry   rl   r   _print_not_supported)r   rV   Z	cond_funcr   Zcondr   r^   r   _print_Functionv  s2   

$
zCodePrinter._print_Functionc                 C   sP   | j ddr| t|| j d S | j|t|| j d f t|S )Nr9   FZ	precision)re   ry   r]   r   Zevalfrc   addrR   r   r   r   r   _print_NumberSymbol  s   zCodePrinter._print_NumberSymbolc                 C   
   |  |S r   r   r   r   r   r   _print_Catalan  r   zCodePrinter._print_Catalanc                 C   r   r   r   r   r   r   r   _print_EulerGamma  r   zCodePrinter._print_EulerGammac                 C   r   r   r   r   r   r   r   _print_GoldenRatio  r   zCodePrinter._print_GoldenRatioc                 C   r   r   r   r   r   r   r   _print_TribonacciConstant  r   z%CodePrinter._print_TribonacciConstantc                 C   r   r   r   r   r   r   r   _print_Exp1  r   zCodePrinter._print_Exp1c                 C   r   r   r   r   r   r   r   	_print_Pi  r   zCodePrinter._print_Pic                    6   t | djd   fddt|jtdD S )N %s r0   c                 3       | ]	} | V  qd S r   r   rF   aPRECr   r   r   	<genexpr>      z)CodePrinter._print_And.<locals>.<genexpr>rY   r   
_operatorsrl   ri   r"   r   r   r   r   r   
_print_And     zCodePrinter._print_Andc                    r   )Nr   r1   c                 3   r   r   r   r   r   r   r   r     r   z(CodePrinter._print_Or.<locals>.<genexpr>rY   r   r   r   r   r   	_print_Or  r   zCodePrinter._print_Orc                    H   j dd u r|S t| dj d   fdd|jD S )Nxorr   c                 3   r   r   r   r   r   r   r   r     r   z)CodePrinter._print_Xor.<locals>.<genexpr>r   ry   r   r   rl   r"   r   r   r   r   
_print_Xor     
zCodePrinter._print_Xorc                    r   )NZ
equivalentr   c                 3   r   r   r   r   r   r   r   r     r   z0CodePrinter._print_Equivalent.<locals>.<genexpr>r   r   r   r   r   _print_Equivalent  r   zCodePrinter._print_Equivalentc                 C   s$   t |}| jd | |jd | S )Nr2   r   )r   r   r   r"   )r   rV   r   r   r   r   
_print_Not  s   zCodePrinter._print_Notc                    s  t | | \}}|dk rt| |}d}nd}g }g }g }jdvr)| }nt|}|D ]I}	|	jrt|	jrt|	j	j
rt|	j	jrt|	j	dkrS|t|	j|	j	 dd q0t|	jd jdkrht|	jtrh||	 |t|	j|	j	  q0||	 q0|ptjg} fd	d
|D }
 fdd
|D }|D ]}	|	j|v rd|||	j  |||	j< q|s|d|
 S t|dkr|d|
 d |d  S |d|
 dd|  S )Nr   - )oldZnoneF)Zevaluate   c                       g | ]} | qS r   r   rF   r   Zprecr   r   r   rJ     rx   z*CodePrinter._print_Mul.<locals>.<listcomp>c                    r   r   r   r   r   r   r   rJ     rx   z(%s)*/z/(%s))r   Zas_coeff_Mulr   r5   Zas_ordered_factorsr
   Z	make_argsZis_commutativeZis_PowZexpZis_RationalZis_negativerf   r   baserN   r"   rK   r   ZOneindexrl   )r   rV   r   r   signr   bZ	pow_parenr"   r   Za_strZb_strr   r   r   
_print_Mul  s@   



 

 zCodePrinter._print_Mulc                 C   s.   z| j | W n	 ty   Y nw | |S r   )rb   r   rT   ZemptyPrinterr   r   r   r   r     s   
z CodePrinter._print_not_supportedr   )Fr)   r*   r+   r,   r   Z_default_settingsr   r   rq   r   r{   r   r   r~   rg   rj   rk   r|   r   r   r   r   r   r   r   r   r   r   r   r   Z_print_ExprZ_print_Heavisider   r   r   r   r   r   r   r   r   r   r   r   r   r   Z_print_BasicZ_print_ComplexInfinityZ_print_DerivativeZ_print_ExprCondPairZ_print_GeometryEntityZ_print_InfinityZ_print_IntegralZ_print_IntervalZ_print_AccumulationBoundsZ_print_LimitZ_print_MatrixBaseZ_print_DeferredVectorZ
_print_NaNZ_print_NegativeInfinityZ_print_OrderZ_print_RootOfZ_print_RootsOfZ_print_RootSumZ_print_UniformZ_print_UnitZ_print_WildZ_print_WildFunctionZ_print_Relational__classcell__r   r   r@   r   r.   #   s    

?O	%
3	r.   Nc99c                 K   $   ddl m} ||  || |S )a  Converts an expr to a string of c code

    Parameters
    ==========

    expr : Expr
        A sympy expression to be converted.
    assign_to : optional
        When given, the argument is used as the name of the variable to which
        the expression is assigned. Can be a string, ``Symbol``,
        ``MatrixSymbol``, or ``Indexed`` type. This is helpful in case of
        line-wrapping, or for expressions that generate multi-line statements.
    standard : str, optional
        String specifying the standard. If your compiler supports a more modern
        standard you may set this to 'c99' to allow the printer to use more math
        functions. [default='c89'].
    precision : integer, optional
        The precision for numbers such as pi [default=17].
    user_functions : dict, optional
        A dictionary where the keys are string representations of either
        ``FunctionClass`` or ``UndefinedFunction`` instances and the values
        are their desired C string representations. Alternatively, the
        dictionary value can be a list of tuples i.e. [(argument_test,
        cfunction_string)] or [(argument_test, cfunction_formater)]. See below
        for examples.
    dereference : iterable, optional
        An iterable of symbols that should be dereferenced in the printed code
        expression. These would be values passed by address to the function.
        For example, if ``dereference=[a]``, the resulting code would print
        ``(*a)`` instead of ``a``.
    human : bool, optional
        If True, the result is a single string that may contain some constant
        declarations for the number symbols. If False, the same information is
        returned in a tuple of (symbols_to_declare, not_supported_functions,
        code_text). [default=True].
    contract: bool, optional
        If True, ``Indexed`` instances are assumed to obey tensor contraction
        rules and the corresponding nested loops over indices are generated.
        Setting contract=False will not generate loops, instead the user is
        responsible to provide values for the indices in the code.
        [default=True].

    Examples
    ========

    >>> from sympy import ccode, symbols, Rational, sin, ceiling, Abs, Function
    >>> x, tau = symbols("x, tau")
    >>> expr = (2*tau)**Rational(7, 2)
    >>> ccode(expr)
    '8*M_SQRT2*pow(tau, 7.0/2.0)'
    >>> ccode(expr, math_macros={})
    '8*sqrt(2)*pow(tau, 7.0/2.0)'
    >>> ccode(sin(x), assign_to="s")
    's = sin(x);'
    >>> from sympy.codegen.ast import real, float80
    >>> ccode(expr, type_aliases={real: float80})
    '8*M_SQRT2l*powl(tau, 7.0L/2.0L)'

    Simple custom printing can be defined for certain types by passing a
    dictionary of {"type" : "function"} to the ``user_functions`` kwarg.
    Alternatively, the dictionary value can be a list of tuples i.e.
    [(argument_test, cfunction_string)].

    >>> custom_functions = {
    ...   "ceiling": "CEIL",
    ...   "Abs": [(lambda x: not x.is_integer, "fabs"),
    ...           (lambda x: x.is_integer, "ABS")],
    ...   "func": "f"
    ... }
    >>> func = Function('func')
    >>> ccode(func(Abs(x) + ceiling(x)), standard='C89', user_functions=custom_functions)
    'f(fabs(x) + CEIL(x))'

    or if the C-function takes a subset of the original arguments:

    >>> ccode(2**x + 3**x, standard='C99', user_functions={'Pow': [
    ...   (lambda b, e: b == 2, lambda b, e: 'exp2(%s)' % e),
    ...   (lambda b, e: b != 2, 'pow')]})
    'exp2(x) + pow(3, x)'

    ``Piecewise`` expressions are converted into conditionals. If an
    ``assign_to`` variable is provided an if statement is created, otherwise
    the ternary operator is used. Note that if the ``Piecewise`` lacks a
    default term, represented by ``(expr, True)`` then an error will be thrown.
    This is to prevent generating an expression that may not evaluate to
    anything.

    >>> from sympy import Piecewise
    >>> expr = Piecewise((x + 1, x > 0), (x, True))
    >>> print(ccode(expr, tau, standard='C89'))
    if (x > 0) {
    tau = x + 1;
    }
    else {
    tau = x;
    }

    Support for loops is provided through ``Indexed`` types. With
    ``contract=True`` these expressions will be turned into loops, whereas
    ``contract=False`` will just print the assignment expression that should be
    looped over:

    >>> from sympy import Eq, IndexedBase, Idx
    >>> len_y = 5
    >>> y = IndexedBase('y', shape=(len_y,))
    >>> t = IndexedBase('t', shape=(len_y,))
    >>> Dy = IndexedBase('Dy', shape=(len_y-1,))
    >>> i = Idx('i', len_y-1)
    >>> e=Eq(Dy[i], (y[i+1]-y[i])/(t[i+1]-t[i]))
    >>> ccode(e.rhs, assign_to=e.lhs, contract=False, standard='C89')
    'Dy[i] = (y[i + 1] - y[i])/(t[i + 1] - t[i]);'

    Matrices are also supported, but a ``MatrixSymbol`` of the same dimensions
    must be provided to ``assign_to``. Note that any expression that can be
    generated normally can also exist inside a Matrix:

    >>> from sympy import Matrix, MatrixSymbol
    >>> mat = Matrix([x**2, Piecewise((x + 1, x > 0), (x, True)), sin(x)])
    >>> A = MatrixSymbol('A', 3, 1)
    >>> print(ccode(mat, A, standard='C89'))
    A[0] = pow(x, 2);
    if (x > 0) {
       A[1] = x + 1;
    }
    else {
       A[1] = x;
    }
    A[2] = sin(x);
    r   )c_code_printers)Zsympy.printing.cr   lowerrq   )rV   rW   standardr;   r   r   r   r   ccode"  s    r   c                 K      t t| fi | dS )z0Prints C representation of the given expression.N)printr   rV   r;   r   r   r   print_ccode  s   r   c                 K   s   ddl m} ||| |S )aH  Converts an expr to a string of fortran code

    Parameters
    ==========

    expr : Expr
        A sympy expression to be converted.
    assign_to : optional
        When given, the argument is used as the name of the variable to which
        the expression is assigned. Can be a string, ``Symbol``,
        ``MatrixSymbol``, or ``Indexed`` type. This is helpful in case of
        line-wrapping, or for expressions that generate multi-line statements.
    precision : integer, optional
        DEPRECATED. Use type_mappings instead. The precision for numbers such
        as pi [default=17].
    user_functions : dict, optional
        A dictionary where keys are ``FunctionClass`` instances and values are
        their string representations. Alternatively, the dictionary value can
        be a list of tuples i.e. [(argument_test, cfunction_string)]. See below
        for examples.
    human : bool, optional
        If True, the result is a single string that may contain some constant
        declarations for the number symbols. If False, the same information is
        returned in a tuple of (symbols_to_declare, not_supported_functions,
        code_text). [default=True].
    contract: bool, optional
        If True, ``Indexed`` instances are assumed to obey tensor contraction
        rules and the corresponding nested loops over indices are generated.
        Setting contract=False will not generate loops, instead the user is
        responsible to provide values for the indices in the code.
        [default=True].
    source_format : optional
        The source format can be either 'fixed' or 'free'. [default='fixed']
    standard : integer, optional
        The Fortran standard to be followed. This is specified as an integer.
        Acceptable standards are 66, 77, 90, 95, 2003, and 2008. Default is 77.
        Note that currently the only distinction internally is between
        standards before 95, and those 95 and after. This may change later as
        more features are added.
    name_mangling : bool, optional
        If True, then the variables that would become identical in
        case-insensitive Fortran are mangled by appending different number
        of ``_`` at the end. If False, SymPy won't interfere with naming of
        variables. [default=True]

    Examples
    ========

    >>> from sympy import fcode, symbols, Rational, sin, ceiling, floor
    >>> x, tau = symbols("x, tau")
    >>> fcode((2*tau)**Rational(7, 2))
    '      8*sqrt(2.0d0)*tau**(7.0d0/2.0d0)'
    >>> fcode(sin(x), assign_to="s")
    '      s = sin(x)'

    Custom printing can be defined for certain types by passing a dictionary of
    "type" : "function" to the ``user_functions`` kwarg. Alternatively, the
    dictionary value can be a list of tuples i.e. [(argument_test,
    cfunction_string)].

    >>> custom_functions = {
    ...   "ceiling": "CEIL",
    ...   "floor": [(lambda x: not x.is_integer, "FLOOR1"),
    ...             (lambda x: x.is_integer, "FLOOR2")]
    ... }
    >>> fcode(floor(x) + ceiling(x), user_functions=custom_functions)
    '      CEIL(x) + FLOOR1(x)'

    ``Piecewise`` expressions are converted into conditionals. If an
    ``assign_to`` variable is provided an if statement is created, otherwise
    the ternary operator is used. Note that if the ``Piecewise`` lacks a
    default term, represented by ``(expr, True)`` then an error will be thrown.
    This is to prevent generating an expression that may not evaluate to
    anything.

    >>> from sympy import Piecewise
    >>> expr = Piecewise((x + 1, x > 0), (x, True))
    >>> print(fcode(expr, tau))
          if (x > 0) then
             tau = x + 1
          else
             tau = x
          end if

    Support for loops is provided through ``Indexed`` types. With
    ``contract=True`` these expressions will be turned into loops, whereas
    ``contract=False`` will just print the assignment expression that should be
    looped over:

    >>> from sympy import Eq, IndexedBase, Idx
    >>> len_y = 5
    >>> y = IndexedBase('y', shape=(len_y,))
    >>> t = IndexedBase('t', shape=(len_y,))
    >>> Dy = IndexedBase('Dy', shape=(len_y-1,))
    >>> i = Idx('i', len_y-1)
    >>> e=Eq(Dy[i], (y[i+1]-y[i])/(t[i+1]-t[i]))
    >>> fcode(e.rhs, assign_to=e.lhs, contract=False)
    '      Dy(i) = (y(i + 1) - y(i))/(t(i + 1) - t(i))'

    Matrices are also supported, but a ``MatrixSymbol`` of the same dimensions
    must be provided to ``assign_to``. Note that any expression that can be
    generated normally can also exist inside a Matrix:

    >>> from sympy import Matrix, MatrixSymbol
    >>> mat = Matrix([x**2, Piecewise((x + 1, x > 0), (x, True)), sin(x)])
    >>> A = MatrixSymbol('A', 3, 1)
    >>> print(fcode(mat, A))
          A(1, 1) = x**2
             if (x > 0) then
          A(2, 1) = x + 1
             else
          A(2, 1) = x
             end if
          A(3, 1) = sin(x)
    r   )FCodePrinter)Zsympy.printing.fortranr   rq   )rV   rW   r;   r   r   r   r   fcode  s   tr   c                 K   r   )z|Prints the Fortran representation of the given expression.

       See fcode for the meaning of the optional arguments.
    N)r   r   r   r   r   r   print_fcode#  s   r   c++11c                 K   r   )z$ C++ equivalent of :func:`~.ccode`. r   )cxx_code_printers)Zsympy.printing.cxxr   r   rq   )rV   rW   r   r;   r   r   r   r   cxxcode*  s   r   )Nr   r   )Nr   )&typingr   r   r   r   	functoolsr   Z
sympy.corer   r	   r
   r   r   r   r   Zsympy.core.basicr   Zsympy.core.compatibilityr   Zsympy.core.functionr   Zsympy.core.mulr   Zsympy.core.symbolr   Zsympy.printing.strr   Zsympy.printing.precedencer   r   	Exceptionr-   r.   r   r   r   r   r   r   r   r   r   <module>   s.    $    
 
x