B
    e‹djX  ã            3   @   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/d0d1d2d3d4d5d6d7d8d9d:g3Zd;d<d=d>d?d@dAdBœZG dCdD„ dDeƒZdJdFdG„ZdHdI„ ZdES )Ka  
Julia code printer

The `JuliaCodePrinter` converts SymPy expressions into Julia expressions.

A complete code generator, which uses `julia_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ÚacosÚatanZacotZasecZacscÚsinhÚcoshÚtanhZcothZsechZcschÚasinhÚacoshÚatanhZacothZasechZacschZsincÚatan2ÚsignÚfloorÚlogÚexpZcbrtÚsqrtÚerfÚerfcZerfiÚ	factorialÚgammaZdigammaZtrigammaZ	polygammaÚbetaZairyaiZairyaiprimeZairybiZairybiprimeÚbesseljÚbesselyZbesseliZbesselkZerfinvZerfcinvÚabsÚceilZconjZhankelh1Zhankelh2ÚimagÚreal)ZAbsZceilingÚ	conjugateZhankel1Zhankel2ÚimÚrec            	       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‡ fd&d'„Zd(d)„ Z‡ fd*d+„Z‡ fd,d-„Z‡ fd.d/„Z‡ fd0d1„Zd2d3„ Zd4d5„ Zd6d7„ Zd8d9„ Zd:d;„ Zd<d=„ Ze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[„ Z/d\d]„ Z0‡  Z1S )^ÚJuliaCodePrinterzD
    A printer to convert expressions to strings of Julia code.
    Z_juliaÚJuliaz&&z||ú!)Ú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 )Nr8   )	ÚsuperÚ__init__ÚdictÚzipÚknown_fcns_src1Zknown_functionsÚupdateÚknown_fcns_src2Úget)ÚselfÚsettingsZ	userfuncs)Ú	__class__© úa/work/yifan.wang/ringdown/master-ringdown-env/lib/python3.7/site-packages/sympy/printing/julia.pyr<   I   s
    zJuliaCodePrinter.__init__c             C   s   |d S )Né   rF   )rC   ÚprF   rF   rG   Ú_rate_index_positionQ   s    z%JuliaCodePrinter._rate_index_positionc             C   s   d| S )Nz%srF   )rC   Z
codestringrF   rF   rG   Ú_get_statementU   s    zJuliaCodePrinter._get_statementc             C   s
   d  |¡S )Nz# {})Úformat)rC   ÚtextrF   rF   rG   Ú_get_commentY   s    zJuliaCodePrinter._get_commentc             C   s   d  ||¡S )Nzconst {} = {})rL   )rC   ÚnameÚvaluerF   rF   rG   Ú_declare_number_const]   s    z&JuliaCodePrinter._declare_number_constc             C   s
   |   |¡S )N)Úindent_code)rC   ÚlinesrF   rF   rG   Ú_format_codea   s    zJuliaCodePrinter._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)ÚrowsrF   rG   ú	<genexpr>h   s    z<JuliaCodePrinter._traverse_matrix_indices.<locals>.<genexpr>)ÚshaperU   )rC   ÚmatÚcolsrF   )rY   rG   Ú_traverse_matrix_indicese   s    
z)JuliaCodePrinter._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)rC   ÚindicesZ
open_linesZclose_linesrX   ÚvarÚstartÚstoprF   rF   rG   Ú_get_loop_opening_endingk   s    
 z)JuliaCodePrinter._get_loop_opening_endingc                sŒ  |j r0|jr0| ¡ d jr0dˆ 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rt|	tjk	rt|	jd	krV| t|	jƒ¡ |	jd	kr~| t|	jƒ¡ q’| |	¡ q’W |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rL|d j r.dnd}||||
ƒ | |d  S tdd„ |D ƒƒrddnd}||||
ƒ | d|||ƒ  S d S )Nr   z%simú-Ú )ÚoldÚnoneéÿÿÿÿF)Úevaluater_   c                s   g | ]}ˆ  |ˆ ¡‘qS rF   )Úparenthesize)rV   Úx)ÚprecrC   rF   rG   ú
<listcomp>¦   s    z/JuliaCodePrinter._print_Mul.<locals>.<listcomp>c                s   g | ]}ˆ  |ˆ ¡‘qS rF   )rr   )rV   rs   )rt   rC   rF   rG   ru   §   s    z(%s)c             S   sJ   |d }x<t dt| ƒƒD ]*}| |d  jr.dnd}|| ||  }qW |S )Nr   r_   Ú*z.*)rU   ÚlenÚ	is_number)ÚaÚa_strÚrrX   ZmulsymrF   rF   rG   Úmultjoin¯   s
    z-JuliaCodePrinter._print_Mul.<locals>.multjoinú/z./c             s   s   | ]}|j V  qd S )N)rx   )rV   ZbirF   rF   rG   rZ   ½   s    z.JuliaCodePrinter._print_Mul.<locals>.<genexpr>)rx   Zis_imaginaryZas_coeff_MulÚ
is_integerrb   r   ZImaginaryUnitr
   r   r6   Zas_ordered_factorsr   Z	make_argsÚis_commutativeZis_Powr   Zis_RationalZis_negativerf   r   Úbaserw   ÚargsÚ
isinstanceÚInfinityrI   r   ÚqÚOneÚindexÚall)rC   ÚexprÚcÚer   ry   ÚbZ	pow_parenr   Úitemrz   Zb_strr|   ZdivsymrF   )rt   rC   rG   Ú
_print_Mulw   sV    





$

&zJuliaCodePrinter._print_Mulc             C   s,   |   |j¡}|   |j¡}|j}d |||¡S )Nz{} {} {})rb   ÚlhsÚrhsZrel_oprL   )rC   rˆ   Úlhs_codeÚrhs_codeÚoprF   rF   rG   Ú_print_RelationalÁ   s    z"JuliaCodePrinter._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)rx   )rV   rs   rF   rF   rG   rZ   È   s    z.JuliaCodePrinter._print_Pow.<locals>.<genexpr>ú^z.^zsqrt(%s)r}   z./Ú1z%sz%s%s%s)r‡   r   r
   r   r   ÚHalfrb   r€   r   rx   r…   rr   )rC   rˆ   Z	powsymbolÚPRECÚsymrF   rF   rG   Ú
_print_PowÇ   s    zJuliaCodePrinter._print_Powc             C   s(   t |ƒ}d|  |j|¡|  |j|¡f S )Nz%s^%s)r
   rr   r€   r   )rC   rˆ   r—   rF   rF   rG   Ú_print_MatPowÛ   s    zJuliaCodePrinter._print_MatPowc                s   | j d rdS tƒ  |¡S d S )Nr:   Úpi)Ú	_settingsr;   Ú_print_NumberSymbol)rC   rˆ   )rE   rF   rG   Ú	_print_Piá   s    
zJuliaCodePrinter._print_Pic             C   s   dS )Nr,   rF   )rC   rˆ   rF   rF   rG   Ú_print_ImaginaryUnitè   s    z%JuliaCodePrinter._print_ImaginaryUnitc                s   | j d rdS tƒ  |¡S d S )Nr:   rŠ   )rœ   r;   r   )rC   rˆ   )rE   rF   rG   Ú_print_Exp1ì   s    
zJuliaCodePrinter._print_Exp1c                s   | j d rdS tƒ  |¡S d S )Nr:   Z
eulergamma)rœ   r;   r   )rC   rˆ   )rE   rF   rG   Ú_print_EulerGammaó   s    
z"JuliaCodePrinter._print_EulerGammac                s   | j d rdS tƒ  |¡S d S )Nr:   Úcatalan)rœ   r;   r   )rC   rˆ   )rE   rF   rG   Ú_print_Catalanú   s    
zJuliaCodePrinter._print_Catalanc                s   | j d rdS tƒ  |¡S d S )Nr:   Zgolden)rœ   r;   r   )rC   rˆ   )rE   rF   rG   Ú_print_GoldenRatio  s    
z#JuliaCodePrinter._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)ÚIndexedBaser:   r9   z%s = %s)Zsympy.codegen.astr¥   Z$sympy.functions.elementary.piecewiser¦   Zsympy.tensor.indexedr§   rŽ   r   rœ   r‚   r   rf   r>   rb   ÚhasZ_doprint_loopsrK   )rC   rˆ   r¥   r¦   r§   rŽ   r   ZexpressionsZ
conditionsrŠ   r‰   Útempr   r‘   rF   rF   rG   Ú_print_Assignment  s&    



z"JuliaCodePrinter._print_Assignmentc             C   s   dS )NZInfrF   )rC   rˆ   rF   rF   rG   Ú_print_Infinity%  s    z JuliaCodePrinter._print_Infinityc             C   s   dS )Nz-InfrF   )rC   rˆ   rF   rF   rG   Ú_print_NegativeInfinity)  s    z(JuliaCodePrinter._print_NegativeInfinityc             C   s   dS )NÚNaNrF   )rC   rˆ   rF   rF   rG   Ú
_print_NaN-  s    zJuliaCodePrinter._print_NaNc                s    dd  ‡ fdd„|D ƒ¡ d S )NzAny[z, c             3   s   | ]}ˆ   |¡V  qd S )N)rb   )rV   ry   )rC   rF   rG   rZ   2  s    z/JuliaCodePrinter._print_list.<locals>.<genexpr>ú])Újoin)rC   rˆ   rF   )rC   rG   Ú_print_list1  s    zJuliaCodePrinter._print_listc             C   s2   t |ƒdkrd|  |d ¡ S d|  |d¡ S d S )Nr_   z(%s,)r   z(%s)z, )rw   rb   Ú	stringify)rC   rˆ   rF   rF   rG   Ú_print_tuple5  s    zJuliaCodePrinter._print_tuplec             C   s   dS )NÚtruerF   )rC   rˆ   rF   rF   rG   Ú_print_BooleanTrue=  s    z#JuliaCodePrinter._print_BooleanTruec             C   s   dS )NÚfalserF   )rC   rˆ   rF   rF   rG   Ú_print_BooleanFalseA  s    z$JuliaCodePrinter._print_BooleanFalsec             C   s   t |ƒ ¡ S )N)Ústrrd   )rC   rˆ   rF   rF   rG   Ú_print_boolE  s    zJuliaCodePrinter._print_boolc                s–   t j|jkrd|j|jf S |j|jfdkr8d|d  S |jdkrXd|jˆ dddd S |jdkr~dd	 ‡ fd
d„|D ƒ¡ S d|jˆ ddddd S )Nzzeros(%s, %s))r_   r_   z[%s])r   r   r_   rm   ú )ÚrowstartÚrowendÚcolsepz, c                s   g | ]}ˆ   |¡‘qS rF   )rb   )rV   ry   )rC   rF   rG   ru   W  s    z6JuliaCodePrinter._print_MatrixBase.<locals>.<listcomp>z;
)r»   r¼   Zrowsepr½   )r   ZZeror[   rY   r]   Útabler°   )rC   ÚArF   )rC   rG   Ú_print_MatrixBaseM  s    

z"JuliaCodePrinter._print_MatrixBasec             C   sr   ddl m} | ¡ }|dd„ |D ƒƒ}|dd„ |D ƒƒ}|dd„ |D ƒƒ}d|  |¡|  |¡|  |¡|j|jf S )Nr   )ÚMatrixc             S   s   g | ]}|d  d ‘qS )r   r_   rF   )rV   ÚkrF   rF   rG   ru   `  s    z;JuliaCodePrinter._print_SparseRepMatrix.<locals>.<listcomp>c             S   s   g | ]}|d  d  ‘qS )r_   rF   )rV   rÂ   rF   rF   rG   ru   a  s    c             S   s   g | ]}|d  ‘qS )é   rF   )rV   rÂ   rF   rF   rG   ru   b  s    zsparse(%s, %s, %s, %s, %s))Zsympy.matricesrÁ   Zcol_listrb   rY   r]   )rC   r¿   rÁ   ÚLÚIÚJZAIJrF   rF   rG   Ú_print_SparseRepMatrix\  s    z'JuliaCodePrinter._print_SparseRepMatrixc             C   s.   | j |jtd ddd|jd |jd f  S )NZAtomT)Ústrictz[%s,%s]r_   )rr   Úparentr   rX   rW   )rC   rˆ   rF   rF   rG   Ú_print_MatrixElementg  s    z%JuliaCodePrinter._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   r_   rÃ   r`   ú:)rb   r°   )rs   ZlimÚlÚhÚstepZlstrZhstr)rC   rF   rG   Ústrslicem  s    
z5JuliaCodePrinter._print_MatrixSlice.<locals>.strsliceú[r   ú,r_   r¯   )rb   rÉ   Zrowslicer[   Zcolslice)rC   rˆ   rÏ   rF   )rC   rG   Ú_print_MatrixSlicel  s    z#JuliaCodePrinter._print_MatrixSlicec                s0   ‡ fdd„|j D ƒ}dˆ  |jj¡d |¡f S )Nc                s   g | ]}ˆ   |¡‘qS rF   )rb   )rV   rX   )rC   rF   rG   ru   ‚  s    z3JuliaCodePrinter._print_Indexed.<locals>.<listcomp>z%s[%s]rÑ   )rg   rb   r€   rc   r°   )rC   rˆ   ZindsrF   )rC   rG   Ú_print_Indexed  s    zJuliaCodePrinter._print_Indexedc             C   s   |   |j¡S )N)rb   rc   )rC   rˆ   rF   rF   rG   Ú
_print_Idx†  s    zJuliaCodePrinter._print_Idxc             C   s   d|   |jd ¡ S )Nzeye(%s)r   )rb   r[   )rC   rˆ   rF   rF   rG   Ú_print_IdentityŠ  s    z JuliaCodePrinter._print_Identityc                s   d  ‡ ‡fdd„ˆ jD ƒ¡S )Nz.*c                s   g | ]}ˆ  |tˆ ƒ¡‘qS rF   )rr   r
   )rV   Úarg)rˆ   rC   rF   rG   ru   Ž  s   z;JuliaCodePrinter._print_HadamardProduct.<locals>.<listcomp>)r°   r   )rC   rˆ   rF   )rˆ   rC   rG   Ú_print_HadamardProduct  s    z'JuliaCodePrinter._print_HadamardProductc             C   s*   t |ƒ}d |  |j|¡|  |j|¡g¡S )Nz.**)r
   r°   rr   r€   r   )rC   rˆ   r—   rF   rF   rG   Ú_print_HadamardPower‘  s    z%JuliaCodePrinter._print_HadamardPowerc             C   sD   ddl m}m} |j}|tjd|  ƒ||jtj |ƒ }|  |¡S )Nr   )r   r%   rÃ   )	Úsympy.functionsr   r%   Úargumentr   ÚPir6   r–   rb   )rC   rˆ   r   r%   rs   Úexpr2rF   rF   rG   Ú	_print_jn™  s    $zJuliaCodePrinter._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Û   r6   r–   rb   )rC   rˆ   r   r&   rs   rÜ   rF   rF   rG   Ú	_print_yn   s    $zJuliaCodePrinter._print_ync       
         s$  |j d jdkrtdƒ‚g }ˆ jd rr‡ fdd„|j d d… D ƒ}dˆ  |j d j¡ }d |¡| }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 )Nrp   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.r:   c                s(   g | ] \}}d   ˆ  |¡ˆ  |¡¡‘qS )z({}) ? ({}) :)rL   rb   )rV   rŠ   r‰   )rC   rF   rG   ru   µ  s   z5JuliaCodePrinter._print_Piecewise.<locals>.<listcomp>z (%s)Ú
ú(ú)r   zif (%s)r_   Úelsezelseif (%s)r`   )
r   ZcondÚ
ValueErrorrœ   rb   rˆ   r°   Ú	enumeraterf   rw   )
rC   rˆ   rS   ZecpairsZelastÚpwrX   rŠ   r‰   Zcode0rF   )rC   rG   Ú_print_Piecewise§  s(    



z!JuliaCodePrinter._print_Piecewisec       
         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 linesTrm   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)rV   ÚlinerF   rF   rG   ru   Ù  s    z0JuliaCodePrinter.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   )rV   r-   )rè   rF   rG   rZ   Û  s    z:JuliaCodePrinter.indent_code.<locals>.<listcomp>.<genexpr>)ÚintÚany)rV   )Ú	inc_regex)rè   rG   ru   Û  s   c                s&   g | ]‰ t t‡ fd d„ˆD ƒƒƒ‘qS )c             3   s   | ]}t |ˆ ƒV  qd S )N)r   )rV   r-   )rè   rF   rG   rZ   Ý  s    z:JuliaCodePrinter.indent_code.<locals>.<listcomp>.<genexpr>)ré   rê   )rV   )Ú	dec_regex)rè   rG   ru   Ý  s   r   )rm   rß   z%s%s)r‚   r¸   rR   Ú
splitlinesr°   rä   rf   )
rC   ÚcodeZ
code_linesÚtabZincreaseZdecreaseÚprettyÚlevelÚnrè   rF   )rì   rë   rG   rR   Ì  s*    




zJuliaCodePrinter.indent_code)2Ú__name__Ú
__module__Ú__qualname__Ú__doc__ZprintmethodÚlanguageÚ
_operatorsZ_default_settingsr<   rJ   rK   rN   rQ   rT   r^   rk   r   r“   r™   rš   rž   rŸ   r    r¡   r£   r¤   rª   r«   r¬   r®   r±   r³   Z_print_Tuplerµ   r·   r¹   rÀ   rÇ   rÊ   rÒ   rÓ   rÔ   rÕ   r×   rØ   rÝ   rÞ   ræ   rR   Ú__classcell__rF   rF   )rE   rG   r.   .   sn   J%r.   Nc             K   s   t |ƒ | |¡S )a   Converts `expr` to a string of Julia 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 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 julia_code, symbols, sin, pi
    >>> x = symbols('x')
    >>> julia_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")
    >>> julia_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 possible in Julia to write "vectorized"
    code.  It is harmless if the values are scalars.

    >>> julia_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)
    >>> julia_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:

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

    Matrices are supported using Julia 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)]])
    >>> julia_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))
    >>> julia_code(pw, assign_to=tau)
    'tau = ((x > 0) ? (x + 1) : (x))'

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

    >>> mat = Matrix([[x**2, pw, sin(x)]])
    >>> julia_code(mat, assign_to='A')
    'A = [x.^2 ((x > 0) ? (x + 1) : (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 Julia function.

    >>> from sympy import Function
    >>> f = Function('f')
    >>> g = Function('g')
    >>> custom_functions = {
    ...   "f": "existing_julia_fcn",
    ...   "g": [(lambda x: x.is_Matrix, "my_mat_fcn"),
    ...         (lambda x: not x.is_Matrix, "my_fcn")]
    ... }
    >>> mat = Matrix([[1, x]])
    >>> julia_code(f(x) + g(x) + g(mat), user_functions=custom_functions)
    'existing_julia_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]))
    >>> julia_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_torD   rF   rF   rG   Ú
julia_codeì  s     rú   c             K   s   t t| f|Žƒ dS )z~Prints the Julia representation of the given expression.

    See `julia_code` for the meaning of the optional arguments.
    N)Úprintrú   )rˆ   rD   rF   rF   rG   Úprint_julia_codeu  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   r-   r   r?   rA   r.   rú   rü   rF   rF   rF   rG   Ú<module>
   s>   
   A
 
