Expression

Expression()

A Symbolica expression.

Supports standard arithmetic operations, such as addition and multiplication.

Examples

>>> x = S('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 an indeterminate.
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 an indeterminate.
collect_factors Collect common factors from (nested) sums.
collect_num Collect numerical factors by removing the numerical content from additions.
collect_symbol Collect terms involving the same power of variables or functions with the name x, e.g.
conj Compute the complex conjugate of the expression.
conjugate Complex conjugate all complex numbers in the expression.
contains Returns true iff self contains a literally.
cos Compute the cosine of the expression.
derivative Derive the expression w.r.t the variable x.
evaluate Evaluate the expression, using a map of all the constants 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.
exp Compute the exponential of the expression.
expand Expand the expression. Optionally, expand in var only.
expand_num Distribute numbers in the expression, for example:
factor Factor the expression over the rationals.
format Convert the expression into a human-readable string, with tunable settings.
format_plain Convert the expression into a plain string, useful for importing and exporting.
get_all_indeterminates Get all symbols and functions in the current expression, optionally considering function arguments as well.
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_attributes Get the attributes of a variable or function if the current atom
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_tags Get the tags of a variable or function if the current atom
get_type Get the type of the atom.
hold Create a held expression that delays the execution of the transformer t until the
is_constant Check if the expression is constant, i.e. contains no user-defined symbols or functions.
is_finite Check if the expression has no infinities and is not indeterminate.
is_integer Check if the expression is integer. Symbols must have the integer attribute.
is_positive Check if the expression is a positive scalar. Symbols must have the positive attribute.
is_real Check if the expression is real. Symbols must have the real attribute.
is_scalar Check if the expression is a scalar. Symbols must have the scalar attribute.
is_type Test if the expression is of a certain type.
load Load an expression and its state from a file. The state will be merged
log Compute the natural logarithm of the expression.
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.
nsolve Find the root of an expression in x numerically over the reals using Newton’s method.
nsolve_system Find a common root of multiple expressions in variables numerically over the reals using Newton’s method.
num Create a new Symbolica number from an int, a float, a Decimal, or a string.
parse Parse a Symbolica expression from a string.
rationalize Map all floating point and rational coefficients to the best rational approximation
rationalize_coefficients Map all floating point and rational coefficients to the best rational approximation
replace Replace all atoms matching the pattern pattern by the right-hand side rhs.
replace_iter Return an iterator over the replacement of the pattern self on lhs by rhs.
replace_multiple Replace all atoms matching the patterns. See replace for more information.
replace_wildcards Replace all wildcards in the expression with the given replacements.
req Create a new pattern restriction that calls the function filter_fn with the matched
req_attr Create a pattern restriction based on the attribute of a matched variable or function.
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_contains Create a pattern restriction that filters for expressions that contain a.
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_tag Create a pattern restriction based on the tag of a matched variable or function.
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.
sin Compute the sine of the expression.
solve_linear_system Solve a linear system in the variables variables, where each expression
sqrt Compute the square root of the 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_canonical_string Convert the expression into a canonical string that
to_float Convert all coefficients to floats with a given precision decimal_prec.
to_latex Convert the expression into a LaTeX string.
to_polynomial Convert the expression to a polynomial, optionally, with the variables and the ordering specified in vars.
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.

apart

Expression.apart(x=None)

Compute the partial fraction decomposition in x.

If None is passed, the expression will be decomposed in all variables which involves a potentially expensive Groebner basis computation.

Examples

>>> p = E('1/((x+y)*(x^2+x*y+1)(x+1))')
>>> print(p.apart(S('x')))

Multivariate partial fractioning:

>>> p = E('(2y-x)/(y*(x+y)*(y-x))')
>>> print(p.apart())

yields 3/2*y^-1*(x+y)^-1+1/2*y^-1*(-x+y)^-1

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 *
>>> p = E('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)

Canonize (products of) tensors in the expression by relabeling repeated indices. The tensors must be written as functions, with its indices as the arguments. Subexpressions, constants and open indices are supported.

If the contracted indices are distinguishable (for example in their dimension), you can provide a group marker as the second element in the tuple of the index specification. This makes sure that an index will not be renamed to an index from a different group.

Examples

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

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 = S('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 are variables or functions. Return the list of key-coefficient pairs.

Examples

>>> from symbolica import *
>>> x, y = S('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 the indeterminate(s) x. 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 *
>>> x, y = S('x', 'y')
>>> e = 5*x + x * y + x**2 + 5
>>>
>>> print(e.collect(x))

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

>>> from symbolica import *
>>> x, y = S('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(s) or function(s) to collect terms in ()
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

collect_factors

Expression.collect_factors()

Collect common factors from (nested) sums.

Examples

>>> from symbolica import *
>>> e = E('x*(x+y*x+x^2+y*(x+x^2))')
>>> e.collect_factors()

yields

v1^2*(1+v1+v2+v2*(1+v1))

collect_num

Expression.collect_num()

Collect numerical factors by removing the content from additions. For example, -2*x + 4*x^2 + 6*x^3 will be transformed into -2*(x - 2*x^2 - 3*x^3).

The first argument of the addition is normalized to a positive quantity.

Examples

>>> from symbolica import *
>>> x, y = S('x', 'y')
>>> e = (-3*x+6*y)*(2*x+2*y)
>>> print(e.collect_num())

yields

-6*(x+y)*(x-2*y)

collect_symbol

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

Collect terms involving the same power of variables or functions with the name x.

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

Examples

>>> from symbolica import *
>>> x, f = S('x', 'f')
>>> e = f(1,2) + x*f(1,2)
>>>
>>> print(e.collect_symbol(f))

yields (1+x)*f(1,2).

Parameters

Name Type Description Default
x Expression The symbol to collect 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

conjugate

Expression.conjugate()

Complex conjugate all complex numbers in the expression.

contains

Expression.contains(a)

Returns true iff self contains a literally.

Examples

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

cos

Expression.cos()

Compute the cosine of the expression.

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 *
>>> x = S('x')
>>> f = S('f')
>>> e = E('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 *
>>> x, y = S('x', 'y')
>>> e = E('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 = S('x', 'f')
>>> e = E('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,
    functions,
    params,
    iterations=100,
    n_cores=4,
    verbose=False,
external_functions=None,
    conditionals=None,
)

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.

Additionally, external functions can be registered that will call a Python function.

If KeyboardInterrupt is triggered during the optimization, the optimization will stop and will yield the current best result.

Examples

>>> from symbolica import *
>>> x, y, z, pi, f, g = S(
>>>     'x', 'y', 'z', 'pi', 'f', 'g')
>>>
>>> e1 = E("x + pi + cos(x) + f(g(x+1),x*2)")
>>> fd = E("y^2 + z^2*y^2")
>>> gd = E("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)

Define an external function:

>>> E("f(x)").evaluator({}, {}, [S("x")],
            external_functions={(S("f"), "F"): lambda args: args[0]**2 + 1})

Define an conditional function which yields x+1 when y != 0 and x+2 when y == 0:

>>> E("if(y, x + 1, x + 2)").evaluator({}, {}, [S("x"), S("y")], conditional=[S("if")])

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,
    functions,
    params,
    iterations=100,
    n_cores=4,
    verbose=False,
external_functions=None,
)

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

Examples

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

will recycle the x^2

exp

Expression.exp()

Compute the exponential of the expression.

expand

Expression.expand(var=None, via_poly=None)

Expand the expression. Optionally, expand in var only.

Using via_poly=True may give a significant speedup for large expressions.

expand_num

Expression.expand_num()

Distribute numbers in the expression, for example: 2*(x+y) -> 2*x+2*y.

Examples

>>> from symbolica import *
>>> x, y = S('x', 'y')
>>> e = 3*(x+y)*(4*x+5*y)
>>> print(e.expand_num())

yields

(3*x+3*y)*(4*x+5*y)

factor

Expression.factor()

Factor the expression over the rationals.

Examples

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

format

Expression.format(
    mode=PrintMode.Symbolica,
    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,
    show_namespaces=False,
    max_terms=100,
    custom_print_mode=None,
)

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

Examples

>>> a = E('128378127123 z^(2/3)*w^2/x/y + y^4 + z^34 + x^(x+2)+3/5+f(x,x^2)')
>>> print(a.format(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.

>>> print(E('x^2 + f(x)').format(PrintMode.Sympy))

yields x**2+f(x)

>>> print(E('x^2 + f(x)').format(PrintMode.Mathematica))

yields x^2 + f[x]

format_plain

Expression.format_plain()

Convert the expression into a plain string, useful for importing and exporting.

Examples

>>> a = E('5 + x^2')
>>> print(a.format_plain())

Yields 5 + x^2, without any coloring.

get_all_indeterminates

Expression.get_all_indeterminates(enter_functions=True)

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

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_attributes

Expression.get_attributes()

Get the attributes of a variable or function if the current atom is a variable or function, otherwise throw an error.

get_attributes

Expression.get_attributes()

Get the attributes of a variable or function if the current atom is a variable or function, otherwise throw an error.

get_byte_size

Expression.get_byte_size()

Get the number of bytes t, otherwise throw an error.

get_tags

Expression.get_tags()

Get the tags of a variable or function if the current atom is a variable or function, otherwise throw an error.

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.

hold

Expression.hold(t)

Create a held expression that delays the execution of the transformer t until the resulting held expression is called. Held expressions can be composed like regular expressions and are useful for the right-hand side of pattern matching, to act a transformer on a wildcard after it has been substituted.

Examples

>>> f, x, x_ = S('f', 'x', 'x_')
>>> e = f((x+1)**2)
>>> e = e.replace(f(x_), f(x_.hold(T().expand())))

is_constant

Expression.is_constant()

Check if the expression is constant, i.e. contains no user-defined symbols or functions.

Examples

>>> e = E('cos(2 + exp(3)) + 5')
>>> print(e.is_constant())
True

is_finite

Expression.is_finite()

Check if the expression has no infinities and is not indeterminate.

Examples

>>> e = E('x + x^2 + log(0)')
>>> print(e.is_finite())
False

is_integer

Expression.is_integer()

Check if the expression is integer. Symbols must have the integer attribute.

Examples

>>> x = S('x', is_integer=True)
>>> e = (x + 1)**2 + 5
>>> print(e.is_integer())
True

is_positive

#og og

Expression.is_positive()
Expression.log()

Compute the natural logarithm of the expression.

map

```opNone

Check if the expression is a positive scalar. Symbols must have the positive attribute.

#### Examples {.doc-section .doc-section-examples}

```python
>>> x = S('x', is_positive=True)
>>> e = (x + 1)**2 + 5
>>> print(e.is_positive())
True

is_real

Expression.is_real()

Check if the expression is real. Symbols must have the real attribute.

Examples

>>> x = S('x', is_real=True)
>>> e = (x + 1)**2 / 2 + 5
>>> print(e.is_real())
True

is_scalar

Expression.is_scalar()

Check if the expression is a scalar. Symbols must have the scalar attribute.

Examples

>>> x = S('x', is_scalar=True)
>>> e = (x +1)**2 + 5
>>> print(e.is_scalar())
True
Expression.is_type(atom_type)

Test if the expression is of a certain type.

load

Expression.load(_cls, filename, conflict_fn=None)

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).

log

Expression.log()

Compute the natural logarithm of the expression.

map

Expression.map(transformations, n_cores=1, stats_to_file=None)

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

Examples

>>> x, x_ = S('x', 'x_')
>>> e = (1+x)**2
>>> r = e.map(T().expand().replace(x, 6))
>>> print(r)

Parameters

Name Type Description Default
transformations Transformer The transformations to apply. required
n_cores Optional[int] The number of cores to use for parallel execution. 1
stats_to_file Optional[str] If set, the output of the stats transformer will be written to a file in JSON format. None

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_ = S('x','x_')
>>> f = S('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 = S('f')
>>> if f(1).matches(f(2)):
>>>    print('match')

nsolve

Expression.nsolve(variable, init, prec=0.0001, max_iterations=1000)

Find the root of an expression in x numerically over the reals using Newton’s method. Use init as the initial guess for the root.

Examples

>>> from symbolica import Expression
>>> x, y, c = S('x', 'y', 'c')
>>> f = S('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)

nsolve_system

Expression.nsolve_system(
    system,
    variables,
    init,
    prec=0.0001,
    max_iterations=1000,
)

Find a common root of multiple expressions in variables numerically over the reals using Newton’s method. Use init as the initial guess for the root.

Examples

>>> from symbolica import Expression
>>> x, y, c = S('x', 'y', 'c')
>>> f = S('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)

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, default_namespace='python')

Parse a Symbolica expression from a string.

Parameters

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

Examples

>>> e = E('x^2+y+y*4')
>>> print(e)
x^2+5*y

Raises

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

rationalize

Expression.rationalize(relative_error=0.01)

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

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(
    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. The right-hand side can be an expression with wildcards, a held expression (see :meth:Expression.hold) or a function that maps a dictionary of wildcards to an expression.

Examples

>>> x, w1_, w2_ = S('x','w1_','w2_')
>>> f = S('f')
>>> e = f(3,x)
>>> r = e.replace(f(w1_,w2_), f(w1_ - 1, w2_**2), w1_ >= 1)
>>> print(r)

Parameters

Name Type Description Default
self The expression to match and replace on. required
pattern Expression | int | float | complex | Decimal The pattern to match. required
rhs HeldExpression | Expression | Callable[[dict[Expression, Expression]], Expression] | int | float | complex | 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 | Condition] 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_iter

Expression.replace_iter(
    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 *
>>> x_ = S('x_')
>>> f = S('f')
>>> e = f(1)*f(2)*f(3)
>>> for r in e.replace_iter(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 Expression | int | float | complex | Decimal The pattern to match. required
rhs HeldExpression | Expression | Callable[[dict[Expression, Expression]], Expression] | int | float | complex | 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 | Condition] 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_multiple

Expression.replace_multiple(replacements, repeat=False)

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

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

Examples

>>> x, y, f = S('x', 'y', 'f')
>>> e = f(x,y)
>>> r = e.replace_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 *
>>> x_ = S('x_')
>>> f = S('f')
>>> e = f(1)*f(2)*f(3)
>>> e = e.replace(f(x_), 1, x_.req(lambda m: m == 2 or m == 3))

req_attr

Expression.req_attr(attribute)

Create a pattern restriction based on the attribute of a matched variable or function.

Examples

>>> from symbolica import *
>>> x = S('f', is_linear=True)
>>> x_ = S('x_')
>>> print(E('f(x)').replace(E('x_(x)'), 1, ~S('x_').req_attr(SymbolAttribute.Linear)))
>>> print(e)

Yields f(x).

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 *
>>> x_, y_ = S('x_', 'y_')
>>> f = S('f')
>>> e = f(1)*f(2)*f(3)
>>> e = e.replace(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 *
>>> x_, y_ = S('x_', 'y_')
>>> f = S('f')
>>> e = f(1,2)
>>> e = e.replace(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 *
>>> x_, y_ = S('x_', 'y_')
>>> f = S('f')
>>> e = f(1,2)
>>> e = e.replace(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 *
>>> x_, y_ = S('x_', 'y_')
>>> f = S('f')
>>> e = f(1,2)
>>> e = e.replace(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 *
>>> x_, y_ = S('x_', 'y_')
>>> f = S('f')
>>> e = f(1,2)
>>> e = e.replace(f(x_,y_), 1, x_.req_cmp_lt(y_))

req_contains

Expression.req_contains(a)

Create a pattern restriction that filters for expressions that contain a.

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 *
>>> x_ = S('x_')
>>> f = S('f')
>>> e = f(1)*f(2)*f(3)
>>> e = e.replace(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 *
>>> x_ = S('x_')
>>> f = S('f')
>>> e = f(1)*f(2)*f(3)
>>> e = e.replace(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 *
>>> x_ = S('x_')
>>> f = S('f')
>>> e = f(1)*f(2)*f(3)
>>> e = e.replace(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 *
>>> x_ = S('x_')
>>> f = S('f')
>>> e = f(1)*f(2)*f(3)
>>> e = e.replace(f(x_), 1, x_.req_lt(2))

req_tag

Expression.req_tag(tag)

Create a pattern restriction based on the tag of a matched variable or function.

Examples

>>> from symbolica import *
>>> x = S('x', tags=['a', 'b'])
>>> x_ = S('x_')
>>> e = x.replace(x_, 1, x_.req_tag('b'))
>>> print(e)
Yields `1`.

req_type

Expression.req_type(atom_type)

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

Examples

>>> from symbolica import *, AtomType
>>> x, x_ = S('x', 'x_')
>>> f = S('f')
>>> e = f(x)*f(2)*f(f(3))
>>> e = e.replace(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.

Examples

>>> from symbolica import Expression
>>> x, y = S('x', 'y')
>>> f = S('f')
>>>
>>> e = 2* x**2 * y + f(x)
>>> e = e.series(x, 0, 2)
>>>
>>> print(e)

yields f(0)+x*der(1,f(0))+1/2*x^2*(der(2,f(0))+4*y).

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

sin

Expression.sin()

Compute the sine of the expression.

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 *
>>> x, y, c = S('x', 'y', 'c')
>>> f = S('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)

sqrt

Expression.sqrt()

Compute the square root of the expression.

to_atom_tree

Expression.to_atom_tree()

Convert the expression to a tree.

to_canonical_string

Expression.to_canonical_string()

Convert the expression into a canonical string that is independent on the order of the variables and other implementation details.

to_float

Expression.to_float(decimal_prec=16)

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.

to_latex

Expression.to_latex()

Convert the expression into a LaTeX string.

Examples

>>> a = E('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 = E('(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(E('x^2+f((1+x)^y)').to_sympy())

together

Expression.together()

Write the expression over a common denominator.

Examples

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