Transformer
Transformer
Transformer()Operations that transform an expression.
Methods
| Name | Description |
|---|---|
__call__ |
Execute an unbound transformer on the given expression |
__eq__ |
Compare two transformers. |
__ge__ |
Compare two transformers |
__gt__ |
Compare two transformers |
__le__ |
Compare two transformers |
__lt__ |
Compare two transformers |
__neq__ |
Compare two transformers. |
__new__ |
Create a new transformer for a term provided by Expression.map. |
apart |
Create a transformer that computes the partial fraction decomposition in x. |
break_chain |
Break the current chain and all higher-level chains containing if transformers. |
cancel |
Create a transformer that cancels common factors between numerators and denominators |
chain |
Chain several transformers |
check_interrupt |
Create a transformer that checks for a Python interrupt, such as ctrl-c and aborts the current transformer. |
coefficient |
Create a transformer that collects terms involving the literal occurrence of x. |
collect |
Create a transformer that collects terms involving the same power of the indeterminate(s) x |
collect_factors |
Create a transformer that collects common factors from (nested) sums. |
collect_horner |
Create a transformer that iteratively extracts the minimal common powers of an indeterminate v for every term that contains v and continues to the next indeterminate in variables |
collect_num |
Create a transformer that collects numerical factors by removing the content from additions |
collect_symbol |
Create a transformer that collects terms involving the same power of variables or functions with the name x |
conjugate |
Complex conjugate the expression. |
contains |
Create a transformer that checks if the expression contains the given element. |
cycle_symmetrize |
Create a transformer that cycle-symmetrizes a function. |
deduplicate |
Create a transformer that removes elements from a list if they occur earlier in the list as well. |
derivative |
Create a transformer that derives self w.r.t the variable x. |
expand |
Create a transformer that expands products and powers |
expand_num |
Create a transformer that distributes numbers in the expression, for example: 2*(x+y) -> 2*x+2*y. |
factor |
Create a transformer that factors the expression over the rationals. |
for_each |
Create a transformer that applies a transformer chain to every argument of the arg() function |
from_coeff |
Create a transformer that extracts a rational polynomial from a coefficient. |
if_changed |
Execute the condition transformer |
if_then |
Evaluate the condition and apply the if_block if the condition is true, otherwise apply the else_block |
is_type |
Test if the transformed expression is of a certain type. |
linearize |
Create a transformer that linearizes a function, optionally extracting symbols as well. |
map |
Create a transformer that applies a Python function. |
map_terms |
Map a chain of transformer over the terms of the expression, optionally using multiple cores. |
matches |
Create a transformer that tests whether the pattern is found in the expression |
nargs |
Create a transformer that returns the number of arguments |
partitions |
Create a transformer that partitions a list of arguments into named bins of a given length, returning all partitions and their multiplicity |
permutations |
Create a transformer that generates all permutations of a list of arguments. |
print |
Create a transformer that prints the expression. |
prod |
Create a transformer that computes the product of a list of arguments. |
repeat |
Create a transformer that repeatedly executes the arguments in order until there are no more changes |
replace |
Create a transformer that replaces all subexpressions matching the pattern pat by the right-hand side rhs. |
replace_multiple |
Create a transformer that replaces all atoms matching the patterns |
series |
Create a transformer that series expands in x around expansion_point to depth depth. |
set_coefficient_ring |
Create a transformer that sets the coefficient ring to contain the variables in the vars list |
sort |
Create a transformer that sorts a list of arguments. |
split |
Create a transformer that split a sum or product into a list of arguments. |
stats |
Print statistics of a transformer, tagging it with tag. |
sum |
Create a transformer that computes the sum of a list of arguments. |
together |
Create a transformer that writes the expression over a common denominator. |
__call__
Transformer.__call__(
expr: Expression | int | float | complex | Decimal,
stats_to_file: Optional[str] = None,
) -> ExpressionExecute an unbound transformer on the given expression. If the transformer is bound, use execute() instead.
Examples
x = S('x')
e = T().expand()((1+x)**2)Parameters
expr(Expression) The expression to transform.stats_to_file(str, optional) If set, the output of thestatstransformer will be written to a file in JSON format.
__eq__
Transformer.__eq__(other: Transformer | Expression | int | float | Decimal) -> ConditionCompare two transformers.
__ge__
Transformer.__ge__(other: Transformer | Expression | int | float | Decimal) -> ConditionCompare two transformers. If any of the two expressions is not a rational number, an interal ordering is used.
__gt__
Transformer.__gt__(other: Transformer | Expression | int | float | Decimal) -> ConditionCompare two transformers. If any of the two expressions is not a rational number, an interal ordering is used.
__le__
Transformer.__le__(other: Transformer | Expression | int | float | Decimal) -> ConditionCompare two transformers. If any of the two expressions is not a rational number, an interal ordering is used.
__lt__
Transformer.__lt__(other: Transformer | Expression | int | float | Decimal) -> ConditionCompare two transformers. If any of the two expressions is not a rational number, an interal ordering is used.
__neq__
Transformer.__neq__(other: Transformer | Expression | int | float | Decimal) -> ConditionCompare two transformers.
__new__
Transformer.__new__() -> TransformerCreate a new transformer for a term provided by Expression.map.
apart
Transformer.apart(x: Expression) -> TransformerCreate a transformer that computes the partial fraction decomposition in x.
break_chain
Transformer.break_chain() -> TransformerBreak the current chain and all higher-level chains containing if transformers.
Examples
from symbolica import *
t = T().map_terms(T().repeat(
T().replace(y, 4),
T().if_changed(T().replace(x, y),
T().break_chain()),
T().print() # print of y is never reached
))
print(t(x))cancel
Transformer.cancel() -> TransformerCreate a transformer that cancels common factors between numerators and denominators. Any non-canceling parts of the expression will not be rewritten.
chain
Transformer.chain(*transformers: Transformer) -> TransformerChain several transformers. chain(A,B,C) is the same as A.B.C, where A, B, C are transformers.
Examples
from symbolica import *
x_ = S('x_')
f = S('f')
e = E("f(5)")
t = T().chain(
T().expand(),
T().replace(f(x_), f(5))
)
e = t(f(5))check_interrupt
Transformer.check_interrupt() -> TransformerCreate a transformer that checks for a Python interrupt, such as ctrl-c and aborts the current transformer.
Examples
from symbolica import *
x_ = S('x_')
f = S('f')
t = T().replace(f(x_), f(x_ + 1)).check_interrupt()
t(f(10))coefficient
Transformer.coefficient(x: Expression) -> TransformerCreate a transformer that collects terms involving the literal occurrence of x.
collect
Transformer.collect(
*x: Expression,
key_map: Optional[Transformer] = None,
coeff_map: Optional[Transformer] = None,
) -> TransformerCreate a transformer that collects 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 transformers respectively.
Examples
from symbolica import *
x, y = S('x', 'y')
e = 5*x + x * y + x**2 + 5
print(e.hold(T().collect(x).execute()))yields x^2+x*(y+5)+5.
from symbolica import *
x, y, x_, var, coeff = S('x', 'y', 'x_', 'var', 'coeff')
e = 5*x + x * y + x**2 + 5
print(e.collect(x, key_map=T().replace(x_, var(x_)),
coeff_map=T().replace(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 inkey_map(Transformer) A transformer to be applied to the quantity collected incoeff_map(Transformer) A transformer to be applied to the coefficient
collect_factors
Transformer.collect_factors() -> TransformerCreate a transformer that collects common factors from (nested) sums.
Examples
from symbolica import *
t = T().collect_factors()
t(E('x*(x+y*x+x^2+y*(x+x^2))'))yields
v1^2*(1+v1+v2+v2*(1+v1))
collect_horner
Transformer.collect_horner(vars: Sequence[Expression] | None = None) -> TransformerCreate a transformer that iteratively extracts the minimal common powers of an indeterminate v for every term that contains v and continues 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.hold(T().collect_horner([S('v1'), S('v2')]))()yields v1*(1+v1*(1+v1*(v1*z+y))+v2*(1+2*v3)).
collect_num
Transformer.collect_num() -> TransformerCreate a transformer that collects 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(T().collect_num()(e))yields
-6*(x+y)*(x-2*y)
collect_symbol
Transformer.collect_symbol(
x: Expression,
key_map: Optional[Callable[[Expression], Expression]] = None,
coeff_map: Optional[Callable[[Expression], Expression]] = None,
) -> TransformerCreate a transformer that collects 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(T().collect_symbol(x)(e))yields (1+x)*f(1,2).
Parameters
x(Expression) The symbol to collect inkey_map(Transformer) A transformer to be applied to the quantity collected incoeff_map(Transformer) A transformer to be applied to the coefficient
conjugate
Transformer.conjugate() -> TransformerComplex conjugate the expression.
contains
Transformer.contains(element: Transformer | HeldExpression | Expression | int | float | Decimal) -> ConditionCreate a transformer that checks if the expression contains the given element.
cycle_symmetrize
Transformer.cycle_symmetrize() -> TransformerCreate a transformer that cycle-symmetrizes a function.
Examples
from symbolica import *
x_ = S('x__')
f = S('f')
e = f(1,2,4,1,2,3).replace(f(x__), x_.hold(T().cycle_symmetrize()))
print(e)Yields f(1,2,3,1,2,4).
deduplicate
Transformer.deduplicate() -> TransformerCreate a transformer that removes elements from a list if they occur earlier in the list as well.
Examples
from symbolica import *
x__ = S('x__')
f = S('f')
e = f(1,2,1,2).replace(f(x__), x__.hold(T().deduplicate()))
print(e)Yields f(1,2).
derivative
Transformer.derivative(x: HeldExpression | Expression) -> TransformerCreate a transformer that derives self w.r.t the variable x.
expand
Transformer.expand(var: Optional[Expression] = None, via_poly: Optional[bool] = None) -> TransformerCreate a transformer that expands products and powers. Optionally, expand in var only.
Using via_poly=True may give a significant speedup for large expressions.
Examples
from symbolica import *
x, x_ = S('x', 'x_')
f = S('f')
e = f((x+1)**2).replace(f(x_), x_.hold(T().expand()))
print(e)expand_num
Transformer.expand_num() -> ExpressionCreate a transformer that distributes 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(T().expand_num()(e))yields
(3*x+3*y)*(4*x+5*y)
factor
Transformer.factor() -> TransformerCreate a transformer that factors the expression over the rationals.
for_each
Transformer.for_each(*transformers: Transformer) -> TransformerCreate a transformer that applies a transformer chain to every argument of the arg() function. If the input is not arg(), the transformer is applied to the input.
Examples
from symbolica import *
x = S('x')
f = S('f')
t = T().split().for_each(T().map(f))
e = t(1+x)from_coeff
Transformer.from_coeff() -> TransformerCreate a transformer that extracts a rational polynomial from a coefficient.
Examples
from symbolica import *, Function
e = Function.COEFF((x^2+1)/y^2).hold(T().from_coeff())
print(e)if_changed
Transformer.if_changed(
condition: Transformer,
if_block: Transformer,
else_block: Optional[Transformer] = None,
) -> TransformerExecute the condition transformer. If the result of the condition transformer is different from the input expression, apply the if_block, otherwise apply the else_block. The input expression of the if_block is the output of the condition transformer.
Examples
t = T().map_terms(T().if_changed(T().replace(x, y), T().print()))
print(t(x + y + 4))prints
y 2*y+4
if_then
Transformer.if_then(
condition: Condition,
if_block: Transformer,
else_block: Optional[Transformer] = None,
) -> TransformerEvaluate the condition and apply the if_block if the condition is true, otherwise apply the else_block. The expression that is the input of the transformer is the input for the condition, the if_block and the else_block.
Examples
t = T().map_terms(T().if_then(T().contains(x), T().print()))
t(x + y + 4)prints x.
is_type
Transformer.is_type(atom_type: AtomType) -> ConditionTest if the transformed expression is of a certain type.
linearize
Transformer.linearize(symbols: Optional[Sequence[Expression]]) -> TransformerCreate a transformer that linearizes a function, optionally extracting symbols as well.
Examples
from symbolica import *
x, y, z, w, f, x__ = S('x', 'y', 'z', 'w', 'f', 'x__')
e = f(x+y, 4*z*w+3).replace(f(x__), f(x__).hold(T().linearize([z])))
print(e)yields f(x,3)+f(y,3)+4*z*f(x,w)+4*z*f(y,w).
map
Transformer.map(f: Callable[[Expression], Expression | int | float | complex | Decimal]) -> TransformerCreate a transformer that applies a Python function.
Examples
from symbolica import *
x_ = S('x_')
f = S('f')
e = f(2).replace(f(x_), x_.hold(T().map(lambda r: r**2)))
print(e)map_terms
Transformer.map_terms(*transformers: Transformer, n_cores: int = 1) -> TransformerMap a chain of transformer over the terms of the expression, optionally using multiple cores.
Examples
from symbolica import *
x, y = S('x', 'y')
t = T().map_terms(T().print(), n_cores=2)
e = t(x + y)matches
Transformer.matches(
lhs: HeldExpression | Expression | int | float | Decimal,
cond: Optional[PatternRestriction | Condition] = None,
min_level: int = 0,
max_level: Optional[int] = None,
level_range: Optional[Tuple[int, Optional[int]]] = None,
level_is_tree_depth: bool = False,
partial: bool = True,
allow_new_wildcards_on_rhs: bool = False,
) -> ConditionCreate a transformer that tests whether the pattern is found in the expression. Restrictions on the pattern can be supplied through cond.
nargs
Transformer.nargs(only_for_arg_fun: bool = False) -> TransformerCreate a transformer that returns the number of arguments. If the argument is not a function, return 0.
If only_for_arg_fun is True, only count the number of arguments in the arg() function and return 1 if the input is not arg. This is useful for obtaining the length of a range during pattern matching.
Examples
from symbolica import *
x__ = S('x__')
f = S('f')
e = f(2,3,4).replace(f(x__), x__.hold(T().nargs()))
print(e)partitions
Transformer.partitions(
bins: Sequence[Tuple[Transformer | Expression, int]],
fill_last: bool = False,
repeat: bool = False,
) -> TransformerCreate a transformer that partitions a list of arguments into named bins of a given length, returning all partitions and their multiplicity.
If the unordered list elements is larger than the bins, setting the flag fill_last will add all remaining elements to the last bin.
Setting the flag repeat means that the bins will be repeated to exactly fit all elements, if possible.
Note that the functions names to be provided for the bin names must be generated through Expression.var.
Examples
from symbolica import *
x_, f_id, g_id = S('x__', 'f', 'g')
f = S('f')
e = f(1,2,1,3).replace(f(x_), x_.hold(T().partitions([(f_id, 2), (g_id, 1), (f_id, 1)])))
print(e)yields:
2*f(1)*f(1,2)*g(3)+2*f(1)*f(1,3)*g(2)+2*f(1)*f(2,3)*g(1)+f(2)*f(1,1)*g(3)+2*f(2)*f(1,3)*g(1)+f(3)*f(1,1)*g(2)+2*f(3)*f(1,2)*g(1)
permutations
Transformer.permutations(function_name: Transformer | Expression) -> TransformerCreate a transformer that generates all permutations of a list of arguments.
Examples
from symbolica import *
x_, f_id = S('x__', 'f')
f = S('f')
e = f(1,2,1,2).replace(f(x_), x_.hold(T().permutations(f_id)))
print(e)yields:
4*f(1,1,2,2)+4*f(1,2,1,2)+4*f(1,2,2,1)+4*f(2,1,1,2)+4*f(2,1,2,1)+4*f(2,2,1,1)
print
Transformer.print(
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: Optional[str] = None,
multiplication_operator: str = '*',
double_star_for_exponentiation: bool = False,
square_brackets_for_function: bool = False,
function_brackets: tuple[str, str] = ('(', ')'),
num_exp_as_superscript: bool = True,
show_namespaces: bool = False,
hide_namespace: Optional[str] = None,
include_attributes: bool = False,
max_terms: Optional[int] = None,
custom_print_mode: Optional[int] = None,
) -> TransformerCreate a transformer that prints the expression.
Examples
T().print(terms_on_new_line = True)prod
Transformer.prod() -> TransformerCreate a transformer that computes the product of a list of arguments.
Examples
from symbolica import *
x__ = S('x__')
f = S('f')
e = f(2,3).replace(f(x__), x__.hold(T().prod()))
print(e)repeat
Transformer.repeat(*transformers: Transformer) -> TransformerCreate a transformer that repeatedly executes the arguments in order until there are no more changes. The output from one transformer is inserted into the next.
Examples
from symbolica import *
x_ = S('x_')
f = S('f')
t = T().repeat(
T().expand(),
T().replace(f(x_), f(x_ - 1) + f(x_ - 2), x_.req_gt(1))
)
e = t(f(5))replace
Transformer.replace(
pat: HeldExpression | Expression | int | float | complex | Decimal,
rhs: HeldExpression | Expression | Callable[[dict[Expression, Expression]], Expression] | int | float | complex | Decimal,
cond: Optional[PatternRestriction | Condition] = None,
non_greedy_wildcards: Optional[Sequence[Expression]] = None,
min_level: int = 0,
max_level: Optional[int] = None,
level_range: Optional[Tuple[int, Optional[int]]] = None,
level_is_tree_depth: bool = False,
partial: bool = True,
allow_new_wildcards_on_rhs: bool = False,
rhs_cache_size: Optional[int] = None,
once: bool = False,
bottom_up: bool = False,
nested: bool = False,
) -> TransformerCreate a transformer that replaces all subexpressions matching the pattern pat by the right-hand side rhs.
Examples
x, w1_, w2_ = S('x','w1_','w2_')
f = S('f')
t = T().replace(f(w1_, w2_), f(w1_ - 1, w2_**2), w1_ >= 1)
r = t(f(3,x))
print(r)Parameters
patThe 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.non_greedy_wildcardsWildcards that try to match as little as possible.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(Optional[int], optional) The maximum level at which the pattern is allowed to match.Nonemeans no maximum.level_rangeSpecifies the[min,max]level at which the pattern is allowed to match. The first level is 0 and the level is increased when going into a function or one level deeper in the expression tree, depending onlevel_is_tree_depth. Prefer settingmin_levelandmax_leveldirectly overlevel_range, as this argument will be deprecated in the future.level_is_tree_depth(bool, optional) If set toTrue, the level is increased when going one level deeper in the expression tree.partial(bool, optional) If set toTrue, allow the pattern to match to a part of a term. For example, withpartial=True, the patternx+ymatches tox+2+y.allow_new_wildcards_on_rhs(bool, optional) If set toTrue, allow wildcards that do not appear in the pattern on the right-hand side.rhs_cache_size(int, optional) Cache the firstrhs_cache_sizesubstituted patterns. If set toNone, an internally determined cache size is used. Warning: caching should be disabled (rhs_cache_size=0) if the right-hand side contains side effects, such as updating a global variable.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_multiple
Transformer.replace_multiple(
replacements: Sequence[Replacement],
once: bool = False,
bottom_up: bool = False,
nested: bool = False,
) -> TransformerCreate a transformer that replaces all atoms matching the patterns. See replace for more information.
Examples
x, y, f = S('x', 'y', 'f')
t = T().replace_multiple([Replacement(x, y), Replacement(y, x)])
r = t(f(x,y))
print(r)series
Transformer.series(
x: Expression,
expansion_point: Expression | int | float | complex | Decimal,
depth: int,
depth_denom: int = 1,
depth_is_absolute: bool = True,
) -> TransformerCreate a transformer that series expands in x around expansion_point to depth depth.
Examples
from symbolica import *
x, y = S('x', 'y')
f = S('f')
e = 2* x**2 * y + f(x)
e = e.series(x, 0, 2)
print(e)yields f(0)+x*der(1,f(0))+1/2*x^2*(der(2,f(0))+4*y).
set_coefficient_ring
Transformer.set_coefficient_ring(vars: Sequence[Expression]) -> TransformerCreate a transformer that sets 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
sort
Transformer.sort() -> TransformerCreate a transformer that sorts a list of arguments.
Examples
from symbolica import *
x__ = S('x__')
f = S('f')
e = f(3,2,1).replace(f(x__), x__.hold(T().sort()))
print(e)split
Transformer.split() -> TransformerCreate a transformer that split a sum or product into a list of arguments.
Examples
from symbolica import *
x, x__ = S('x', 'x__')
f = S('f')
e = (x + 1).replace(x__, f(x_.hold(T().split())))
print(e)stats
Transformer.stats(
tag: str,
transformer: Transformer,
color_medium_change_threshold: Optional[float] = 10.0,
color_large_change_threshold: Optional[float] = 100.0,
) -> TransformerPrint statistics of a transformer, tagging it with tag.
Examples
from symbolica import *
x_ = S('x_')
f = S('f')
t = T().stats('replace', T().replace(f(x_), 1)).execute()
t(eE('f(5)'))yields
Stats for replace: In │ 1 │ 10.00 B │ Out │ 1 │ 3.00 B │ ⧗ 40.15µs
sum
Transformer.sum() -> TransformerCreate a transformer that computes the sum of a list of arguments.
Examples
from symbolica import *
x__ = S('x__')
f = S('f')
e = f(2,3).replace(f(x__), x__.hold(T().sum()))
print(e)together
Transformer.together() -> TransformerCreate a transformer that writes the expression over a common denominator.