K i[dZddlmZddlmZddlmZmZmZm Z ddl m Z ddl m Z ddlmZddlmZmZdd lmZgd Zd d d dddddZGddeZddZdZy)a 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. ) annotations)Any)MulPowSRational) _keep_coeff) equal_valued) CodePrinter) precedence PRECEDENCEsearch)2sincostancotseccscasinacosatanacotasecacscsinhcoshtanhcothsechcschasinhacoshatanhacothasechacschatan2signfloorlogexpcbrtsqrterferfcerfi factorialgammadigammatrigamma polygammabetaairyai airyaiprimeairybi airybiprimebesseljbesselybesselibesselkerfinverfcinvabsceilconjhankelh1hankelh2imagreal)Absceiling conjugatehankel1hankel2imrec eZdZUdZdZdZddddZeejfidid d d Z d e d <iffd Z dZ dZ dZdZdZdZdZdZdZdZdZfdZdZfdZfdZfdZfdZdZd Zd!Zd"Z d#Z!d$Z"e"Z#d%Z$d&Z%d'Z&d(Z'd)Z(d*Z)d+Z*d,Z+d-Z,d.Z-d/Z.d0Z/d1Z0d2Z1d3Z2d4Z3d5Z4d6Z5xZ6S)7JuliaCodePrinterzD A printer to convert expressions to strings of Julia code. _juliaJuliaz&&z||!)andornotT) precisionuser_functionscontractinlinezdict[str, Any]_default_settingsct||tttt|_|j j tt|jdi}|j j |y)NrZ) super__init__dictzipknown_fcns_src1known_functionsupdateknown_fcns_src2get)selfsettings userfuncs __class__s Z/mnt/ssd/data/python-lab/Trading/venv/lib/python3.12/site-packages/sympy/printing/julia.pyr`zJuliaCodePrinter.__init__Gsb "#C$IJ ##D$9:LL!126  ##I.c |dzS)N)rhps rl_rate_index_positionz%JuliaCodePrinter._rate_index_positionOs s rmc d|zS)Nz%srp)rh codestrings rl_get_statementzJuliaCodePrinter._get_statementSs j  rmc$dj|S)Nz# {}format)rhtexts rl _get_commentzJuliaCodePrinter._get_commentWs}}T""rmc&dj||S)Nz const {} = {}rw)rhnamevalues rl_declare_number_constz&JuliaCodePrinter._declare_number_const[s%%dE22rmc$|j|SN) indent_code)rhliness rl _format_codezJuliaCodePrinter._format_code_s&&rmcJ|j\}fdt|DS)Nc3FK|]}tD]}||f ywr)range).0jirowss rl z.fs%A1U4[AAAAs!)shaper)rhmatcolsrs @rl_traverse_matrix_indicesz)JuliaCodePrinter._traverse_matrix_indicescsYY dAd AArmc g}g}|D]n}t|j|j|jdz|jdzg\}}}|j d|d|d||j dp||fS)Nzfor  = :end)map_printlabellowerupperappend)rhindices open_lines close_linesrvarstartstops rl_get_loop_opening_endingz)JuliaCodePrinter._get_loop_opening_endingis   &A"4;;WWaggk177Q;7 9 C   #udC D   u %  & ;&&rmc|jrO|jrC|jdjr&d|j t j |zzSt|}|j\}}|dkrt| |}d}nd}g}g}g}|jdvr|j} ntj|} | D]o} | jr| jr| jj r| jj"r| jdk7r3|j%t'| j(| j dt+| j,dj,d k7r+t/| j(tr|j%| |j%t'| j(| j  | j rG| t j0ur5| j2d k(r&|j%t5| j6_|j%| r|xst j8g}|D cgc]} |j;| |} } |D cgc]} |j;| |} } |D]N} | j(|vsd | |j=| j(z| |j=| j(<Pd }|s |||| zSt+|d k(r*|djrd nd }|||| zd|d| dSt?d|Drd nd }|||| zd|d||| dScc} wcc} w)Nrz%sim-)oldnoneF)evaluater(%s)c|d}tdt|D]%}||dz jrdnd}|d|d||}'|S)Nrr*z.* )rlen is_number)aa_strrrmulsyms rlmultjoinz-JuliaCodePrinter._print_Mul..multjoinsSaA1c!f% 7 !!A# 0 0d"#VU1X6 7Hrm/./rc34K|]}|jywrr)rbis rlrz.JuliaCodePrinter._print_Mul..s9 9z ()) r is_imaginary as_coeff_Mul is_integerrr ImaginaryUnitr r orderas_ordered_factorsr make_argsis_commutativeis_Powr, is_Rational is_negativerrbaserargs isinstanceInfinityrqrqOne parenthesizeindexall)rhexprpreccer)rb pow_parenritemxrb_strrdivsyms rl _print_MulzJuliaCodePrinter._print_Mulus NNt00!!#A&11DKK(8(=>> >$  "1 q5r1%DDD   ::_ ,**,D==&D D## 8L8L,,88r>HHSTXXIFG499Q<,,-2z$))S7Q!((.HHSTXXI67!!d!**&<1 $&&)*! $ L!%%567""1d+77567""1d+77 ODyyA~,2U177499;M5N,Naggdii() O  (1e,, , Vq[aDNNSF!%hq%&8!8&%(K K9q99StF#'(1e*<#.s>qq{{>r^z.^g?zsqrt(%s)grrz1 z sqrt(rrr) rrr r r,rrrrr)rhr powsymbolPRECsyms rl _print_PowzJuliaCodePrinter._print_Pows>DII>>CD $ # & DII 66 6   DHHd+!YY00cd*-t{{499/EFFDHHb)!YY00cd%($*;*;DIIt*LMM!..tyy$?,,TXXt<> >rmct|}|j|j|d|j|j|S)Nz ^ )r rrr,rhrrs rl _print_MatPowzJuliaCodePrinter._print_MatPows>$ --dii>++DHHd;= =rmcB|jdryt| |S)Nr\pi _settingsr__print_NumberSymbolrhrrks rl _print_PizJuliaCodePrinter._print_Pis" >>( #7.t4 4rmcy)NrNrprhrs rl_print_ImaginaryUnitz%JuliaCodePrinter._print_ImaginaryUnitsrmcB|jdryt| |S)Nr\rrrs rl _print_Exp1zJuliaCodePrinter._print_Exp1s" >>( #7.t4 4rmcB|jdryt| |S)Nr\ eulergammarrs rl_print_EulerGammaz"JuliaCodePrinter._print_EulerGammas" >>( #7.t4 4rmcB|jdryt| |S)Nr\catalanrrs rl_print_CatalanzJuliaCodePrinter._print_Catalans" >>( #7.t4 4rmcB|jdryt| |S)Nr\goldenrrs rl_print_GoldenRatioz#JuliaCodePrinter._print_GoldenRatios" >>( #7.t4 4rmcXddlm}ddlm}ddlm}|j }|j}|jdswt|j|rag}g}|jD].\} } |j||| |j| 0|t||} |j| S|jdr4|j|s|j|r|j||S|j|} |j|} |j!| d| S)Nr) Assignment) Piecewise) IndexedBaser\r[r)sympy.codegen.astr$sympy.functions.elementary.piecewisersympy.tensor.indexedrrrrrrrrbrhas_doprint_loopsru)rhrrrrrr expressions conditionsrrtemprrs rl_print_Assignmentz"JuliaCodePrinter._print_Assignments0B4hhhh~~h'Jtxx,KKJ(( %A"":c1#56!!!$ %c+z:;D;;t$ $ >>* %377;+? $&&sC0 0{{3'H{{3'H&&Hh'GH Hrmcy)NInfrprs rl_print_Infinityz JuliaCodePrinter._print_Infinity#rmcy)Nz-Infrprs rl_print_NegativeInfinityz(JuliaCodePrinter._print_NegativeInfinity'rmcy)NNaNrprs rl _print_NaNzJuliaCodePrinter._print_NaN+rrmcDddjfd|DzdzS)NzAny[, c3@K|]}j|ywr)r)rrrhs rlrz/JuliaCodePrinter._print_list..0s!?Q$++a.!?s])joinrs` rl _print_listzJuliaCodePrinter._print_list/s" !?$!???#EErmcvt|dk(rd|j|dzSd|j|dzS)Nrz(%s,)rrr)rr stringifyrs rl _print_tuplezJuliaCodePrinter._print_tuple3s; t9>T[[a11 1DNN466 6rmcy)Ntruerprs rl_print_BooleanTruez#JuliaCodePrinter._print_BooleanTrue;rrmcy)Nfalserprs rl_print_BooleanFalsez$JuliaCodePrinter._print_BooleanFalse?srmc4t|jSr)strrrs rl _print_boolzJuliaCodePrinter._print_boolCs4y  rmc tj|jvrd|jd|jdS|j|jfdk(rd|dzS|jdk(rd|j |ddd zS|jdk(r1ddj |Dcgc]}|j|c}zSd|j |ddd d zScc}w) Nzzeros(rr)rrz[%s])rrrrr)rowstartrowendcolsepz; )r+r,rowsepr-)rZerorrrtablerr)rhArs rl_print_MatrixBasez"JuliaCodePrinter._print_MatrixBaseKs 66QWW &'ffaff5 5ffaff  'AdG# # VVq[AGGD2bGMM M VVq[DIIq&A!t{{1~&ABB Br"',S :: :'Bs#C c ddlm}|j}||Dcgc] }|ddz c}}||Dcgc] }|ddz c}}||Dcgc]}|d c}}d|j|d|j|d|j|d|jd|j d Scc}wcc}wcc}w)Nr)Matrixrzsparse(rr)sympy.matricesr4col_listrrr)rhr1r4LkIJAIJs rl_print_SparseRepMatrixz'JuliaCodePrinter._print_SparseRepMatrixZs) JJL a(AaD1H( ) a(AaD1H( )A&qad&'/3{{1~t{{1~,0KK,.strsliceks!qA!AQ4D;;q>DH5$++a.Dqy6a3h6K#:,,xxt{{4'8$ ?@@rmrArrBrr)rrCrowslicercolslice)rhrrMs` rl_print_MatrixSlicez#JuliaCodePrinter._print_MatrixSlicejs| A DKK(3. (9(9!(<=>@CD (9(9!(<=>@CD Ermc|jDcgc]}|j|}}|j|jjddj |dScc}w)NrArBr)rrrrr)rhrrindss rl_print_IndexedzJuliaCodePrinter._print_IndexedsJ)-7AQ77;;tyy7$HH8sA#cDd|j|jdzS)Nzeye(%s)r)rrrs rl_print_Identityz JuliaCodePrinter._print_Identitys4;;tzz!}555rmc dj|jDcgc]}|j|t|c}Scc}w)Nz .* )rrrr )rhrargs rl_print_HadamardProductz'JuliaCodePrinter._print_HadamardProductsD{{%)YY0!!--c:d3CD01 10s"Act|}dj|j|j||j|j|gS)Nz.**)r rrrr,rs rl_print_HadamardPowerz%JuliaCodePrinter._print_HadamardPowersJ$zz   dii .   dhh - rmc|jdk(rt|jS|jd|jS)Nrz // )rr(rqrs rl_print_Rationalz JuliaCodePrinter._print_Rationals. 66Q;tvv; !VVTVV,,rmcddlm}m}|j}|tj d|zz ||j tjz|z}|j|S)Nr)r.r<r5) sympy.functionsr.r<argumentrPirHalfr)rhrr.r<rexpr2s rl _print_jnzJuliaCodePrinter._print_jnL1 MMQTT1Q3Z aff)>( # $(99Sb>31a'-- A A83G3dkk$))B-*<*<==E7#e+B8c> !&tyy1 ( 6Aq6LLT[[^!;<#dii.1,,dLL(LLQ!?@ A U#DII**LL' (99U# #)3s :G c\j\}}d}|jrb|j\}}|jr|jrt | |d}n'|jr|jrt | |d}|dj fdjDzS)Nrrz * c3TK|]}j|t!ywr)rr )rrWrrhs rlrz1JuliaCodePrinter._print_MatMul..s# K#T  sJt$4 5 Ks%() as_coeff_mmulr as_real_imagis_zerorr rr)rhrrmr)rOrNs`` rl _print_MatMulzJuliaCodePrinter._print_MatMuls!!#1 ;;^^%FBzzbnn"A2q)"A2q)ejj K K   rmc Ft|tr1|j|jd}dj |Sd}d}d}|Dcgc]}|j d}}|Dcgc]t tfd|D!}}|Dcgc]t tfd|D!}}g} d } t|D]C\} d vr| j| || z} | j|| z| || z } E| Scc}wcc}wcc}w) z0Accepts a string of code or a list of code linesTrz )z ^function z^if ^elseif ^else$z^for )z^end$r}r~z c36K|]}t|ywrrrrOlines rlrz/JuliaCodePrinter.indent_code..B"VB-Bc36K|]}t|ywrrrs rlrz/JuliaCodePrinter.indent_code..rrr)rrj) rr(r splitlinesrlstripintanyror) rhcode code_linestab inc_regex dec_regexrincreasedecreaseprettylevelns ` rlrzJuliaCodePrinter.indent_codesC dC ))$//$*?@J77:& &I 3 156U#66"&(B BBC(("&(B BBC((  !GAtz! d# Xa[ E MMCIt4 5 Xa[ E  ! !7((s D,$D$D)7__name__ __module__ __qualname____doc__ printmethodlanguage _operatorsrar r]__annotations__r`rrrurzr~rrrrrrrrrrrrrr rrrrr  _print_Tupler#r&r)r2r=rDrPrSrUrXrZr\rcrfrhrtr{r __classcell__)rks@rlrQrQ0sBKHJ )-[-J-J) O)~!#/!#3'B 'HZT9 >(= 55555I:F7  L! :N3 E*I61- "" C"$H $rmrQNc 8t|j||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])' )rQdoprint)r assign_toris rl julia_codersL H % - -dI >>rmc .tt|fi|y)z~Prints the Julia representation of the given expression. See `julia_code` for the meaning of the optional arguments. N)printr)rris rlprint_julia_coders  *T &X &'rmr)r __future__rtypingr sympy.corerrrrsympy.core.mulr sympy.core.numbersr sympy.printing.codeprinterr sympy.printing.precedencer r rOrrcrfrQrrrprmrlrsg #,,&+2< (   K{K\F?R(rm