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.
canonize_tensors Canonize (products of) tensors in the expression by relabeling repeated indices.
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.
contains Returns true iff self contains a literally.
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
evaluator Create an evaluator that can evaluate (nested) expressions in an optimized fashion.
evaluator_multiple Create an evaluator that can jointly evaluate (nested) expressions in an optimized fashion.
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_all_symbols Get all symbols in the current expression, optionally including function symbols.
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.
load Load an expression and its state from a file. The state will be merged
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.
save Save the expression and its state to a binary file.
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.
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.
to_rational_polynomial Convert the expression to a rational polynomial, optionally, with the variable ordering specified in vars.
to_sympy Convert the expression into a sympy-parsable string.
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)

canonize_tensors

Expression.canonize_tensors(contracted_indices, index_group=None)

Canonize (products of) tensors in the expression by relabeling repeated indices. The tensors must be written as functions, with its indices are the arguments. The repeated indices should be provided in contracted_indices.

If the contracted indices are distinguishable (for example in their dimension), you can provide an optional group marker for each index using index_group. This makes sure that an index will not be renamed to an index from a different group.

Examples

>>> g = Expression.symbol('g', is_symmetric=True)
>>> fc = Expression.symbol('fc', is_cyclesymmetric=True)
>>> mu1, mu2, mu3, mu4, k1 = Expression.symbol('mu1', 'mu2', 'mu3', 'mu4', 'k1')
>>> e = g(mu2, mu3)*fc(mu4, mu2, k1, mu4, k1, mu3)
>>> print(e.canonize_tensors([mu1, mu2, mu3, mu4]))

yields g(mu1,mu2)*fc(mu1,mu3,mu2,k1,mu3,k1).

coefficient

Expression.coefficient(x)

Collect terms involving the literal occurrence of x.

Examples

>>> from symbolica import *
>>> x, y = Expression.symbol('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.symbol('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.symbol('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.symbol('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
x Expression The variable to collect terms in required
key_map Optional[Callable[[Expression], Expression]] A function to be applied to the quantity collected in None
coeff_map Optional[Callable[[Expression], Expression]] A function to be applied to the coefficient None

contains

Expression.contains(a)

Returns true iff self contains a literally.

Examples

>>> from symbolica import *
>>> x, y, z = Expression.symbol('x', 'y', 'z')
>>> e = x * y * z
>>> e.contains(x) # True
>>> e.contains(x*y*z) # True
>>> e.contains(x*y) # False

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.symbol('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.symbol('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)

evaluator

Expression.evaluator(constants, funs, params, iterations=100, n_cores=4, verbose=False)

Create an evaluator that can evaluate (nested) expressions in an optimized fashion. All constants and functions should be provided as dictionaries, where the function dictionary has a key (name, printable name, arguments) and the value is the function body. For example the function f(x,y)=x^2+y should be provided as {(f, "f", (x, y)): x**2 + y}. All free parameters should be provided in the params list.

Examples

>>> from symbolica import *
>>> x, y, z, pi, f, g = Expression.symbol(
>>>     'x', 'y', 'z', 'pi', 'f', 'g')
>>>
>>> e1 = Expression.parse("x + pi + cos(x) + f(g(x+1),x*2)")
>>> fd = Expression.parse("y^2 + z^2*y^2")
>>> gd = Expression.parse("y + 5")
>>>
>>> ev = e1.evaluator({pi: Expression.num(22)/7},
>>>              {(f, "f", (y, z)): fd, (g, "g", (y, )): gd}, [x])
>>> res = ev.evaluate([[1.], [2.], [3.]])  # evaluate at x=1, x=2, x=3
>>> print(res)

Parameters

Name Type Description Default
constants dict[Expression, Expression] A map of expressions to constants. The constants should be numerical expressions. required
funs dict[Tuple[Expression, str, Sequence[Expression]], Expression] A dictionary of functions. The key is a tuple of the function name, printable name and the argument variables. The value is the function body. required
params Sequence[Expression] A list of free parameters. required
iterations int The number of optimization iterations to perform. 100
n_cores int The number of cores to use for the optimization. 4
verbose bool If set to True, print the progress of the optimization. False

evaluator_multiple

Expression.evaluator_multiple(_cls, exprs, constants, funs, params, iterations=100, n_cores=4, verbose=False)

Create an evaluator that can jointly evaluate (nested) expressions in an optimized fashion. See Expression.evaluator() for more information.

Examples

>>> from symbolica import *
>>> x = Expression.symbol('x')
>>> e1 = Expression.parse("x^2 + 1")
>>> e2 = Expression.parse("x^2 + 2)
>>> ev = Expression.evaluator_multiple([e1, e2], {}, {}, [x])

will recycle the x^2

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_all_symbols

Expression.get_all_symbols(include_function_symbols=True)

Get all symbols in the current expression, optionally including function symbols. The symbols are sorted in Symbolica’s internal ordering.

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.

load

Expression.load(_cls, filename, conflict_fn)

Load an expression and its state from a file. The state will be merged with the current one. If a symbol has conflicting attributes, the conflict can be resolved using the renaming function conflict_fn.

Expressions can be saved using Expression.save.

Examples

If export.dat contains a serialized expression: f(x)+f(y):

>>> e = Expression.load('export.dat')

whill yield f(x)+f(y).

If we have defined symbols in a different order:

>>> y, x = S('y', 'x')
>>> e = Expression.load('export.dat')

we get f(y)+f(x).

If we define a symbol with conflicting attributes, we can resolve the conflict using a renaming function:

>>> x = S('x', is_symmetric=True)
>>> e = Expression.load('export.dat', lambda x: x + '_new')
print(e)

will yield f(x_new)+f(y).

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.symbol('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, allow_new_wildcards_on_rhs=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.symbol('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, allow_new_wildcards_on_rhs=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='*', double_star_for_exponentiation=False, 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, allow_new_wildcards_on_rhs=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 Transformer | Expression | int | float | Decimal The pattern to match. required
rhs Transformer | Expression | Callable[[dict[Expression, Expression]], Expression] | int | float | Decimal The right-hand side to replace the matched subexpression with. Can be a transformer, expression or a function that maps a dictionary of wildcards to an expression. required
cond Optional[PatternRestriction] Conditions on the pattern. None
level_range Optional[Tuple[int, Optional[int]]] 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. None
level_is_tree_depth Optional[bool] If set to True, the level is increased when going one level deeper in the expression tree. False
allow_new_wildcards_on_rhs Optional[bool] If set to True, allow wildcards that do not appear in the pattern on the right-hand side. False

replace_all

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

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

Examples

>>> x, w1_, w2_ = Expression.symbol('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 The expression to match and replace on. required
pattern Transformer | Expression | int | float | Decimal The pattern to match. required
rhs Transformer | Expression | Callable[[dict[Expression, Expression]], Expression] | int | float | Decimal The right-hand side to replace the matched subexpression with. Can be a transformer, expression or a function that maps a dictionary of wildcards to an expression. required
cond Optional[PatternRestriction] Conditions on the pattern. None
non_greedy_wildcards Optional[Sequence[Expression]] Wildcards that try to match as little as possible. None
level_range Optional[Tuple[int, Optional[int]]] 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. None
level_is_tree_depth Optional[bool] If set to True, the level is increased when going one level deeper in the expression tree. False
allow_new_wildcards_on_rhs Optional[bool] If set to True, allow wildcards that do not appear in the pattern on the right-hand side. False
rhs_cache_size Optional[int] Cache the first rhs_cache_size substituted patterns. If set to None, an internally determined cache size is used. Warning: caching should be disabled (rhs_cache_size=0) if the right-hand side contains side effects, such as updating a global variable. None
repeat Optional[bool] If set to True, the entire operation will be repeated until there are no more matches. 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.symbol('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 Sequence[Replacement] The list of replacements to apply. required
repeat 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.symbol('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.symbol('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).

save

Expression.save(filename, compression_level=9)

Save the expression and its state to a binary file. The data is compressed and the compression level can be set between 0 and 11.

The data can be loaded using Expression.load.

Examples

>>> e = E("f(x)+f(y)").expand()
>>> e.save('export.dat')

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 Sequence[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.symbol('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_cyclesymmetric=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, cyclesymmetric using is_cyclesymmetric=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.symbol('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)

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)

to_sympy

Expression.to_sympy()

Convert the expression into a sympy-parsable string.

Examples

>>> from sympy import *
>>> s = sympy.parse_expr(Expression.parse('x^2+f((1+x)^y)').to_sympy())

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.