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.
cancel Cancel common factors between numerators and denominators.
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.
coefficients_to_float Convert all coefficients to floats with a given precision decimal_prec.
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
evaluate_with_prec Evaluate the expression, using a map of all the constants and
expand Expand the expression. Optionally, expand in var only.
factor Factor the expression over the rationals.
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.
matches Test whether the pattern is found in the expression.
num Create a new Symbolica number from an int, a float, or a string.
parse Parse a Symbolica expression from a string.
pretty_str Convert the expression into a human-readable string, with tunable settings.
rationalize_coefficients Map all floating point and rational coefficients to the best rational approximation
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.
replace_all_multiple Replace all atoms matching the patterns. See replace_all for more information.
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_rational_polynomial Convert the expression to a rational polynomial, optionally, with the variable ordering specified in vars.
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))

cancel

Expression.cancel()

Cancel common factors between numerators and denominators. Any non-canceling parts of the expression will not be rewritten.

Examples

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

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

coefficients_to_float

Expression.coefficients_to_float(decimal_prec)

Convert all coefficients to floats with a given precision decimal_prec. The precision of floating point coefficients in the input will be truncated to decimal_prec.

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}, {}))

evaluate_with_prec

Expression.evaluate_with_prec(constants, funs, decimal_digit_precision)

Evaluate the expression, using a map of all the constants and user functions using arbitrary precision arithmetic. The user has to specify the number of decimal digits of precision and provide all input numbers as floats, strings or Decimal.

Examples

>>> from symbolica import *
>>> from decimal import Decimal, getcontext
>>> x = Expression.symbols('x', 'f')
>>> e = Expression.parse('cos(x)')*3 + f(x, 2)
>>> getcontext().prec = 100
>>> a = e.evaluate_with_prec({x: Decimal('1.123456789')}, {
>>>                         f: lambda args: args[0] + args[1]}, 100)

expand

Expression.expand(var=None)

Expand the expression. Optionally, expand in var only.

factor

Expression.factor()

Factor the expression over the rationals.

Examples

>>> from symbolica import Expression
>>> p = Expression.parse('(6 + x)/(7776 + 6480*x + 2160*x^2 + 360*x^3 + 30*x^4 + x^5)')
>>> print(p.factor())
(x+6)**-4

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, n_cores=1)

Map the transformations to every term in the expression. The execution happens in parallel using n_cores.

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 the 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])

matches

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

Test whether the pattern is found in the expression. Restrictions on the pattern can be supplied through cond.

Examples

>>> f = Expression.symbol('f')
>>> if f(1).matches(f(2)):
>>>    print('match')

num

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

Create a new Symbolica number from an int, a float, or a string. A floating point number is kept as a float with the same precision as the input, but it can also be converted to the smallest rational number given a relative_error.

Examples

>>> e = Expression.num(1) / 2
>>> print(e)
1/2
>>> print(Expression.num(1/3))
>>> print(Expression.num(0.33, 0.1))
>>> print(Expression.num('0.333`3'))
>>> print(Expression.num(Decimal('0.1234')))
3.3333333333333331e-1
1/3
3.33e-1
1.2340e-1

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.

rationalize_coefficients

Expression.rationalize_coefficients(relative_error)

Map all floating point and rational coefficients to the best rational approximation in the interval [self*(1-relative_error),self*(1+relative_error)].

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 | float | decimal.Decimal required
rhs symbolica.Transformer | symbolica.Expression | int | float | decimal.Decimal 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 | float | decimal.Decimal required
rhs symbolica.Transformer | symbolica.Expression | int | float | decimal.Decimal 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

replace_all_multiple

Expression.replace_all_multiple(replacements, repeat=False)

Replace all atoms matching the patterns. See replace_all for more information.

The entire operation can be repeated until there are no more matches using repeat=True.

Examples

>>> x, y, f = Expression.symbols('x', 'y', 'f')
>>> e = f(x,y)
>>> r = e.replace_all_multiple(Replacement(x, y), Replacement(y, x))
>>> print(r)
f(y,x)

Parameters

Name Type Description Default
replacements typing.Sequence[symbolica.Replacement] The list of replacements to apply. required
repeat typing.Optional[bool] If set to True, the entire operation will be repeated until there are no more matches. 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, depth_is_absolute=True)

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:

>>> x = 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_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)

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.