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())
+6)**-4 (x
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)
^2+5*y x
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)
**2 + 5 x
Define a regular symbol and use it as a function:
>>> f = Expression.symbol('f')
>>> e = f(1,2)
>>> print(e)
1,2) f(
Define a symmetric function:
>>> f = Expression.symbol('f', is_symmetric=True)
>>> e = f(2,1)
>>> print(e)
1,2) f(
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)
+2*dot(p1,p3)+3*dot(p2,p2)-dot(p2,p3)+6*dot(p2,p3)-2*dot(p3,p3) dot(p1,p2)
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.