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)Methods
| Name | Description |
|---|---|
__add__ |
Add this expression to other, returning the result. |
__bool__ |
Return numeric truth for scalar numbers; raise TypeError for ambiguous symbolic truth. |
__call__ |
Create a Symbolica expression or transformer by calling the function with appropriate arguments. |
__complex__ |
Convert the expression to a complex number if possible |
__copy__ |
Copy the expression. |
__eq__ |
Compare structural equality and exact scalar values |
__float__ |
Convert the expression to a float if possible |
__ge__ |
Construct a mathematical ordering Condition |
__getitem__ |
Get the idxth component of the expression. |
__getstate__ |
Get a serialized version of the expression. |
__gt__ |
Construct a mathematical ordering Condition |
__hash__ |
Hash the expression. |
__int__ |
Convert the expression to an integer if possible |
__iter__ |
Create an iterator over all subexpressions of the expression. |
__le__ |
Construct a mathematical ordering Condition |
__len__ |
Return the number of terms in this expression. |
__lt__ |
Construct a mathematical ordering Condition |
__mul__ |
Multiply this expression with other, returning the result. |
__ne__ |
Compare structural equality and exact scalar values |
__neg__ |
Negate the current expression, returning the result. |
__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. |
__reduce__ |
Reconstruct an expression from a serialized version. |
__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. |
_repr_html_ |
Convert the expression into an HTML representation. |
_repr_latex_ |
Convert the expression into a LaTeX representation. |
_repr_pretty_ |
Convert the expression into a pretty string representation. |
abs |
Take the absolute value of this expression, returning the result. |
acos |
Take the inverse cosine of this expression, returning the result |
acosh |
Take the inverse hyperbolic cosine of this expression, returning the result |
acot |
Take the inverse cotangent of this expression, returning the result |
acoth |
Take the inverse hyperbolic cotangent of this expression, returning the result |
acsc |
Take the inverse cosecant of this expression, returning the result |
acsch |
Take the inverse hyperbolic cosecant of this expression, returning the result |
alt |
Create an alternative pattern that matches this expression or any of the supplied alternatives. |
apart |
Compute a partial fraction decomposition in the specified variables |
asec |
Take the inverse secant of this expression, returning the result |
asech |
Take the inverse hyperbolic secant of this expression, returning the result |
asin |
Take the inverse sine of this expression, returning the result |
asinh |
Take the inverse hyperbolic sine of this expression, returning the result |
atan |
Take the inverse tangent of this expression, returning the result |
atanh |
Take the inverse hyperbolic tangent of this expression, returning the result |
bessel_i |
Apply the modified Bessel function of the first kind of order nu to this expression |
bessel_j |
Apply the cylindrical Bessel function of the first kind of order nu to this expression |
bessel_k |
Apply the modified Bessel function of the second kind of order nu to this expression |
bessel_y |
Apply the cylindrical Bessel function of the second kind of order nu to this expression |
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_by_coefficient |
Collect terms that have the same numerical coefficient |
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 |
compare_structure |
Return -1, 0, or 1 for internal structural ordering; this order may change between versions. |
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. |
cosh |
Take the hyperbolic cosine of this expression, returning the result |
cot |
Take the cotangent of this expression, returning the result |
coth |
Take the hyperbolic cotangent of this expression, returning the result |
csc |
Take the cosecant of this expression, returning the result |
csch |
Take the hyperbolic cosecant of this expression, returning the result |
derivative |
Derive the expression w.r.t the variable x. |
eq |
Construct a deferred equality Condition for solve, matching, or Transformers |
erf |
Compute the error function of the expression |
evaluate |
Evaluate the expression, using a map of all constants and user functions. |
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, over the complex rationals, or over an algebraic number field generated by extension. |
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. |
formatted |
Convert the expression into a rich display object, with tunable settings. |
gamma |
Apply the gamma function to this expression |
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_head |
Get the function symbol of a function or return the variable itself |
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 |
integrate |
Integrate the expression with respect to x |
integrate_with_steps |
Integrate the expression and return the result, an overview of the steps, and each individual transformation step |
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_nonnegative |
Check if the expression is real and greater than or equal to zero |
is_positive |
Check if the expression is strictly positive |
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 |
ne |
Construct a deferred disequality Condition for solve, matching, or Transformers |
nsolve |
Find a real root with Newton’s method, using the precision of init |
nsolve_system |
Find a common real root using the precision of the initial guesses. |
num |
Create a new Symbolica number from an int, a float, or a string |
opt |
Turn a wildcard x_ into an optional wildcard which will match a default value if the wildcard is not matched |
parse |
Parse a Symbolica expression from a string. |
polygamma |
Apply the polygamma function of order n to this expression |
polylog |
Apply the polylogarithm of order s to this expression |
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 |
Restrict a wildcard using a callback receiving its matched expression |
req_attr |
Create a pattern restriction based on the attributes of a matched variable or function. |
req_cmp |
Restrict two wildcards using a callback receiving their matched expressions |
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. |
root |
Construct the root with index index of the polynomial represented by this expression |
save |
Save the expression and its state to a binary file |
sec |
Take the secant of this expression, returning the result |
sech |
Take the hyperbolic secant of this expression, returning the result |
series |
Series expand in x around expansion_point, including powers through depth / depth_denom |
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. |
sinh |
Take the hyperbolic sine of this expression, returning the result |
solve |
Find exact solutions to an equation or a system of equations |
sqrt |
Take the square root of this expression, returning the result. |
symbol |
Create new symbols from names |
tan |
Take the tangent of this expression, returning the result |
tanh |
Take the hyperbolic tangent of this expression, returning the result |
terms |
Create an iterator over all terms in the expression. |
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_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 over an automatically constructed algebraic number field |
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. |
zeta |
Compute the Riemann zeta function symbol zeta |
__add__
Expression.__add__(other: Expression | int | float | complex | Float | ComplexFloat | Decimal) -> ExpressionAdd this expression to other, returning the result.
Parameters
other(Expression | int | float | complex | Float | ComplexFloat | Decimal) The other operand to combine or compare with.
__bool__
Expression.__bool__() -> boolReturn numeric truth for scalar numbers; raise TypeError for ambiguous symbolic truth.
__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 | Float | ComplexFloat | Decimal) -> ExpressionParameters
args(Expression | int | float | complex | Float | ComplexFloat | Decimal) The arguments passed to the expression call.
__call__ returning HeldExpression
Expression.__call__(*args: HeldExpression | Expression | int | float | complex | Float | ComplexFloat | Decimal) -> HeldExpressionParameters
args(HeldExpression | Expression | int | float | complex | Float | ComplexFloat | Decimal) The arguments passed to the expression or transformer call.
__complex__
Expression.__complex__() -> complexConvert the expression to a complex number if possible. Raises a ValueError if the expression cannot be converted to a complex number.
__copy__
Expression.__copy__() -> ExpressionCopy the expression.
__eq__
Expression.__eq__(other: object) -> boolCompare structural equality and exact scalar values. Use .eq() for a deferred Condition.
__float__
Expression.__float__() -> floatConvert the expression to a float if possible. Raises a ValueError if the expression cannot be converted to a float.
__ge__
Expression.__ge__(other: Expression | int | float | complex | Decimal | Transformer | HeldExpression) -> ConditionConstruct a mathematical ordering Condition. Undecidable bool conversion raises TypeError.
__getitem__
Expression.__getitem__(idx: int) -> ExpressionGet the idxth component of the expression.
Parameters
idx(int) The zero-based index to access.
__getstate__
Expression.__getstate__() -> bytesGet a serialized version of the expression.
__gt__
Expression.__gt__(other: Expression | int | float | complex | Decimal | Transformer | HeldExpression) -> ConditionConstruct a mathematical ordering Condition. Undecidable bool conversion raises TypeError.
__hash__
Expression.__hash__() -> intHash the expression.
__int__
Expression.__int__() -> intConvert the expression to an integer if possible. Raises a ValueError if the expression cannot be converted to an integer.
__iter__
Expression.__iter__() -> Iterator[Expression]Create an iterator over all subexpressions of the expression.
__le__
Expression.__le__(other: Expression | int | float | complex | Decimal | Transformer | HeldExpression) -> ConditionConstruct a mathematical ordering Condition. Undecidable bool conversion raises TypeError.
__len__
Expression.__len__() -> intReturn the number of terms in this expression.
__lt__
Expression.__lt__(other: Expression | int | float | complex | Decimal | Transformer | HeldExpression) -> ConditionConstruct a mathematical ordering Condition. Undecidable bool conversion raises TypeError.
__mul__
Expression.__mul__(other: Expression | int | float | complex | Float | ComplexFloat | Decimal) -> ExpressionMultiply this expression with other, returning the result.
Parameters
other(Expression | int | float | complex | Float | ComplexFloat | Decimal) The other operand to combine or compare with.
__ne__
Expression.__ne__(other: object) -> boolCompare structural equality and exact scalar values. Use .ne() for a deferred Condition.
__neg__
Expression.__neg__() -> ExpressionNegate the current expression, returning the result.
__new__
Expression.__new__() -> ExpressionCreate a new expression that represents 0.
__pow__
Expression.__pow__(exp: Expression | int | float | complex | Float | ComplexFloat | Decimal) -> ExpressionTake self to power exp, returning the result.
Parameters
exp(Expression | int | float | complex | Float | ComplexFloat | Decimal) The exponent.
__radd__
Expression.__radd__(other: Expression | int | float | complex | Float | ComplexFloat | Decimal) -> ExpressionAdd this expression to other, returning the result.
Parameters
other(Expression | int | float | complex | Float | ComplexFloat | Decimal) The other operand to combine or compare with.
__reduce__
Expression.__reduce__() -> tuple[Callable[[bytes], Expression], tuple[bytes]]Reconstruct an expression from a serialized version.
__rmul__
Expression.__rmul__(other: Expression | int | float | complex | Float | ComplexFloat | Decimal) -> ExpressionMultiply this expression with other, returning the result.
Parameters
other(Expression | int | float | complex | Float | ComplexFloat | Decimal) The other operand to combine or compare with.
__rpow__
Expression.__rpow__(base: Expression | int | float | complex | Float | ComplexFloat | Decimal) -> ExpressionTake base to power self, returning the result.
Parameters
base(Expression | int | float | complex | Float | ComplexFloat | Decimal) The base expression.
__rsub__
Expression.__rsub__(other: Expression | int | float | complex | Float | ComplexFloat | Decimal) -> ExpressionSubtract this expression from other, returning the result.
Parameters
other(Expression | int | float | complex | Float | ComplexFloat | Decimal) The other operand to combine or compare with.
__rtruediv__
Expression.__rtruediv__(other: Expression | int | float | complex | Float | ComplexFloat | Decimal) -> ExpressionDivide other by this expression, returning the result.
Parameters
other(Expression | int | float | complex | Float | ComplexFloat | 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 | Float | ComplexFloat | Decimal) -> ExpressionSubtract other from this expression, returning the result.
Parameters
other(Expression | int | float | complex | Float | ComplexFloat | Decimal) The other operand to combine or compare with.
__truediv__
Expression.__truediv__(other: Expression | int | float | complex | Float | ComplexFloat | Decimal) -> ExpressionDivide this expression by other, returning the result.
Parameters
other(Expression | int | float | complex | Float | ComplexFloat | 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.
_repr_html_
Expression._repr_html_() -> strConvert the expression into an HTML representation.
_repr_latex_
Expression._repr_latex_() -> strConvert the expression into a LaTeX representation.
_repr_pretty_
Expression._repr_pretty_(pretty, cycle: bool)Convert the expression into a pretty string representation.
abs
Expression.abs() -> ExpressionTake the absolute value of this expression, returning the result.
acos
Expression.acos() -> ExpressionTake the inverse cosine of this expression, returning the result. Uses the principal branch with cuts on (-infinity, -1] and [1, +infinity).
acosh
Expression.acosh() -> ExpressionTake the inverse hyperbolic cosine of this expression, returning the result. Uses the principal branch with branch cut on (-infinity, 1].
acot
Expression.acot() -> ExpressionTake the inverse cotangent of this expression, returning the result. Uses the principal branch with cuts on (-i infinity, -i] and [i, i infinity).
acoth
Expression.acoth() -> ExpressionTake the inverse hyperbolic cotangent of this expression, returning the result. Uses the principal branch with branch cut on [-1, 1].
acsc
Expression.acsc() -> ExpressionTake the inverse cosecant of this expression, returning the result. Uses the principal branch with branch cut on [-1, 1].
acsch
Expression.acsch() -> ExpressionTake the inverse hyperbolic cosecant of this expression, returning the result. Uses the principal branch with branch cut on the imaginary interval [-i, i].
alt
Expression.alt(
other: Expression | int | float | complex | Float | ComplexFloat | Decimal,
*others: Expression | int | float | complex | Float | ComplexFloat | Decimal,
) -> ExpressionCreate an alternative pattern that matches this expression or any of the supplied alternatives.
Examples
x, y, z, w_ = S('x', 'y', 'z', 'w_')
next(E('y*a').match(x.alt(y, z) * w_), None) is not None
TrueParameters
other(Expression | int | float | complex | Float | ComplexFloat | Decimal) The first alternative.others(Expression | int | float | complex | Float | ComplexFloat | Decimal) Additional alternatives.
apart
Expression.apart(*variables: Expression) -> ExpressionCompute a partial fraction decomposition in the specified variables.
A single variable uses univariate partial fractioning. Multiple variables use multivariate partial fractioning in the chosen variables. With no arguments, the expression is decomposed in all variables. Multivariate decomposition computes a Groebner basis and may be expensive.
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
Multivariate partial fractioning in chosen variables:
p = E('(2*y-x)/(y*(x+z*y)*(y-x))')
print(p.apart(S('x'), S('y')))Parameters
variables(Expression) No variables for decomposition in all variables, one variable for univariate decomposition, or multiple chosen variables for multivariate decomposition.
asec
Expression.asec() -> ExpressionTake the inverse secant of this expression, returning the result. Uses the principal branch with branch cut on [-1, 1].
asech
Expression.asech() -> ExpressionTake the inverse hyperbolic secant of this expression, returning the result. Uses the principal branch with cuts on (-infinity, 0] and [1, +infinity).
asin
Expression.asin() -> ExpressionTake the inverse sine of this expression, returning the result. Uses the principal branch with cuts on (-infinity, -1] and [1, +infinity).
asinh
Expression.asinh() -> ExpressionTake the inverse hyperbolic sine of this expression, returning the result. Uses the principal branch with cuts on (-i infinity, -i] and [i, i infinity).
atan
Expression.atan(y: Expression | int | float | complex | Float | ComplexFloat | Decimal | None = None) -> ExpressionTake the inverse tangent of this expression, returning the result. Uses the principal branch with cuts on (-i infinity, -i] and [i, i infinity).
If y is provided, compute atan(self, y), the quadrant-aware inverse tangent equivalent to atan2(y, self) for real numeric inputs.
atanh
Expression.atanh() -> ExpressionTake the inverse hyperbolic tangent of this expression, returning the result. Uses the principal branch with cuts on (-infinity, -1] and [1, +infinity).
bessel_i
Expression.bessel_i(nu: Expression | int | Float | float | Decimal) -> ExpressionApply the modified Bessel function of the first kind of order nu to this expression. For fixed nu, bessel_i(nu, z) is entire in z.
bessel_j
Expression.bessel_j(nu: Expression | int | Float | float | Decimal) -> ExpressionApply the cylindrical Bessel function of the first kind of order nu to this expression. For fixed nu, bessel_j(nu, z) is entire in z.
bessel_k
Expression.bessel_k(nu: Expression | int | Float | float | Decimal) -> ExpressionApply the modified Bessel function of the second kind of order nu to this expression. Uses the principal branch in z, with branch cut on (-infinity, 0].
bessel_y
Expression.bessel_y(nu: Expression | int | Float | float | Decimal) -> ExpressionApply the cylindrical Bessel function of the second kind of order nu to this expression. Uses the principal branch in z, with branch cut on (-infinity, 0].
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_by_coefficient
Expression.collect_by_coefficient() -> ExpressionCollect terms that have the same numerical coefficient. For example, 2*x + 2*x^2 + x^3 will be transformed into 2*(x+x^2)+x^3.
Examples
from symbolica import *
x = S('x')
e = 2*x + 2*x**2 + x**3
print(e.collect_by_coefficient())yields
x^3+2*(x+x^2)
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
compare_structure
Expression.compare_structure(other: Expression) -> intReturn -1, 0, or 1 for internal structural ordering; this order may change between versions.
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 | 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 | float | Decimal) The subexpression or pattern that should be contained literally.
cos
Expression.cos() -> ExpressionTake the cosine of this expression, returning the result.
cosh
Expression.cosh() -> ExpressionTake the hyperbolic cosine of this expression, returning the result. cosh(z) is entire.
cot
Expression.cot() -> ExpressionTake the cotangent of this expression, returning the result. cot(z) is meromorphic with simple poles at k pi.
coth
Expression.coth() -> ExpressionTake the hyperbolic cotangent of this expression, returning the result. coth(z) is meromorphic with simple poles at i k pi.
csc
Expression.csc() -> ExpressionTake the cosecant of this expression, returning the result. csc(z) is meromorphic with simple poles at k pi.
csch
Expression.csch() -> ExpressionTake the hyperbolic cosecant of this expression, returning the result. csch(z) is meromorphic with simple poles at i k pi.
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.
eq
Expression.eq(other: Expression | HeldExpression | Transformer | int | float | complex | Float | ComplexFloat | Decimal) -> ConditionConstruct a deferred equality Condition for solve, matching, or Transformers.
Predicate evaluation compares substituted expressions structurally, with exact-value equality for scalar numbers.
erf
Expression.erf() -> ExpressionCompute the error function of the expression. erf(z) is entire and odd, with derivative 2*exp(-z^2)/sqrt(pi).
evaluate
evaluate has 2 variants:
Examples
from symbolica import *
x, f = S('x', 'f')
e = E('cos(x)')*3 + f(2)
print(e.evaluate({x: 1, f(2): 4.}))evaluate returning complex
Expression.evaluate(constants: dict[Expression, int | float | complex | Float | ComplexFloat | Decimal | tuple[Decimal, Decimal]]) -> complexParameters
constants(dict[Expression, int | float | complex | Float | ComplexFloat | Decimal | tuple[Decimal, Decimal]]) The constant substitutions applied during evaluation.decimal_digit_precision(int | None) If omitted, evaluates at double precision and returns a complex. If specified, sets the working precision in decimal digits and returns a ComplexFloat.
evaluate returning ComplexFloat
Expression.evaluate(
constants: dict[Expression, int | float | complex | Float | ComplexFloat | Decimal | tuple[Decimal, Decimal]],
decimal_digit_precision: int,
) -> ComplexFloatParameters
constants(dict[Expression, int | float | complex | Float | ComplexFloat | Decimal | tuple[Decimal, Decimal]]) The constant substitutions applied during evaluation.decimal_digit_precision(int) If omitted, evaluates at double precision and returns a complex. If specified, sets the working precision in decimal digits and returns a ComplexFloat.
evaluator
Expression.evaluator(
params: Sequence[Expression],
functions: Sequence[FunctionDefinition] = [],
iterations: int = 1,
cpe_iterations: int | None = None,
n_cores: int = 4,
verbose: bool = False,
jit_compile: bool = True,
direct_translation: bool = True,
jit_direct_translation: bool = False,
jit_optimization_level: int = 3,
jit_options: dict[str, str] = {},
max_horner_scheme_variables: int = 500,
max_common_pair_cache_entries: int = 1000000,
max_common_pair_distance: int = 100,
) -> EvaluatorCreate an evaluator that can evaluate (nested) expressions in an optimized fashion. Function definitions can be provided with functions. All free parameters should be provided in the params list.
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(
[x],
functions=[
FunctionDefinition(f, [y, z], fd, inlining="never"),
FunctionDefinition(g, [y], gd),
],
)
res = ev.evaluate([[1.], [2.], [3.]]) # evaluate at x=1, x=2, x=3
print(res)The built-in if yields x+1 when y != 0 and x+2 when y == 0:
E("if(y, x + 1, x + 2)").evaluator([S("x"), S("y")])Parameters
params(Sequence[Expression]) A list of free parameters.functions(Sequence[FunctionDefinition]) Function definitions available to the evaluator.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.jit_direct_translation(bool, optional) If set toTrue, JIT compilation directly translates Symbolica instructions to SymJIT IR.jit_optimization_level(int, optional) The optimization level to use for JIT compilation.jit_options(dict[str, str], optional) A dictionary of options to pass to the JIT compiler.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.
evaluator_multiple
Expression.evaluator_multiple(
exprs: Sequence[Expression],
params: Sequence[Expression],
functions: Sequence[FunctionDefinition] = [],
iterations: int = 1,
cpe_iterations: int | None = None,
n_cores: int = 4,
verbose: bool = False,
jit_compile: bool = True,
direct_translation: bool = True,
jit_direct_translation: bool = False,
jit_optimization_level: int = 3,
jit_options: dict[str, str] = {},
max_horner_scheme_variables: int = 500,
max_common_pair_cache_entries: int = 1000000,
max_common_pair_distance: int = 100,
) -> 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.params(Sequence[Expression]) The evaluator parameters, in input order.functions(Sequence[FunctionDefinition]) Function definitions available to the evaluator.iterations(int, optional) The number of optimization passes to run.cpe_iterations(int | None, optional) The number of common subexpression elimination iterations to perform.n_cores(int, optional) The number of CPU cores used for parallel optimization.verbose(bool, optional) Whether verbose output should be enabled.jit_compile(bool, optional) Whether JIT compilation should be enabled.direct_translation(bool, optional) Whether to prefer direct translation when compiling the evaluator.jit_direct_translation(bool, optional) Whether to directly translate Symbolica instructions to SymJIT IR.jit_optimization_level(int, optional) The optimization level to use for JIT compilation.jit_options(dict[str, str], optional) A dictionary of options to pass to the JIT compiler.max_horner_scheme_variables(int, optional) The maximum number of variables considered for Horner-scheme optimization.max_common_pair_cache_entries(int, optional) The maximum number of common-subexpression pairs to cache.max_common_pair_distance(int, optional) The maximum distance between factors when searching for common pairs.
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(
complex: bool = False,
extension: Sequence[Expression] | None = None,
) -> ExpressionFactor the expression over the rationals, over the complex rationals, or over an algebraic number field generated by extension.
Examples
from symbolica import *
p = E('(6 + x)/(7776 + 6480*x + 2160*x^2 + 360*x^3 + 30*x^4 + x^5)')
print(p.factor()) # (x+6)**-4
E("x^2-2").factor(extension=[E("sqrt(2)")])Parameters
complex(bool) IfTrue, factor over the complex rationals.extension(Sequence[Expression] | None) Algebraic generators to adjoin. Algebraic numbers already present in the expression define the initial field.
format
Expression.format(
max_terms: int | None = 100,
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,
function_brackets: tuple[str, str] = ('(', ')'),
num_exp_as_superscript: bool = True,
precision: int | None = None,
show_namespaces: bool = False,
hide_namespace: str | None = None,
include_attributes: bool = False,
custom_print_mode: dict[str, int | str | dict[str | int, Any]] | None = None,
) -> strConvert the expression into a human-readable string, with tunable settings. Use formatted instead if you need rich output for interactive notebooks.
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
max_terms(int | None) The maximum number of terms to print before truncating the output.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^.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.precision(int | None) The number of digits to use when printing approximate numbers.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.custom_print_mode(dict[str, int | str | dict[str | int, Any]] | None) Custom print data 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.
formatted
Expression.formatted(
max_terms: int | None = 100,
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,
function_brackets: tuple[str, str] = ('(', ')'),
num_exp_as_superscript: bool = True,
precision: int | None = None,
show_namespaces: bool = False,
hide_namespace: str | None = None,
include_attributes: bool = False,
custom_print_mode: dict[str, int | str | dict[str | int, Any]] | None = None,
) -> FormattedOutputConvert the expression into a rich display object, with tunable settings.
Parameters
max_terms(int | None) The maximum number of terms to print before truncating the output.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^.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.precision(int | None) The number of digits to use when printing approximate numbers.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.custom_print_mode(dict[str, int | str | dict[str | int, Any]] | None) Custom print data passed through to custom print callbacks.
gamma
Expression.gamma() -> ExpressionApply the gamma function to this expression. gamma(z) is meromorphic with simple poles at the non-positive integers.
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_head
Expression.get_head() -> ExpressionGet the function symbol of a function or return the variable itself. Throw an error if the current atom is neither a variable nor a function.
Examples
x, f = S('x', 'f')
f(x).get_head() == f
True
x.get_head() == x
Trueget_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.
integrate
Expression.integrate(x: Expression) -> ExpressionIntegrate the expression with respect to x.
If the integral cannot be completely solved, the best-effort result is returned and may contain an unevaluated integral.
Examples
from symbolica import *
x = S('x')
e = 1/(x**2+1)
print(e.integrate(x)) # atan(x)Parameters
x(Expression) The variable with respect to which to integrate.
integrate_with_steps
Expression.integrate_with_steps(x: Expression) -> tuple[Expression, str, list[IntegrationStep]]Integrate the expression and return the result, an overview of the steps, and each individual transformation step.
Steps are ordered from the outer transformation to recursively solved subintegrals.
Examples
from symbolica import *
x = S('x')
e = x/(1+x)
result, overview, steps = e.integrate_with_steps(x)
print(overview)yields
∫ x/(1+x) dx = ∫ 1-1/(1+x) dx ∫ 1-1/(1+x) dx = ∫ 1 dx+∫ 1/(-1-x) dx ∫ 1 dx = x ∫ -1/(1+x) dx = -log(1+x) = x-log(1+x)
Parameters
x(Expression) The variable with respect to which to integrate.
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() -> bool | NoneCheck if the expression is integer. Symbols must have the integer attribute.
Returns None when the property is unknown. Use is True or is False to distinguish a proof from an inconclusive result.
Examples
x = S('x', is_integer=True)
e = (x + 1)**2 + 5
print(e.is_integer()) # Trueis_nonnegative
Expression.is_nonnegative() -> bool | NoneCheck if the expression is real and greater than or equal to zero. Returns None when its sign is unknown. This does not test absence of poles.
is_positive
Expression.is_positive() -> bool | NoneCheck if the expression is strictly positive. Zero returns False. A real square may vanish: use is_nonnegative() for a weak inequality.
Returns None when the property is unknown. Use is True or is False to distinguish a proof from an inconclusive result.
Examples
x = S('x', is_positive=True)
e = (x + 1)**2 + 5
print(e.is_positive()) # Trueis_real
Expression.is_real() -> bool | NoneCheck if the expression is real. Symbols must have the real attribute.
Returns None when the property is unknown. Use is True or is False to distinguish a proof from an inconclusive result.
Examples
x = S('x', is_real=True)
e = (x + 1)**2 / 2 + 5
print(e.is_real()) # Trueis_scalar
Expression.is_scalar() -> bool | NoneCheck if the expression is a scalar. Symbols must have the scalar attribute.
Returns None when the property is unknown. Use is True or is False to distinguish a proof from an inconclusive result.
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 | Float | ComplexFloat | Decimal,
cond: PatternRestriction | Condition | None = None,
min_level: int = 0,
max_level: int | None = None,
level_is_tree_depth: bool = False,
partial: bool = True,
) -> MatchIteratorReturn an iterator over the pattern self matching to lhs. Restrictions on the pattern can be supplied through cond.
min_level and max_level specify the inclusive matching bounds. 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 | Float | ComplexFloat | 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_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.
matches
Expression.matches(
lhs: Expression | int | float | complex | Float | ComplexFloat | Decimal,
cond: PatternRestriction | Condition | None = None,
min_level: int = 0,
max_level: int | None = None,
level_is_tree_depth: bool = False,
partial: bool = True,
) -> 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 | Float | ComplexFloat | 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_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.
ne
Expression.ne(other: Expression | HeldExpression | Transformer | int | float | complex | Float | ComplexFloat | Decimal) -> ConditionConstruct a deferred disequality Condition for solve, matching, or Transformers.
Predicate evaluation compares substituted expressions structurally, with exact-value equality for scalar numbers.
nsolve
Expression.nsolve(
variable: Expression,
init: Float | int | float | str | Decimal,
prec: float = 0.0001,
max_iterations: int = 1000,
) -> FloatFind a real root with Newton’s method, using the precision of init.
Use Float(1, decimal_digits=80) for an 80-digit initial guess. The return value is always Float, including for native float inputs.
nsolve_system
Expression.nsolve_system(
system: Sequence[Expression | int | float | complex | Float | ComplexFloat | Decimal],
variables: Sequence[Expression],
init: Sequence[Float | int | float | str | Decimal],
prec: float = 0.0001,
max_iterations: int = 1000,
) -> list[Float]Find a common real root using the precision of the initial guesses.
num
Expression.num(
num: int | float | complex | str | Float | ComplexFloat | 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 | Float | ComplexFloat | 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.
opt
Expression.opt() -> ExpressionTurn a wildcard x_ into an optional wildcard which will match a default value if the wildcard is not matched. Equivalent to writing opt(x_).
Examples
from symbolica import *
x, b_, e_ = S('x', 'b_', 'e_')
x.replace(b_**e_.opt(), 1) # 1parse
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.
polygamma
Expression.polygamma(n: Expression | int | Float | float | Decimal) -> ExpressionApply the polygamma function of order n to this expression. For fixed non-negative integer n, this is meromorphic with poles at the non-positive integers.
polylog
Expression.polylog(s: Expression | int | Float | float | Decimal) -> ExpressionApply the polylogarithm of order s to this expression. Uses the principal branch in z, with the standard branch cut on [1, +infinity).
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 | Float | ComplexFloat | Decimal,
rhs: HeldExpression | Expression | Callable[[dict[Expression, Expression]], Expression] | int | float | complex | Float | ComplexFloat | Decimal,
cond: PatternRestriction | Condition | None = None,
non_greedy_wildcards: Sequence[Expression] | None = None,
min_level: int = 0,
max_level: int | 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_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 | Float | ComplexFloat | Decimal,
rhs: HeldExpression | Expression | Callable[[dict[Expression, Expression]], Expression] | int | float | complex | Float | ComplexFloat | Decimal,
cond: PatternRestriction | Condition | None = None,
min_level: int = 0,
max_level: int | 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_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 | None | Condition]) -> PatternRestrictionRestrict a wildcard using a callback receiving its matched expression. Return True to accept, False to reject, or None when undecidable. A returned Condition is evaluated explicitly and may also be undecidable. Unknown decisions stay unknown under negation and do not complete a match.
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 | None | Condition]) A callback deciding whether the wildcard value is accepted.
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 | Float | ComplexFloat | Decimal,
cmp_fn: Callable[[Expression, Expression], bool | None | Condition],
) -> PatternRestrictionRestrict two wildcards using a callback receiving their matched expressions. The callback runs only once both wildcards have values. Return True to accept, False to reject, or None when undecidable. A returned Condition is evaluated explicitly and may also be undecidable.
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 | Float | ComplexFloat | Decimal) The other operand to combine or compare with.cmp_fn(Callable[[Expression, Expression], bool | None | 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 | Float | ComplexFloat | 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 | Float | ComplexFloat | 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 | Float | ComplexFloat | 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 | Float | ComplexFloat | 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 | Float | ComplexFloat | 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 | Float | ComplexFloat | 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 | Float | ComplexFloat | 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 | Float | ComplexFloat | 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.
root
Expression.root(index: int, variable: Expression | None = None) -> ExpressionConstruct the root with index index of the polynomial represented by this expression. If variable is provided, explicitly select it as the polynomial variable.
Examples
E("x^3-1").root(1) == E("root(x^3-1,1)")
TrueIf the polynomial contains parameters, explicitly select the polynomial variable:
x = E("x")
E("x^2-a").root(1, x) == E("root(x^2-a,x,1)")
Truesave
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.
sec
Expression.sec() -> ExpressionTake the secant of this expression, returning the result. sec(z) is meromorphic with simple poles at pi/2 + k pi.
sech
Expression.sech() -> ExpressionTake the hyperbolic secant of this expression, returning the result. sech(z) is meromorphic with simple poles at i (pi/2 + k pi).
series
Expression.series(
x: Expression,
expansion_point: Expression | int | float | complex | Float | ComplexFloat | Decimal,
depth: int,
depth_denom: int = 1,
depth_is_absolute: bool = True,
) -> SeriesSeries expand in x around expansion_point, including powers through depth / depth_denom. The remainder starts at Series.get_absolute_order().
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 | Float | ComplexFloat | 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.
sinh
Expression.sinh() -> ExpressionTake the hyperbolic sine of this expression, returning the result. sinh(z) is entire.
solve
Expression.solve(
system: Expression | Condition | bool | int | float | complex | Float | ComplexFloat | Decimal | Sequence[Expression | Condition | bool | int | float | complex | Float | ComplexFloat | Decimal],
variables: Sequence[Expression],
*,
domain: SolveDomain | None = None,
) -> SolutionSetFind exact solutions to an equation or a system of equations.
An expression represents an equation equal to zero; a list asks for solutions that satisfy every equation. The returned SolutionSet contains solution branches. Each branch maps solved variables directly to Expressions and may include conditions on when those assignments are valid.
Examples
Solve a linear system, then read an individual value or extract a dictionary:
from symbolica import Expression, S, Reals
x, y, a = S("x", "y", "a")
result = Expression.solve([x + y - 3, x - y - 1], [x, y])
result[0][x]
2
dict(result[0])
{x: 2, y: 1}Use eq to write a right-hand side. Python == tests equality immediately instead of constructing an equation:
Expression.solve(x.eq(2), [x])[0][x]
2Nonlinear systems can have several solutions. Iterate over the result to collect them; their order is not guaranteed:
result = Expression.solve([x**2 + y**2 - 5, x*y - 2], [x, y])
len(result)
4
points = [dict(branch) for branch in result]
{x: 1, y: 2} in points
TrueSolutions are complex by default. Choose Reals to keep only real solutions:
len(Expression.solve(x**2 + 1, [x]))
2
Expression.solve(x**2 + 1, [x], domain=Reals).is_empty()
True
roots = Expression.solve(x**2 - 1, [x], domain=Reals)
{branch[x] for branch in roots} == {-1, 1}
TrueA branch can describe a whole family. Free variables are omitted from its dictionary and are available through free_variables():
family = Expression.solve(x + y - 1, [x, y])
dict(family[0])
{x: 1-y}
family[0].free_variables()
[y]Symbols outside the variables list act as parameters. A symbolic answer may exclude some parameter values; inspect coverage_guard before substituting values. Excluded values may need to be solved separately:
result = Expression.solve(a*x - 1, [x])
result[0][x]
1/a
print(result.coverage_guard)
a != 0Other restrictions stay with the branch. For example, a denominator must remain nonzero even when it no longer appears in the answer:
branch = Expression.solve(x/y, [x, y])[0]
dict(branch)
{x: 0}
print(branch.conditions()[0])
y != 0Parameters
system(Expression, Condition, bool, number, or sequence of these) Equation or equations to satisfy, written as expressions equal to zero or usingeq. Supports polynomial and rational equations and some equations involving rational powers. Inequalities and general Boolean combinations are not supported. True and an empty list impose no constraints; False has no solutions. Use exact coefficients, such asExpression.parse("1/10")instead of the Python float0.1.variables(Sequence[Expression]) Variables to solve for. Earlier variables are solved for preferentially, leaving later ones free when possible. Forx + y = 1,[x, y]gives x = 1 - y;[y, x]gives y = 1 - x. Symbols outside this list are parameters.domain(SolveDomain | None) Domain of variables and parameters: Complexes (default), Reals, Rationals, or Integers. Symbol attributes, such asis_integer=True, can restrict individual symbols further. For example, Reals also treats parameters as real for this solve, without changing their attributes. Any domain restrictions that cannot be resolved remain inbranch.conditions().
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_flat: 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,
normalization: Transformer | Callable[[Expression], Expression] | None = None,
print: Callable[..., str | None] | None = None,
derivative: Callable[[Expression, int], Expression] | None = None,
series: Callable[[Sequence[Series]], tuple[Expression, Expression] | None] | None = None,
eval: dict[str, Any] | 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', 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, mode: PrintMode, **kwargs) -> str | None:
if mode == PrintMode.Latex:
if mu.get_type() == AtomType.Fn:
return "\mu_{" + ",".join(a.format() for a in mu) + "}"
else:
return "\mu"
mu = S("mu", 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', derivative=lambda f, index: f)
x = S('x')
tag(3, x).derivative(x)Define a custom series function that returns the principal part and the regular part, or None if a standard construction through the derivative can be used:
def inv_series(args: Sequence[Series]) -> tuple[Expression, Expression] | None:
return (N(0), args[0].pow(-1).to_expression())
t = S('t')
inv = S('inv', series=inv_series)Define a function with a custom evaluation:
cosh = S(
"my_cosh",
eval={
"float": lambda args: math.cosh(args[0]),
"complex": lambda args: cmath.cosh(args[0]),
"cpp": "template<typename T> T python_my_cosh(T a) { return std::cosh(a); }",
},
)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_flat(bool | None) Set to true if the symbol is flat (associative). A flat function removes nesting.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.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.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.derivative(Callable[[Expression, int], Expression] | None:) A function that is called when computing the derivative of a function in a given argument.series(Callable[[Sequence[Series]], tuple[Expression, Expression] | None] | None:) A function that is called for custom series expansion. It receives the argument series and can return the singular factor and regularized expression, orNoneto use the default series expansion.eval(dict[str, Any] | None:) Numeric evaluation function(s). The dictionary may contain: -tag_count: int: the number of leading symbolic tag arguments. -cpp: str: a C++ function definition inserted into exported C++ code for this symbol. For arbitrary precision evaluation of constant functions, register a function that maps the tags and the requested decimal precision to a number: -constant: (Sequence[Expression], int) -> Float | ComplexFloat | Decimal | float | complex | tuple[Decimal, Decimal] Evaluators for non-constant functions whentag_count = 0: -float: Sequence[float] -> float -complex: Sequence[complex] -> complex -decimal: Sequence[Float] -> Float -decimal_complex: Sequence[ComplexFloat] -> ComplexFloat Evaluators for non-constant functions whentag_count > 0are generators: -float: Sequence[Expression] -> (Sequence[float] -> float) -complex: Sequence[Expression] -> (Sequence[complex] -> complex) -decimal: Sequence[Expression] -> (Sequence[Float] -> Float) -decimal_complex: Sequence[Expression] -> (Sequence[ComplexFloat] -> ComplexFloat)data(str | int | Expression | bytes | list | dict | None = None) Custom user data to associate with the symbol.
symbol returning list[Expression]
Expression.symbol(
name0: str,
name1: str,
*names: str,
is_symmetric: bool | None = None,
is_antisymmetric: bool | None = None,
is_cyclesymmetric: bool | None = None,
is_linear: bool | None = None,
is_flat: 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,
normalization: Transformer | Callable[[Expression], Expression] | None = None,
print: Callable[..., str | None] | None = None,
derivative: Callable[[Expression, int], Expression] | None = None,
series: Callable[[Sequence[Series]], tuple[Expression, Expression] | None] | None = None,
eval: dict[str, Any] | None = None,
data: str | int | Expression | bytes | list[Any] | dict[str | int | Expression, Any] | None = None,
) -> list[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_flat(bool | None) Set to true if the symbol is flat (associative).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.
tan
Expression.tan() -> ExpressionTake the tangent of this expression, returning the result. tan(z) is meromorphic with simple poles at pi/2 + k pi.
tanh
Expression.tanh() -> ExpressionTake the hyperbolic tangent of this expression, returning the result. tanh(z) is meromorphic with simple poles at i (pi/2 + k pi).
terms
Expression.terms() -> Iterator[Expression]Create an iterator over all terms in the expression.
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_latex
Expression.to_latex(max_line_length: int | None = None) -> 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}$$.
Parameters
max_line_length(int | None) The preferred maximum line length before wrapping top-level sums.
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 4 variants:
to_polynomial with extensions: Sequence[Expression], vars: Sequence[Expression] | None = None
Expression.to_polynomial(
*,
extensions: Sequence[Expression],
vars: Sequence[Expression] | None = None,
) -> NumberFieldPolynomialConvert the expression to a polynomial over an automatically constructed algebraic number field.
An empty extensions sequence discovers algebraic coefficients already in the expression. Any supplied generators are adjoined to the discovered field.
Parameters
extensions(Sequence[Expression]) Additional algebraic generators to adjoin. Use an empty sequence for automatic discovery only.vars(Sequence[Expression] | None) The variables treated as polynomial variables, in the given order.
to_polynomial with vars: Sequence[Expression] | None = None, extensions: None = None
Expression.to_polynomial(
*,
vars: Sequence[Expression] | None = None,
extensions: 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 with minimal_poly: Polynomial, vars: Sequence[Expression] | None = None, ...
Expression.to_polynomial(
*,
minimal_poly: Polynomial,
vars: Sequence[Expression] | None = None,
extensions: 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 with modulus: int, power: tuple[int, Expression] | None = None, ...
Expression.to_polynomial(
modulus: int,
power: tuple[int, Expression] | None = None,
minimal_poly: Polynomial | None = None,
vars: Sequence[Expression] | None = None,
*,
extensions: 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())zeta
Expression.zeta() -> ExpressionCompute the Riemann zeta function symbol zeta. zeta(s) is meromorphic with a simple pole at s = 1 and no branch cuts.