Expression

Expression()

A Symbolica expression.

Supports standard arithmetic operations, such as addition and multiplication.

Examples

>>> x = Expression.symbol('x')
>>> e = x**2 + 2 - x + 1 / x**4
>>> print(e)

Attributes

Name Description
COEFF The built-in function that convert a rational polynomials to a coefficient.
COS The built-in cosine function.
E Euler’s number e.
EXP The built-in exponential function.
I The mathematical constant i, where i^2 = -1.
LOG The built-in logarithm function.
PI The mathematical constant π.
SIN The built-in sine function.

Methods

Name Description
apart Compute the partial fraction decomposition in x.
coefficient Collect terms involving the literal occurrence of x.
coefficient_list Collect terms involving the same power of x, where x is a variable or function name.
collect Collect terms involving the same power of x, where x is a variable or function name.
derivative Derive the expression w.r.t the variable x.
evaluate Evaluate the expression, using a map of all the variables and
evaluate_complex Evaluate the expression, using a map of all the variables and
expand Expand the expression. Optionally, expand in var only.
get_all_symbol_names Return all defined symbol names (function names and variables).
get_byte_size Get the number of bytes that this expression takes up in memory.
get_name Get the name of a variable or function if the current atom
get_type Get the type of the atom.
map Map the transformations to every term in the expression.
match Return an iterator over the pattern self matching to lhs.
num Create a new Symbolica number from an int or a float.
parse Parse a Symbolica expression from a string.
pretty_str Convert the expression into a human-readable string, with tunable settings.
replace Return an iterator over the replacement of the pattern self on lhs by rhs.
replace_all Replace all subexpressions matching the pattern pattern by the right-hand side rhs.
req Create a new pattern restriction that calls the function filter_fn with the matched
req_cmp Create a new pattern restriction that calls the function cmp_fn with another the matched
req_cmp_ge Create a pattern restriction that passes when the wildcard is greater than or equal to another wildcard.
req_cmp_gt Create a pattern restriction that passes when the wildcard is greater than another wildcard.
req_cmp_le Create a pattern restriction that passes when the wildcard is smaller than or equal to another wildcard.
req_cmp_lt Create a pattern restriction that passes when the wildcard is smaller than another wildcard.
req_ge Create a pattern restriction that passes when the wildcard is greater than or equal to a number num.
req_gt Create a pattern restriction that passes when the wildcard is greater than a number num.
req_le Create a pattern restriction that passes when the wildcard is smaller than or equal to a number num.
req_len Create a pattern restriction based on the wildcard length before downcasting.
req_lit Create a pattern restriction that treats the wildcard as a literal variable,
req_lt Create a pattern restriction that passes when the wildcard is smaller than a number num.
req_type Create a pattern restriction that tests the type of the atom.
series Series expand in x around expansion_point to depth depth.
set_coefficient_ring Set the coefficient ring to contain the variables in the vars list.
solve_linear_system Solve a linear system in the variables variables, where each expression
symbol Create a new symbol from a name. Symbols carry information about their attributes.
symbols Create a Symbolica symbol for every name in *names. See Expression.symbol for more information.
to_atom_tree Convert the expression to a tree.
to_latex Convert the expression into a LaTeX string.
to_polynomial Convert the expression to a polynomial, optionally, with the variable ordering specified in vars.
to_rational_polynomial Convert the expression to a rational polynomial, optionally, with the variable ordering specified in vars.
to_rational_polynomial_small_exponent Similar to to_rational_polynomial(), but the power of each variable is limited to 255.
together Write the expression over a common denominator.
transform Convert the input to a transformer, on which subsequent

apart

Expression.apart(x)

Compute the partial fraction decomposition in x.

Examples

>>> from symbolica import Expression
>>> x = Expression.symbol('x')
>>> p = Expression.parse('1/((x+y)*(x^2+x*y+1)(x+1))')
>>> print(p.apart(x))

coefficient

Expression.coefficient(x)

Collect terms involving the literal occurrence of x.

Examples

>>> from symbolica import *
>>> x, y = Expression.symbols('x', 'y')
>>> e = 5*x + x * y + x**2 + y*x**2
>>> print(e.coefficient(x**2))

yields

y + 1

coefficient_list

Expression.coefficient_list(x)

Collect terms involving the same power of x, where x is a variable or function name. Return the list of key-coefficient pairs and the remainder that matched no key.

Examples

>>> from symbolica import *
>>> x, y = Expression.symbols('x', 'y')
>>> e = 5*x + x * y + x**2 + 5
>>>
>>> for a in e.coefficient_list(x):
>>>     print(a[0], a[1])

yields

x y+5
x^2 1
1 5

collect

Expression.collect(x, key_map=None, coeff_map=None)

Collect terms involving the same power of x, where x is a variable or function name. Return the list of key-coefficient pairs and the remainder that matched no key.

Both the key (the quantity collected in) and its coefficient can be mapped using key_map and coeff_map respectively.

Examples

>>> from symbolica import Expression
>>> x, y = Expression.symbols('x', 'y')
>>> e = 5*x + x * y + x**2 + 5
>>>
>>> print(e.collect(x))

yields x^2+x*(y+5)+5.

>>> from symbolica import Expression
>>> x, y = Expression.symbols('x', 'y')
>>> var, coeff = Expression.funs('var', 'coeff')
>>> e = 5*x + x * y + x**2 + 5
>>>
>>> print(e.collect(x, key_map=lambda x: var(x), coeff_map=lambda x: coeff(x)))

yields var(1)*coeff(5)+var(x)*coeff(y+5)+var(x^2)*coeff(1).

Parameters

Name Type Description Default
key_map typing.Optional[typing.Callable[[symbolica.Expression], symbolica.Expression]] None
coeff_map typing.Optional[typing.Callable[[symbolica.Expression], symbolica.Expression]] None

derivative

Expression.derivative(x)

Derive the expression w.r.t the variable x.

evaluate

Expression.evaluate(constants, funs)

Evaluate the expression, using a map of all the variables and user functions to a float.

Examples

>>> from symbolica import Expression
>>> x = Expression.symbol('x')
>>> f = Expression.symbol('f')
>>> e = Expression.parse('cos(x)')*3 + f(x,2)
>>> print(e.evaluate({x: 1}, {f: lambda args: args[0]+args[1]}))

evaluate_complex

Expression.evaluate_complex(constants, funs)

Evaluate the expression, using a map of all the variables and user functions to a complex number.

Examples

>>> from symbolica import Expression
>>> x, y = Expression.symbols('x', 'y')
>>> e = Expression.parse('sqrt(x)')*y
>>> print(e.evaluate_complex({x: 1 + 2j, y: 4 + 3j}, {}))

expand

Expression.expand(var=None)

Expand the expression. Optionally, expand in var only.

get_all_symbol_names

Expression.get_all_symbol_names(_cls)

Return all defined symbol names (function names and variables).

get_byte_size

Expression.get_byte_size()

Get the number of bytes that this expression takes up in memory.

get_name

Expression.get_name()

Get the name of a variable or function if the current atom is a variable or function.

get_type

Expression.get_type()

Get the type of the atom.

map

Expression.map(transformations)

Map the transformations to every term in the expression. The execution happen in parallel.

No new functions or variables can be defined and no new expressions can be parsed inside the map. Doing so will result in a deadlock.

Examples

>>> x, x_ = Expression.symbols('x', 'x_')
>>> e = (1+x)**2
>>> r = e.map(Transformer().expand().replace_all(x, 6))
>>> print(r)

match

Expression.match(lhs, cond=None, level_range=None, level_is_tree_depth=False)

Return an iterator over the pattern self matching to lhs. Restrictions on pattern can be supplied through cond.

The level_range specifies the [min,max] level at which the pattern is allowed to match. The first level is 0 and the level is increased when going into a function or one level deeper in the expression tree, depending on level_is_tree_depth.

Examples

>>> x, x_ = Expression.symbols('x','x_')
>>> f = Expression.symbol('f')
>>> e = f(x)*f(1)*f(2)*f(3)
>>> for match in e.match(f(x_)):
>>>    for map in match:
>>>        print(map[0],'=', map[1])

num

Expression.num(_cls, num, max_denom=None)

Create a new Symbolica number from an int or a float. A floating point number is converted to its rational number equivalent, but it can also be truncated by specifying the maximal denominator value.

Examples

>>> e = Expression.num(1) / 2
>>> print(e)
1/2
>>> print(Expression.num(0.33))
>>> print(Expression.num(0.33, 5))
5944751508129055/18014398509481984
1/3

parse

Expression.parse(_cls, input)

Parse a Symbolica expression from a string.

Parameters

Name Type Description Default
input str An input string. UTF-8 character are allowed. required

Examples

>>> e = Expression.parse('x^2+y+y*4')
>>> print(e)
x^2+5*y

Raises

Type Description
ValueError If the input is not a valid Symbolica expression.

pretty_str

Expression.pretty_str(terms_on_new_line=False, color_top_level_sum=True, color_builtin_symbols=True, print_finite_field=True, symmetric_representation_for_finite_field=False, explicit_rational_polynomial=False, number_thousands_separator=None, multiplication_operator='*', square_brackets_for_function=False, num_exp_as_superscript=True, latex=False)

Convert the expression into a human-readable string, with tunable settings.

Examples

>>> a = Expression.parse('128378127123 z^(2/3)*w^2/x/y + y^4 + z^34 + x^(x+2)+3/5+f(x,x^2)')
>>> print(a.pretty_str(number_thousands_separator='_', multiplication_operator=' '))

Yields z³⁴+x^(x+2)+y⁴+f(x,x²)+128_378_127_123 z^(2/3) w² x⁻¹ y⁻¹+3/5.

replace

Expression.replace(lhs, rhs, cond=None, level_range=None, level_is_tree_depth=False)

Return an iterator over the replacement of the pattern self on lhs by rhs. Restrictions on pattern can be supplied through cond.

Examples

>>> from symbolica import Expression
>>> x_ = Expression.symbol('x_')
>>> f = Expression.symbol('f')
>>> e = f(1)*f(2)*f(3)
>>> for r in e.replace(f(x_), f(x_ + 1)):
>>>     print(r)

Yields:

f(2)*f(2)*f(3)
f(1)*f(3)*f(3)
f(1)*f(2)*f(4)

Parameters

Name Type Description Default
lhs symbolica.Transformer | symbolica.Expression | int required
rhs symbolica.Transformer | symbolica.Expression | int required
cond typing.Optional[symbolica.PatternRestriction] None
level_range typing.Optional[typing.Tuple[int, typing.Optional[int]]] None
level_is_tree_depth typing.Optional[bool] False

replace_all

Expression.replace_all(pattern, rhs, cond=None, non_greedy_wildcards=None, level_range=None, level_is_tree_depth=False, repeat=False)

Replace all subexpressions matching the pattern pattern by the right-hand side rhs.

Examples

>>> x, w1_, w2_ = Expression.symbols('x','w1_','w2_')
>>> f = Expression.symbol('f')
>>> e = f(3,x)
>>> r = e.replace_all(f(w1_,w2_), f(w1_ - 1, w2_**2), (w1_ >= 1) & w2_.is_var())
>>> print(r)

Parameters

Name Type Description Default
self required
pattern symbolica.Transformer | symbolica.Expression | int required
rhs symbolica.Transformer | symbolica.Expression | int required
cond typing.Optional[symbolica.PatternRestriction] None
non_greedy_wildcards typing.Optional[typing.Sequence[symbolica.Expression]] None
level_range typing.Optional[typing.Tuple[int, typing.Optional[int]]] None
level_is_tree_depth typing.Optional[bool] False
repeat typing.Optional[bool] False

req

Expression.req(filter_fn)

Create a new pattern restriction that calls the function filter_fn with the matched atom that should return a boolean. If true, the pattern matches.

Examples

>>> from symbolica import Expression
>>> x_ = Expression.symbol('x_')
>>> f = Expression.symbol('f')
>>> e = f(1)*f(2)*f(3)
>>> e = e.replace_all(f(x_), 1, x_.req(lambda m: m == 2 or m == 3))

req_cmp

Expression.req_cmp(other, cmp_fn)

Create a new pattern restriction that calls the function cmp_fn with another the matched atom and the match atom of the other wildcard that should return a boolean. If true, the pattern matches.

Examples

>>> from symbolica import Expression
>>> x_, y_ = Expression.symbols('x_', 'y_')
>>> f = Expression.symbol('f')
>>> e = f(1)*f(2)*f(3)
>>> e = e.replace_all(f(x_)*f(y_), 1, x_.req_cmp(y_, lambda m1, m2: m1 + m2 == 4))

req_cmp_ge

Expression.req_cmp_ge(num, cmp_any_atom=False)

Create a pattern restriction that passes when the wildcard is greater than or equal to another wildcard. If the matched wildcards are not a numbers, the pattern fails.

When the option cmp_any_atom is set to True, this function compares atoms of any type. The result depends on the internal ordering and may change between different Symbolica versions.

Examples

>>> from symbolica import Expression
>>> x_, y_ = Expression.symbol('x_', 'y_')
>>> f = Expression.symbol('f')
>>> e = f(1,2)
>>> e = e.replace_all(f(x_,y_), 1, x_.req_cmp_ge(y_))

req_cmp_gt

Expression.req_cmp_gt(num, cmp_any_atom=False)

Create a pattern restriction that passes when the wildcard is greater than another wildcard. If the matched wildcards are not a numbers, the pattern fails.

When the option cmp_any_atom is set to True, this function compares atoms of any type. The result depends on the internal ordering and may change between different Symbolica versions.

Examples

>>> from symbolica import Expression
>>> x_, y_ = Expression.symbol('x_', 'y_')
>>> f = Expression.symbol('f')
>>> e = f(1,2)
>>> e = e.replace_all(f(x_,y_), 1, x_.req_cmp_gt(y_))

req_cmp_le

Expression.req_cmp_le(num, cmp_any_atom=False)

Create a pattern restriction that passes when the wildcard is smaller than or equal to another wildcard. If the matched wildcards are not a numbers, the pattern fails.

When the option cmp_any_atom is set to True, this function compares atoms of any type. The result depends on the internal ordering and may change between different Symbolica versions.

Examples

>>> from symbolica import Expression
>>> x_, y_ = Expression.symbol('x_', 'y_')
>>> f = Expression.symbol('f')
>>> e = f(1,2)
>>> e = e.replace_all(f(x_,y_), 1, x_.req_cmp_le(y_))

req_cmp_lt

Expression.req_cmp_lt(num, cmp_any_atom=False)

Create a pattern restriction that passes when the wildcard is smaller than another wildcard. If the matched wildcards are not a numbers, the pattern fails.

When the option cmp_any_atom is set to True, this function compares atoms of any type. The result depends on the internal ordering and may change between different Symbolica versions.

Examples

>>> from symbolica import Expression
>>> x_, y_ = Expression.symbol('x_', 'y_')
>>> f = Expression.symbol('f')
>>> e = f(1,2)
>>> e = e.replace_all(f(x_,y_), 1, x_.req_cmp_lt(y_))

req_ge

Expression.req_ge(num, cmp_any_atom=False)

Create a pattern restriction that passes when the wildcard is greater than or equal to a number num. If the matched wildcard is not a number, the pattern fails.

When the option cmp_any_atom is set to True, this function compares atoms of any type. The result depends on the internal ordering and may change between different Symbolica versions.

Examples

>>> from symbolica import Expression
>>> x_ = Expression.symbol('x_')
>>> f = Expression.symbol('f')
>>> e = f(1)*f(2)*f(3)
>>> e = e.replace_all(f(x_), 1, x_.req_ge(2))

req_gt

Expression.req_gt(num, cmp_any_atom=False)

Create a pattern restriction that passes when the wildcard is greater than a number num. If the matched wildcard is not a number, the pattern fails.

When the option cmp_any_atom is set to True, this function compares atoms of any type. The result depends on the internal ordering and may change between different Symbolica versions.

Examples

>>> from symbolica import Expression
>>> x_ = Expression.symbol('x_')
>>> f = Expression.symbol('f')
>>> e = f(1)*f(2)*f(3)
>>> e = e.replace_all(f(x_), 1, x_.req_gt(2))

req_le

Expression.req_le(num, cmp_any_atom=False)

Create a pattern restriction that passes when the wildcard is smaller than or equal to a number num. If the matched wildcard is not a number, the pattern fails.

When the option cmp_any_atom is set to True, this function compares atoms of any type. The result depends on the internal ordering and may change between different Symbolica versions.

Examples

>>> from symbolica import Expression
>>> x_ = Expression.symbol('x_')
>>> f = Expression.symbol('f')
>>> e = f(1)*f(2)*f(3)
>>> e = e.replace_all(f(x_), 1, x_.req_le(2))

req_len

Expression.req_len(min_length, max_length)

Create a pattern restriction based on the wildcard length before downcasting.

req_lit

Expression.req_lit()

Create a pattern restriction that treats the wildcard as a literal variable, so that it only matches to itself.

req_lt

Expression.req_lt(num, cmp_any_atom=False)

Create a pattern restriction that passes when the wildcard is smaller than a number num. If the matched wildcard is not a number, the pattern fails.

When the option cmp_any_atom is set to True, this function compares atoms of any type. The result depends on the internal ordering and may change between different Symbolica versions.

Examples

>>> from symbolica import Expression
>>> x_ = Expression.symbol('x_')
>>> f = Expression.symbol('f')
>>> e = f(1)*f(2)*f(3)
>>> e = e.replace_all(f(x_), 1, x_.req_lt(2))

req_type

Expression.req_type(atom_type)

Create a pattern restriction that tests the type of the atom.

Examples

>>> from symbolica import Expression, AtomType
>>> x, x_ = Expression.symbols('x', 'x_')
>>> f = Expression.symbol('f')
>>> e = f(x)*f(2)*f(f(3))
>>> e = e.replace_all(f(x_), 1, x_.req_type(AtomType.Num))
>>> print(e)

Yields f(x)*f(1).

series

Expression.series(x, expansion_point, depth, depth_denom=1)

Series expand in x around expansion_point to depth depth.

set_coefficient_ring

Expression.set_coefficient_ring(vars)

Set the coefficient ring to contain the variables in the vars list. This will move all variables into a rational polynomial function.

Parameters

Name Type Description Default
vars typing.Sequence[symbolica.Expression] A list of variables required

solve_linear_system

Expression.solve_linear_system(_cls, system, variables)

Solve a linear system in the variables variables, where each expression in the system is understood to yield 0.

Examples

>>> from symbolica import Expression
>>> x, y, c = Expression.symbols('x', 'y', 'c')
>>> f = Expression.symbol('f')
>>> x_r, y_r = Expression.solve_linear_system([f(c)*x + y/c - 1, y-c/2], [x, y])
>>> print('x =', x_r, ', y =', y_r)

symbol

Expression.symbol(_cls, name, is_symmetric=None, is_antisymmetric=None, is_linear=None)

Create a new symbol from a name. Symbols carry information about their attributes. The symbol can signal that it is symmetric if it is used as a function using is_symmetric=True, antisymmetric using is_antisymmetric=True, and multilinear using is_linear=True. If no attributes are specified, the attributes are inherited from the symbol if it was already defined, otherwise all attributes are set to false.

Once attributes are defined on a symbol, they cannot be redefined later.

Examples

Define a regular symbol and use it as a variable:

>>> f = Expression.symbol('x')
>>> e = x**2 + 5
>>> print(e)
x**2 + 5

Define a regular symbol and use it as a function:

>>> f = Expression.symbol('f')
>>> e = f(1,2)
>>> print(e)
f(1,2)

Define a symmetric function:

>>> f = Expression.symbol('f', is_symmetric=True)
>>> e = f(2,1)
>>> print(e)
f(1,2)

Define a linear and symmetric function:

>>> p1, p2, p3, p4 = Expression.symbols('p1', 'p2', 'p3', 'p4')
>>> dot = Expression.symbol('dot', is_symmetric=True, is_linear=True)
>>> e = dot(p2+2*p3,p1+3*p2-p3)
dot(p1,p2)+2*dot(p1,p3)+3*dot(p2,p2)-dot(p2,p3)+6*dot(p2,p3)-2*dot(p3,p3)

symbols

Expression.symbols(_cls, *names, is_symmetric=None, is_antisymmetric=None, is_linear=None)

Create a Symbolica symbol for every name in *names. See Expression.symbol for more information.

Examples

>>> f, x = Expression.symbols('x', 'f')
>>> e = f(1,x)
>>> print(e)
f(1,x)

to_atom_tree

Expression.to_atom_tree()

Convert the expression to a tree.

to_latex

Expression.to_latex()

Convert the expression into a LaTeX string.

Examples

>>> a = Expression.parse('128378127123 z^(2/3)*w^2/x/y + y^4 + z^34 + x^(x+2)+3/5+f(x,x^2)')
>>> print(a.to_latex())

Yields $$z^{34}+x^{x+2}+y^{4}+f(x,x^{2})+128378127123 z^{\frac{2}{3}} w^{2} \frac{1}{x} \frac{1}{y}+\frac{3}{5}$$.

to_polynomial

Expression.to_polynomial(vars=None)

Convert the expression to a polynomial, optionally, with the variable ordering specified in vars. All non-polynomial parts will be converted to new, independent variables.

to_rational_polynomial

Expression.to_rational_polynomial(vars=None)

Convert the expression to a rational polynomial, optionally, with the variable ordering specified in vars. The latter is useful if it is known in advance that more variables may be added in the future to the rational polynomial through composition with other rational polynomials.

All non-rational polynomial parts are converted to new, independent variables.

Examples

>>> a = Expression.parse('(1 + 3*x1 + 5*x2 + 7*x3 + 9*x4 + 11*x5 + 13*x6 + 15*x7)^2 - 1').to_rational_polynomial()
>>> print(a)

to_rational_polynomial_small_exponent

Expression.to_rational_polynomial_small_exponent(vars=None)

Similar to to_rational_polynomial(), but the power of each variable is limited to 255.

together

Expression.together()

Write the expression over a common denominator.

Examples

>>> from symbolica import Expression
>>> p = Expression.parse('v1^2/2+v1^3/v4*v2+v3/(1+v4)')
>>> print(p.together())

transform

Expression.transform()

Convert the input to a transformer, on which subsequent transformations can be applied.