Parsing#
Parsing Functions Reference#
- sympy.parsing.sympy_parser.parse_expr(s: str, local_dict: ~typing.Dict[str, ~typing.Any] | None = None, transformations: ~typing.Tuple[~typing.Callable[[~typing.List[~typing.Tuple[int, str]], ~typing.Dict[str, ~typing.Any], ~typing.Dict[str, ~typing.Any]], ~typing.List[~typing.Tuple[int, str]]], ...] | str = (<function lambda_notation>, <function auto_symbol>, <function repeated_decimals>, <function auto_number>, <function factorial_notation>), global_dict: ~typing.Dict[str, ~typing.Any] | None = None, evaluate=True)[source]#
Converts the string
s
to a SymPy expression, inlocal_dict
- Parameters:
s : str
The string to parse.
local_dict : dict, optional
A dictionary of local variables to use when parsing.
global_dict : dict, optional
A dictionary of global variables. By default, this is initialized with
from sympy import *
; provide this parameter to override this behavior (for instance, to parse"Q & S"
).transformations : tuple or str
A tuple of transformation functions used to modify the tokens of the parsed expression before evaluation. The default transformations convert numeric literals into their SymPy equivalents, convert undefined variables into SymPy symbols, and allow the use of standard mathematical factorial notation (e.g.
x!
). Selection via string is available (see below).evaluate : bool, optional
When False, the order of the arguments will remain as they were in the string and automatic simplification that would normally occur is suppressed. (see examples)
Examples
>>> from sympy.parsing.sympy_parser import parse_expr >>> parse_expr("1/2") 1/2 >>> type(_) <class 'sympy.core.numbers.Half'> >>> from sympy.parsing.sympy_parser import standard_transformations,\ ... implicit_multiplication_application >>> transformations = (standard_transformations + ... (implicit_multiplication_application,)) >>> parse_expr("2x", transformations=transformations) 2*x
When evaluate=False, some automatic simplifications will not occur:
>>> parse_expr("2**3"), parse_expr("2**3", evaluate=False) (8, 2**3)
In addition the order of the arguments will not be made canonical. This feature allows one to tell exactly how the expression was entered:
>>> a = parse_expr('1 + x', evaluate=False) >>> b = parse_expr('x + 1', evaluate=0) >>> a == b False >>> a.args (1, x) >>> b.args (x, 1)
Note, however, that when these expressions are printed they will appear the same:
>>> assert str(a) == str(b)
As a convenience, transformations can be seen by printing
transformations
:>>> from sympy.parsing.sympy_parser import transformations
>>> print(transformations) 0: lambda_notation 1: auto_symbol 2: repeated_decimals 3: auto_number 4: factorial_notation 5: implicit_multiplication_application 6: convert_xor 7: implicit_application 8: implicit_multiplication 9: convert_equals_signs 10: function_exponentiation 11: rationalize
The
T
object provides a way to select these transformations:>>> from sympy.parsing.sympy_parser import T
If you print it, you will see the same list as shown above.
>>> str(T) == str(transformations) True
Standard slicing will return a tuple of transformations:
>>> T[:5] == standard_transformations True
So
T
can be used to specify the parsing transformations:>>> parse_expr("2x", transformations=T[:5]) Traceback (most recent call last): ... SyntaxError: invalid syntax >>> parse_expr("2x", transformations=T[:6]) 2*x >>> parse_expr('.3', transformations=T[3, 11]) 3/10 >>> parse_expr('.3x', transformations=T[:]) 3*x/10
As a further convenience, strings ‘implicit’ and ‘all’ can be used to select 0-5 and all the transformations, respectively.
>>> parse_expr('.3x', transformations='all') 3*x/10
- sympy.parsing.sympy_parser.stringify_expr(s: str, local_dict: Dict[str, Any], global_dict: Dict[str, Any], transformations: Tuple[Callable[[List[Tuple[int, str]], Dict[str, Any], Dict[str, Any]], List[Tuple[int, str]]], ...]) str [source]#
Converts the string
s
to Python code, inlocal_dict
Generally,
parse_expr
should be used.
- sympy.parsing.sympy_parser.eval_expr(code, local_dict: Dict[str, Any], global_dict: Dict[str, Any])[source]#
Evaluate Python code generated by
stringify_expr
.Generally,
parse_expr
should be used.
- sympy.parsing.mathematica.parse_mathematica(s)[source]#
Translate a string containing a Wolfram Mathematica expression to a SymPy expression.
If the translator is unable to find a suitable SymPy expression, the
FullForm
of the Mathematica expression will be output, using SymPyFunction
objects as nodes of the syntax tree.Examples
>>> from sympy.parsing.mathematica import parse_mathematica >>> parse_mathematica("Sin[x]^2 Tan[y]") sin(x)**2*tan(y) >>> e = parse_mathematica("F[7,5,3]") >>> e F(7, 5, 3) >>> from sympy import Function, Max, Min >>> e.replace(Function("F"), lambda *x: Max(*x)*Min(*x)) 21
Both standard input form and Mathematica full form are supported:
>>> parse_mathematica("x*(a + b)") x*(a + b) >>> parse_mathematica("Times[x, Plus[a, b]]") x*(a + b)
To get a matrix from Wolfram’s code:
>>> m = parse_mathematica("{{a, b}, {c, d}}") >>> m ((a, b), (c, d)) >>> from sympy import Matrix >>> Matrix(m) Matrix([ [a, b], [c, d]])
If the translation into equivalent SymPy expressions fails, an SymPy expression equivalent to Wolfram Mathematica’s “FullForm” will be created:
>>> parse_mathematica("x_.") Optional(Pattern(x, Blank())) >>> parse_mathematica("Plus @@ {x, y, z}") Apply(Plus, (x, y, z)) >>> parse_mathematica("f[x_, 3] := x^3 /; x > 0") SetDelayed(f(Pattern(x, Blank()), 3), Condition(x**3, x > 0))
Parsing Transformations Reference#
A transformation is a function that accepts the arguments tokens,
local_dict, global_dict
and returns a list of transformed tokens. They can
be used by passing a list of functions to parse_expr()
and are
applied in the order given.
- sympy.parsing.sympy_parser.standard_transformations: Tuple[Callable[[List[Tuple[int, str]], Dict[str, Any], Dict[str, Any]], List[Tuple[int, str]]], ...] = (<function lambda_notation>, <function auto_symbol>, <function repeated_decimals>, <function auto_number>, <function factorial_notation>)#
Standard transformations for
parse_expr()
. Inserts calls toSymbol
,Integer
, and other SymPy datatypes and allows the use of standard factorial notation (e.g.x!
).
- sympy.parsing.sympy_parser.split_symbols(tokens: List[Tuple[int, str]], local_dict: Dict[str, Any], global_dict: Dict[str, Any])[source]#
Splits symbol names for implicit multiplication.
Intended to let expressions like
xyz
be parsed asx*y*z
. Does not split Greek character names, sotheta
will not becomet*h*e*t*a
. Generally this should be used withimplicit_multiplication
.
- sympy.parsing.sympy_parser.split_symbols_custom(predicate: Callable[[str], bool])[source]#
Creates a transformation that splits symbol names.
predicate
should return True if the symbol name is to be split.For instance, to retain the default behavior but avoid splitting certain symbol names, a predicate like this would work:
>>> from sympy.parsing.sympy_parser import (parse_expr, _token_splittable, ... standard_transformations, implicit_multiplication, ... split_symbols_custom) >>> def can_split(symbol): ... if symbol not in ('list', 'of', 'unsplittable', 'names'): ... return _token_splittable(symbol) ... return False ... >>> transformation = split_symbols_custom(can_split) >>> parse_expr('unsplittable', transformations=standard_transformations + ... (transformation, implicit_multiplication)) unsplittable
- sympy.parsing.sympy_parser.implicit_multiplication(tokens: List[Tuple[int, str]], local_dict: Dict[str, Any], global_dict: Dict[str, Any]) List[Tuple[int, str]] [source]#
Makes the multiplication operator optional in most cases.
Use this before
implicit_application()
, otherwise expressions likesin 2x
will be parsed asx * sin(2)
rather thansin(2*x)
.Examples
>>> from sympy.parsing.sympy_parser import (parse_expr, ... standard_transformations, implicit_multiplication) >>> transformations = standard_transformations + (implicit_multiplication,) >>> parse_expr('3 x y', transformations=transformations) 3*x*y
- sympy.parsing.sympy_parser.implicit_application(tokens: List[Tuple[int, str]], local_dict: Dict[str, Any], global_dict: Dict[str, Any]) List[Tuple[int, str]] [source]#
Makes parentheses optional in some cases for function calls.
Use this after
implicit_multiplication()
, otherwise expressions likesin 2x
will be parsed asx * sin(2)
rather thansin(2*x)
.Examples
>>> from sympy.parsing.sympy_parser import (parse_expr, ... standard_transformations, implicit_application) >>> transformations = standard_transformations + (implicit_application,) >>> parse_expr('cot z + csc z', transformations=transformations) cot(z) + csc(z)
- sympy.parsing.sympy_parser.function_exponentiation(tokens: List[Tuple[int, str]], local_dict: Dict[str, Any], global_dict: Dict[str, Any])[source]#
Allows functions to be exponentiated, e.g.
cos**2(x)
.Examples
>>> from sympy.parsing.sympy_parser import (parse_expr, ... standard_transformations, function_exponentiation) >>> transformations = standard_transformations + (function_exponentiation,) >>> parse_expr('sin**4(x)', transformations=transformations) sin(x)**4
- sympy.parsing.sympy_parser.implicit_multiplication_application(result: List[Tuple[int, str]], local_dict: Dict[str, Any], global_dict: Dict[str, Any]) List[Tuple[int, str]] [source]#
Allows a slightly relaxed syntax.
Parentheses for single-argument method calls are optional.
Multiplication is implicit.
Symbol names can be split (i.e. spaces are not needed between symbols).
Functions can be exponentiated.
Examples
>>> from sympy.parsing.sympy_parser import (parse_expr, ... standard_transformations, implicit_multiplication_application) >>> parse_expr("10sin**2 x**2 + 3xyz + tan theta", ... transformations=(standard_transformations + ... (implicit_multiplication_application,))) 3*x*y*z + 10*sin(x**2)**2 + tan(theta)
- sympy.parsing.sympy_parser.rationalize(tokens: List[Tuple[int, str]], local_dict: Dict[str, Any], global_dict: Dict[str, Any])[source]#
Converts floats into
Rational
. Run AFTERauto_number
.
- sympy.parsing.sympy_parser.convert_xor(tokens: List[Tuple[int, str]], local_dict: Dict[str, Any], global_dict: Dict[str, Any])[source]#
Treats XOR,
^
, as exponentiation,**
.
These are included in
sympy.parsing.sympy_parser.standard_transformations
and generally
don’t need to be manually added by the user.
- sympy.parsing.sympy_parser.lambda_notation(tokens: List[Tuple[int, str]], local_dict: Dict[str, Any], global_dict: Dict[str, Any])[source]#
Substitutes “lambda” with its SymPy equivalent Lambda(). However, the conversion does not take place if only “lambda” is passed because that is a syntax error.
- sympy.parsing.sympy_parser.auto_symbol(tokens: List[Tuple[int, str]], local_dict: Dict[str, Any], global_dict: Dict[str, Any])[source]#
Inserts calls to
Symbol
/Function
for undefined variables.
- sympy.parsing.sympy_parser.repeated_decimals(tokens: List[Tuple[int, str]], local_dict: Dict[str, Any], global_dict: Dict[str, Any])[source]#
Allows 0.2[1] notation to represent the repeated decimal 0.2111… (19/90)
Run this before auto_number.
Experimental \(\mathrm{\LaTeX}\) Parsing#
\(\mathrm{\LaTeX}\) parsing was ported from latex2sympy. While functional and its API should remain stable, the parsing behavior or backend may change in future releases.
\(\mathrm{\LaTeX}\) Parsing Caveats#
The current implementation is experimental. The behavior, parser backend and API might change in the future. Unlike some of the other parsers, \(\mathrm{\LaTeX}\) is designed as a type-setting language, not a computer algebra system and so can contain typographical conventions that might be interpreted multiple ways.
In its current definition, the parser will at times will fail to fully parse the expression, but not throw a warning:
parse_latex(r'x -')
Will simply find x
. What is covered by this behavior will almost certainly
change between releases, and become stricter, more relaxed, or some mix.
\(\mathrm{\LaTeX}\) Parsing Functions Reference#
- sympy.parsing.latex.parse_latex(s)[source]#
Converts the string
s
to a SymPyExpr
- Parameters:
s : str
The LaTeX string to parse. In Python source containing LaTeX, raw strings (denoted with
r"
, like this one) are preferred, as LaTeX makes liberal use of the\
character, which would trigger escaping in normal Python strings.
Examples
>>> from sympy.parsing.latex import parse_latex >>> expr = parse_latex(r"\frac {1 + \sqrt {\a}} {\b}") >>> expr (sqrt(a) + 1)/b >>> expr.evalf(4, subs=dict(a=5, b=2)) 1.618
\(\mathrm{\LaTeX}\) Parsing Exceptions Reference#
SymPy Expression Reference#
- class sympy.parsing.sym_expr.SymPyExpression(source_code=None, mode=None)[source]#
Class to store and handle SymPy expressions
This class will hold SymPy Expressions and handle the API for the conversion to and from different languages.
It works with the C and the Fortran Parser to generate SymPy expressions which are stored here and which can be converted to multiple language’s source code.
Notes
The module and its API are currently under development and experimental and can be changed during development.
The Fortran parser does not support numeric assignments, so all the variables have been Initialized to zero.
The module also depends on external dependencies:
LFortran which is required to use the Fortran parser
Clang which is required for the C parser
Examples
Example of parsing C code:
>>> from sympy.parsing.sym_expr import SymPyExpression >>> src = ''' ... int a,b; ... float c = 2, d =4; ... ''' >>> a = SymPyExpression(src, 'c') >>> a.return_expr() [Declaration(Variable(a, type=intc)), Declaration(Variable(b, type=intc)), Declaration(Variable(c, type=float32, value=2.0)), Declaration(Variable(d, type=float32, value=4.0))]
An example of variable definiton:
>>> from sympy.parsing.sym_expr import SymPyExpression >>> src2 = ''' ... integer :: a, b, c, d ... real :: p, q, r, s ... ''' >>> p = SymPyExpression() >>> p.convert_to_expr(src2, 'f') >>> p.convert_to_c() ['int a = 0', 'int b = 0', 'int c = 0', 'int d = 0', 'double p = 0.0', 'double q = 0.0', 'double r = 0.0', 'double s = 0.0']
An example of Assignment:
>>> from sympy.parsing.sym_expr import SymPyExpression >>> src3 = ''' ... integer :: a, b, c, d, e ... d = a + b - c ... e = b * d + c * e / a ... ''' >>> p = SymPyExpression(src3, 'f') >>> p.convert_to_python() ['a = 0', 'b = 0', 'c = 0', 'd = 0', 'e = 0', 'd = a + b - c', 'e = b*d + c*e/a']
An example of function definition:
>>> from sympy.parsing.sym_expr import SymPyExpression >>> src = ''' ... integer function f(a,b) ... integer, intent(in) :: a, b ... integer :: r ... end function ... ''' >>> a = SymPyExpression(src, 'f') >>> a.convert_to_python() ['def f(a, b):\n f = 0\n r = 0\n return f']
- convert_to_c()[source]#
Returns a list with the c source code for the SymPy expressions
Examples
>>> from sympy.parsing.sym_expr import SymPyExpression >>> src2 = ''' ... integer :: a, b, c, d ... real :: p, q, r, s ... c = a/b ... d = c/a ... s = p/q ... r = q/p ... ''' >>> p = SymPyExpression() >>> p.convert_to_expr(src2, 'f') >>> p.convert_to_c() ['int a = 0', 'int b = 0', 'int c = 0', 'int d = 0', 'double p = 0.0', 'double q = 0.0', 'double r = 0.0', 'double s = 0.0', 'c = a/b;', 'd = c/a;', 's = p/q;', 'r = q/p;']
- convert_to_expr(src_code, mode)[source]#
Converts the given source code to SymPy Expressions
Examples
>>> from sympy.parsing.sym_expr import SymPyExpression >>> src3 = ''' ... integer function f(a,b) result(r) ... integer, intent(in) :: a, b ... integer :: x ... r = a + b -x ... end function ... ''' >>> p = SymPyExpression() >>> p.convert_to_expr(src3, 'f') >>> p.return_expr() [FunctionDefinition(integer, name=f, parameters=(Variable(a), Variable(b)), body=CodeBlock( Declaration(Variable(r, type=integer, value=0)), Declaration(Variable(x, type=integer, value=0)), Assignment(Variable(r), a + b - x), Return(Variable(r)) ))]
Attributes
src_code
(String) the source code or filename of the source code that is to be converted
mode: String
the mode to determine which parser is to be used according to the language of the source code f or F for Fortran c or C for C/C++
- convert_to_fortran()[source]#
Returns a list with the fortran source code for the SymPy expressions
Examples
>>> from sympy.parsing.sym_expr import SymPyExpression >>> src2 = ''' ... integer :: a, b, c, d ... real :: p, q, r, s ... c = a/b ... d = c/a ... s = p/q ... r = q/p ... ''' >>> p = SymPyExpression(src2, 'f') >>> p.convert_to_fortran() [' integer*4 a', ' integer*4 b', ' integer*4 c', ' integer*4 d', ' real*8 p', ' real*8 q', ' real*8 r', ' real*8 s', ' c = a/b', ' d = c/a', ' s = p/q', ' r = q/p']
- convert_to_python()[source]#
Returns a list with Python code for the SymPy expressions
Examples
>>> from sympy.parsing.sym_expr import SymPyExpression >>> src2 = ''' ... integer :: a, b, c, d ... real :: p, q, r, s ... c = a/b ... d = c/a ... s = p/q ... r = q/p ... ''' >>> p = SymPyExpression(src2, 'f') >>> p.convert_to_python() ['a = 0', 'b = 0', 'c = 0', 'd = 0', 'p = 0.0', 'q = 0.0', 'r = 0.0', 's = 0.0', 'c = a/b', 'd = c/a', 's = p/q', 'r = q/p']
- return_expr()[source]#
Returns the expression list
Examples
>>> from sympy.parsing.sym_expr import SymPyExpression >>> src3 = ''' ... integer function f(a,b) ... integer, intent(in) :: a, b ... integer :: r ... r = a+b ... f = r ... end function ... ''' >>> p = SymPyExpression() >>> p.convert_to_expr(src3, 'f') >>> p.return_expr() [FunctionDefinition(integer, name=f, parameters=(Variable(a), Variable(b)), body=CodeBlock( Declaration(Variable(f, type=integer, value=0)), Declaration(Variable(r, type=integer, value=0)), Assignment(Variable(f), Variable(r)), Return(Variable(f)) ))]
Runtime Installation#
The currently-packaged LaTeX parser backend is partially generated with
ANTLR4,
but to use the parser, you only need the antlr4
Python package available.
Depending on your package manager, you can install the right package with, for
example, pip
:
$ pip install antlr4-python3-runtime==4.10
or conda
:
$ conda install -c conda-forge antlr-python-runtime==4.10
The C parser depends on clang
and the Fortran parser depends on LFortran
.
You can install these packages using:
$ conda install -c conda-forge lfortran clang