K i.dZddlmZddlmZddlmZddlmZddl m Z ddl m Z m Z idd d d d d ddddddddddddddddddd d!d"d#d$d%d&d'd(d)d*d+d,d-d.ZGd/d0e Zd4d2Zd3Zy1)5z Javascript code printer The JavascriptCodePrinter converts single SymPy expressions into single Javascript expressions, using the functions defined in the Javascript Math object where possible. ) annotations)Any)S) equal_valued) CodePrinter) precedence PRECEDENCEAbszMath.absacosz Math.acosacoshz Math.acoshasinz Math.asinasinhz Math.asinhatanz Math.atanatan2z Math.atan2atanhz Math.atanhceilingz Math.ceilcoszMath.coscoshz Math.coshexpzMath.expfloorz Math.floorlogzMath.logMaxzMath.maxMinzMath.minsignz Math.signzMath.sinz Math.sinhzMath.tanz Math.tanh)sinsinhtantanhceZdZUdZdZdZeejfididdZde d<ifd Z d Z d Z d Z d ZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZy)JavascriptCodePrinterzK"A Printer to convert Python expressions to strings of JavaScript code _javascript JavaScriptT) precisionuser_functionscontractzdict[str, Any]_default_settingsctj||tt|_|j di}|jj |y)Nr%)r__init__dictknown_functionsgetupdate)selfsettings userfuncss [/mnt/ssd/data/python-lab/Trading/venv/lib/python3.12/site-packages/sympy/printing/jscode.pyr)zJavascriptCodePrinter.__init__:sDT8,#O4LL!126  ##I.c |dzS)N)r.ps r1_rate_index_positionz*JavascriptCodePrinter._rate_index_position@s s r2c d|zS)Nz%s;r5)r. codestrings r1_get_statementz$JavascriptCodePrinter._get_statementCs z!!r2c$dj|S)Nz// {})format)r.texts r1 _get_commentz"JavascriptCodePrinter._get_commentFs~~d##r2c^dj||j|jdS)Nz var {} = {};r$)r<evalf _settings)r.namevalues r1_declare_number_constz+JavascriptCodePrinter._declare_number_constIs'$$T5;;t~~k7R+STTr2c$|j|SN) indent_code)r.liness r1 _format_codez"JavascriptCodePrinter._format_codeLs&&r2cJ|j\}fdt|DS)Nc3FK|]}tD]}||f ywrF)range).0ijcolss r1 zAJavascriptCodePrinter._traverse_matrix_indices..Qs%A1U4[AAAAs!)shaperL)r.matrowsrPs @r1_traverse_matrix_indicesz.JavascriptCodePrinter._traverse_matrix_indicesOsYY dAd AAr2c g}g}d}|D]y}|j||j|j|j|j|j|jdzdz|jd{||fS)NzAfor (var %(varble)s=%(start)s; %(varble)s<%(end)s; %(varble)s++){)varblestartend})append_printlabellowerupper)r.indices open_lines close_lines loopstartrNs r1_get_loop_opening_endingz.JavascriptCodePrinter._get_loop_opening_endingSs  W  $A   i++agg.QWW-{{177Q;/+11 2   s #  $;&&r2ct|}t|jdrd|j|j|zSt|jdrd|j |jzS|jt jdz k(rd|j |jzSd|j |jd|j |jd S) Nz1/%sg?z Math.sqrt(%s)z Math.cbrt(%s)z Math.pow(z, ))rrr parenthesizebaser]rOne)r.exprPRECs r1 _print_Powz JavascriptCodePrinter._print_Pow`s$ " %T..tyy$?@ @ $((C ("T[[%;; ; XXq "T[[%;; ;!*.TYY)?!%TXX!68 8r2cdt|jt|j}}d||fzS)Nz%d/%d)intr6q)r.rmr6rrs r1_print_Rationalz%JavascriptCodePrinter._print_Rationalls*466{CK1!Qr2c$|j\}}t|}|jDcgc]}|j||c}\}}|jr |js|jr|jr|d|Sd|d|d|d|Scc}w)Nz % ((z) + z) % )argsrrjis_nonnegativeis_nonpositive)r.rmnumdenrnargsnumsdens r1 _print_Modz JavascriptCodePrinter._print_Modps99S$>BiiHsd''T2H d   3#5#5   3#5#5V3tf% %D6TF$tfD77IsB c|j|j}|j|j}|j}dj |||S)Nz{} {} {})r]lhsrhsrel_opr<)r.rmlhs_coderhs_codeops r1_print_Relationalz'JavascriptCodePrinter._print_Relational|sD;;txx(;;txx( [[  2x88r2cN|j}tj}tj}t t |j D]}||j||zz }|||z}!|j|jjd|j|dS)N[]) rRrZerorlreversedrLrankrar]rkr^)r.rmdimselemoffsetrNs r1_print_Indexedz$JavascriptCodePrinter._print_Indexedszzvv% *+ A DLLOF* *D d1g F  ;;tyy7T9JKKr2cy)NzMath.Er5r.rms r1 _print_Exp1z!JavascriptCodePrinter._print_Exp1sr2cy)NzMath.PIr5rs r1 _print_PizJavascriptCodePrinter._print_Pisr2cy)NzNumber.POSITIVE_INFINITYr5rs r1_print_Infinityz%JavascriptCodePrinter._print_Infinity)r2cy)NzNumber.NEGATIVE_INFINITYr5rs r1_print_NegativeInfinityz-JavascriptCodePrinter._print_NegativeInfinityrr2c ddlm}|jdjdk7r t dg}|j |rt |jD]\}\}}|dk(r$|jd|j|znU|t|jdz k(r|dk(r|jdn#|jd |j|z|j|}|j||jd d j|S|jddDcgc],\}}d |j|d |j|d.}}}d|j|jdjz} dj|| zdjdt|zgzScc}}w)Nr) AssignmentrgTzAll 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.z if (%s) {rWzelse {zelse if (%s) {r[ ruz) ? ( z ) z: ( %s )z:  ri) sympy.codegen.astrrvcond ValueErrorhas enumerater\r]lenjoinrm) r.rmrrHrNeccode0ecpairs last_lines r1_print_Piecewisez&JavascriptCodePrinter._print_Piecewises0 99R=   %/0 0  88J &tyy1 " 6Aq6LLt{{1~!=>#dii.1,,dLL*LL!1DKKN!BC A U# S! "99U# #!% #20104{{1~t{{1~N0G0$t{{499R=3E3E'FFI99W% 1CHHc#g,>N=O4PP P0s51Gcdj|j|jtdd|j|j |jj dzzS)Nz{}[{}]AtomT)strictrW)r<rjparentr rOrNrRrs r1_print_MatrixElementz*JavascriptCodePrinter._print_MatrixElementsYt00 v t 1 - FFTVVDKK--a00 02 2r2c lt|tr1|j|jd}dj |Sd}d}d}|Dcgc]}|j d}}|Dcgc]*}t tt|j|,}}|Dcgc]*}t tt|j|,}}g} d} t|D]C\} }|dvr| j|| || z} | j|| z|| || z } E| Scc}wcc}wcc}w) z0Accepts a string of code or a list of code linesTz ){(z{ z( )r[riz r)rr) isinstancestrrG splitlinesrlstriprqanymapendswith startswithrr\) r.code code_linestab inc_token dec_tokenlineincreasedecreaseprettylevelns r1rGz!JavascriptCodePrinter.indent_codes: dC ))$//$*?@J77:& &,  046U#66IMOSS :;<OO!%(S)<=>((  !GAtz! d# Xa[ E MMCIt4 5 Xa[ E  ! 7O(s D'*/D,/D1N)__name__ __module__ __qualname____doc__ printmethodlanguager*rr'__annotations__r)r7r:r>rDrIrUrerorsr~rrrrrrrrrGr5r2r1r r .sKH(,[-J-J)O)~ !#/ "$U'B ' 8  89 L**QB2 r2r Nc 8t|j||S)aConverts an expr to a string of javascript 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 is helpful in case of line-wrapping, or for expressions that generate multi-line statements. precision : integer, optional The precision for numbers such as pi [default=15]. 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, js_function_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]. Examples ======== >>> from sympy import jscode, symbols, Rational, sin, ceiling, Abs >>> x, tau = symbols("x, tau") >>> jscode((2*tau)**Rational(7, 2)) '8*Math.sqrt(2)*Math.pow(tau, 7/2)' >>> jscode(sin(x), assign_to="s") 's = Math.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, js_function_string)]. >>> custom_functions = { ... "ceiling": "CEIL", ... "Abs": [(lambda x: not x.is_integer, "fabs"), ... (lambda x: x.is_integer, "ABS")] ... } >>> jscode(Abs(x) + ceiling(x), user_functions=custom_functions) 'fabs(x) + CEIL(x)' ``Piecewise`` expressions are converted into conditionals. If an ``assign_to`` variable is provided an if statement is created, otherwise the ternary operator is used. 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 >>> expr = Piecewise((x + 1, x > 0), (x, True)) >>> print(jscode(expr, tau)) if (x > 0) { tau = x + 1; } else { tau = 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])) >>> jscode(e.rhs, assign_to=e.lhs, contract=False) 'Dy[i] = (y[i + 1] - y[i])/(t[i + 1] - t[i]);' Matrices are also supported, but a ``MatrixSymbol`` of the same dimensions must be provided to ``assign_to``. Note that any expression that can be generated normally can also exist inside a Matrix: >>> from sympy import Matrix, MatrixSymbol >>> mat = Matrix([x**2, Piecewise((x + 1, x > 0), (x, True)), sin(x)]) >>> A = MatrixSymbol('A', 3, 1) >>> print(jscode(mat, A)) A[0] = Math.pow(x, 2); if (x > 0) { A[1] = x + 1; } else { A[1] = x; } A[2] = Math.sin(x); )r doprint)rm assign_tor/s r1jscodersR ! * 2 24 CCr2c .tt|fi|y)zPrints the Javascript representation of the given expression. See jscode for the meaning of the optional arguments. N)printr)rmr/s r1 print_jscoderGs  & " "#r2rF)r __future__rtypingr sympy.corersympy.core.numbersrsympy.printing.codeprinterrsympy.printing.precedencerr r+r rrr5r2r1rs#+2<  : K \ K   \   K  \ \{ : K : \ : :  :!" K#$    +2jKjZiDX$r2