o
    8Vac                  	   @   s  d Z ddlmZmZ ddlmZmZmZmZ ddl	m
Z
 ddlmZ ddlmZmZ ddlmZ g d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/d0d1d2ZG d3d4 d4eZd:d6d7Zd8d9 Zd5S );ai  
Octave (and Matlab) code printer

The `OctaveCodePrinter` converts SymPy expressions into Octave expressions.
It uses a subset of the Octave language for Matlab compatibility.

A complete code generator, which uses `octave_code` extensively, can be found
in `sympy.utilities.codegen`.  The `codegen` module can be used to generate
complete source code files.

    )AnyDict)MulPowSRational)_keep_coeff)CodePrinter)
precedence
PRECEDENCEsearch)1ZsinZcosZtanZcotZsecZcscZasinZacosZacotZatanZatan2ZasecZacscZsinhZcoshZtanhZcothZcschZsechZasinhZacoshZatanhZacothZasechZacschZerfcZerfiZerfZerfinvZerfcinvZbesselibesseljZbesselkbesselyZ	bernoulliZbetaZeulerexpZ	factorialZfloorZfresnelcZfresnelsZgammaZharmoniclogZpolylogsignZzetaZlegendreZAbsabsargZangleZbinomialZbincoeffZceilingZceilZ
chebyshevuZ
chebyshevUZ
chebyshevtZ
chebyshevTZChiZcoshintZCiZcosint	conjugateZconjZ
DiracDeltaZdiracZ	HeavisideZ	heavisideZimimagZlaguerreZ	laguerreLZLambertWZlambertwZliZlogintZloggammaZgammalnZMaxmaxminmodZpsirealZ
pochhammerZsinhintZsinint)ZMinZModZ	polygammareZRisingFactorialZShiZSic                	       s  e Zd ZdZdZdZddddZdd	d
i dddddZi f 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d,d- Zd.d/ Zd0d1 Zd2d3 Zd4d5 Zd6d7 Zd8d9 ZeZeZd:d; Z d<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/dZd[ Z0d\d] Z1d^d_ Z2d`da Z3dbdc Z4ddde Z5dfdg Z6dhdi Z7djdk Z8dldm Z9e9 Z:Z;dndo Z<e< Z=Z>dpdq Z?drds Z@dtdu ZA  ZBS )vOctaveCodePrinterzL
    A printer to convert expressions to strings of Octave/Matlab code.
    Z_octaveZOctave&|~)andornotNauto   TF)orderZ	full_precZ	precisionuser_functionsZhumanZallow_unknown_functionscontractinlinec                    sH   t  | tttt| _| jtt |di }| j| d S )Nr&   )	super__init__dictzipknown_fcns_src1known_functionsupdateknown_fcns_src2get)selfsettingsZ	userfuncs	__class__ 7/usr/lib/python3/dist-packages/sympy/printing/octave.pyr*   [   s
   zOctaveCodePrinter.__init__c                 C   s   |d S )N   r6   )r2   pr6   r6   r7   _rate_index_positionc      z&OctaveCodePrinter._rate_index_positionc                 C   s   d| S )Nz%s;r6   )r2   Z
codestringr6   r6   r7   _get_statementg   r;   z OctaveCodePrinter._get_statementc                 C   s
   d |S )Nz% {}format)r2   textr6   r6   r7   _get_commentk      
zOctaveCodePrinter._get_commentc                 C   s   d ||S )Nz{} = {};r=   )r2   namevaluer6   r6   r7   _declare_number_consto      z'OctaveCodePrinter._declare_number_constc                 C   s
   |  |S N)indent_code)r2   linesr6   r6   r7   _format_codes   rA   zOctaveCodePrinter._format_codec                    s    |j \ } fddt|D S )Nc                 3   s&    | ]}t  D ]}||fV  qqd S rF   )range).0jirowsr6   r7   	<genexpr>z   s   $ z=OctaveCodePrinter._traverse_matrix_indices.<locals>.<genexpr>)shaperJ   )r2   Zmatcolsr6   rN   r7   _traverse_matrix_indicesw   s   
z*OctaveCodePrinter._traverse_matrix_indicesc                 C   s^   g }g }|D ]$}t | j|j|jd |jd g\}}}|d|||f  |d q||fS )N   zfor %s = %s:%send)map_printlabellowerupperappend)r2   indicesZ
open_linesZclose_linesrM   varstartstopr6   r6   r7   _get_loop_opening_ending}   s   
z*OctaveCodePrinter._get_loop_opening_endingc                    sb  |j r|jrtj| jrdtj |  S t| | \}}|dk r.t| |}d}nd}g }g }g }j	dvr@|
 }nt|}|D ]l}	|	jr|	jr|	jjr|	jjr|	jdkrj|t|	j|	j dd qGt|	jd jd	krt|	jtr||	 |t|	j|	j  qG|	jr|	tjur|	jd	kr|t|	j |	jd	kr|t|	j qG||	 qG|ptjg} fd
d|D }
 fdd|D }|D ]}	|	j|v rd|||	j  |||	j< qdd }|s||||
 S t|d	kr|d j rdnd}||||
 | |d  S tdd |D rdnd}||||
 | d|||  S )Nz%sir   - )oldZnoneF)ZevaluaterT   c                       g | ]} | qS r6   parenthesizerK   xZprecr2   r6   r7   
<listcomp>       z0OctaveCodePrinter._print_Mul.<locals>.<listcomp>c                    re   r6   rf   rh   rj   r6   r7   rk      rl   z(%s)c                 S   sF   |d }t dt| D ]}| |d  jrdnd}|| ||  }q|S )Nr   rT   *.*)rJ   len	is_number)aa_strrrM   Zmulsymr6   r6   r7   multjoin   s
   z.OctaveCodePrinter._print_Mul.<locals>.multjoin/./c                 S      g | ]}|j qS r6   rp   )rK   Zbir6   r6   r7   rk          )rp   Zis_imaginaryr   ZImaginaryUnitZ
is_IntegerrW   r
   Zas_coeff_Mulr   r%   Zas_ordered_factorsr   Z	make_argsis_commutativeZis_Powr   Zis_RationalZis_negativer[   r   basero   args
isinstanceZInfinityr9   r   qOneindexall)r2   exprcer   rq   bZ	pow_parenr|   itemrr   Zb_strrt   Zdivsymr6   rj   r7   
_print_Mul   sf   




 



 zOctaveCodePrinter._print_Mulc                 C   s,   |  |j}|  |j}|j}d|||S )Nz{} {} {})rW   lhsrhsZrel_opr>   )r2   r   lhs_coderhs_codeopr6   r6   r7   _print_Relational   s   z#OctaveCodePrinter._print_Relationalc                 C   s   t dd |jD rdnd}t|}|jtjkr d| |j S |jrZ|jtj kr>|jj	r0dnd}d| d| |j  S |jtj
 krZ|jj	rKdnd}d| d	| |j|  S d
| |j||| |j|f S )Nc                 S   rw   r6   rx   rh   r6   r6   r7   rk      ry   z0OctaveCodePrinter._print_Pow.<locals>.<listcomp>^z.^zsqrt(%s)ru   rv   1%sz%s%s%s)r   r|   r
   r   r   HalfrW   r{   rz   rp   r   rg   )r2   r   Z	powsymbolPRECZsymr6   r6   r7   
_print_Pow   s   zOctaveCodePrinter._print_Powc                 C   (   t |}d| |j|| |j|f S )Nz%s^%s)r
   rg   r{   r   r2   r   r   r6   r6   r7   _print_MatPow      zOctaveCodePrinter._print_MatPowc                 C   r   )Nz%s \ %s)r
   rg   ZmatrixZvectorr   r6   r6   r7   _print_MatrixSolve   r   z$OctaveCodePrinter._print_MatrixSolvec                 C      dS )NZpir6   r2   r   r6   r6   r7   	_print_Pi      zOctaveCodePrinter._print_Pic                 C   r   )NZ1ir6   r   r6   r6   r7   _print_ImaginaryUnit   r   z&OctaveCodePrinter._print_ImaginaryUnitc                 C   r   )Nzexp(1)r6   r   r6   r6   r7   _print_Exp1   r   zOctaveCodePrinter._print_Exp1c                 C   r   )Nz(1+sqrt(5))/2r6   r   r6   r6   r7   _print_GoldenRatio  s   z$OctaveCodePrinter._print_GoldenRatioc                 C   s   ddl m} ddlm} ddlm} |j}|j}| jd sHt	|j|rHg }g }|j
D ]\}	}
||||	 ||
 q*|t|| }| |S | jd r]||sW||r]| ||S | |}| |}| d||f S )Nr   )
Assignment)	Piecewise)IndexedBaser(   r'   z%s = %s)Zsympy.codegen.astr   Z$sympy.functions.elementary.piecewiser   Zsympy.tensor.indexedr   r   r   	_settingsr}   r|   r[   r,   rW   ZhasZ_doprint_loopsr<   )r2   r   r   r   r   r   r   ZexpressionsZ
conditionsr   r   Ztempr   r   r6   r6   r7   _print_Assignment	  s(   


z#OctaveCodePrinter._print_Assignmentc                 C   r   )Ninfr6   r   r6   r6   r7   _print_Infinity&  r   z!OctaveCodePrinter._print_Infinityc                 C   r   )Nz-infr6   r   r6   r6   r7   _print_NegativeInfinity*  r   z)OctaveCodePrinter._print_NegativeInfinityc                 C   r   )NZNaNr6   r   r6   r6   r7   
_print_NaN.  r   zOctaveCodePrinter._print_NaNc                    s    dd  fdd|D  d S )N{, c                 3       | ]}  |V  qd S rF   rW   rK   rq   r2   r6   r7   rP   3      z0OctaveCodePrinter._print_list.<locals>.<genexpr>}joinr   r6   r   r7   _print_list2  s    zOctaveCodePrinter._print_listc                 C   r   )Ntruer6   r   r6   r6   r7   _print_BooleanTrue8  r   z$OctaveCodePrinter._print_BooleanTruec                 C   r   )NZfalser6   r   r6   r6   r7   _print_BooleanFalse<  r   z%OctaveCodePrinter._print_BooleanFalsec                 C   s   t | S rF   )strrY   r   r6   r6   r7   _print_bool@  rE   zOctaveCodePrinter._print_boolc                    sz    j  jfdkr
dS  j dks jdkrd j  jf S  j  jfdkr+ d S dd fdd	t j D  S )
N)r   r   z[]r   zzeros(%s, %s))rT   rT   z[%s]z; c                 3   s4    | ]}d  fdd |ddf D V  qdS ) c                       g | ]}  |qS r6   r   r   r   r6   r7   rk   Q      zAOctaveCodePrinter._print_MatrixBase.<locals>.<genexpr>.<listcomp>Nr   )rK   rs   Ar2   r6   r7   rP   Q  s    ,z6OctaveCodePrinter._print_MatrixBase.<locals>.<genexpr>)rO   rR   rW   r   rJ   )r2   r   r6   r   r7   _print_MatrixBaseH  s   
z#OctaveCodePrinter._print_MatrixBasec                 C   sx   ddl m} | }|dd |D g}|dd |D g}|dd |D g}d| || || ||j|jf S )Nr   )Matrixc                 S   s   g | ]}|d  d qS )r   rT   r6   rK   kr6   r6   r7   rk   Y  rl   z9OctaveCodePrinter._print_SparseMatrix.<locals>.<listcomp>c                 S   s   g | ]}|d  d  qS )rT   r6   r   r6   r6   r7   rk   Z  rl   c                 S   s   g | ]}|d  qS )   r6   r   r6   r6   r7   rk   [  s    zsparse(%s, %s, %s, %s, %s))Zsympy.matricesr   Zcol_listrW   rO   rR   )r2   r   r   LIJZAIJr6   r6   r7   _print_SparseMatrixU  s   z%OctaveCodePrinter._print_SparseMatrixc                 C   s.   | j |jtd ddd|jd |jd f  S )NZAtomT)strictz(%s, %s)rT   )rg   parentr   rM   rL   r   r6   r6   r7   _print_MatrixElement`  s   z&OctaveCodePrinter._print_MatrixElementc                    sL    fdd}  |jd ||j|jjd  d ||j|jjd  d S )Nc                    s   | d d }| d }| d }  |}||krdn  |}|dkr8|dkr,||kr,dS ||kr2|S |d | S d|  ||fS )Nr   rT   r   rU   :)rW   r   )ri   ZlimlhstepZlstrZhstrr   r6   r7   strslicef  s   
z6OctaveCodePrinter._print_MatrixSlice.<locals>.strslice(r   r   rT   ))rW   r   ZrowslicerQ   Zcolslice)r2   r   r   r6   r   r7   _print_MatrixSlicee  s   z$OctaveCodePrinter._print_MatrixSlicec                    s0    fdd|j D }d |jjd|f S )Nc                    r   r6   r   )rK   rM   r   r6   r7   rk   {  r   z4OctaveCodePrinter._print_Indexed.<locals>.<listcomp>z%s(%s)r   )r\   rW   r{   rX   r   )r2   r   Zindsr6   r   r7   _print_Indexedz  s   z OctaveCodePrinter._print_Indexedc                 C   s   |  |jS rF   )rW   rX   r   r6   r6   r7   
_print_Idx  rE   zOctaveCodePrinter._print_Idxc                    s&   t d  dt fdd|jD  S )Nr   zdouble(%s == %s)c                 3   s    | ]	} | V  qd S rF   rf   rh   rj   r6   r7   rP     s    z:OctaveCodePrinter._print_KroneckerDelta.<locals>.<genexpr>)r   tupler|   r   r6   rj   r7   _print_KroneckerDelta  s   
z'OctaveCodePrinter._print_KroneckerDeltac                    s   d  fdd jD S )Nrn   c                    s   g | ]
} |t qS r6   )rg   r
   )rK   r   r   r2   r6   r7   rk     s    z<OctaveCodePrinter._print_HadamardProduct.<locals>.<listcomp>)r   r|   r   r6   r   r7   _print_HadamardProduct  s   z(OctaveCodePrinter._print_HadamardProductc                 C   s*   t |}d| |j|| |j|gS )Nz.**)r
   r   rg   r{   r   r   r6   r6   r7   _print_HadamardPower  s
   z&OctaveCodePrinter._print_HadamardPowerc                    sP   |j }t|dkr|d |d kr|d g}d fdd|D }d| d S )	Nr   r   rT   r   c                 3   r   rF   r   )rK   nr   r6   r7   rP     r   z4OctaveCodePrinter._print_Identity.<locals>.<genexpr>zeye(r   )rQ   ro   r   )r2   r   rQ   sr6   r   r7   _print_Identity  s
   
z!OctaveCodePrinter._print_Identityc                 C   $   d | |jd | |jd S )Nz (gammainc({1}, {0}).*gamma({0}))r   rT   r>   rW   r|   r   r6   r6   r7   _print_lowergamma  s   z#OctaveCodePrinter._print_lowergammac                 C   r   )Nz)(gammainc({1}, {0}, 'upper').*gamma({0}))r   rT   r   r   r6   r6   r7   _print_uppergamma  s   z#OctaveCodePrinter._print_uppergammac                 C   s   d|  |jd tj  S )Nzsinc(%s)r   )rW   r|   r   Pir   r6   r6   r7   _print_sinc  s   zOctaveCodePrinter._print_sincc                 C      d|  |j|  |jf S )Nzbesselh(%s, 1, %s)rW   r%   argumentr   r6   r6   r7   _print_hankel1     
z OctaveCodePrinter._print_hankel1c                 C   r   )Nzbesselh(%s, 2, %s)r   r   r6   r6   r7   _print_hankel2  r   z OctaveCodePrinter._print_hankel2c                 C   D   ddl m}m} |j}|tjd|  ||jtj | }| |S )Nr   )sqrtr   r   )	sympy.functionsr   r   r   r   r   r%   r   rW   )r2   r   r   r   ri   expr2r6   r6   r7   	_print_jn     $
zOctaveCodePrinter._print_jnc                 C   r   )Nr   )r   r   r   )	r   r   r   r   r   r   r%   r   rW   )r2   r   r   r   ri   r   r6   r6   r7   	_print_yn  r   zOctaveCodePrinter._print_ync                 C      d|  |jd  S )Nzairy(0, %s)r   rW   r|   r   r6   r6   r7   _print_airyai     zOctaveCodePrinter._print_airyaic                 C   r   )Nzairy(1, %s)r   r   r   r6   r6   r7   _print_airyaiprime  r   z$OctaveCodePrinter._print_airyaiprimec                 C   r   )Nzairy(2, %s)r   r   r   r6   r6   r7   _print_airybi  r   zOctaveCodePrinter._print_airybic                 C   r   )Nzairy(3, %s)r   r   r   r6   r6   r7   _print_airybiprime  r   z$OctaveCodePrinter._print_airybiprimec                 C   s*   |j \}}|dkr| |S d| | S )NrT   z
expint(%s))r|   _print_not_supportedrW   )r2   r   Zmuri   r6   r6   r7   _print_expint  s   

zOctaveCodePrinter._print_expintc                    sD   t |jdks	J dj j|jj d fddt|jD dS )Nr   z{name}({args})r   c                    r   r6   r   rh   r   r6   r7   rk     r   z?OctaveCodePrinter._one_or_two_reversed_args.<locals>.<listcomp>)rB   r|   )ro   r|   r>   r.   r5   __name__r   reversedr   r6   r   r7   _one_or_two_reversed_args  s
   z+OctaveCodePrinter._one_or_two_reversed_argsc              	   C   s<   dj | j|jj | |jd | |j|jdd   dS )Nz{name}({arg1}, {arg2})r   rT   )rB   Zarg1Zarg2)r>   r.   r5   r   rW   r|   funcr   r6   r6   r7   _nested_binary_math_func  s
   z*OctaveCodePrinter._nested_binary_math_funcc           
         s(  |j d jdkrtdg } jd r? fdd|j d d D }d |j d j }d|| d	t|  }d
| d	 S t|j D ]J\}\}}|dkrY|	d |  n|t|j d krl|dkrl|	d n
|	d |   |}	|	|	 |t|j d kr|	d qDd|S )Nrd   TzAll Piecewise expressions must contain an (expr, True) statement to be used as a default condition. Without one, the generated expression may not evaluate to anything under some condition.r(   c                    s(   g | ]\}}d   | |qS )z({0}).*({1}) + (~({0})).*()r>   rW   )rK   r   r   r   r6   r7   rk     s
    z6OctaveCodePrinter._print_Piecewise.<locals>.<listcomp>r   z ...
r   r   r   zif (%s)rT   elsezelseif (%s)rU   
)
r|   Zcond
ValueErrorr   rW   r   r   ro   	enumerater[   )
r2   r   rH   ZecpairsZelastZpwrM   r   r   Zcode0r6   r   r7   _print_Piecewise  s,   





z"OctaveCodePrinter._print_Piecewisec                 C   s,   t |jdkrd| |jd  S | |S )NrT   zzeta(%s)r   )ro   r|   rW   r   r   r6   r6   r7   _print_zeta  s   
zOctaveCodePrinter._print_zetac           
         s   t |tr| |d}d|S d}dd dd |D }fdd|D } fd	d|D }g }d
}t|D ])\}}	|	dksE|	dkrK||	 q9||| 8 }|d|| |	f  ||| 7 }q9|S )z0Accepts a string of code or a list of code linesTrb   z  )z
^function z^if ^elseif ^else$z^for )z^end$r  r  c                 S   s   g | ]}| d qS )z 	)lstrip)rK   liner6   r6   r7   rk   )  r   z1OctaveCodePrinter.indent_code.<locals>.<listcomp>c                    &   g | ] t t fd dD qS )c                       g | ]}t | qS r6   r   rK   r   r  r6   r7   rk   +  r   <OctaveCodePrinter.indent_code.<locals>.<listcomp>.<listcomp>intanyrK   )	inc_regexr
  r7   rk   +      c                    r  )c                    r  r6   r   r	  r
  r6   r7   rk   -  r   r  r  r  )	dec_regexr
  r7   rk   -  r  r   r   z%s%s)r}   r   rG   
splitlinesr   r   r[   )
r2   codeZ
code_linesZtabZincreaseZdecreaseZprettylevelr   r  r6   )r  r  r7   rG     s.   




zOctaveCodePrinter.indent_code)Cr   
__module____qualname____doc__ZprintmethodlanguageZ
_operatorsZ_default_settingsr*   r:   r<   r@   rD   rI   rS   r`   r   r   r   r   r   r   r   r   r   r   r   r   r   r   Z_print_tupleZ_print_Tupler   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_print_DiracDeltaZ_print_LambertWr   Z
_print_MaxZ
_print_Minr  r  rG   __classcell__r6   r6   r4   r7   r   ?   s    J%r   Nc                 K   s   t || |S )a  Converts `expr` to a string of Octave (or Matlab) code.

    The string uses a subset of the Octave language for Matlab compatibility.

    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 can be helpful for
        expressions that generate multi-line statements.
    precision : integer, optional
        The precision for numbers such as pi  [default=16].
    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].
    inline: bool, optional
        If True, we try to create single-statement code instead of multiple
        statements.  [default=True].

    Examples
    ========

    >>> from sympy import octave_code, symbols, sin, pi
    >>> x = symbols('x')
    >>> octave_code(sin(x).series(x).removeO())
    'x.^5/120 - x.^3/6 + x'

    >>> from sympy import Rational, ceiling
    >>> x, y, tau = symbols("x, y, tau")
    >>> octave_code((2*tau)**Rational(7, 2))
    '8*sqrt(2)*tau.^(7/2)'

    Note that element-wise (Hadamard) operations are used by default between
    symbols.  This is because its very common in Octave to write "vectorized"
    code.  It is harmless if the values are scalars.

    >>> octave_code(sin(pi*x*y), assign_to="s")
    's = sin(pi*x.*y);'

    If you need a matrix product "*" or matrix power "^", you can specify the
    symbol as a ``MatrixSymbol``.

    >>> from sympy import Symbol, MatrixSymbol
    >>> n = Symbol('n', integer=True, positive=True)
    >>> A = MatrixSymbol('A', n, n)
    >>> octave_code(3*pi*A**3)
    '(3*pi)*A^3'

    This class uses several rules to decide which symbol to use a product.
    Pure numbers use "*", Symbols use ".*" and MatrixSymbols use "*".
    A HadamardProduct can be used to specify componentwise multiplication ".*"
    of two MatrixSymbols.  There is currently there is no easy way to specify
    scalar symbols, so sometimes the code might have some minor cosmetic
    issues.  For example, suppose x and y are scalars and A is a Matrix, then
    while a human programmer might write "(x^2*y)*A^3", we generate:

    >>> octave_code(x**2*y*A**3)
    '(x.^2.*y)*A^3'

    Matrices are supported using Octave inline notation.  When using
    ``assign_to`` with matrices, the name can be specified either as a string
    or as a ``MatrixSymbol``.  The dimensions must align in the latter case.

    >>> from sympy import Matrix, MatrixSymbol
    >>> mat = Matrix([[x**2, sin(x), ceiling(x)]])
    >>> octave_code(mat, assign_to='A')
    'A = [x.^2 sin(x) ceil(x)];'

    ``Piecewise`` expressions are implemented with logical masking by default.
    Alternatively, you can pass "inline=False" to use if-else conditionals.
    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
    >>> pw = Piecewise((x + 1, x > 0), (x, True))
    >>> octave_code(pw, assign_to=tau)
    'tau = ((x > 0).*(x + 1) + (~(x > 0)).*(x));'

    Note that any expression that can be generated normally can also exist
    inside a Matrix:

    >>> mat = Matrix([[x**2, pw, sin(x)]])
    >>> octave_code(mat, assign_to='A')
    'A = [x.^2 ((x > 0).*(x + 1) + (~(x > 0)).*(x)) 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)].  This can be used to call a custom Octave function.

    >>> from sympy import Function
    >>> f = Function('f')
    >>> g = Function('g')
    >>> custom_functions = {
    ...   "f": "existing_octave_fcn",
    ...   "g": [(lambda x: x.is_Matrix, "my_mat_fcn"),
    ...         (lambda x: not x.is_Matrix, "my_fcn")]
    ... }
    >>> mat = Matrix([[1, x]])
    >>> octave_code(f(x) + g(x) + g(mat), user_functions=custom_functions)
    'existing_octave_fcn(x) + my_fcn(x) + my_mat_fcn([1 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]))
    >>> octave_code(e.rhs, assign_to=e.lhs, contract=False)
    'Dy(i) = (y(i + 1) - y(i))./(t(i + 1) - t(i));'
    )r   Zdoprint)r   Z	assign_tor3   r6   r6   r7   octave_code<  s    	r  c                 K   s   t t| fi | dS )zPrints the Octave (or Matlab) representation of the given expression.

    See `octave_code` for the meaning of the optional arguments.
    N)printr  )r   r3   r6   r6   r7   print_octave_code  s   r  rF   )r  typingr   r   Z
sympy.corer   r   r   r   Zsympy.core.mulr   Zsympy.printing.codeprinterr	   Zsympy.printing.precedencer
   r   r   r   r-   r0   r   r  r  r6   r6   r6   r7   <module>   sv    	
    
 