Expression
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 |
|---|---|
ABS |
The built-in absolute value function. |
COEFF |
The built-in function that convert a rational polynomials to a coefficient. |
COMPLEX_INFINITY |
The number that represents infinity with an unknown complex phase: ∞. |
CONJ |
The built-in complex conjugate function. |
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. |
IF |
The built-in function for piecewise-defined expressions |
INDETERMINATE |
The number that represents indeterminacy: ¿. |
INFINITY |
The number that represents infinity: ∞. |
LOG |
The built-in logarithm function. |
PI |
The mathematical constant π. |
SIN |
The built-in sine function. |
SQRT |
The built-in square root function. |
ABS
ABS: ExpressionThe built-in absolute value function.
COEFF
COEFF: ExpressionThe built-in function that convert a rational polynomials to a coefficient.
COMPLEX_INFINITY
COMPLEX_INFINITY: ExpressionThe number that represents infinity with an unknown complex phase: ∞.
CONJ
CONJ: ExpressionThe built-in complex conjugate function.
COS
COS: ExpressionThe built-in cosine function.
E
E: ExpressionEuler’s number e.
EXP
EXP: ExpressionThe built-in exponential function.
I
I: ExpressionThe mathematical constant i, where i^2 = -1.
IF
IF: ExpressionThe built-in function for piecewise-defined expressions. IF(cond, true_expr, false_expr) evaluates to true_expr if cond is non-zero and false_expr otherwise.
INDETERMINATE
INDETERMINATE: ExpressionThe number that represents indeterminacy: ¿.
INFINITY
INFINITY: ExpressionThe number that represents infinity: ∞.
LOG
LOG: ExpressionThe built-in logarithm function.
PI
PI: ExpressionThe mathematical constant π.
SIN
SIN: ExpressionThe built-in sine function.
SQRT
SQRT: ExpressionThe built-in square root function.
Methods
| Name | Description |
|---|---|
__add__ |
Add this expression to other, returning the result. |
__call__ |
Create a Symbolica expression or transformer by calling the function with appropriate arguments. |
__copy__ |
Copy the expression. |
__eq__ |
Compare two expressions. |
__ge__ |
Compare two expressions |
__getitem__ |
Get the idxth component of the expression. |
__gt__ |
Compare two expressions |
__hash__ |
Hash the expression. |
__iter__ |
Create an iterator over all subexpressions of the expression. |
__le__ |
Compare two expressions |
__len__ |
Return the number of terms in this expression. |
__lt__ |
Compare two expressions |
__mul__ |
Multiply this expression with other, returning the result. |
__neg__ |
Negate the current expression, returning the result. |
__neq__ |
Compare two expressions. |
__new__ |
Create a new expression that represents 0. |
__pow__ |
Take self to power exp, returning the result. |
__radd__ |
Add this expression to other, returning the result. |
__rmul__ |
Multiply this expression with other, returning the result. |
__rpow__ |
Take base to power self, returning the result. |
__rsub__ |
Subtract this expression from other, returning the result. |
__rtruediv__ |
Divide other by this expression, returning the result. |
__rxor__ |
Returns a warning that ** should be used instead of ^ for taking a power. |
__str__ |
Convert the expression into a human-readable string. |
__sub__ |
Subtract other from this expression, returning the result. |
__truediv__ |
Divide this expression by other, returning the result. |
__xor__ |
Returns a warning that ** should be used instead of ^ for taking a power. |
abs |
Take the absolute value of this expression, returning the result. |
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 are variables or functions |
collect |
Collect terms involving the same power of the indeterminate(s) x |
collect_factors |
Collect common factors from (nested) sums. |
collect_horner |
Iteratively extract the minimal common powers of an indeterminate v for every term that contains v and continue to the next indeterminate in variables |
collect_num |
Collect numerical factors by removing the content from additions |
collect_symbol |
Collect terms involving the same power of variables or functions with the name x |
conj |
Take the complex conjugate of this expression, returning the result. |
contains |
Returns true iff self contains a literally. |
cos |
Take the cosine of this expression, returning the result. |
derivative |
Derive the expression w.r.t the variable x. |
evaluate |
Evaluate the expression, using a map of all the variables and user functions to a float. |
evaluate_complex |
Evaluate the expression, using a map of all the variables and user functions to a complex number. |
evaluate_with_prec |
Evaluate the expression, using a map of all the constants and user functions using arbitrary precision arithmetic |
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 |
Take the exponential of this expression, returning the result. |
expand |
Expand the expression |
expand_num |
Distribute numbers in the expression, for example: 2*(x+y) -> 2*x+2*y. |
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 including function symbols |
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 is a variable or function, otherwise throw an error. |
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 is a variable or function, otherwise throw an error. |
get_symbol_data |
Get the data of a variable or function if the current atom is a variable or function, otherwise throw an error |
get_tags |
Get the tags of a variable or function if the current atom is a variable or function, otherwise throw an error. |
get_type |
Get the type of the atom. |
hold |
Create a held expression that delays the execution of the transformer t until the resulting held expression is called |
is_constant |
Check if the expression is constant, i.e |
is_finite |
Check if the expression has no infinities and is not indeterminate. |
is_integer |
Check if the expression is integer |
is_positive |
Check if the expression is a positive scalar |
is_real |
Check if the expression is real |
is_scalar |
Check if the expression is a scalar |
is_type |
Test if the expression is of a certain type. |
load |
Load an expression and its state from a file |
log |
Take the logarithm of this expression, returning the result. |
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, or a string |
parse |
Parse a Symbolica expression from a string. |
rationalize |
Map all floating point and rational coefficients to the best rational approximation in the interval [self*(1-relative_error),self*(1+relative_error)]. |
replace |
Replace all subexpressions 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 |
replace_wildcards |
Replace all wildcards in the expression with the corresponding values in replacements |
req |
Create a new pattern restriction that calls the function filter_fn with the matched atom that should return a boolean |
req_attr |
Create a pattern restriction based on the attributes of a matched variable or function. |
req_cmp |
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 |
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, so that it only matches to itself. |
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 |
Take the sine of this expression, returning the result. |
solve_linear_system |
Solve a linear system in the variables variables, where each expression in the system is understood to yield 0 |
sqrt |
Take the square root of this expression, returning the result. |
symbol |
Create new symbols from names |
to_atom_tree |
Convert the expression to a tree. |
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 |
Convert all coefficients and built-in functions to floats with a given precision decimal_prec |
to_int |
Convert the expression to an integer if possible |
to_latex |
Convert the expression into a LaTeX string. |
to_mathematica |
Convert the expression into a Mathematica-parsable string. |
to_polynomial |
Convert the expression to a polynomial, optionally, with the variable ordering specified in vars |
to_rational_polynomial |
Convert the expression to a rational polynomial, optionally, with the variable ordering specified in vars |
to_sympy |
Convert the expression into a sympy-parsable string. |
to_typst |
Convert the expression into a Typst string. |
together |
Write the expression over a common denominator. |
__add__
Expression.__add__(other: Expression | int | float | complex | Decimal) -> ExpressionAdd this expression to other, returning the result.
Parameters
other(Expression | int | float | complex | Decimal) The other operand to combine or compare with.
__call__
__call__ has 2 variants:
Examples
x, f = S('x', 'f')
e = f(3,x)
print(e) # f(3,x)__call__ returning Expression
Expression.__call__(*args: Expression | int | float | complex | Decimal) -> ExpressionParameters
args(Expression | int | float | complex | Decimal) The arguments passed to the expression call.
__call__ returning HeldExpression
Expression.__call__(*args: HeldExpression | Expression | int | float | complex | Decimal) -> HeldExpressionParameters
args(HeldExpression | Expression | int | float | complex | Decimal) The arguments passed to the expression or transformer call.
__copy__
Expression.__copy__() -> ExpressionCopy the expression.
__eq__
Expression.__eq__(other: Expression | int | float | complex | Decimal) -> ConditionCompare two expressions.
Parameters
other(Expression | int | float | complex | Decimal) The other operand to combine or compare with.
__ge__
Expression.__ge__(other: Expression | int | float | complex | Decimal) -> ConditionCompare two expressions. If any of the two expressions is not a rational number, an interal ordering is used.
Parameters
other(Expression | int | float | complex | Decimal) The other operand to combine or compare with.
__getitem__
Expression.__getitem__(idx: int) -> ExpressionGet the idxth component of the expression.
Parameters
idx(int) The zero-based index to access.
__gt__
Expression.__gt__(other: Expression | int | float | complex | Decimal) -> ConditionCompare two expressions. If any of the two expressions is not a rational number, an interal ordering is used.
Parameters
other(Expression | int | float | complex | Decimal) The other operand to combine or compare with.
__hash__
Expression.__hash__() -> intHash the expression.
__iter__
Expression.__iter__() -> Iterator[Expression]Create an iterator over all subexpressions of the expression.
__le__
Expression.__le__(other: Expression | int | float | complex | Decimal) -> ConditionCompare two expressions. If any of the two expressions is not a rational number, an interal ordering is used.
Parameters
other(Expression | int | float | complex | Decimal) The other operand to combine or compare with.
__len__
Expression.__len__() -> intReturn the number of terms in this expression.
__lt__
Expression.__lt__(other: Expression | int | float | complex | Decimal) -> ConditionCompare two expressions. If any of the two expressions is not a rational number, an interal ordering is used.
Parameters
other(Expression | int | float | complex | Decimal) The other operand to combine or compare with.
__mul__
Expression.__mul__(other: Expression | int | float | complex | Decimal) -> ExpressionMultiply this expression with other, returning the result.
Parameters
other(Expression | int | float | complex | Decimal) The other operand to combine or compare with.
__neg__
Expression.__neg__() -> ExpressionNegate the current expression, returning the result.
__neq__
Expression.__neq__(other: Expression | int | float | complex | Decimal) -> ConditionCompare two expressions.
Parameters
other(Expression | int | float | complex | Decimal) The other operand to combine or compare with.
__new__
Expression.__new__() -> ExpressionCreate a new expression that represents 0.
__pow__
Expression.__pow__(exp: Expression | int | float | complex | Decimal) -> ExpressionTake self to power exp, returning the result.
Parameters
exp(Expression | int | float | complex | Decimal) The exponent.
__radd__
Expression.__radd__(other: Expression | int | float | complex | Decimal) -> ExpressionAdd this expression to other, returning the result.
Parameters
other(Expression | int | float | complex | Decimal) The other operand to combine or compare with.
__rmul__
Expression.__rmul__(other: Expression | int | float | complex | Decimal) -> ExpressionMultiply this expression with other, returning the result.
Parameters
other(Expression | int | float | complex | Decimal) The other operand to combine or compare with.
__rpow__
Expression.__rpow__(base: Expression | int | float | complex | Decimal) -> ExpressionTake base to power self, returning the result.
Parameters
base(Expression | int | float | complex | Decimal) The base expression.
__rsub__
Expression.__rsub__(other: Expression | int | float | complex | Decimal) -> ExpressionSubtract this expression from other, returning the result.
Parameters
other(Expression | int | float | complex | Decimal) The other operand to combine or compare with.
__rtruediv__
Expression.__rtruediv__(other: Expression | int | float | complex | Decimal) -> ExpressionDivide other by this expression, returning the result.
Parameters
other(Expression | int | float | complex | Decimal) The other operand to combine or compare with.
__rxor__
Expression.__rxor__(a: Any) -> ExpressionReturns a warning that ** should be used instead of ^ for taking a power.
Parameters
a(Any) The operand passed with^; use**for exponentiation instead.
__str__
Expression.__str__() -> strConvert the expression into a human-readable string.
__sub__
Expression.__sub__(other: Expression | int | float | complex | Decimal) -> ExpressionSubtract other from this expression, returning the result.
Parameters
other(Expression | int | float | complex | Decimal) The other operand to combine or compare with.
__truediv__
Expression.__truediv__(other: Expression | int | float | complex | Decimal) -> ExpressionDivide this expression by other, returning the result.
Parameters
other(Expression | int | float | complex | Decimal) The other operand to combine or compare with.
__xor__
Expression.__xor__(a: Any) -> ExpressionReturns a warning that ** should be used instead of ^ for taking a power.
Parameters
a(Any) The operand passed with^; use**for exponentiation instead.
abs
Expression.abs() -> ExpressionTake the absolute value of this expression, returning the result.
apart
Expression.apart(x: Expression | None = None) -> ExpressionCompute 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
Parameters
x(Expression | None) The variable with respect to which to perform the partial-fraction decomposition.
cancel
Expression.cancel() -> ExpressionCancel 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: Sequence[tuple[Expression | int, Expression | int]]) -> tuple[Expression, list[tuple[Expression, Expression]], list[tuple[Expression, Expression]]]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.
Returns the canonical expression, as well as the external indices and ordered dummy indices appearing in the canonical expression.
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)
(r, external, dummy) = e.canonize_tensors([(mu1, 0), (mu2, 0), (mu3, 0), (mu4, 0)])
print(r)yields g(mu1, mu2)*fc(mu1, mu3, mu2, k1, mu3, k1).
Parameters
contracted_indices(Sequence[tuple[Expression | int, Expression | int]]) The index patterns that should be treated as contracted, optionally grouped by a marker.
coefficient
Expression.coefficient(x: Expression) -> ExpressionCollect 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
Parameters
x(Expression) The variable whose coefficient should be extracted.
coefficient_list
Expression.coefficient_list(*x: Expression) -> Sequence[tuple[Expression, Expression]]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
Parameters
x(Expression) The variables whose coefficient exponents should be listed.
collect
Expression.collect(
*x: Expression,
key_map: Callable[[Expression], Expression] | None = None,
coeff_map: Callable[[Expression], Expression] | None = None,
) -> ExpressionCollect 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)) # x^2+x*(y+5)+5
from symbolica import *
x, y = S('x', 'y')
var, coeff = S('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
*x(Expression) The variable(s) or function(s) to collect terms in key_map A function to be applied to the quantity collected in coeff_map A function to be applied to the coefficient
collect_factors
Expression.collect_factors() -> ExpressionCollect 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_horner
Expression.collect_horner(vars: Sequence[Expression] | None = None) -> ExpressionIteratively extract the minimal common powers of an indeterminate v for every term that contains v and continue to the next indeterminate in variables. This is a generalization of Horner’s method for polynomials.
If no variables are provided, a heuristically determined variable ordering is used that minimizes the number of operations.
Examples
from symbolica import *
expr = E('v1 + v1*v2 + 2 v1*v2*v3 + v1^2 + v1^3*y + v1^4*z')
collected = expr.collect_horner([S('v1'), S('v2')])yields v1*(1+v1*(1+v1*(v1*z+y))+v2*(1+2*v3)).
Parameters
vars(Sequence[Expression] | None) The variables treated as polynomial variables, in the given order.
collect_num
Expression.collect_num() -> ExpressionCollect 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: Expression,
key_map: Callable[[Expression], Expression] | None = None,
coeff_map: Callable[[Expression], Expression] | None = None,
) -> ExpressionCollect 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)) # (1+x)*f(1,2)Parameters
x(Expression) The symbol to collect in key_map A function to be applied to the quantity collected in coeff_map A function to be applied to the coefficient
conj
Expression.conj() -> ExpressionTake the complex conjugate of this expression, returning the result.
Examples
e = E('x+2 + 3^x + (5+2i) * (test::{real}::real) + (-2)^x')
print(e.conj())Yields (5-2𝑖)*real+3^conj(x)+conj(x)+conj((-2)^x)+2.
contains
Expression.contains(a: Transformer | HeldExpression | Expression | int | float | Decimal) -> ConditionReturns 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) # FalseParameters
a(Transformer | HeldExpression | Expression | int | float | Decimal) The subexpression or pattern that should be contained literally.
cos
Expression.cos() -> ExpressionTake the cosine of this expression, returning the result.
derivative
Expression.derivative(x: Expression) -> ExpressionDerive the expression w.r.t the variable x.
Parameters
x(Expression) The variable with respect to which to differentiate.
evaluate
Expression.evaluate(
constants: dict[Expression, float],
functions: dict[Expression, Callable[[Sequence[float]], float]],
) -> floatEvaluate 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]}))Parameters
constants(dict[Expression, float]) The constant substitutions applied during evaluation.functions(dict[Expression, Callable[[Sequence[float]], float]]) The function callback table used during evaluation.
evaluate_complex
Expression.evaluate_complex(
constants: dict[Expression, float | complex],
functions: dict[Expression, Callable[[Sequence[complex]], float | complex]],
) -> complexEvaluate 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}, {}))Parameters
constants(dict[Expression, float | complex]) The constant substitutions applied during evaluation.functions(dict[Expression, Callable[[Sequence[complex]], float | complex]]) The function callback table used during evaluation.
evaluate_with_prec
Expression.evaluate_with_prec(
constants: dict[Expression, float | str | Decimal],
functions: dict[Expression, Callable[[Sequence[Decimal]], float | str | Decimal]],
decimal_digit_precision: int,
) -> DecimalEvaluate 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)Parameters
constants(dict[Expression, float | str | Decimal]) The constant substitutions applied during evaluation.functions(dict[Expression, Callable[[Sequence[Decimal]], float | str | Decimal]]) The function callback table used during evaluation.decimal_digit_precision(int) The decimal precision used for arbitrary-precision evaluation.
evaluator
Expression.evaluator(
constants: dict[Expression, Expression],
functions: dict[tuple[Expression, str, Sequence[Expression]], Expression],
params: Sequence[Expression],
iterations: int = 1,
cpe_iterations: int | None = None,
n_cores: int = 4,
verbose: bool = False,
jit_compile: bool = True,
direct_translation: bool = True,
max_horner_scheme_variables: int = 500,
max_common_pair_cache_entries: int = 1000000,
max_common_pair_distance: int = 100,
external_functions: dict[tuple[Expression, str], Callable[[Sequence[float | complex]], float | complex]] | None = None,
conditionals: Sequence[Expression] | None = None,
) -> EvaluatorCreate 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
constants(dict[Expression, Expression]) A map of expressions to constants. The constants should be numerical expressions.functions(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. If the function name entry contains arguments, these are considered tags.params(Sequence[Expression]) A list of free parameters.iterations(int, optional) The number of Horner schemes to try.cpe_iterations(int | None, optional) The number of CPE iterations to perform. The number if unbounded ifNone.n_cores(int, optional) The number of CPU cores used for the optimization.verbose(bool, optional) Print the progress of the optimization.jit_compile(bool, optional) Just-in-time compile the evaluator upon first use with SymJIT. This can provide significant performance improvements.direct_translation(bool, optional) If set toTrue, the optimized expression will be directly constructed from atoms without building a tree.max_horner_scheme_variables(int, optional) The maximum number of variables in a Horner scheme.max_common_pair_cache_entries(int, optional) The maximum number of entries in the common pair cache.max_common_pair_distance(int, optional) The maximum distance between common pairs. Used when clearing cache entries.external_functions(dict[tuple[Expression, str], Callable[[Sequence[float | complex]], float | complex]] | None) A dictionary of external functions that can be called during evaluation. The key is a tuple of the function symbol and a printable function name. The value is a callable that takes a list of arguments and returns a float or complex number. This is useful for functions that are not defined in Symbolica but are available in Python.conditionals(Sequence[Expression] | None, optional) A list of conditional functions. These functions should take three argument: a condition that is tested for inequality with 0, the true branch and the false branch.
evaluator_multiple
Expression.evaluator_multiple(
exprs: Sequence[Expression],
constants: dict[Expression, Expression],
functions: dict[tuple[Expression, str, Sequence[Expression]], Expression],
params: Sequence[Expression],
iterations: int = 1,
cpe_iterations: int | None = None,
n_cores: int = 4,
verbose: bool = False,
jit_compile: bool = True,
direct_translation: bool = True,
max_horner_scheme_variables: int = 500,
max_common_pair_cache_entries: int = 1000000,
max_common_pair_distance: int = 100,
external_functions: dict[tuple[Expression, str], Callable[[Sequence[float | complex]], float | complex]] | None = None,
conditionals: Sequence[Expression] | None = None,
) -> EvaluatorCreate 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
Parameters
exprs(Sequence[Expression]) The expressions to compile into a joint evaluator.constants(dict[Expression, Expression]) The symbolic substitutions applied to constant symbols when building the evaluator.functions(dict[tuple[Expression, str, Sequence[Expression]], Expression]) The symbolic function implementations applied when building the evaluator.params(Sequence[Expression]) The evaluator parameters, in input order.iterations(int) The number of optimization passes to run.cpe_iterations(int | None) The number of common subexpression elimination iterations to perform.n_cores(int) The number of CPU cores used for parallel optimization.verbose(bool) Whether verbose output should be enabled.jit_compile(bool) Whether JIT compilation should be enabled.direct_translation(bool) Whether to prefer direct translation when compiling the evaluator.max_horner_scheme_variables(int) The maximum number of variables considered for Horner-scheme optimization.max_common_pair_cache_entries(int) The maximum number of common-subexpression pairs to cache.max_common_pair_distance(int) The maximum distance between factors when searching for common pairs.external_functions(dict[tuple[Expression, str], Callable[[ Sequence[float | complex]], float | complex]] | None) The external functions to register.conditionals(Sequence[Expression] | None) Expressions that should be treated as conditional branches during evaluator construction.
exp
Expression.exp() -> ExpressionTake the exponential of this expression, returning the result.
expand
Expression.expand(var: Expression | None = None, via_poly: bool | None = None) -> ExpressionExpand the expression. Optionally, expand in var only. var can be a variable or a function. If it is a variable, any function with that variable name is also expanded in. To expand in multiple functions at the same time, wrap them in a function with the same symbol first, using a match and replace, and then expand in that function.
Using via_poly=True may give a significant speedup for large expressions.
Examples
from symbolica import *
x, y, f, g = S('x', 'y', 'f', 'g')
e = (f(1) + g(2))*(f(3) + (y+1)**2)
print(e.expand(f))yields f(1)*f(3)+f(3)*g(2)+(1+y)^2*f(1)+(1+y)^2*g(2).
Parameters
var(Expression | None) The variable to expand with respect to. If omitted, expand all variables.via_poly(bool | None) Whether the operation should use an intermediate polynomial representation.
expand_num
Expression.expand_num() -> ExpressionDistribute 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() -> ExpressionFactor 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)**-4format
Expression.format(
mode: PrintMode = PrintMode.Symbolica,
max_line_length: int | None = 80,
indentation: int = 4,
fill_indented_lines: bool = True,
terms_on_new_line: bool = False,
color_top_level_sum: bool = True,
color_builtin_symbols: bool = True,
bracket_level_colors: Sequence[int] | None = [244, 25, 97, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60],
print_ring: bool = True,
symmetric_representation_for_finite_field: bool = False,
explicit_rational_polynomial: bool = False,
number_thousands_separator: str | None = None,
multiplication_operator: str = '*',
double_star_for_exponentiation: bool = False,
square_brackets_for_function: bool = False,
function_brackets: tuple[str, str] = ('(', ')'),
num_exp_as_superscript: bool = True,
show_namespaces: bool = False,
hide_namespace: str | None = None,
include_attributes: bool = False,
max_terms: int | None = 100,
custom_print_mode: int | None = None,
) -> strConvert 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]
Parameters
mode(PrintMode) The mode that controls how the input is interpreted or formatted.max_line_length(int | None) The preferred maximum line length before wrapping.indentation(int) The number of spaces used for wrapped lines.fill_indented_lines(bool) Whether wrapped lines should be padded to the configured indentation.terms_on_new_line(bool) Whether wrapped output should place terms on separate lines.color_top_level_sum(bool) Whether top-level sums should be colorized.color_builtin_symbols(bool) Whether built-in symbols should be colorized.bracket_level_colors(Sequence[int] | None) The colors assigned to successive nested bracket levels.print_ring(bool) Whether the coefficient ring should be included in the printed output.symmetric_representation_for_finite_field(bool) Whether finite-field elements should be printed using symmetric representatives.explicit_rational_polynomial(bool) Whether rational polynomials should be printed explicitly as numerator and denominator.number_thousands_separator(str | None) The separator inserted between groups of digits in printed integers.multiplication_operator(str) The string used to print multiplication.double_star_for_exponentiation(bool) Whether exponentiation should be printed as**instead of^.square_brackets_for_function(bool) Whether function calls should be printed with square brackets.function_brackets(tuple[str, str]) The opening and closing brackets used when printing function arguments.num_exp_as_superscript(bool) Whether small integer exponents should be printed as superscripts.show_namespaces(bool) Whether namespaces should be included in the formatted output.hide_namespace(str | None) A namespace prefix to omit from printed symbol names.include_attributes(bool) Whether symbol attributes should be included in the printed output.max_terms(int | None) The maximum number of terms to print before truncating the output.custom_print_mode(int | None) A custom print-mode identifier passed through to custom print callbacks.
format_plain
Expression.format_plain() -> strConvert 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: bool = True) -> Sequence[Expression]Get all symbols and functions in the current expression, optionally including function symbols. The symbols are sorted in Symbolica’s internal ordering.
Parameters
enter_functions(bool) Whether function arguments should be traversed when collecting indeterminates.
get_all_symbol_names
Expression.get_all_symbol_names() -> list[str]Return all defined symbol names (function names and variables).
get_all_symbols
Expression.get_all_symbols(include_function_symbols: bool = True) -> Sequence[Expression]Get all symbols in the current expression, optionally including function symbols. The symbols are sorted in Symbolica’s internal ordering.
Parameters
include_function_symbols(bool) Whether function symbols should be included in the collected symbol set.
get_attributes
Expression.get_attributes() -> list[SymbolAttribute]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() -> intGet the number of bytes that this expression takes up in memory.
get_name
Expression.get_name() -> strGet the name of a variable or function if the current atom is a variable or function, otherwise throw an error.
get_symbol_data
Expression.get_symbol_data(key: str | int | Expression | None = None) -> str | int | Expression | bytes | dict[str | int | Expression, Any] | list[Any]Get the data of a variable or function if the current atom is a variable or function, otherwise throw an error. Optionally, provide a key to access a specific entry in the data map, if the data is a map.
Examples
x = S('x', data={'my_tag': 'my_value'})
print(x.get_symbol_data('my_tag')) # my_value
y = S('y', data=3)
print(y.get_symbol_data()) # 3Parameters
key(str | int | Expression | None) The symbol-data key to retrieve. Omit it to return all stored data.
get_type
Expression.get_type() -> AtomTypeGet the type of the atom.
hold
Expression.hold(t: Transformer) -> HeldExpressionCreate 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())))Parameters
t(Transformer) The transformer to bind to the expression.
is_constant
Expression.is_constant() -> boolCheck 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()) # Trueis_finite
Expression.is_finite() -> boolCheck if the expression has no infinities and is not indeterminate.
Examples
e = E('1/x + x^2 + log(0)')
print(e.is_finite()) # Falseis_integer
Expression.is_integer() -> boolCheck 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()) # Trueis_positive
Expression.is_positive() -> boolCheck if the expression is a positive scalar. Symbols must have the positive attribute.
Examples
x = S('x', is_positive=True)
e = (x + 1)**2 + 5
print(e.is_positive()) # Trueis_real
Expression.is_real() -> boolCheck 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()) # Trueis_scalar
Expression.is_scalar() -> boolCheck 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()) # Trueis_type
Expression.is_type(atom_type: AtomType) -> ConditionTest if the expression is of a certain type.
Parameters
atom_type(AtomType) The atom type to test or require.
load
Expression.load(filename: str, conflict_fn: Callable[[str], str] | None = None) -> ExpressionLoad 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).
Parameters
filename(str) The file path to load from or save to.conflict_fn(Callable[[str], str] | None) A callback that resolves symbol conflicts during loading.
log
Expression.log() -> ExpressionTake the logarithm of this expression, returning the result.
map
Expression.map(
transformations: Transformer,
n_cores: int | None = 1,
stats_to_file: str | None = None,
) -> ExpressionMap 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
transformations(Transformer) The transformations to apply.n_cores(int, optional) The number of CPU cores used for parallel execution.stats_to_file(str, optional) If set, the output of thestatstransformer will be written to a file in JSON format.
match
Expression.match(
lhs: Expression | int | float | complex | Decimal,
cond: PatternRestriction | Condition | None = None,
min_level: int = 0,
max_level: int | None = None,
level_range: tuple[int, int | None] | None = None,
level_is_tree_depth: bool = False,
partial: bool = True,
allow_new_wildcards_on_rhs: bool = False,
) -> MatchIteratorReturn 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])Parameters
lhs(Expression | int | float | complex | Decimal) The expression to match against.cond(PatternRestriction | Condition | None) An additional restriction that a match or replacement must satisfy.min_level(int) The minimum level at which a match is allowed.max_level(int | None) The maximum level at which a match is allowed.level_range(tuple[int, int | None] | None) The(min_level, max_level)range in which matches are allowed.level_is_tree_depth(bool) Whether levels should be measured by tree depth instead of function nesting.partial(bool) Whether matches are allowed inside larger expressions instead of only at the top level.allow_new_wildcards_on_rhs(bool) Whether wildcards that appear only on the right-hand side are allowed.
matches
Expression.matches(
lhs: Expression | int | float | complex | Decimal,
cond: PatternRestriction | Condition | None = None,
min_level: int = 0,
max_level: int | None = None,
level_range: tuple[int, int | None] | None = None,
level_is_tree_depth: bool = False,
partial: bool = True,
allow_new_wildcards_on_rhs: bool = False,
) -> ConditionTest 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')Parameters
lhs(Expression | int | float | complex | Decimal) The expression to match against.cond(PatternRestriction | Condition | None) An additional restriction that a match or replacement must satisfy.min_level(int) The minimum level at which a match is allowed.max_level(int | None) The maximum level at which a match is allowed.level_range(tuple[int, int | None] | None) The(min_level, max_level)range in which matches are allowed.level_is_tree_depth(bool) Whether levels should be measured by tree depth instead of function nesting.partial(bool) Whether matches are allowed inside larger expressions instead of only at the top level.allow_new_wildcards_on_rhs(bool) Whether wildcards that appear only on the right-hand side are allowed.
nsolve
nsolve has 2 variants:
nsolve returning float
Expression.nsolve(
variable: Expression,
init: float,
prec: float = 0.0001,
max_iter: int = 10000,
) -> floatExamples
from symbolica import *
a = E("x^2-2").nsolve(E("x"), 1., 0.0001, 1000000)Parameters
variable(Expression) The variable to solve for.init(float) The initial guess for Newton’s method.prec(float) The numerical tolerance for the Newton iteration.max_iter(int) The maximum number of Newton iterations.
nsolve returning Decimal
Expression.nsolve(
variable: Expression,
init: Decimal,
prec: float = 0.0001,
max_iter: int = 10000,
) -> DecimalExamples
from symbolica import *
a = E("x^2-2").nsolve(E("x"),
Decimal("1.000000000000000000000000000000000000000000000000000000000000000000000000"), 1e-74, 1000000)Parameters
variable(Expression) The variable to solve for.init(Decimal) The initial guess for Newton’s method.prec(float) The numerical tolerance for the Newton iteration.max_iter(int) The maximum number of Newton iterations.
nsolve_system
nsolve_system has 2 variants:
nsolve_system returning Sequence[float]
Expression.nsolve_system(
system: Sequence[Expression],
variables: Sequence[Expression],
init: Sequence[float],
prec: float = 0.0001,
max_iter: int = 10000,
) -> Sequence[float]Examples
from symbolica import *
a = Expression.nsolve_system([E("5x^2+x*y^2+sin(2y)^2 - 2"), E("exp(2x-y)+4y - 3")], [S("x"), S("y")],
[1., 1.], 1e-20, 1000000)Parameters
system(Sequence[Expression]) The equations or polynomials that define the system.variables(Sequence[Expression]) The variables to solve for, in order.init(Sequence[float]) The initial guess for Newton’s method.prec(float) The numerical tolerance for the Newton iteration.max_iter(int) The maximum number of Newton iterations.
nsolve_system returning Sequence[Decimal]
Expression.nsolve_system(
system: Sequence[Expression],
variables: Sequence[Expression],
init: Sequence[Decimal],
prec: float = 0.0001,
max_iter: int = 10000,
) -> Sequence[Decimal]Examples
from symbolica import *
a = Expression.nsolve_system([E("5x^2+x*y^2+sin(2y)^2 - 2"), E("exp(2x-y)+4y - 3")], [S("x"), S("y")],
[Decimal("1.00000000000000000"), Decimal("1.00000000000000000")], 1e-20, 1000000)Parameters
system(Sequence[Expression]) The equations or polynomials that define the system.variables(Sequence[Expression]) The variables to solve for, in order.init(Sequence[Decimal]) The initial guess for Newton’s method.prec(float) The numerical tolerance for the Newton iteration.max_iter(int) The maximum number of Newton iterations.
num
Expression.num(
num: int | float | complex | str | Decimal,
relative_error: float | None = None,
) -> ExpressionCreate 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/2print(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-1Parameters
num(int | float | complex | str | Decimal) The value to convert into a Symbolica number.relative_error(float | None) The maximum relative error used when converting floating-point input to a rational number.
parse
Expression.parse(
input: str,
mode: ParseMode = ParseMode.Symbolica,
default_namespace: str | None = None,
) -> ExpressionParse a Symbolica expression from a string.
Examples
e = E('x^2+y+y*4')
print(e) # x^2+5*yParse a Mathematica expression:
e = E('Cos[test`x] (2 + 3 I)', mode=ParseMode.Mathematica)
print(e) # cos(test::x)(2+3i)Parameters
input(str) An input string. UTF-8 characters are allowed.mode(ParseMode) The parsing mode. UseParseMode.Mathematicato parse Mathematica expressions.default_namespace(str) The namespace assumed for unqualified symbols during parsing.
Raises
ValueError: If the input is not a valid expression.
rationalize
Expression.rationalize(relative_error: float = 0.01) -> ExpressionMap all floating point and rational coefficients to the best rational approximation in the interval [self*(1-relative_error),self*(1+relative_error)].
Parameters
relative_error(float) The maximum relative error used when converting floating-point input to a rational number.
replace
Expression.replace(
pattern: Expression | int | float | complex | Decimal,
rhs: HeldExpression | Expression | Callable[[dict[Expression, Expression]], Expression] | int | float | complex | Decimal,
cond: PatternRestriction | Condition | None = None,
non_greedy_wildcards: Sequence[Expression] | None = None,
min_level: int = 0,
max_level: int | None = None,
level_range: tuple[int, int | None] | None = None,
level_is_tree_depth: bool = False,
partial: bool = True,
allow_new_wildcards_on_rhs: bool = False,
rhs_cache_size: int | None = None,
repeat: bool = False,
once: bool = False,
bottom_up: bool = False,
nested: bool = False,
) -> ExpressionReplace 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
selfThe expression to match and replace on.patternThe pattern to match.rhsThe 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.cond(PatternRestriction | Condition, optional) Conditions on the pattern.non_greedy_wildcards(Sequence[Expression], optional) Wildcards that try to match as little as possible.min_level(int, optional) The minimum 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 onlevel_is_tree_depth.max_level(int | None, optional) The maximum level at which the pattern is allowed to match.Nonemeans no maximum.level_rangeSpecifies 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 onlevel_is_tree_depth. Prefer settingmin_levelandmax_leveldirectly overlevel_range, as this argument will be deprecated in the future.level_is_tree_depth(bool, optional) If set toTrue, the level is increased when going one level deeper in the expression tree.partial(bool, optional) If set toTrue, allow the pattern to match to a part of a term. For example, withpartial=True, the patternx+ymatches tox+2+y.allow_new_wildcards_on_rhs(bool, optional) If set toTrue, allow wildcards that do not appear in the pattern on the right-hand side.rhs_cache_size(int, optional) Cache the firstrhs_cache_sizesubstituted patterns. If set toNone, 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.repeat(bool, optional) If set toTrue, the entire operation will be repeated until there are no more matches.once(bool, optional) If set toTrue, only the first match will be replaced, instead of all non-overlapping matches.bottom_up(bool, optional) Replace deepest nested matches first instead of replacing the outermost matches first. For example, replacingf(x_)withx_^2inf(f(x))would yieldf(x)^2with the default settings andf(x^2)with bottom-up replacement.nested(bool, optional) Replace nested matches, starting from the deepest first and acting on the result of that replacement. For example, replacingf(x_)withx_^2inf(f(x))would yieldf(x)^2with the default settings andf(x^2)^2with nested replacement.
replace_iter
Expression.replace_iter(
lhs: Expression | int | float | complex | Decimal,
rhs: HeldExpression | Expression | Callable[[dict[Expression, Expression]], Expression] | int | float | complex | Decimal,
cond: PatternRestriction | Condition | None = None,
min_level: int = 0,
max_level: int | None = None,
level_range: tuple[int, int | None] | None = None,
level_is_tree_depth: bool = False,
partial: bool = True,
allow_new_wildcards_on_rhs: bool = False,
) -> ReplaceIteratorReturn 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
lhsThe pattern to match.rhsThe 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.condConditions on the pattern.min_level(int, optional) The minimum 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 onlevel_is_tree_depth.max_level(int | None, optional) The maximum level at which the pattern is allowed to match.Nonemeans no maximum.level_rangeSpecifies 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 onlevel_is_tree_depth. Prefer settingmin_levelandmax_leveldirectly overlevel_range, as this argument will be deprecated in the future.level_is_tree_depth(bool, optional) If set toTrue, the level is increased when going one level deeper in the expression tree.partial(bool, optional) If set toTrue, allow the pattern to match to a part of a term. For example, withpartial=True, the patternx+ymatches tox+2+y.allow_new_wildcards_on_rhs(bool, optional) If set toTrue, allow wildcards that do not appear in the pattern on the right-hand side.
replace_multiple
Expression.replace_multiple(
replacements: Sequence[Replacement],
repeat: bool = False,
once: bool = False,
bottom_up: bool = False,
nested: bool = False,
) -> ExpressionReplace 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
replacements(Sequence[Replacement]) The list of replacements to apply.repeat(bool, optional) If set toTrue, the entire operation will be repeated until there are no more matches.
replace_wildcards
Expression.replace_wildcards(replacements: dict[Expression, Expression]) -> ExpressionReplace all wildcards in the expression with the corresponding values in replacements. This function can be used to substitute the result from (see :meth:Expression.match) into its pattern.
Examples
x, x_, f= S('x', 'x_', 'f')
e = 1 + x + f(2)
p = f(x_)
r = next(e.match(p))
p.replace_wildcards(r)
f(2)Parameters
replacements(dict[Expression, Expression]) A map of wildcards to their replacements.
req
Expression.req(filter_fn: Callable[[Expression], bool | Condition]) -> PatternRestrictionCreate 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))Parameters
filter_fn(Callable[[Expression], bool | Condition]) A callback that filters partially constructed graphs.
req_attr
Expression.req_attr(tag: SymbolAttribute) -> PatternRestrictionCreate a pattern restriction based on the attributes 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) # f(x)Parameters
tag(SymbolAttribute) The tag to test or require.
req_cmp
Expression.req_cmp(
other: Expression | int | float | complex | Decimal,
cmp_fn: Callable[[Expression, Expression], bool | Condition],
) -> PatternRestrictionCreate 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))Parameters
other(Expression | int | float | complex | Decimal) The other operand to combine or compare with.cmp_fn(Callable[[Expression, Expression], bool | Condition]) The comparison callback applied to the matched values.
req_cmp_ge
Expression.req_cmp_ge(num: Expression, cmp_any_atom = False) -> PatternRestrictionCreate 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_))Parameters
num(Expression) The expression that the match is compared against.cmp_any_atom(Any) Whether the comparison may be satisfied by any atom in the expression instead of only the whole match.
req_cmp_gt
Expression.req_cmp_gt(num: Expression, cmp_any_atom = False) -> PatternRestrictionCreate 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_))Parameters
num(Expression) The expression that the match is compared against.cmp_any_atom(Any) Whether the comparison may be satisfied by any atom in the expression instead of only the whole match.
req_cmp_le
Expression.req_cmp_le(num: Expression, cmp_any_atom = False) -> PatternRestrictionCreate 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_))Parameters
num(Expression) The expression that the match is compared against.cmp_any_atom(Any) Whether the comparison may be satisfied by any atom in the expression instead of only the whole match.
req_cmp_lt
Expression.req_cmp_lt(num: Expression, cmp_any_atom = False) -> PatternRestrictionCreate 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_))Parameters
num(Expression) The expression that the match is compared against.cmp_any_atom(Any) Whether the comparison may be satisfied by any atom in the expression instead of only the whole match.
req_contains
Expression.req_contains(a: Expression) -> PatternRestrictionCreate a pattern restriction that filters for expressions that contain a.
Parameters
a(Expression) The expression that must occur inside the match.
req_ge
Expression.req_ge(
num: Expression | int | float | complex | Decimal,
cmp_any_atom = False,
) -> PatternRestrictionCreate 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))Parameters
num(Expression | int | float | complex | Decimal) The value that the match is compared against.cmp_any_atom(Any) Whether the comparison may be satisfied by any atom in the expression instead of only the whole match.
req_gt
Expression.req_gt(
num: Expression | int | float | complex | Decimal,
cmp_any_atom = False,
) -> PatternRestrictionCreate 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))Parameters
num(Expression | int | float | complex | Decimal) The value that the match is compared against.cmp_any_atom(Any) Whether the comparison may be satisfied by any atom in the expression instead of only the whole match.
req_le
Expression.req_le(
num: Expression | int | float | complex | Decimal,
cmp_any_atom = False,
) -> PatternRestrictionCreate 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))Parameters
num(Expression | int | float | complex | Decimal) The value that the match is compared against.cmp_any_atom(Any) Whether the comparison may be satisfied by any atom in the expression instead of only the whole match.
req_len
Expression.req_len(min_length: int, max_length: int | None) -> PatternRestrictionCreate a pattern restriction based on the wildcard length before downcasting.
Parameters
min_length(int) The minimum required match length.max_length(int | None) The maximum allowed match length.
req_lit
Expression.req_lit() -> PatternRestrictionCreate a pattern restriction that treats the wildcard as a literal variable, so that it only matches to itself.
req_lt
Expression.req_lt(
num: Expression | int | float | complex | Decimal,
cmp_any_atom = False,
) -> PatternRestrictionCreate 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))Parameters
num(Expression | int | float | complex | Decimal) The value that the match is compared against.cmp_any_atom(Any) Whether the comparison may be satisfied by any atom in the expression instead of only the whole match.
req_tag
Expression.req_tag(tag: str) -> PatternRestrictionCreate 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) # 1Parameters
tag(str) The tag to test or require.
req_type
Expression.req_type(atom_type: AtomType) -> PatternRestrictionCreate a pattern restriction that tests the type of the atom.
Examples
from symbolica import *
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) # f(x)*f(1)Parameters
atom_type(AtomType) The atom type to test or require.
save
Expression.save(filename: str, compression_level: int = 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')Parameters
filename(str) The file path to load from or save to.compression_level(int) The compression level for serialized output.
series
Expression.series(
x: Expression,
expansion_point: Expression | int | float | complex | Decimal,
depth: int,
depth_denom: int = 1,
depth_is_absolute: bool = True,
) -> SeriesSeries expand in x around expansion_point to depth depth.
Examples
p = E('cos(x)/(x+1)')
print(p.series(S('x'), 0, 3))yields -1-x-1/2*x^2-1/2*x^3+𝒪(x^4)
Parameters
x(Expression) The variable to expand in.expansion_point(Expression | int | float | complex | Decimal) The point around which to expand.depth(int) The depth of the expansion.depth_denom(int, optional) The denominator of the depth (for a rational depth), by default 1.depth_is_absolute(bool, optional) IfTrue,depthis the absolute depth inx; ifFalse,depthis the relative to the lowest order encountered in the expression.
set_coefficient_ring
Expression.set_coefficient_ring(vars: Sequence[Expression]) -> ExpressionSet the coefficient ring to contain the variables in the vars list. This will move all variables into a rational polynomial function.
Parameters
vars(Sequence[Expression]) A list of variables
sin
Expression.sin() -> ExpressionTake the sine of this expression, returning the result.
solve_linear_system
Expression.solve_linear_system(
system: Sequence[Expression],
variables: Sequence[Expression],
warn_if_underdetermined: bool = True,
) -> Sequence[Expression]Solve a linear system in the variables variables, where each expression in the system is understood to yield 0.
If the system is underdetermined, a partial solution is returned where each bound variable is a linear combination of the free variables. The free variables are chosen such that they have the highest index in the vars list.
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)Parameters
system(Sequence[Expression]) The equations or polynomials that define the system.variables(Sequence[Expression]) The variables to solve for, in order.warn_if_underdetermined(bool) Whether to warn when the system is underdetermined.
sqrt
Expression.sqrt() -> ExpressionTake the square root of this expression, returning the result.
symbol
symbol has 2 variants:
symbol returning Expression
Expression.symbol(
name: str,
is_symmetric: bool | None = None,
is_antisymmetric: bool | None = None,
is_cyclesymmetric: bool | None = None,
is_linear: bool | None = None,
is_scalar: bool | None = None,
is_real: bool | None = None,
is_integer: bool | None = None,
is_positive: bool | None = None,
tags: Sequence[str] | None = None,
aliases: Sequence[str] | None = None,
custom_normalization: Transformer | None = None,
custom_print: Callable[..., str | None] | None = None,
custom_derivative: Callable[[Expression, int], Expression] | None = None,
data: str | int | Expression | bytes | list[Any] | dict[str | int | Expression, Any] | None = None,
) -> ExpressionExamples
Define a regular symbol and use it as a variable:
x = S('x')
e = x**2 + 5
print(e) # x**2 + 5Define a regular symbol and use it as a function:
f = S('f')
e = f(1,2)
print(e) # f(1,2)Define a symmetric function:
f = S('f', is_symmetric=True)
e = f(2,1)
print(e) # f(1,2)Define a linear and symmetric function:
p1, p2, p3, p4 = S('p1', 'p2', 'p3', 'p4')
dot = S('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)Define a custom normalization function:
e = S('real_log', custom_normalization=T().replace(E("x_(exp(x1_))"), E("x1_")))
E("real_log(exp(x)) + real_log(5)")Define a custom print function:
def print_mu(mu: Expression, latex: bool, **kwargs) -> str | None:
if latex:
if mu.get_type() == AtomType.Fn:
return "\mu_{" + ",".join(a.format() for a in mu) + "}"
else:
return "\mu"
mu = S("mu", custom_print=print_mu)
expr = E("mu + mu(1,2)")
print(expr.to_latex())If the function returns None, the default print function is used.
Define a custom derivative function:
tag = S('tag', custom_derivative=lambda f, index: f)
x = S('x')
tag(3, x).derivative(x)Add custom data to a symbol:
x = S('x', data={'my_tag': 'my_value'})
r = x.get_symbol_data('my_tag')Parameters
name(str) The name of the symbolis_symmetric(bool | None) Set to true if the symbol is symmetric.is_antisymmetric(bool | None) Set to true if the symbol is antisymmetric.is_cyclesymmetric(bool | None) Set to true if the symbol is cyclesymmetric.is_linear(bool | None) Set to true if the symbol is linear.is_scalar(bool | None) Set to true if the symbol is a scalar. It will be moved out of linear functions.is_real(bool | None) Set to true if the symbol is a real number.is_integer(bool | None) Set to true if the symbol is an integer.is_positive(bool | None) Set to true if the symbol is a positive number.tags(Sequence[str] | None) A list of tags to associate with the symbol.aliases(Sequence[str] | None) A list of aliases to associate with the symbol.custom_normalization(Transformer | None) A transformer that is called after every normalization. Note that the symbol name cannot be used in the transformer as this will lead to a definition of the symbol. Use a wildcard with the same attributes instead.custom_print(Callable[…, str | None] | None:) A function that is called when printing the variable/function, which is provided as its first argument. This function should return a string, orNoneif the default print function should be used. The custom print function takes in keyword arguments that are the same as the arguments of theformatfunction.custom_derivative(Callable[[Expression, int], Expression] | None:) A function that is called when computing the derivative of a function in a given argument.data(str | int | Expression | bytes | list | dict | None = None) Custom user data to associate with the symbol.
symbol returning Sequence[Expression]
Expression.symbol(
*names: str,
is_symmetric: bool | None = None,
is_antisymmetric: bool | None = None,
is_cyclesymmetric: bool | None = None,
is_linear: bool | None = None,
is_real: bool | None = None,
is_scalar: bool | None = None,
is_integer: bool | None = None,
is_positive: bool | None = None,
tags: Sequence[str] | None = None,
) -> Sequence[Expression]Examples
Define two regular symbols:
x, y = S('x', 'y')Define two symmetric functions:
f, g = S('f', 'g', is_symmetric=True)
e = f(2,1)
print(e) # f(1,2)Parameters
name(str) The name of the symbolis_symmetric(bool | None) Set to true if the symbol is symmetric.is_antisymmetric(bool | None) Set to true if the symbol is antisymmetric.is_cyclesymmetric(bool | None) Set to true if the symbol is cyclesymmetric.is_linear(bool | None) Set to true if the symbol is multilinear.is_scalar(bool | None) Set to true if the symbol is a scalar. It will be moved out of linear functions.is_real(bool | None) Set to true if the symbol is a real number.is_integer(bool | None) Set to true if the symbol is an integer.is_positive(bool | None) Set to true if the symbol is a positive number.tags(Sequence[str] | None) A list of tags to associate with the symbol.
to_atom_tree
Expression.to_atom_tree() -> AtomTreeConvert the expression to a tree.
to_canonical_string
Expression.to_canonical_string() -> strConvert 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: int = 16) -> ExpressionConvert all coefficients and built-in functions to floats with a given precision decimal_prec. The precision of floating point coefficients in the input will be truncated to decimal_prec.
Parameters
decimal_prec(int) The decimal precision used during numerical evaluation.
to_int
Expression.to_int() -> intConvert the expression to an integer if possible. Raises a ValueError if the expression is not an integer.
Examples
e = E('7')
n = e.to_int()to_latex
Expression.to_latex() -> strConvert 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_mathematica
Expression.to_mathematica(show_namespaces: bool = True) -> strConvert the expression into a Mathematica-parsable string.
Examples
a = E('cos(x+2i + 3)+sqrt(conj(x)) + test::y')
print(a.to_mathematica(show_namespaces=True))Yields test`y+Cos[x+3+2I]+Sqrt[Conjugate[x]].
Parameters
show_namespaces(bool) Whether namespaces should be included in the formatted output.
to_polynomial
to_polynomial has 3 variants:
to_polynomial returning Polynomial
Expression.to_polynomial(vars: Sequence[Expression] | None = None) -> PolynomialConvert the expression to a polynomial, optionally, with the variable ordering specified in vars. All non-polynomial parts will be converted to new, independent variables.
Parameters
vars(Sequence[Expression] | None) The variables treated as polynomial variables, in the given order.
to_polynomial returning NumberFieldPolynomial
Expression.to_polynomial(
minimal_poly: Polynomial,
vars: Sequence[Expression] | None = None,
) -> NumberFieldPolynomialConvert the expression to a polynomial, optionally, with the variables and the ordering specified in vars. All non-polynomial elements will be converted to new independent variables.
The coefficients will be converted to a number field with the minimal polynomial minimal_poly. The minimal polynomial must be a monic, irreducible univariate polynomial.
Parameters
minimal_poly(Polynomial) The minimal polynomial that defines the algebraic extension.vars(Sequence[Expression] | None) The variables treated as polynomial variables, in the given order.
to_polynomial returning FiniteFieldPolynomial
Expression.to_polynomial(
modulus: int,
power: tuple[int, Expression] | None = None,
minimal_poly: Polynomial | None = None,
vars: Sequence[Expression] | None = None,
) -> FiniteFieldPolynomialConvert the expression to a polynomial, optionally, with the variables and the ordering specified in vars. All non-polynomial elements will be converted to new independent variables.
The coefficients will be converted to finite field elements modulo modulus. If on top a power is provided, for example (2, a), the polynomial will be converted to the Galois field GF(modulus^2) where a is the variable of the minimal polynomial of the field.
If a minimal_poly is provided, the Galois field will be created with minimal_poly as the minimal polynomial.
Parameters
modulus(int) The modulus that defines the finite field.power(tuple[int, Expression] | None) The extension degree and generator that define the finite field.minimal_poly(Polynomial | None) The minimal polynomial that defines the algebraic extension.vars(Sequence[Expression] | None) The variables treated as polynomial variables, in the given order.
to_rational_polynomial
Expression.to_rational_polynomial(vars: Sequence[Expression] | None = None) -> RationalPolynomialConvert 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)Parameters
vars(Sequence[Expression] | None) The variables treated as polynomial variables, in the given order.
to_sympy
Expression.to_sympy() -> strConvert the expression into a sympy-parsable string.
Examples
from sympy import *
s = sympy.parse_expr(E('x^2+f((1+x)^y)').to_sympy())to_typst
Expression.to_typst(show_namespaces: bool = False) -> strConvert the expression into a Typst string.
Examples
a = E('f(x+2i + 3) * 2 / x')
print(a.to_typst())Yields (2 op("f")(3+2𝑖+"x"))/"x".
Parameters
show_namespaces(bool) Whether namespaces should be included in the formatted output.
together
Expression.together() -> ExpressionWrite 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())