U
    hc                  1   @  s6  d Z ddlmZ ddl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 ddlmZmZ dd	lmZ 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/d0d1d2d3d4d5d6d7d8d9d:g1Zd;d<d=d>d?d@dAdBdCdDdEdFdGdHdIdJdKdLdMdNdOdPdQdRdSZG dTdU dUeZd[dWdXZdYdZ ZdVS )\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.

    )annotations)Any)MulPowSRational)_keep_coeff)equal_valued)CodePrinter)
precedence
PRECEDENCEsearchsincostanZcotsecZcscasinacosZacotatanatan2ZasecZacscsinhcoshtanhZcothZcschZsechasinhacoshatanhZacothZasechZacscherfcZerfierfZerfinvZerfcinvZbesselibesseljZbesselkbesselyZ	bernoullibetaZeulerexp	factorialfloorZfresnelcZfresnelsgammaZharmoniclogZpolylogsignzetaZlegendreabsZangleZbincoeffceilZ
chebyshevUZ
chebyshevTZcoshintZcosintZconjZdiracZ	heavisideimagZ	laguerreLZlambertwZlogintZgammalnmaxminmodpsirealZ
pochhammerZsinhintZsinint)ZAbsargZbinomialZceilingZ
chebyshevuZ
chebyshevtChiZCi	conjugateZ
DiracDeltaZ	HeavisideZimZlaguerreZLambertWliZloggammaZMaxZMinZModZ	polygammareZRisingFactorialZShiZSic                      s  e Zd ZU dZdZdZddddZeej	fdi d	d	d
Z	de
d< 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d/d0 Zd1d2 Zd3d4 Zd5d6 Zd7d8 Z e Z!e Z"e Z#d9d: Z$d;d< Z%d=d> Z&d?d@ Z'dAdB Z(dCdD Z)dEdF Z*dGdH Z+dIdJ Z,dKdL Z-dMdN Z.dOdP Z/dQdR Z0dSdT Z1dUdV Z2dWdX Z3dYdZ Z4d[d\ Z5d]d^ Z6d_d` Z7dadb Z8dcdd Z9dedf Z:dgdh Z;didj Z<dkdl Z=e= Z>Z?dmdn Z@e@ ZAZBdodp ZCdqdr ZDdsdt ZE  ZFS )uOctaveCodePrinterzL
    A printer to convert expressions to strings of Octave/Matlab code.
    Z_octaveZOctave&|~)andornot   T)Z	precisionuser_functionscontractinlinezdict[str, Any]_default_settingsc                   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__ 9/tmp/pip-unpacked-wheel-6t8vlncq/sympy/printing/octave.pyrC   Y   s
    zOctaveCodePrinter.__init__c                 C  s   |d S )N   rO   )rK   prO   rO   rP   _rate_index_positiona   s    z&OctaveCodePrinter._rate_index_positionc                 C  s   d| S )Nz%s;rO   )rK   Z
codestringrO   rO   rP   _get_statemente   s    z OctaveCodePrinter._get_statementc                 C  s
   d |S )Nz% {}format)rK   textrO   rO   rP   _get_commenti   s    zOctaveCodePrinter._get_commentc                 C  s   d ||S )Nz{} = {};rU   )rK   namevaluerO   rO   rP   _declare_number_constm   s    z'OctaveCodePrinter._declare_number_constc                 C  s
   |  |S N)indent_code)rK   linesrO   rO   rP   _format_codeq   s    zOctaveCodePrinter._format_codec                   s    |j \ } fddt|D S )Nc                 3  s$   | ]}t  D ]}||fV  qqd S r\   )range).0jirowsrO   rP   	<genexpr>x   s     
  z=OctaveCodePrinter._traverse_matrix_indices.<locals>.<genexpr>)shaper`   )rK   matcolsrO   rd   rP   _traverse_matrix_indicesu   s    
z*OctaveCodePrinter._traverse_matrix_indicesc                 C  s^   g }g }|D ]H}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)rK   indicesZ
open_linesZclose_linesrc   varstartstoprO   rO   rP   _get_loop_opening_ending{   s    
z*OctaveCodePrinter._get_loop_opening_endingc                   s  |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kr|
 }n
t|}|D ]}	|	jr"|	jr"|	jjr"|	jjr"|	jdkr|t|	j|	j dd nDt|	jd jd	kr
t|	jtr
||	 |t|	j|	j  q|	jrp|	tjk	rp|	jd	krR|t|	j |	jd	krz|t|	j q||	 q|ptjg} fd
d|D }
 fdd|D }|D ]2}	|	j|krd|||	j  |||	j< qdd }|s||||
 S t|d	krB|d j r$dnd}||||
 | |d  S tdd |D rZdnd}||||
 | d|||  S d S )Nz%sir   - )oldnoneF)evaluaterk   c                   s   g | ]} | qS rO   parenthesizera   xprecrK   rO   rP   
<listcomp>   s     z0OctaveCodePrinter._print_Mul.<locals>.<listcomp>c                   s   g | ]} | qS rO   r~   r   r   rO   rP   r      s     z(%s)c                 S  sF   |d }t dt| D ]*}| |d  jr,dnd}|| ||  }q|S )Nr   rk   *.*)r`   len	is_number)aa_strrrc   ZmulsymrO   rO   rP   multjoin   s
    z.OctaveCodePrinter._print_Mul.<locals>.multjoin/./c                 s  s   | ]}|j V  qd S r\   r   )ra   ZbirO   rO   rP   rf      s     z/OctaveCodePrinter._print_Mul.<locals>.<genexpr>)r   Zis_imaginaryr   ZImaginaryUnitZ
is_Integerrn   r   Zas_coeff_Mulr   orderZas_ordered_factorsr   Z	make_argsis_commutativeZis_Powr"   Zis_RationalZis_negativerr   r   baser   args
isinstanceInfinityrR   r   qZOneindexall)rK   exprcer'   r   bZ	pow_parenr   itemr   Zb_strr   ZdivsymrO   r   rP   
_print_Mul   sb    




$
$zOctaveCodePrinter._print_Mulc                 C  s,   |  |j}|  |j}|j}d|||S )Nz{} {} {})rn   lhsrhsZrel_oprV   )rK   r   lhs_coderhs_codeoprO   rO   rP   _print_Relational   s    z#OctaveCodePrinter._print_Relationalc                 C  s   t dd |jD rdnd}t|}t|jdr@d| |j S |jrt|jdrz|jjr^dnd	}d
| d| |j  S t|jdr|jjrdnd	}d
| d| 	|j|  S d| 	|j||| 	|j|f S )Nc                 s  s   | ]}|j V  qd S r\   r   r   rO   rO   rP   rf      s     z/OctaveCodePrinter._print_Pow.<locals>.<genexpr>^z.^g      ?zsqrt(%s)g      r   r   1r|   %sz%s%s%s)
r   r   r   r	   r"   rn   r   r   r   r   )rK   r   Z	powsymbolPRECsymrO   rO   rP   
_print_Pow   s    zOctaveCodePrinter._print_Powc                 C  s(   t |}d| |j|| |j|f S )Nz%s^%s)r   r   r   r"   rK   r   r   rO   rO   rP   _print_MatPow   s    zOctaveCodePrinter._print_MatPowc                 C  s(   t |}d| |j|| |j|f S )Nz%s \ %s)r   r   ZmatrixZvectorr   rO   rO   rP   _print_MatrixSolve   s    z$OctaveCodePrinter._print_MatrixSolvec                 C  s   dS )NpirO   rK   r   rO   rO   rP   	_print_Pi   s    zOctaveCodePrinter._print_Pic                 C  s   dS )NZ1irO   r   rO   rO   rP   _print_ImaginaryUnit   s    z&OctaveCodePrinter._print_ImaginaryUnitc                 C  s   dS )Nzexp(1)rO   r   rO   rO   rP   _print_Exp1   s    zOctaveCodePrinter._print_Exp1c                 C  s   dS )Nz(1+sqrt(5))/2rO   r   rO   rO   rP   _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 st	|j|rg }g }|j
D ]"\}	}
||||	 ||
 qT|t|| }| |S | jd r||s||r| ||S | |}| |}| d||f S d 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   rr   rE   rn   ZhasZ_doprint_loopsrT   )rK   r   r   r   r   r   r   ZexpressionsZ
conditionsr   r   tempr   r   rO   rO   rP   _print_Assignment  s(    


z#OctaveCodePrinter._print_Assignmentc                 C  s   dS )NinfrO   r   rO   rO   rP   _print_Infinity$  s    z!OctaveCodePrinter._print_Infinityc                 C  s   dS )Nz-infrO   r   rO   rO   rP   _print_NegativeInfinity(  s    z)OctaveCodePrinter._print_NegativeInfinityc                 C  s   dS )NNaNrO   r   rO   rO   rP   
_print_NaN,  s    zOctaveCodePrinter._print_NaNc                   s    dd  fdd|D  d S )N{, c                 3  s   | ]}  |V  qd S r\   rn   ra   r   rK   rO   rP   rf   1  s     z0OctaveCodePrinter._print_list.<locals>.<genexpr>}joinr   rO   r   rP   _print_list0  s    zOctaveCodePrinter._print_listc                 C  s   dS )NtruerO   r   rO   rO   rP   _print_BooleanTrue7  s    z$OctaveCodePrinter._print_BooleanTruec                 C  s   dS )NfalserO   r   rO   rO   rP   _print_BooleanFalse;  s    z%OctaveCodePrinter._print_BooleanFalsec                 C  s   t | S r\   )strrp   r   rO   rO   rP   _print_bool?  s    zOctaveCodePrinter._print_boolc                   sr    j  jfdkrdS tj jkr0d j  jf S  j  jfdkrN d S dd fddt j D  S )	N)r   r   z[]zzeros(%s, %s))rk   rk   z[%s]z; c                 3  s2   | ]*}d  fdd |ddf D V  qdS ) c                   s   g | ]}  |qS rO   r   r   r   rO   rP   r   P  s     zAOctaveCodePrinter._print_MatrixBase.<locals>.<genexpr>.<listcomp>Nr   )ra   r   ArK   rO   rP   rf   P  s   z6OctaveCodePrinter._print_MatrixBase.<locals>.<genexpr>)re   ri   r   ZZerorg   rn   r   r`   )rK   r   rO   r   rP   _print_MatrixBaseG  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   rk   rO   ra   krO   rO   rP   r   X  s     z<OctaveCodePrinter._print_SparseRepMatrix.<locals>.<listcomp>c                 S  s   g | ]}|d  d  qS )rk   rO   r   rO   rO   rP   r   Y  s     c                 S  s   g | ]}|d  qS )   rO   r   rO   rO   rP   r   Z  s     zsparse(%s, %s, %s, %s, %s))Zsympy.matricesr   Zcol_listrn   re   ri   )rK   r   r   LIJZAIJrO   rO   rP   _print_SparseRepMatrixT  s      z(OctaveCodePrinter._print_SparseRepMatrixc                 C  s.   | j |jtd ddd|jd |jd f  S )NZAtomT)strictz(%s, %s)rk   )r   parentr   rc   rb   r   rO   rO   rP   _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r2dn  |}|dkrr|dkrX||krXdS ||krd|S |d | S nd|  ||fS d S )Nr   rk   r   rl   :)rn   r   )r   ZlimlhstepZlstrZhstrr   rO   rP   strslicee  s    
z6OctaveCodePrinter._print_MatrixSlice.<locals>.strslice(r   r   rk   ))rn   r   Zrowslicerg   Zcolslice)rK   r   r   rO   r   rP   _print_MatrixSliced  s    z$OctaveCodePrinter._print_MatrixSlicec                   s0    fdd|j D }d |jjd|f S )Nc                   s   g | ]}  |qS rO   r   )ra   rc   r   rO   rP   r   z  s     z4OctaveCodePrinter._print_Indexed.<locals>.<listcomp>z%s(%s)r   )rs   rn   r   ro   r   )rK   r   ZindsrO   r   rP   _print_Indexedy  s    z OctaveCodePrinter._print_Indexedc                 C  s   |  |jS r\   )rn   ro   r   rO   rO   rP   
_print_Idx~  s    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 r\   r~   r   r   rO   rP   rf     s   z:OctaveCodePrinter._print_KroneckerDelta.<locals>.<genexpr>)r   tupler   r   rO   r   rP   _print_KroneckerDelta  s    z'OctaveCodePrinter._print_KroneckerDeltac                   s   d  fdd jD S )Nr   c                   s   g | ]} |t qS rO   )r   r   )ra   r1   r   rK   rO   rP   r     s   z<OctaveCodePrinter._print_HadamardProduct.<locals>.<listcomp>)r   r   r   rO   r   rP   _print_HadamardProduct  s    z(OctaveCodePrinter._print_HadamardProductc                 C  s*   t |}d| |j|| |j|gS )Nz.**)r   r   r   r   r"   r   rO   rO   rP   _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   rk   r   c                 3  s   | ]}  |V  qd S r\   r   )ra   nr   rO   rP   rf     s     z4OctaveCodePrinter._print_Identity.<locals>.<genexpr>zeye(r   )rg   r   r   )rK   r   rg   srO   r   rP   _print_Identity  s
    
z!OctaveCodePrinter._print_Identityc                 C  s$   d | |jd | |jd S )Nz (gammainc({1}, {0}).*gamma({0}))r   rk   rV   rn   r   r   rO   rO   rP   _print_lowergamma  s     z#OctaveCodePrinter._print_lowergammac                 C  s$   d | |jd | |jd S )Nz)(gammainc({1}, {0}, 'upper').*gamma({0}))r   rk   r   r   rO   rO   rP   _print_uppergamma  s     z#OctaveCodePrinter._print_uppergammac                 C  s   d|  |jd tj  S )Nzsinc(%s)r   )rn   r   r   Pir   rO   rO   rP   _print_sinc  s    zOctaveCodePrinter._print_sincc                 C  s   d|  |j|  |jf S )Nzbesselh(%s, 1, %s)rn   r   argumentr   rO   rO   rP   _print_hankel1  s    
z OctaveCodePrinter._print_hankel1c                 C  s   d|  |j|  |jf S )Nzbesselh(%s, 2, %s)r   r   rO   rO   rP   _print_hankel2  s    
z OctaveCodePrinter._print_hankel2c                 C  sD   ddl m}m} |j}|tjd|  ||jtj | }| |S )Nr   )sqrtr   r   )	sympy.functionsr   r   r   r   r   r   Halfrn   )rK   r   r   r   r   expr2rO   rO   rP   	_print_jn  s    $zOctaveCodePrinter._print_jnc                 C  sD   ddl m}m} |j}|tjd|  ||jtj | }| |S )Nr   )r   r    r   )	r   r   r    r   r   r   r   r   rn   )rK   r   r   r    r   r   rO   rO   rP   	_print_yn  s    $zOctaveCodePrinter._print_ync                 C  s   d|  |jd  S )Nzairy(0, %s)r   rn   r   r   rO   rO   rP   _print_airyai  s    zOctaveCodePrinter._print_airyaic                 C  s   d|  |jd  S )Nzairy(1, %s)r   r   r   rO   rO   rP   _print_airyaiprime  s    z$OctaveCodePrinter._print_airyaiprimec                 C  s   d|  |jd  S )Nzairy(2, %s)r   r   r   rO   rO   rP   _print_airybi  s    zOctaveCodePrinter._print_airybic                 C  s   d|  |jd  S )Nzairy(3, %s)r   r   r   rO   rO   rP   _print_airybiprime  s    z$OctaveCodePrinter._print_airybiprimec                 C  s*   |j \}}|dkr| |S d| | S )Nrk   z
expint(%s))r   _print_not_supportedrn   )rK   r   mur   rO   rO   rP   _print_expint  s    

zOctaveCodePrinter._print_expintc                   sD   t |jdkstdj j|jj d fddt|jD dS )Nr   z{name}({args})r   c                   s   g | ]}  |qS rO   r   r   r   rO   rP   r     s     z?OctaveCodePrinter._one_or_two_reversed_args.<locals>.<listcomp>)rY   r   )	r   r   AssertionErrorrV   rG   rN   __name__r   reversedr   rO   r   rP   _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   rk   )rY   Zarg1Zarg2)rV   rG   rN   r  rn   r   funcr   rO   rO   rP   _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 ]\}\}}|dkr|	d |  n:|t|j d kr|dkr|	d n|	d |   |}	|	|	 |t|j d kr|	d qd|S d S )Nr|   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})).*()rV   rn   )ra   r   r   r   rO   rP   r     s
    z6OctaveCodePrinter._print_Piecewise.<locals>.<listcomp>r   z ...
r   r   r   zif (%s)rk   elsezelseif (%s)rl   
)
r   Zcond
ValueErrorr   rn   r   r   r   	enumeraterr   )
rK   r   r^   ZecpairsZelastpwrc   r   r   Zcode0rO   r   rP   _print_Piecewise  s*    



z"OctaveCodePrinter._print_Piecewisec                 C  s0   t |jdkr"d| |jd  S | |S d S )Nrk   zzeta(%s)r   )r   r   rn   r  r   rO   rO   rP   _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 ]J\}}	|	dkr||	 qr||| 8 }|d|| |	f  ||| 7 }qr|S )z0Accepts a string of code or a list of code linesTry   z  )z
^function z^if ^elseif ^else$z^for )z^end$r  r  c                 S  s   g | ]}| d qS )z 	)lstrip)ra   linerO   rO   rP   r   (  s     z1OctaveCodePrinter.indent_code.<locals>.<listcomp>c                   s&   g | ] t t fd dD qS )c                 3  s   | ]}t | V  qd S r\   r   ra   r5   r  rO   rP   rf   *  s     ;OctaveCodePrinter.indent_code.<locals>.<listcomp>.<genexpr>intanyra   )	inc_regexr  rP   r   *  s   c                   s&   g | ] t t fd dD qS )c                 3  s   | ]}t | V  qd S r\   r   r  r  rO   rP   rf   ,  s     r  r  r  )	dec_regexr  rP   r   ,  s   r   )ry   r  z%s%s)r   r   r]   
splitlinesr   r  rr   )
rK   codeZ
code_linestabZincreaseZdecreaseprettylevelr   r  rO   )r  r  rP   r]     s.    




zOctaveCodePrinter.indent_code)Gr  
__module____qualname____doc__Zprintmethodlanguage
_operatorsrD   r
   rA   __annotations__rC   rS   rT   rX   r[   r_   rj   rw   r   r   r   r   r   r   r   r   r   r   r   r   r   r   Z_print_tupleZ_print_TupleZ_print_Listr   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  r]   __classcell__rO   rO   rM   rP   r6   A   s   
J%r6   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));'
    )r6   Zdoprint)r   Z	assign_torL   rO   rO   rP   octave_code;  s     	r,  c                 K  s   t t| f| 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   rL   rO   rO   rP   print_octave_code  s    r.  )N)r'  
__future__r   typingr   Z
sympy.corer   r   r   r   Zsympy.core.mulr   Zsympy.core.numbersr	   Zsympy.printing.codeprinterr
   Zsympy.printing.precedencer   r   r5   r   rF   rI   r6   r,  r.  rO   rO   rO   rP   <module>   s                                         }
 