B
    e‹dÄc  ã            1   @   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 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/d0d1d2d3d4d5d6d7d8g1Zd9d:d;d<d=d>d?d@dAdBdCdDdEdFdGdHdIdJdKdLdMdNdOdPdQœZG dRdS„ dSeƒZdYdUdV„ZdWdX„ ZdTS )Zai  
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Ú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LambertWZliZloggammaZMaxZMinÚ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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„ Z0dZd[„ Z1d\d]„ Z2d^d_„ Z3d`da„ Z4dbdc„ Z5ddde„ Z6dfdg„ Z7dhdi„ Z8djdk„ Z9dldm„ Z:e: Z;Z<dndo„ Z=e= Z>Z?dpdq„ Z@drds„ ZAdtdu„ ZB‡  ZCS )vÚOctaveCodePrinterzL
    A printer to convert expressions to strings of Octave/Matlab code.
    Z_octaveÚOctaveú&ú|ú~)ÚandÚorÚnotNÚautoé   TF)ÚorderZ	full_precÚ	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__© úb/work/yifan.wang/ringdown/master-ringdown-env/lib/python3.7/site-packages/sympy/printing/octave.pyrD   [   s
    zOctaveCodePrinter.__init__c             C   s   |d S )Né   rO   )rL   ÚprO   rO   rP   Ú_rate_index_positionc   s    z&OctaveCodePrinter._rate_index_positionc             C   s   d| S )Nz%s;rO   )rL   Z
codestringrO   rO   rP   Ú_get_statementg   s    z OctaveCodePrinter._get_statementc             C   s
   d  |¡S )Nz% {})Úformat)rL   ÚtextrO   rO   rP   Ú_get_commentk   s    zOctaveCodePrinter._get_commentc             C   s   d  ||¡S )Nz{} = {};)rU   )rL   ÚnameÚvaluerO   rO   rP   Ú_declare_number_consto   s    z'OctaveCodePrinter._declare_number_constc             C   s
   |   |¡S )N)Úindent_code)rL   ÚlinesrO   rO   rP   Ú_format_codes   s    zOctaveCodePrinter._format_codec                s    |j \‰ }‡ fdd„t|ƒD ƒS )Nc             3   s$   | ]}t ˆ ƒD ]}||fV  qqd S )N)Úrange)Ú.0ÚjÚi)ÚrowsrO   rP   ú	<genexpr>z   s    z=OctaveCodePrinter._traverse_matrix_indices.<locals>.<genexpr>)Úshaper^   )rL   ÚmatÚcolsrO   )rb   rP   Ú_traverse_matrix_indicesw   s    
z*OctaveCodePrinter._traverse_matrix_indicesc             C   sb   g }g }xP|D ]H}t | j|j|jd |jd gƒ\}}}| d|||f ¡ | d¡ qW ||fS )Né   zfor %s = %s:%sÚend)ÚmapÚ_printÚlabelÚlowerÚupperÚappend)rL   ÚindicesZ
open_linesZclose_linesra   Ú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 |¡}xô|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rr|	tjk	rr|	jd	krT| t|	jƒ¡ |	jd	kr|| t|	jƒ¡ q| |	¡ qW |pŒtjg}‡ ‡fd
d„|D ƒ}
‡ ‡fdd„|D ƒ}x:|D ]2}	|	j|kr¼d|| |	j¡  || |	j¡< q¼W dd„ }|s||||
ƒ S t|ƒd	krJ|d j r,dnd}||||
ƒ | |d  S tdd„ |D ƒƒrbdnd}||||
ƒ | d|||ƒ  S d S )Nz%sir   ú-Ú )ÚoldÚnoneéÿÿÿÿF)Úevaluaterh   c                s   g | ]}ˆ  |ˆ ¡‘qS rO   )Úparenthesize)r_   Úx)ÚprecrL   rO   rP   ú
<listcomp>¸   s    z0OctaveCodePrinter._print_Mul.<locals>.<listcomp>c                s   g | ]}ˆ  |ˆ ¡‘qS rO   )r{   )r_   r|   )r}   rL   rO   rP   r~   ¹   s    z(%s)c             S   sJ   |d }x<t dt| ƒƒD ]*}| |d  jr.dnd}|| ||  }qW |S )Nr   rh   Ú*z.*)r^   ÚlenÚ	is_number)ÚaÚa_strÚrra   ZmulsymrO   rO   rP   ÚmultjoinÁ   s
    z.OctaveCodePrinter._print_Mul.<locals>.multjoinú/z./c             s   s   | ]}|j V  qd S )N)r   )r_   ZbirO   rO   rP   rc   Ï   s    z/OctaveCodePrinter._print_Mul.<locals>.<genexpr>)r   Zis_imaginaryr   ZImaginaryUnitZ
is_Integerrk   r
   Zas_coeff_Mulr   r>   Zas_ordered_factorsr   Z	make_argsÚis_commutativeZis_Powr    Zis_RationalZis_negativero   r   Úbaser€   ÚargsÚ
isinstanceÚInfinityrR   r   ÚqÚOneÚindexÚall)rL   ÚexprÚcÚer%   r‚   ÚbZ	pow_parenr‰   Úitemrƒ   Zb_strr…   ZdivsymrO   )r}   rL   rP   Ú
_print_Mul‰   sV    





$

&zOctaveCodePrinter._print_Mulc             C   s,   |   |j¡}|   |j¡}|j}d |||¡S )Nz{} {} {})rk   ÚlhsÚrhsZrel_oprU   )rL   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|ƒ}|jtjkr@d|  |j¡ S |jr´|jtj kr||jj	r`dnd}d| d|  |j¡  S |jtj
 kr´|jj	r–dnd}d| d	|  |j|¡  S d
|  |j|¡||  |j|¡f S )Nc             s   s   | ]}|j V  qd S )N)r   )r_   r|   rO   rO   rP   rc   Ú   s    z/OctaveCodePrinter._print_Pow.<locals>.<genexpr>ú^z.^zsqrt(%s)r†   z./Ú1z%sz%s%s%s)r   r‰   r
   r    r   ÚHalfrk   rˆ   r‡   r   r   r{   )rL   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    )rL   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{   ÚmatrixZvector)rL   r   rŸ   rO   rO   rP   Ú_print_MatrixSolveò   s    z$OctaveCodePrinter._print_MatrixSolvec             C   s   dS )NÚpirO   )rL   r   rO   rO   rP   Ú	_print_Pi÷   s    zOctaveCodePrinter._print_Pic             C   s   dS )NZ1irO   )rL   r   rO   rO   rP   Ú_print_ImaginaryUnitû   s    z&OctaveCodePrinter._print_ImaginaryUnitc             C   s   dS )Nzexp(1)rO   )rL   r   rO   rO   rP   Ú_print_Exp1ÿ   s    zOctaveCodePrinter._print_Exp1c             C   s   dS )Nz(1+sqrt(5))/2rO   )rL   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 s”t	|j|ƒr”g }g }x,|j
D ]"\}	}
| |||	ƒ¡ | |
¡ qVW |t||ƒŽ }|  |¡S | jd r¾| |¡s²| |¡r¾|  ||¡S |  |¡}|  |¡}|  d||f ¡S d S )Nr   )Ú
Assignment)Ú	Piecewise)ÚIndexedBaserB   rA   z%s = %s)Zsympy.codegen.astrª   Z$sympy.functions.elementary.piecewiser«   Zsympy.tensor.indexedr¬   r–   r—   Ú	_settingsrŠ   r‰   ro   rF   rk   ÚhasZ_doprint_loopsrT   )rL   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   )rL   r   rO   rO   rP   Ú_print_Infinity&  s    z!OctaveCodePrinter._print_Infinityc             C   s   dS )Nz-infrO   )rL   r   rO   rO   rP   Ú_print_NegativeInfinity*  s    z)OctaveCodePrinter._print_NegativeInfinityc             C   s   dS )NÚNaNrO   )rL   r   rO   rO   rP   Ú
_print_NaN.  s    zOctaveCodePrinter._print_NaNc                s    dd  ‡ fdd„|D ƒ¡ d S )NÚ{z, c             3   s   | ]}ˆ   |¡V  qd S )N)rk   )r_   r‚   )rL   rO   rP   rc   3  s    z0OctaveCodePrinter._print_list.<locals>.<genexpr>Ú})Újoin)rL   r   rO   )rL   rP   Ú_print_list2  s    zOctaveCodePrinter._print_listc             C   s   dS )NÚtruerO   )rL   r   rO   rO   rP   Ú_print_BooleanTrue9  s    z$OctaveCodePrinter._print_BooleanTruec             C   s   dS )NÚfalserO   )rL   r   rO   rO   rP   Ú_print_BooleanFalse=  s    z%OctaveCodePrinter._print_BooleanFalsec             C   s   t |ƒ ¡ S )N)Ústrrm   )rL   r   rO   rO   rP   Ú_print_boolA  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))rh   rh   z[%s]z; c             3   s2   | ]*}d   ‡fdd„ˆ |dd…f D ƒ¡V  qdS )ú c                s   g | ]}ˆ   |¡‘qS rO   )rk   )r_   r‚   )rL   rO   rP   r~   R  s    zAOctaveCodePrinter._print_MatrixBase.<locals>.<genexpr>.<listcomp>N)r¸   )r_   r„   )ÚArL   rO   rP   rc   R  s   z6OctaveCodePrinter._print_MatrixBase.<locals>.<genexpr>)rb   rf   r   ZZerord   rk   r¸   r^   )rL   rÁ   rO   )rÁ   rL   rP   Ú_print_MatrixBaseI  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   rh   rO   )r_   ÚkrO   rO   rP   r~   Z  s    z<OctaveCodePrinter._print_SparseRepMatrix.<locals>.<listcomp>c             S   s   g | ]}|d  d  ‘qS )rh   rO   )r_   rÄ   rO   rO   rP   r~   [  s    c             S   s   g | ]}|d  ‘qS )é   rO   )r_   rÄ   rO   rO   rP   r~   \  s    zsparse(%s, %s, %s, %s, %s))Zsympy.matricesrÃ   Zcol_listrk   rb   rf   )rL   rÁ   rÃ   ÚLÚIÚJZAIJrO   rO   rP   Ú_print_SparseRepMatrixV  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)rh   )r{   Úparentr   ra   r`   )rL   r   rO   rO   rP   Ú_print_MatrixElementa  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   rh   rÅ   ri   ú:)rk   r¸   )r|   ZlimÚlÚhÚstepZlstrZhstr)rL   rO   rP   Ústrsliceg  s    
z6OctaveCodePrinter._print_MatrixSlice.<locals>.strsliceú(r   z, rh   ú))rk   rË   Zrowslicerd   Zcolslice)rL   r   rÑ   rO   )rL   rP   Ú_print_MatrixSlicef  s    z$OctaveCodePrinter._print_MatrixSlicec                s0   ‡ fdd„|j D ƒ}dˆ  |jj¡d |¡f S )Nc                s   g | ]}ˆ   |¡‘qS rO   )rk   )r_   ra   )rL   rO   rP   r~   |  s    z4OctaveCodePrinter._print_Indexed.<locals>.<listcomp>z%s(%s)z, )rp   rk   rˆ   rl   r¸   )rL   r   ZindsrO   )rL   rP   Ú_print_Indexed{  s    z OctaveCodePrinter._print_Indexedc             C   s   |   |j¡S )N)rk   rl   )rL   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 )N)r{   )r_   r|   )r}   rL   rO   rP   rc   †  s   z:OctaveCodePrinter._print_KroneckerDelta.<locals>.<genexpr>)r   Útupler‰   )rL   r   rO   )r}   rL   rP   Ú_print_KroneckerDelta„  s    z'OctaveCodePrinter._print_KroneckerDeltac                s   d  ‡ ‡fdd„ˆ jD ƒ¡S )Nz.*c                s   g | ]}ˆ  |tˆ ƒ¡‘qS rO   )r{   r
   )r_   r/   )r   rL   rO   rP   r~   Š  s   z<OctaveCodePrinter._print_HadamardProduct.<locals>.<listcomp>)r¸   r‰   )rL   r   rO   )r   rL   rP   Ú_print_HadamardProduct‰  s    z(OctaveCodePrinter._print_HadamardProductc             C   s*   t |ƒ}d |  |j|¡|  |j|¡g¡S )Nz.**)r
   r¸   r{   rˆ   r    )rL   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   rh   z, c             3   s   | ]}ˆ   |¡V  qd S )N)rk   )r_   Ún)rL   rO   rP   rc   ˜  s    z4OctaveCodePrinter._print_Identity.<locals>.<genexpr>zeye(rÓ   )rd   r€   r¸   )rL   r   rd   ÚsrO   )rL   rP   Ú_print_Identity”  s
    
z!OctaveCodePrinter._print_Identityc             C   s$   d  |  |jd ¡|  |jd ¡¡S )Nz (gammainc({1}, {0}).*gamma({0}))r   rh   )rU   rk   r‰   )rL   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   rh   )rU   rk   r‰   )rL   r   rO   rO   rP   Ú_print_uppergamma¡  s    z#OctaveCodePrinter._print_uppergammac             C   s   d|   |jd tj ¡ S )Nzsinc(%s)r   )rk   r‰   r   ÚPi)rL   r   rO   rO   rP   Ú_print_sinc¦  s    zOctaveCodePrinter._print_sincc             C   s   d|   |j¡|   |j¡f S )Nzbesselh(%s, 1, %s))rk   r>   Úargument)rL   r   rO   rO   rP   Ú_print_hankel1«  s    z OctaveCodePrinter._print_hankel1c             C   s   d|   |j¡|   |j¡f S )Nzbesselh(%s, 2, %s))rk   r>   râ   )rL   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>   rž   rk   )rL   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ž   rk   )rL   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   )rk   r‰   )rL   r   rO   rO   rP   Ú_print_airyaiÄ  s    zOctaveCodePrinter._print_airyaic             C   s   d|   |jd ¡ S )Nzairy(1, %s)r   )rk   r‰   )rL   r   rO   rO   rP   Ú_print_airyaiprimeÈ  s    z$OctaveCodePrinter._print_airyaiprimec             C   s   d|   |jd ¡ S )Nzairy(2, %s)r   )rk   r‰   )rL   r   rO   rO   rP   Ú_print_airybiÌ  s    zOctaveCodePrinter._print_airybic             C   s   d|   |jd ¡ S )Nzairy(3, %s)r   )rk   r‰   )rL   r   rO   rO   rP   Ú_print_airybiprimeÐ  s    z$OctaveCodePrinter._print_airybiprimec             C   s*   |j \}}|dkr|  |¡S d|  |¡ S )Nrh   z
expint(%s))r‰   Ú_print_not_supportedrk   )rL   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})z, c                s   g | ]}ˆ   |¡‘qS rO   )rk   )r_   r|   )rL   rO   rP   r~   ß  s    z?OctaveCodePrinter._one_or_two_reversed_args.<locals>.<listcomp>)rX   r‰   )	r€   r‰   ÚAssertionErrorrU   rH   rN   Ú__name__r¸   Úreversed)rL   r   rO   )rL   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   rh   )rX   Zarg1Zarg2)rU   rH   rN   rò   rk   r‰   Úfunc)rL   r   rO   rO   rP   Ú_nested_binary_math_funcæ  s    z*OctaveCodePrinter._nested_binary_math_funcc       
         s0  |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 x¢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¡ qŠW d |¡S d S )Nry   Tz¼All 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.rB   c                s(   g | ] \}}d   ˆ  |¡ˆ  |¡¡‘qS )z({0}).*({1}) + (~({0})).*()rU   rk   )r_   r’   r‘   )rL   rO   rP   r~   þ  s   z6OctaveCodePrinter._print_Piecewise.<locals>.<listcomp>z%sz ...
rÓ   rÒ   r   zif (%s)rh   Úelsezelseif (%s)ri   Ú
)
r‰   ZcondÚ
ValueErrorr­   rk   r   r¸   r€   Ú	enumeratero   )
rL   r   r\   ZecpairsZelastÚpwra   r’   r‘   Zcode0rO   )rL   rP   Ú_print_Piecewiseð  s(    



z"OctaveCodePrinter._print_Piecewisec             C   s0   t |jƒdkr"d|  |jd ¡ S |  |¡S d S )Nrh   zzeta(%s)r   )r€   r‰   rk   rî   )rL   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
}xVt|ƒD ]J\}}	|	dkr| |	¡ qt||| 8 }| d|| |	f ¡ ||| 7 }qtW |S )z0Accepts a string of code or a list of code linesTrv   z  )z
^function z^if z^elseif z^else$z^for )z^end$z^elseif z^else$c             S   s   g | ]}|  d ¡‘qS )z 	)Úlstrip)r_   Ú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 )N)r   )r_   r3   )rÿ   rO   rP   rc   ,  s    z;OctaveCodePrinter.indent_code.<locals>.<listcomp>.<genexpr>)ÚintÚany)r_   )Ú	inc_regex)rÿ   rP   r~   ,  s   c                s&   g | ]‰ t t‡ fd d„ˆD ƒƒƒ‘qS )c             3   s   | ]}t |ˆ ƒV  qd S )N)r   )r_   r3   )rÿ   rO   rP   rc   .  s    z;OctaveCodePrinter.indent_code.<locals>.<listcomp>.<genexpr>)r   r  )r_   )Ú	dec_regex)rÿ   rP   r~   .  s   r   )rv   rø   z%s%s)rŠ   r¾   r[   Ú
splitlinesr¸   rú   ro   )
rL   ÚcodeZ
code_linesÚtabZincreaseZdecreaseÚprettyÚlevelrÛ   rÿ   rO   )r  r  rP   r[     s*    




zOctaveCodePrinter.indent_code)Drò   Ú
__module__Ú__qualname__Ú__doc__ZprintmethodÚlanguageÚ
_operatorsZ_default_settingsrD   rS   rT   rW   rZ   r]   rg   rt   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   )rN   rP   r4   ?   sŽ   J%r4   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));'
    )r4   Zdoprint)r   Z	assign_torM   rO   rO   rP   Úoctave_code=  s     	r  c             K   s   t t| f|Žƒ dS )zŒPrints the Octave (or Matlab) representation of the given expression.

    See `octave_code` for the meaning of the optional arguments.
    N)Úprintr  )r   rM   rO   rO   rP   Úprint_octave_codeÈ  s    r  )N)r  Útypingr   r   ZtDictZ
sympy.corer   r   r   r   Zsympy.core.mulr   Zsympy.printing.codeprinterr	   Zsympy.printing.precedencer
   r   r3   r   rG   rJ   r4   r  r  rO   rO   rO   rP   Ú<module>   s^   

    
 