K i4dZddlmZddlmZddlmZddlmZm Z m Z m Z ddl m Z mZmZddlmZddlmZmZdd lmZmZmZdd lmZmZmZdd lmZmZm Z m!Z!d Z"Gd deZ#Gdde#Z$Gdde$Z%e%Z&Gdde$Z'e'Z(Gdde$Z)e)Z*Gdde#Z+Gdde+Z,Gdde+Z-Gdde-Z.Gdd e-Z/Gd!d"e-Z0Gd#d$e-Z1Gd%d&e-Z2e.e/e0e1e2fDcic]}|jf|c}Z4d'Z5Gd(d)e#Z6Gd*d+e$Z7Gd,d-ee$Z8Gd.d/e8Z9Gd0d1e8Z:Gd2d3e$Z;Gd4d5e$Z<Gd6d7e<Z=Gd8d9e=Z>Gd:d;e>Z?Gd<d=e>Z@ed>ZAGd?d@e<ZBGdAdBeBZCGdCdDeBZDGdEdFeDeCZEe=dGZFe=dHZGe?dIdJZHe?dKdLZIe?dMdNZJe?dOdPZKe@dQdJZLe@dRdLZMe@dSdNZNe@dTdPZOeCdUdLdVdWXZPeCdYdNdJdZXZQeCd[dPd\d]XZReCd^d_d`daXZSeCdbdcd`ddXZTeCdedfdgdhXZUeEddidPieQjdjkZWeEddidcieRjdjkZXeAssignmentBase | |--->Assignment | |--->AugmentedAssignment | |--->AddAugmentedAssignment | |--->SubAugmentedAssignment | |--->MulAugmentedAssignment | |--->DivAugmentedAssignment | |--->ModAugmentedAssignment | |--->CodeBlock | | |--->Token |--->Attribute |--->For |--->String | |--->QuotedString | |--->Comment |--->Type | |--->IntBaseType | | |--->_SizedIntType | | |--->SignedIntType | | |--->UnsignedIntType | |--->FloatBaseType | |--->FloatType | |--->ComplexBaseType | |--->ComplexType |--->Node | |--->Variable | | |---> Pointer | |--->FunctionPrototype | |--->FunctionDefinition |--->Element |--->Declaration |--->While |--->Scope |--->Stream |--->Print |--->FunctionCall |--->BreakToken |--->ContinueToken |--->NoneToken |--->Return Predefined types ---------------- A number of ``Type`` instances are provided in the ``sympy.codegen.ast`` module for convenience. Perhaps the two most common ones for code-generation (of numeric codes) are ``float32`` and ``float64`` (known as single and double precision respectively). There are also precision generic versions of Types (for which the codeprinters selects the underlying data type at time of printing): ``real``, ``integer``, ``complex_``, ``bool_``. The other ``Type`` instances defined are: - ``intc``: Integer type used by C's "int". - ``intp``: Integer type used by C's "unsigned". - ``int8``, ``int16``, ``int32``, ``int64``: n-bit integers. - ``uint8``, ``uint16``, ``uint32``, ``uint64``: n-bit unsigned integers. - ``float80``: known as "extended precision" on modern x86/amd64 hardware. - ``complex64``: Complex number represented by two ``float32`` numbers - ``complex128``: Complex number represented by two ``float64`` numbers Using the nodes --------------- It is possible to construct simple algorithms using the AST nodes. Let's construct a loop applying Newton's method:: >>> from sympy import symbols, cos >>> from sympy.codegen.ast import While, Assignment, aug_assign, Print, QuotedString >>> t, dx, x = symbols('tol delta val') >>> expr = cos(x) - x**3 >>> whl = While(abs(dx) > t, [ ... Assignment(dx, -expr/expr.diff(x)), ... aug_assign(x, '+', dx), ... Print([x]) ... ]) >>> from sympy import pycode >>> py_str = pycode(whl) >>> print(py_str) while (abs(delta) > tol): delta = (val**3 - math.cos(val))/(-3*val**2 - math.sin(val)) val += delta print(val) >>> import math >>> tol, val, delta = 1e-5, 0.5, float('inf') >>> exec(py_str) 1.1121416371 0.909672693737 0.867263818209 0.865477135298 0.865474033111 >>> print('%3.1g' % (math.cos(val) - val**3)) -3e-11 If we want to generate Fortran code for the same while loop we simple call ``fcode``:: >>> from sympy import fcode >>> print(fcode(whl, standard=2003, source_format='free')) do while (abs(delta) > tol) delta = (val**3 - cos(val))/(-3*val**2 - sin(val)) val = val + delta print *, val end do There is a function constructing a loop (or a complete function) like this in :mod:`sympy.codegen.algorithms`. ) annotations)Any) defaultdict)GeGtLeLt)SymbolTupleDummy)Basic)ExprAtom)FloatIntegeroo)_sympifysympify SympifyError)iterabletopological_sortnumbered_symbolsfilter_symbolscp|Dcgc]}t|tr t|n|!}}t|Scc}w)z Create a SymPy Tuple object from an iterable, converting Python strings to AST strings. Parameters ========== args: iterable Arguments to :class:`sympy.Tuple`. Returns ======= sympy.Tuple ) isinstancestrStringr )argsargs W/mnt/ssd/data/python-lab/Trading/venv/lib/python3.12/site-packages/sympy/codegen/ast.py _mk_Tupler!s; EI IS:c3/F3KS 8 ID I $< Js$3ceZdZdZy) CodegenASTN)__name__ __module__ __qualname__ __slots__r$r r#r#sIr)r#ceZdZUdZdZded<eZiZded<gZded<d gZ e d Z e d Z e d Zd ZdZdZfdZdZdZdddZeZdZddZxZS)Tokena Base class for the AST types. Explanation =========== Defining fields are set in ``_fields``. Attributes (defined in _fields) are only allowed to contain instances of Basic (unless atomic, see ``String``). The arguments to ``__new__()`` correspond to the attributes in the order defined in ``_fields`. The ``defaults`` class attribute is a dictionary mapping attribute names to their default values. Subclasses should not need to override the ``__new__()`` method. They may define a class or static method named ``_construct_`` for each attribute to process the value passed to ``__new__()``. Attributes listed in the class attribute ``not_in_args`` are not passed to :class:`~.Basic`. r$tuple[str, ...]r(dict[str, Any]defaultsz list[str] not_in_argsbodyc2t|jdk(SNr)len_fieldsselfs r is_Atomz Token.is_Atoms4<< A%%r)c$t|d|zdS)z8 Get the constructor function for an attribute by name. z _construct_%sc|SNr$)xs r z(Token._get_constructor..sar))getattr)clsattrs r _get_constructorzToken._get_constructorssOd2K@@r)c|dk(r |jj|tSt|tr|S|j ||S)zE Construct an attribute value from argument passed to ``__new__()``. N)r.getnonerr r@)r>r?rs r _constructzToken._constructsI $;<<##D$/ /#u% 1s++D1#66r)ct|dk(r|st|d|r|dSt|t|jkDr,tdt|t|jfzg}t |j|D]8\}}||vrt d|z|j |j||:|jt|dD]e}||vr|j|}n,||jvr|j|}nt d|z|j |j||g|rtddj|zt |j|Dcgc]\}}||jvr|}}}tj|g|} t |j|D]\}} t| || | Scc}}w)Nrz,Too many arguments (%d), expected at most %dz$Got multiple values for attribute %rz2No value for %r given and attribute has no defaultzUnknown keyword arguments: %s )r3rr4 ValueErrorzip TypeErrorappendrDpopr.joinr/r#__new__setattr) r>rkwargsattrvalsattrnameargvalr?val basic_argsobjrs r rNz Token.__new__s t9>&ZQ-E7N t9s3;;' 'KsSWyZ]^a^i^iZjNkkl l!$CKK 6 > Hf6! F QRR OOCNN8V< =  > CIJ/ >H6!H-S\\)h/ TW_ _`` OOCNN8V< = > ._printsT#u%%w~~cWDWa9LWPVWW%w~~c;D;F;;r)z( rGre)rFz({0},)z({0})) _contextrr rjrMrrgr3format) r6rprhvrrPrnrjoinedros ``` `` @r _indentedzToken._indenteds   n - < < a \\!R(--aff.Msvc{.MNFD&&&s2v~.6b1fEKK$'K1$4II&QQ'II&QQ!9  /NsCrf)rmcddlm}|jdd}|jDcgc]}t ||}}|j jdd} g} t t|j|D]\} \} } | |vr| |jvr| |j| k(r/| |jvr| dznd}|||5|j|| | g|i|}ddd| j| dk(rdnd j| jd j|jj|j!| Scc}w#1swY{xYw) Nr)printer_contextexcluder$rirq)riz{1}z{0}={1}z{}({}))sympy.printing.printerryrBr4r=rs enumeraterIr.rgrwrKrtlstriprXr%rM)r6rprmrrPryrzrhvaluesri arg_reprsir?valueilvlindenteds r _sympyreprzToken._sympyrepr%sT:**Y+,0LL9q'$"99''++NA>  )#dllF*C D _ A}ewt}}$$--2E)E'+t/A/A'A>'4PPP Q   qAve9DDT8??K\] ^ _t~~66 I8NOO%: Q QsEEE# cddlm}||S)Nr)srepr)sympy.printingr)r6rs r __repr__zToken.__repr__>s(T{r)c|jDcic]}||vs|t||}}|*|jDcic]\}}|||c}}S|Scc}wcc}}w)a  Get instance's attributes as dict of keyword arguments. Parameters ========== exclude : collection of str Collection of keywords to exclude. apply : callable, optional Function to apply to all values. )r4r=items)r6rzapplyrhrPrus r rPz Token.kwargsBse04||P!q?O!WT1%%PP  ,2LLN;DAqAuQxK; ;M Q;s AAAr$N)r%r&r'__doc__r(__annotations__r4r.r/rgpropertyr7 classmethodr@rDrNrZr]rarjrwr _sympystrrrP __classcell__rXs@r r+r+s""$I#G!Hn!KHM &&AA 7 7,\E"O"15P.Ir)r+ceZdZdZy) BreakTokenaD Represents 'break' in C/Python ('exit' in Fortran). Use the premade instance ``break_`` or instantiate manually. Examples ======== >>> from sympy import ccode, fcode >>> from sympy.codegen.ast import break_ >>> ccode(break_) 'break' >>> fcode(break_, source_format='free') 'exit' Nr%r&r'rr$r)r rrT r)rceZdZdZy) ContinueTokenaW Represents 'continue' in C/Python ('cycle' in Fortran) Use the premade instance ``continue_`` or instantiate manually. Examples ======== >>> from sympy import ccode, fcode >>> from sympy.codegen.ast import continue_ >>> ccode(continue_) 'continue' >>> fcode(continue_, source_format='free') 'cycle' Nrr$r)r rrgrr)rc.eZdZdZdZdZfdZxZS) NoneTokena0 The AST equivalence of Python's NoneType The corresponding instance of Python's ``None`` is ``none``. Examples ======== >>> from sympy.codegen.ast import none, Variable >>> from sympy import pycode >>> print(pycode(Variable('x').as_Declaration(value=none))) x = None c.|duxst|tSr:)rrr6rYs r rZzNoneToken.__eq__s}< 5) <rrrrrr assignable lhs_is_mat rhs_is_mats r rzAssignmentBase._check_argss  )0?lM7GX #z*>cJK K S'*K:c73K/K S'*K:c73K/K   !FGGcii' !JKK(  BC C!+Zr)) r%r&r'rrNrrrrrrrs@r rrsK.DDr)rceZdZdZdZy) Assignmentam Represents variable assignment for code generation. Parameters ========== lhs : Expr SymPy object representing the lhs of the expression. These should be singular objects, such as one would use in writing code. Notable types include Symbol, MatrixSymbol, MatrixElement, and Indexed. Types that subclass these types are also supported. rhs : Expr SymPy object representing the rhs of the expression. This can be any type, provided its shape corresponds to that of the lhs. For example, a Matrix type can be assigned to MatrixSymbol, but not to Symbol, as the dimensions will not align. Examples ======== >>> from sympy import symbols, MatrixSymbol, Matrix >>> from sympy.codegen.ast import Assignment >>> x, y, z = symbols('x, y, z') >>> Assignment(x, y) Assignment(x, y) >>> Assignment(x, 0) Assignment(x, 0) >>> A = MatrixSymbol('A', 1, 3) >>> mat = Matrix([x, y, z]).T >>> Assignment(A, mat) Assignment(A, Matrix([[x, y, z]])) >>> Assignment(A[0, 1], x) Assignment(A[0, 1], x) z:=N)r%r&r'ropr$r)r rrs"H Br)rc,eZdZUdZded<edZy)AugmentedAssignmentz Base class for augmented assignments. Attributes: =========== binop : str Symbol for binary operation being applied in the assignment, such as "+", "*", etc. z str | Nonebinopc |jdzS)N=)rr5s r rzAugmentedAssignment.opszzCr)N)r%r&r'rrrrr$r)r rrs!     r)rceZdZdZy)AddAugmentedAssignment+Nr%r&r'rr$r)r rr  Er)rceZdZdZy)SubAugmentedAssignment-Nrr$r)r rr rr)rceZdZdZy)MulAugmentedAssignment*Nrr$r)r rrrr)rceZdZdZy)DivAugmentedAssignment/Nrr$r)r rrrr)rceZdZdZy)ModAugmentedAssignment%Nrr$r)r rrrr)rcL|tvrtd|zt|||S)ao Create 'lhs op= rhs'. Explanation =========== Represents augmented variable assignment for code generation. This is a convenience function. You can also use the AugmentedAssignment classes directly, like AddAugmentedAssignment(x, y). Parameters ========== lhs : Expr SymPy object representing the lhs of the expression. These should be singular objects, such as one would use in writing code. Notable types include Symbol, MatrixSymbol, MatrixElement, and Indexed. Types that subclass these types are also supported. op : str Operator (+, -, /, \*, %). rhs : Expr SymPy object representing the rhs of the expression. This can be any type, provided its shape corresponds to that of the lhs. For example, a Matrix type can be assigned to MatrixSymbol, but not to Symbol, as the dimensions will not align. Examples ======== >>> from sympy import symbols >>> from sympy.codegen.ast import aug_assign >>> x, y = symbols('x, y') >>> aug_assign(x, '+', y) AddAugmentedAssignment(x, y) zUnrecognized operator %s)augassign_classesrH)rrrs r aug_assignr&s1L ""3b899 R c **r)c^eZdZdZdZdZdZeZefdZ e dZ ddZ xZ S) CodeBlocka_ Represents a block of code. Explanation =========== For now only assignments are supported. This restriction will be lifted in the future. Useful attributes on this object are: ``left_hand_sides``: Tuple of left-hand sides of assignments, in order. ``left_hand_sides``: Tuple of right-hand sides of assignments, in order. ``free_symbols``: Free symbols of the expressions in the right-hand sides which do not appear in the left-hand side of an assignment. Useful methods on this object are: ``topological_sort``: Class method. Return a CodeBlock with assignments sorted so that variables are assigned before they are used. ``cse``: Return a new CodeBlock with common subexpressions eliminated and pulled out as assignments. Examples ======== >>> from sympy import symbols, ccode >>> from sympy.codegen.ast import CodeBlock, Assignment >>> x, y = symbols('x y') >>> c = CodeBlock(Assignment(x, 1), Assignment(y, x + 1)) >>> print(ccode(c)) x = 1; y = x + 1; cg}g}|D]D}t|ts|j\}}|j||j|Ft j |g|}t ||_t ||_|Sr:) rrrrKr#rNr left_hand_sidesright_hand_sides)r>rrrrrrrVs r rNzCodeBlock.__new__zs -A!Z(66S&&s+ '',  -   ,t,#_5$&67 r)c,t|jSr:)iterrr5s r __iter__zCodeBlock.__iter__sDIIr)c4|jjdd}dd|zz}|jt|j|j }dj d|dz z|jjzd|zz|zdzd|dz zzdzS) NrirrerGz{}( rq rr) rsrBrMmaprnrrtrXr%)r6rprrPrormrvs r rzCodeBlock._sympyreprs    ! !.! 4RS;<sBqDzDNN,C,CCEB "&'),b1f68;< =r)cDt|t|jz Sr:)r` free_symbolssetrrbs r rzCodeBlock.free_symbolssw#c$*>*>&???r)ctd|Ds tdtd|Dr tdtt |}t t}|D]%}|\}}||j j|'g}|D]?}|\}}|jjD]} || D]} |j| |f!At||g} || Dcgc]\}}| c}}Scc}}w)a Return a CodeBlock with topologically sorted assignments so that variables are assigned before they are used. Examples ======== The existing order of assignments is preserved as much as possible. This function assumes that variables are assigned to only once. This is a class constructor so that the default constructor for CodeBlock can error when variables are used before they are assigned. >>> from sympy import symbols >>> from sympy.codegen.ast import CodeBlock, Assignment >>> x, y, z = symbols('x y z') >>> assignments = [ ... Assignment(x, y + z), ... Assignment(y, z + 1), ... Assignment(z, 2), ... ] >>> CodeBlock.topological_sort(assignments) CodeBlock( Assignment(z, 2), Assignment(y, z + 1), Assignment(x, y + z) ) c3<K|]}t|tywr:rr.0rs r z-CodeBlock.topological_sort..sB:a,Bz4CodeBlock.topological_sort only supports Assignmentsc3<K|]}t|tywr:rrrs r rz-CodeBlock.topological_sort..sGaz!01GrzFCodeBlock.topological_sort does not yet work with AugmentedAssignments) allNotImplementedErroranylistr|rrrKrrr) r> assignmentsAvar_mapnoderaEdst_nodessrc_nodeordered_assignmentss r rzCodeBlock.topological_sortsDBkBB%&\] ] G;G G%&no o( ;' (d# (DDAq AEEN ! !$ ' (  3HDAqUU'' 3 ' 3HHHh123 3 3 /1v6#6741aQ7887s" C3 cddlm}td|jDs t dt d|jDr t dt |jD]$\}}||jd|vst d|z|jt}| t}t||}|t|j|||| \} } t|j| D cgc]\} } t| | } } } | D cgc]\} } t| | }} } |j!|| zScc} } wcc} } w) a Return a new code block with common subexpressions eliminated. Explanation =========== See the docstring of :func:`sympy.simplify.cse_main.cse` for more information. Examples ======== >>> from sympy import symbols, sin >>> from sympy.codegen.ast import CodeBlock, Assignment >>> x, y, z = symbols('x y z') >>> c = CodeBlock( ... Assignment(x, 1), ... Assignment(y, sin(x) + 1), ... Assignment(z, sin(x) - 1), ... ) ... >>> c.cse() CodeBlock( Assignment(x, 1), Assignment(x0, sin(x)), Assignment(y, x0 + 1), Assignment(z, x0 - 1) ) r)csec3<K|]}t|tywr:rrs r rz CodeBlock.cse..s@:a,@rz'CodeBlock.cse only supports Assignmentsc3<K|]}t|tywr:rrs r rz CodeBlock.cse..sEaz!01Erz9CodeBlock.cse does not yet work with AugmentedAssignmentsNzEDuplicate assignments to the same variable are not yet supported (%s))symbols optimizations postprocessorder)sympy.simplify.cse_mainrrrrrr|ratomsr rrrrrIrr)r6rrrrrrrexisting_symbols replacements reduced_exprsvarexpr new_blocknew_assignmentss r rz CodeBlock.csesXB 0@dii@@%&OP P E499E E%&ab b 4 45 AFAsd**2A..)+:>> from sympy import symbols, Range >>> from sympy.codegen.ast import aug_assign, For >>> x, i, j, k = symbols('x i j k') >>> for_i = For(i, Range(10), [aug_assign(x, '+', i*j*k)]) >>> for_i # doctest: -NORMALIZE_WHITESPACE For(i, iterable=Range(0, 10, 1), body=CodeBlock( AddAugmentedAssignment(x, i*j*k) )) >>> for_ji = For(j, Range(7), [for_i]) >>> for_ji # doctest: -NORMALIZE_WHITESPACE For(j, iterable=Range(0, 7, 1), body=CodeBlock( For(i, iterable=Range(0, 10, 1), body=CodeBlock( AddAugmentedAssignment(x, i*j*k) )) )) >>> for_kji =For(k, Range(5), [for_ji]) >>> for_kji # doctest: -NORMALIZE_WHITESPACE For(k, iterable=Range(0, 5, 1), body=CodeBlock( For(j, iterable=Range(0, 7, 1), body=CodeBlock( For(i, iterable=Range(0, 10, 1), body=CodeBlock( AddAugmentedAssignment(x, i*j*k) )) )) )) )targetrr0c6t|tr|St|Sr:rrr>itrs r _construct_bodyzFor._construct_bodyX c9 %Jc? "r)czt|s tdt|tr t |}t |S)Nziterable must be an iterable)rrJrrr\rrs r _construct_iterablezFor._construct_iterable_s2}:; ; c4 *C}r)N) r%r&r'rr(r4 staticmethodr_construct_targetrrrr$r)r rr*sE)T98I$X.## r)rcVeZdZdZdxZZdgZdZedZ dZ d dZ e d Z d Zy) rao SymPy object representing a string. Atomic object which is not an expression (as opposed to Symbol). Parameters ========== text : str Examples ======== >>> from sympy.codegen.ast import String >>> f = String('foo') >>> f foo >>> str(f) 'foo' >>> f.text 'foo' >>> print(repr(f)) String('foo') textrTc<t|ts td|S)Nz#Argument text is not a string type.)rrrJ)r>rs r _construct_textzString._construct_texts$$AB B r)c|jSr:rr6rprrPs r rzString._sympystrs yyr)NciSr:r$)r6rzrs r rPz String.kwargss r)cfdS)NcSr:r$r5sr r<zString.func..str)r$r5s`r funcz String.funcs r)cPddlm}dj||jS)Nr latex_escapez\texttt{{"{}"}})sympy.printing.latexr'rtr)r6rpr's r _latexz String._latexs5!((dii)@AAr)r)r%r&r'rr(r4r/r7rrrrPrr$r)r$r)r rrhsU0$#I(KG Br)rceZdZdZy) QuotedStringz: Represents a string which should be printed with quotes. Nrr$r)r r+r+sDr)r+ceZdZdZy)Commentz Represents a comment. Nrr$r)r r-r-s!r)r-cVeZdZUdZdZded<eZdeiZded<e e Z dZ y ) Nodea| Subclass of Token, carrying the attribute 'attrs' (Tuple) Examples ======== >>> from sympy.codegen.ast import Node, value_const, pointer_const >>> n1 = Node([value_const]) >>> n1.attr_params('value_const') # get the parameters of attribute (by name) () >>> from sympy.codegen.fnodes import dimension >>> n2 = Node([value_const, dimension(5, 3)]) >>> n2.attr_params(value_const) # get the parameters of attribute (by Attribute instance) () >>> n2.attr_params('dimension') # get the parameters of attribute (by name) (5, 3) >>> n2.attr_params(pointer_const) is None True )attrsr,r(r0r-r.c|jD]1}t|jt|k(s%|jcSy)zQ Returns the parameters of the Attribute with name ``looking_for`` in self.attrs N)r0rname parameters)r6 looking_forr?s r attr_paramszNode.attr_paramss4JJ 'D499~[!11& 'r)N) r%r&r'rr(rr4r r.rr!_construct_attrsr5r$r)r r/r/s9(",I+G '1Hn1#I.'r)r/cReZdZUdZdZded<eZeZdZ e dZ dZ d d Z d Zy) Typea Represents a type. Explanation =========== The naming is a super-set of NumPy naming. Type has a classmethod ``from_expr`` which offer type deduction. It also has a method ``cast_check`` which casts the argument to its type, possibly raising an exception if rounding error is not within tolerances, or if the value is not representable by the underlying data type (e.g. unsigned integers). Parameters ========== name : str Name of the type, e.g. ``object``, ``int16``, ``float16`` (where the latter two would use the ``Type`` sub-classes ``IntType`` and ``FloatType`` respectively). If a ``Type`` instance is given, the said instance is returned. Examples ======== >>> from sympy.codegen.ast import Type >>> t = Type.from_expr(42) >>> t integer >>> print(repr(t)) IntBaseType(String('integer')) >>> from sympy.codegen.ast import uint8 >>> uint8.cast_check(-1) # doctest: +ELLIPSIS Traceback (most recent call last): ... ValueError: Minimum value for data type bigger than new value. >>> from sympy.codegen.ast import float32 >>> v6 = 0.123456 >>> float32.cast_check(v6) 0.123456 >>> v10 = 12345.67894 >>> float32.cast_check(v10) # doctest: +ELLIPSIS Traceback (most recent call last): ... ValueError: Casting gives a significantly different value. >>> boost_mp50 = Type('boost::multiprecision::cpp_dec_float_50') >>> from sympy import cxxcode >>> from sympy.codegen.ast import Declaration, Variable >>> cxxcode(Declaration(Variable('x', type=boost_mp50))) 'boost::multiprecision::cpp_dec_float_50 x' References ========== .. [1] https://numpy.org/doc/stable/user/basics.types.html r2r,r(c,t|jSr:)rr2r s r rzType._sympystrs499~r)cTt|ttfrtSt|tt fs t |ddrtSt |ddrtSt|ts t |ddrtSt|ts t |ddrtStd)a Deduces type from an expression or a ``Symbol``. Parameters ========== expr : number or SymPy object The type will be deduced from type or properties. Examples ======== >>> from sympy.codegen.ast import Type, integer, complex_ >>> Type.from_expr(2) == integer True >>> from sympy import Symbol >>> Type.from_expr(Symbol('z', complex=True)) == complex_ True >>> Type.from_expr(sum) # doctest: +ELLIPSIS Traceback (most recent call last): ... ValueError: Could not deduce type from expr. Raises ====== ValueError when type deduction fails. is_integerFis_real is_complex is_Relationalz Could not deduce type from expr.) rfloatrrealintrr=integercomplexcomplex_boolbool_rH)r>r s r from_exprzType.from_exprs< dUEN +K dS'N +wt\5/QN 4E *K dG $lE(JO dD !WT?E%JL?@ @r)cyr:r$r6rs r _checkz Type._check-s r)Nct|}td}t|dd} |dnd|| zzfd}|j|} |j | | |z } t | ||kDr t d| S)a[ Casts a value to the data type of the instance. Parameters ========== value : number rtol : floating point number Relative tolerance. (will be deduced if not given). atol : floating point number Absolute tolerance (in addition to ``rtol``). type_aliases : dict Maps substitutions for Type, e.g. {integer: int64, real: float32} Examples ======== >>> from sympy.codegen.ast import integer, float32, int8 >>> integer.cast_check(3.0) == 3 True >>> float32.cast_check(1e-40) # doctest: +ELLIPSIS Traceback (most recent call last): ... ValueError: Minimum value for data type bigger than new value. >>> int8.cast_check(256) # doctest: +ELLIPSIS Traceback (most recent call last): ... ValueError: Maximum value for data type smaller than new value. >>> v10 = 12345.67894 >>> float32.cast_check(v10) # doctest: +ELLIPSIS Traceback (most recent call last): ... ValueError: Casting gives a significantly different value. >>> from sympy.codegen.ast import float64 >>> float64.cast_check(v10) 12345.67894 >>> from sympy import Float >>> v18 = Float('0.123456789012345646') >>> float64.cast_check(v18) Traceback (most recent call last): ... ValueError: Casting gives a significantly different value. >>> from sympy.codegen.ast import float80 >>> float80.cast_check(v18) 0.123456789012345649 decimal_digNgV瞯.tolgs$s3x-' 'r)z.Casting gives a significantly different value.)rrr= cast_nocheckrKrPrH) r6rrSrRprecision_targetsrTtenexp10rTnew_valdeltas `` r cast_checkzType.cast_check0s^enbkmT2 <!M5s3%=/@D (##E* G#  u:C MN Nr)cddlm}||jj}||jj }dj ||S)Nrr&z%\text{{{}}}\left(\texttt{{{}}}\right))r(r'rXr%r2rrt)r6rpr' type_namer2s r r)z Type._latexss>5 !8!89 DIINN+7>>y$OOr))NrN)r%r&r'rr(rr4r_construct_namerrrHrKr[r)r$r)r r8r8sL5l"+I*GO(A(AT AFPr)r8ceZdZdZdZdZy) IntBaseTypez2 Integer base type, contains no size information. r$c*tt|Sr:)rrB)r6rs r r<zIntBaseType.}s73q6?r)N)r%r&r'rr(rUr$r)r r`r`zs<I2Lr)r`c8eZdZdZej ezZeZdZy) _SizedIntTypenbitsc||jkrtd||jfz||jkDrtd||jfzy)NValue is too small: %d < %dValue is too big: %d > %d)minrHmaxrJs r rKz_SizedIntType._checksS 488 :eTXX=NNO O 488 8E488;LLM M r)N) r%r&r'r(r8r4r_construct_nbitsrKr$r)r rcrcs!IllY&GNr)rcc4eZdZdZdZedZedZy) SignedIntTypez# Represents a signed integer type. r$c(d|jdz z SNrFrdr5s r rizSignedIntType.minsDJJqL!!!r)c,d|jdz zdz Srordr5s r rjzSignedIntType.maxs4::a< 1$$r)Nr%r&r'rr(rrirjr$r)r rmrms0-I ""%%r)rmc4eZdZdZdZedZedZy)UnsignedIntTypez& Represents an unsigned integer type. r$cyr2r$r5s r rizUnsignedIntType.minsr)c&d|jzdz Srordr5s r rjzUnsignedIntType.maxs$**}q  r)Nrrr$r)r rtrts00I !!r)rtrpceZdZdZdZeZy) FloatBaseTypez* Represents a floating point number type. r$N)r%r&r'rr(rrUr$r)r rxrxs4ILr)rxceZdZdZdZej ezZexZxZ Z e dZ e dZ e dZe dZe dZe dZe d Zd Zd Zy ) FloatTypea Represents a floating point type with fixed bit width. Base 2 & one sign bit is assumed. Parameters ========== name : str Name of the type. nbits : integer Number of bits used (storage). nmant : integer Number of bits used to represent the mantissa. nexp : integer Number of bits used to represent the mantissa. Examples ======== >>> from sympy import S >>> from sympy.codegen.ast import FloatType >>> half_precision = FloatType('f16', nbits=16, nmant=10, nexp=5) >>> half_precision.max 65504 >>> half_precision.tiny == S(2)**-14 True >>> half_precision.eps == S(2)**-10 True >>> half_precision.dig == 3 True >>> half_precision.decimal_dig == 5 True >>> half_precision.cast_check(1.0) 1.0 >>> half_precision.cast_check(1e5) # doctest: +ELLIPSIS Traceback (most recent call last): ... ValueError: Maximum value for data type smaller than new value. )renmantnexpc.t|jdz zS)zV The largest positive number n, such that 2**(n - 1) is a representable finite value. rF)twor|r5s r max_exponentzFloatType.max_exponentsTYY]##r)c d|jz S)zR The lowest negative number n, such that 2**(n - 1) is a valid normalized number. )rr5s r min_exponentzFloatType.min_exponents4$$$$r)c^dt|jdz zz t|jzzS)z Maximum value representable. rF)r~r{rr5s r rjz FloatType.maxs.C4::a<((#t/@/@*@@@r)c.t|jdz zS)z( The minimum positive normalized value. rF)r~rr5s r tinyzFloatType.tinys T&&*++r)c*t|j zS)z: Difference between 1.0 and the next representable value. )r~r{r5s r epsz FloatType.epssdjj[!!r)cZddlm}m}||j|dz|dz S)z Number of decimal digits that are guaranteed to be preserved in text. When converting text -> float -> text, you are guaranteed that at least ``dig`` number of digits are preserved with respect to rounding or overflow. r)floorlogrprM)sympy.functionsrrr{)r6rrs r digz FloatType.digs( /TZZ#a&(R011r)cfddlm}m}||jdz|dz|dz dzS)a} Number of digits needed to store & load without loss. Explanation =========== Number of decimal digits needed to guarantee that two consecutive conversions (float -> text -> float) to be idempotent. This is useful when one do not want to loose precision due to rounding errors when storing a floating point value as text. r)ceilingrrFrprM)rrrr{)r6rrs r rNzFloatType.decimal_digs1 1 Q#a&0R81<==r)c|tk(rttS|t k(rtt Sttt |j |j |j S)7 Casts without checking if out of bounds or subnormal. )rr@rrrevalfrNrJs r rUzFloatType.cast_nochecksU B;9  rc\": S--d.>.>?@$BRBRSSr)c||j krtd||j fz||jkDrtd||jfzt||jkr tdy)Nrgrhz>Smallest (absolute) value for data type bigger than new value.)rjrHrPrrJs r rKzFloatType._checkss DHH9 :edhhY=OOP P 488 8E488;LLM M u: !]^ ^ "r)N)r%r&r'rr(r8r4rrk_construct_nmant_construct_nexprrrrjrrrrNrUrKr$r)r rzrzs&P,IllY&G >T_r)rzc,eZdZdZfdZfdZxZS)ComplexBaseTyper$cpddlm}m}t|||t|||dzzS)rrreimy?)rrrr`rUr6rrrrXs r rUzComplexBaseType.cast_nocheck&s7* G E + G E +B . / r)cjddlm}m}t|||t|||y)Nrr)rrrr`rKrs r rKzComplexBaseType._check.s&* r%y! r%y!r))r%r&r'r(rUrKrrs@r rr"sI ""r)rceZdZdZdZy) ComplexTypez- Represents a complex floating point number. r$N)r%r&r'rr(r$r)r rr4s 7Ir)rintcintpint8int16int32 int64@uint8uint16uint32uint64float16rM)r|r{float32float64 4float80P?float128pfloat256re)r2rerzuntypedrArCrDrFcDeZdZdZdxZZdeiZeZ e e Z dZ y) Attributea Attribute (possibly parametrized) For use with :class:`sympy.codegen.ast.Node` (which takes instances of ``Attribute`` as ``attrs``). Parameters ========== name : str parameters : Tuple Examples ======== >>> from sympy.codegen.ast import Attribute >>> volatile = Attribute('volatile') >>> volatile volatile >>> print(repr(volatile)) Attribute(String('volatile')) >>> a = Attribute('foo', [1, 2, 3]) >>> a foo(1, 2, 3) >>> a.parameters == (1, 2, 3) True )r2r3r3ct|j}|jr,|ddjfd|jDzz }|S)Nz(%s)rfc3JK|]}j|giywr:)rn)rrrrPrps r rz&Attribute._sympystr..zs9*B*-+9'..+&+&$+&*Bs #)rr2r3rM)r6rprrPresults ``` r rzAttribute._sympystrwsNTYY ?? ftyy*B15*B CC CF r)N)r%r&r'rr(r4r r.rr^rr!_construct_parametersrr$r)r rrVs4410Ieg&HO(3r)r value_const pointer_constceZdZdZdZeej zZejjZeje e de e Ze e ZededfdZdZdZd Zd Zd Zd Zy) ra Represents a variable. Parameters ========== symbol : Symbol type : Type (optional) Type of the variable. attrs : iterable of Attribute instances Will be stored as a Tuple. Examples ======== >>> from sympy import Symbol >>> from sympy.codegen.ast import Variable, float32, integer >>> x = Symbol('x') >>> v = Variable(x, type=float32) >>> v.attrs () >>> v == Variable('x') False >>> v == Variable('x', type=float32) True >>> v Variable(x, type=float32) One may also construct a ``Variable`` instance with the type deduced from assumptions about the symbol using the ``deduced`` classmethod: >>> i = Symbol('i', integer=True) >>> v = Variable.deduced(i) >>> v.type == integer True >>> v == Variable('i') False >>> from sympy.codegen.ast import value_const >>> value_const in v.attrs False >>> w = Variable('w', attrs=[value_const]) >>> w Variable(w, attrs=(value_const,)) >>> value_const in w.attrs True >>> w.as_Declaration(value=42) Declaration(Variable(w, value=42, attrs=(value_const,))) )symbolrr)rrNTct|tr|S tj|}||r|j |}|||||S#t$rtj|}YAwxYw)a` Alt. constructor with type deduction from ``Type.from_expr``. Deduces type primarily from ``symbol``, secondarily from ``value``. Parameters ========== symbol : Symbol value : expr (optional) value of the variable. attrs : iterable of Attribute instances cast_check : bool Whether to apply ``Type.cast_check`` on ``value``. Examples ======== >>> from sympy import Symbol >>> from sympy.codegen.ast import Variable, complex_ >>> n = Symbol('n', integer=True) >>> str(Variable.deduced(n).type) 'integer' >>> x = Symbol('x', real=True) >>> v = Variable.deduced(x) >>> v.type real >>> z = Symbol('z', complex=True) >>> Variable.deduced(z).type == complex_ True )rrr0)rrr8rHrHr[)r>rrr0r[type_s r deducedzVariable.deducedsqB fh 'M *NN6*E  $$U+E6U%@@  *NN5)E *sA A+*A+c z|j}|j|t|jdi|S)aV Convenience method for creating a Declaration instance. Explanation =========== If the variable of the Declaration need to wrap a modified variable keyword arguments may be passed (overriding e.g. the ``value`` of the Variable instance). Examples ======== >>> from sympy.codegen.ast import Variable, NoneToken >>> x = Variable('x') >>> decl1 = x.as_Declaration() >>> # value is special NoneToken() which must be tested with == operator >>> decl1.variable.value is None # won't work False >>> decl1.variable.value == None # not PEP-8 compliant True >>> decl1.variable.value == NoneToken() # OK True >>> decl2 = x.as_Declaration(value=42.0) >>> decl2.variable.value == 42.0 True r$)rPupdate Declarationr$)r6rPkws r as_DeclarationzVariable.as_Declarations28[[] &9499?r?++r)cl t|}|||dS#t$rtd|d|wxYw)NzInvalid comparison z < F)evaluate)rrrJ)r6rrs r _relationzVariable._relation sE H3-C$e,, HD#FG G Hs 3c.|j|tSr:)rr rs r r<zVariable.r!:r)c.|j|tSr:)rrrs r r<zVariable.rr)c.|j|tSr:)rrrs r r<zVariable.rr)c.|j|tSr:)rrrs r r<zVariable.rr))r%r&r'rr(r/r4r.copyrrrCrr_construct_symbol_construct_valuerr rrr__lt____le____ge____gt__r$r)r rrs/b,I$,,&G}}!!#H OOWt45$W-#G,#'uw4*A*AX,@-;F :F :F :Fr)rceZdZdZdZdZy)Pointera2 Represents a pointer. See ``Variable``. Examples ======== Can create instances of ``Element``: >>> from sympy import Symbol >>> from sympy.codegen.ast import Pointer >>> i = Symbol('i', integer=True) >>> p = Pointer('x') >>> p[i+1] Element(x, indices=(i + 1,)) r$c| t|j|S#t$rt|j|fcYSwxYwr:)rrrJ)r6keys r __getitem__zPointer.__getitem__(s: 04;;, , 04;;/ / 0s  ;;N)r%r&r'rr(rr$r)r rrsI0r)rcfeZdZdZdxZZeedZee Z edZ edZ ee Z y)ra Element in (a possibly N-dimensional) array. Examples ======== >>> from sympy.codegen.ast import Element >>> elem = Element('x', 'ijk') >>> elem.symbol.name == 'x' True >>> elem.indices (i, j, k) >>> from sympy import ccode >>> ccode(elem) 'x[i][j][k]' >>> ccode(Element('x', 'ijk', strides='lmn', offset='o')) 'x[i*l + j*m + k*n + o]' )rindicesstridesoffset)rrct|Sr:r rs r r<zElement.E %+r)ct|Sr:rrs r r<zElement.Frr)N)r%r&r'rr(r4rCr.rrr_construct_indices_construct_strides_construct_offsetr$r)r rr/sL$EDI40H$W-%&=>%&=>$W-r)rceZdZdZdxZZeZy)ra Represents a variable declaration Parameters ========== variable : Variable Examples ======== >>> from sympy.codegen.ast import Declaration, NoneToken, untyped >>> z = Declaration('z') >>> z.variable.type == untyped True >>> # value is special NoneToken() which must be tested with == operator >>> z.variable.value is None # won't work False >>> z.variable.value == None # not PEP-8 compliant True >>> z.variable.value == NoneToken() # OK True )variableN)r%r&r'rr(r4r_construct_variabler$r)r rrJs,('I"r)rc:eZdZdZdxZZedZedZ y)Whilea} Represents a 'for-loop' in the code. Expressions are of the form: "while condition: body..." Parameters ========== condition : expression convertible to Boolean body : CodeBlock or iterable When passed an iterable it is used to instantiate a CodeBlock. Examples ======== >>> from sympy import symbols, Gt, Abs >>> from sympy.codegen import aug_assign, Assignment, While >>> x, dx = symbols('x dx') >>> expr = 1 - x**2 >>> whl = While(Gt(Abs(dx), 1e-9), [ ... Assignment(dx, -expr/expr.diff(x)), ... aug_assign(x, '+', dx) ... ]) ) conditionr0ct|Sr:)r)conds r r<zWhile.s Xd^r)c6t|tr|St|Sr:rrs r rzWhile._construct_bodyrr)N) r%r&r'rr(r4r_construct_conditionrrr$r)r rres140/I'(CD##r)rc(eZdZdZdxZZedZy)Scopez Represents a scope in the code. Parameters ========== body : CodeBlock or iterable When passed an iterable it is used to instantiate a CodeBlock. r0c6t|tr|St|Sr:rrs r rzScope._construct_bodyrr)N)r%r&r'rr(r4rrr$r)r rrs%$#I##r)rceZdZdZdxZZeZy)Streama Represents a stream. There are two predefined Stream instances ``stdout`` & ``stderr``. Parameters ========== name : str Examples ======== >>> from sympy import pycode, Symbol >>> from sympy.codegen.ast import Print, stderr, QuotedString >>> print(pycode(Print(['x'], file=stderr))) print(x, file=sys.stderr) >>> x = Symbol('x') >>> print(pycode(Print([QuotedString('x')], file=stderr))) # print literally "x" print("x", file=sys.stderr) r9N)r%r&r'rr(r4rr^r$r)r rrs*$#IOr)rstdoutstderrc:eZdZdZdxZZeedZee Z e Z e Zy)Printa Represents print command in the code. Parameters ========== formatstring : str *args : Basic instances (or convertible to such through sympify) Examples ======== >>> from sympy.codegen.ast import Print >>> from sympy import pycode >>> print(pycode(Print('x y'.split(), "coordinate: %12.5g %12.5g\\n"))) print("coordinate: %12.5g %12.5g\n" % (x, y), end="") ) print_args format_stringfile)rr N)r%r&r'rr(r4rCr.rr!_construct_print_argsr+_construct_format_stringr_construct_filer$r)r rrs4$BAI!%t4H(3+Or)rcfeZdZUdZdZeej zZded<eZ e Z e dZ edZy)FunctionPrototypea" Represents a function prototype Allows the user to generate forward declaration in e.g. C/C++. Parameters ========== return_type : Type name : str parameters: iterable of Variable instances attrs : iterable of Attribute instances Examples ======== >>> from sympy import ccode, symbols >>> from sympy.codegen.ast import real, FunctionPrototype >>> x, y = symbols('x y', real=True) >>> fp = FunctionPrototype(real, 'foo', [x, y]) >>> ccode(fp) 'double foo(double x, double y)' ) return_typer2r3r,r4c,d}tt||S)Nct|tr |jSt|tr|Stj |Sr:)rrrrrrs r _varz5FunctionPrototype._construct_parameters.._vars6#{+||#C* '',,r))r r)rrs r rz'FunctionPrototype._construct_parameterss -c$o&&r)cht|ts td|di|jdS)Nz1func_def is not an instance of FunctionDefinitionrrr$)rFunctionDefinitionrJrP)r>func_defs r from_FunctionDefinitionz)FunctionPrototype.from_FunctionDefinitions2($67OP P8X__Y_788r)N)r%r&r'rr(r/r4rr8_construct_return_typerr^rrrrr$r)r rrsR06I(4<<7G_7!O''99r)rcreZdZdZdZej ddezej zZedZ edZ y)ra Represents a function definition in the code. Parameters ========== return_type : Type name : str parameters: iterable of Variable instances body : CodeBlock or iterable attrs : iterable of Attribute instances Examples ======== >>> from sympy import ccode, symbols >>> from sympy.codegen.ast import real, FunctionPrototype >>> x, y = symbols('x y', real=True) >>> fp = FunctionPrototype(real, 'foo', [x, y]) >>> ccode(fp) 'double foo(double x, double y)' >>> from sympy.codegen.ast import FunctionDefinition, Return >>> body = [Return(x*y)] >>> fd = FunctionDefinition.from_FunctionPrototype(fp, body) >>> print(ccode(fd)) double foo(double x, double y){ return x*y; } rNc6t|tr|St|Sr:rrs r rz"FunctionDefinition._construct_body)rr)cht|ts td|dd|i|jS)Nz2func_proto is not an instance of FunctionPrototyper0r$)rrrJrP)r> func_protor0s r from_FunctionPrototypez)FunctionDefinition.from_FunctionPrototype0s5*&78PQ Q44 1 1 344r)) r%r&r'rr(rr4r/rrrr$r)r rrsT:I'',y84<<GG## 55r)rc(eZdZdZdxZZeeZy)ReturnaC Represents a return command in the code. Parameters ========== return : Basic Examples ======== >>> from sympy.codegen.ast import Return >>> from sympy.printing.pycode import pycode >>> from sympy import Symbol >>> x = Symbol('x') >>> print(pycode(Return(x))) return x )returnN) r%r&r'rr(r4rr_construct_returnr$r)r rr7s$&%I"8,r)rc.eZdZdZdxZZeZedZ y) FunctionCallaR Represents a call to a function in the code. Parameters ========== name : str function_args : Tuple Examples ======== >>> from sympy.codegen.ast import FunctionCall >>> from sympy import pycode >>> fcall = FunctionCall('foo', 'bar baz'.split()) >>> print(pycode(fcall)) foo(bar, baz) )r2 function_argsct|Sr:rrs r r<zFunctionCall.ds r)N) r%r&r'rr(r4rr^r_construct_function_argsr$r)r r#r#Ns$$43IO+,EFr)r#ceZdZdZdxZZy)Raisez4 Prints as 'raise ...' in Python, 'throw ...' in C++) exceptionN)r%r&r'rr(r4r$r)r r(r(gs>((Ir)r(ceZdZdZdxZZeZy) RuntimeError_z Represents 'std::runtime_error' in C++ and 'RuntimeError' in Python. Note that the latter is uncommon, and you might want to use e.g. ValueError. )messageN)r%r&r'rr(r4r_construct_messager$r)r r+r+ls'&Ir)r+N) complex64) complex128)qr __future__rtypingr collectionsrsympy.core.relationalrrrr sympy.corer r r sympy.core.basicr sympy.core.exprrrsympy.core.numbersrrrsympy.core.sympifyrrrsympy.utilities.iterablesrrrrr!r#r+rbreak_r continue_rrCrrrrrrrrrrrrrrr+r-r/r8r`rcrmrtr~rxrzrrrrrrrrrrrrrrrrrrrPr.r/rrArCrErGrrrrrrrrrrrrrrrrr#r(r+)r>s0r r<sQ~@##22++"&11>>II(jJjX E O ""0{8DZ8Dv%%P . $00000  68N 6CIIsN(+VVB VBr;%;|0BT50BdE6E"f" '5 'FtP5tPn3$3 NK N %M % !m !ajD u_ u_n"m"$/9 66VQgr"gr"gr"# 2 & 2 & 2 & Ir 4 Ir 4 Ir" 5 Ir" 5 Z2S 9 Z2S 9  [2 [HY1Z [  ^S ^GNNK\N4] ^  y/V i  9 % V &&P & /* R;tR;h0h02.e.6#%#6##E##L#E#(U2    E6.9.9b,5*,5^-U-.G5$G2)E)  E ]*s N