Mappers

Basic dispatch

class pymbolic.mapper.ResultT

A type variable for the result returned by a Mapper.

class pymbolic.mapper.Mapper[source]

A visitor for trees of pymbolic.ExpressionNode subclasses. Each expression-derived object is dispatched to the method named by the pymbolic.ExpressionNode.mapper_method attribute and if not found, the methods named by the class attribute mapper_method in the method resolution order of the object.

..automethod:: handle_unsupported_expression ..automethod:: __call__ ..automethod:: rec

__call__(expr: Expression, *args: ~typing.~P, **kwargs: ~typing.~P) ResultT[source]

Dispatch expr to its corresponding mapper method. Pass on *args and **kwargs unmodified.

This method is intended as the top-level dispatch entry point and may be overridden by subclasses to present a different/more convenient interface. rec() on the other hand is intended as the recursive dispatch method to be used to recurse within mapper method implementations.

rec(expr, *args, **kwargs)[source]

Identical to __call__(), but intended for use in recursive dispatch in mapper methods.

handle_unsupported_expression(expr: object, *args: ~typing.~P, **kwargs: ~typing.~P) ResultT[source]

Mapper method that is invoked for pymbolic.ExpressionNode subclasses for which a mapper method does not exist in this mapper.

Handling objects that don’t declare mapper methods

In particular, this includes many non-subclasses of pymbolic.ExpressionNode.

map_foreign(expr: object, *args: ~typing.~P, **kwargs: ~typing.~P) ResultT[source]

Mapper method dispatch for non-pymbolic objects.

These are abstract methods for foreign objects that should be overridden in subclasses:

map_constant(expr, *args, **kwargs)[source]

Mapper method for constants. See pymbolic.primitives.register_constant_class().

map_list(expr, *args, **kwargs)[source]
map_tuple(expr, *args, **kwargs)[source]
map_numpy_array(expr, *args, **kwargs)[source]

Base classes for new mappers

class pymbolic.mapper.CombineMapper[source]

A mapper whose goal it is to combine all branches of the expression tree into one final result. The default implementation of all mapper methods simply recurse (Mapper.rec()) on all branches emanating from the current expression, and then call combine() on a tuple of results.

combine(values)[source]

Combine the mapped results of multiple expressions (given in values) into a single result, often by summing or taking set unions.

The pymbolic.mapper.flop_counter.FlopCounter is a very simple example. (Look at its source for an idea of how to derive from CombineMapper.) The pymbolic.mapper.dependency.DependencyMapper is another example.

class pymbolic.mapper.Collector[source]

A subclass of CombineMapper for the common purpose of collecting data derived from an expression in a set that gets ‘unioned’ across children at each non-leaf node in the expression tree.

By default, nothing is collected. All leaves return empty sets.

Added in version 2014.3.

class pymbolic.mapper.IdentityMapper[source]

A Mapper whose default mapper methods make a deep copy of each subexpression.

See Manipulating expressions for an example of the manipulations that can be implemented this way.

rec_arith(expr: ArithmeticExpression, *args: ~typing.~P, **kwargs: ~typing.~P) ArithmeticExpression[source]
class pymbolic.mapper.WalkMapper[source]

A mapper whose default mapper method implementations simply recurse without propagating any result. Also calls visit() for each visited subexpression.

map_... methods are required to call visit() before

descending to visit their children.

visit(expr, *args, **kwargs)[source]

Returns False if no children of this node should be examined.

post_visit(expr, *args, **kwargs)[source]

Is called after a node’s children are visited.

class pymbolic.mapper.CSECachingMapperMixin[source]

A mix-in that helps subclassed mappers implement caching for pymbolic.primitives.CommonSubexpression instances.

Instead of the common mapper method for pymbolic.primitives.CommonSubexpression, subclasses should implement the following method:

map_common_subexpression_uncached(expr)[source]

This method deliberately does not support extra arguments in mapper dispatch, to avoid spurious dependencies of the cache on these arguments.

Base classes for mappers with memoization support

class pymbolic.mapper.CachedMapper[source]

A mapper that memoizes the mapped result for the expressions traversed.

get_cache_key(expr: Expression, *args: ~typing.~P, **kwargs: ~typing.~P) Hashable[source]

Returns the key corresponding to which the result of a mapper method is stored in the cache.

Warning

Assumes that elements of args and kwargs are immutable, and that self does not store any mutable state. Derived mappers must override this method.

class pymbolic.mapper.CachedIdentityMapper[source]
class pymbolic.mapper.CachedCombineMapper[source]
class pymbolic.mapper.CachedCollector[source]
class pymbolic.mapper.CachedWalkMapper[source]

More specialized mappers

Converting to strings and code

Precedence constants

pymbolic.mapper.stringifier.PREC_CALL
pymbolic.mapper.stringifier.PREC_POWER
pymbolic.mapper.stringifier.PREC_UNARY
pymbolic.mapper.stringifier.PREC_PRODUCT
pymbolic.mapper.stringifier.PREC_SUM
pymbolic.mapper.stringifier.PREC_SHIFT
pymbolic.mapper.stringifier.PREC_BITWISE_AND
pymbolic.mapper.stringifier.PREC_BITWISE_XOR
pymbolic.mapper.stringifier.PREC_BITWISE_OR
pymbolic.mapper.stringifier.PREC_COMPARISON
pymbolic.mapper.stringifier.PREC_LOGICAL_AND
pymbolic.mapper.stringifier.PREC_LOGICAL_OR
pymbolic.mapper.stringifier.PREC_IF
pymbolic.mapper.stringifier.PREC_NONE

Mappers

class pymbolic.mapper.stringifier.StringifyMapper[source]

A mapper to turn an expression tree into a string.

pymbolic.ExpressionNode.__str__ is often implemented using this mapper.

When it encounters an unsupported pymbolic.ExpressionNode subclass, it calls its pymbolic.ExpressionNode.make_stringifier() method to get a StringifyMapper that potentially does.

__call__(expr, prec=0, *args: ~typing.~P, **kwargs: ~typing.~P) str[source]

Return a string corresponding to expr. If the enclosing precedence level prec is higher than prec (see Precedence constants), parenthesize the result.

class pymbolic.mapper.stringifier.CSESplittingStringifyMapperMixin[source]

A mix-in for subclasses of StringifyMapper that collects “variable assignments” for pymbolic.primitives.CommonSubexpression objects.

cse_to_name

A dict mapping expressions to CSE variable names.

cse_names

A set of names already assigned.

cse_name_list

A list of tuples of names and their string representations, in order of their dependencies. When generating code, walk down these names in order, and the generated code will never reference an undefined variable.

See pymbolic.mapper.c_code.CCodeMapper for an example of the use of this mix-in.

class pymbolic.mapper.stringifier.LaTeXMapper[source]
class pymbolic.mapper.c_code.CCodeMapper(reverse=True, cse_prefix='_cse', complex_constant_base_type='double', cse_name_list=None)[source]

Generate C code for expressions, while extracting pymbolic.primitives.CommonSubexpression instances.

As an example, define a fairly simple expression expr:

>>> import pymbolic.primitives as p
>>> CSE = p.make_common_subexpression
>>> x = p.Variable("x")
>>> u = CSE(3*x**2-5, "u")
>>> expr = u/(u+3)*(u+5)
>>> print(expr)
(CSE(3*x**2 + -5) / (CSE(3*x**2 + -5) + 3))*(CSE(3*x**2 + -5) + 5)

Notice that if we were to directly generate this code without the added CSE, the subexpression u would be evaluated multiple times. Wrapping the expression as above avoids this unnecessary cost.

>>> from pymbolic.mapper.c_code import CCodeMapper as CCM
>>> ccm = CCM()
>>> result = ccm(expr)

>>> for name, value in ccm.cse_name_list:
...     print("%s = %s;" % (name, value))
...
_cse_u = 3 * x * x + -5;
>>> print(result)
_cse_u / (_cse_u + 3) * (_cse_u + 5)

See pymbolic.mapper.stringifier.CSESplittingStringifyMapperMixin for the cse_* attributes.

class pymbolic.mapper.graphviz.GraphvizMapper[source]

Produces code for dot that yields an expression tree of the traversed expression(s).

get_dot_code()[source]

Return the dot source code for a previously traversed expression.

Added in version 2015.1.

Some minimal mathematics

class pymbolic.mapper.evaluator.EvaluationMapper(context: Mapping[str, ResultT] | None = None)[source]

Example usage:

>>> import pymbolic.primitives as p
>>> x = p.Variable("x")

>>> u = 5*x**2 - 3*x
>>> print(u)
5*x**2 + (-1)*3*x

>>> from pymbolic.mapper.evaluator import EvaluationMapper as EM
>>> EM(context={"x": 5})(u)
110
class pymbolic.mapper.evaluator.CachedEvaluationMapper(context=None)[source]
class pymbolic.mapper.evaluator.FloatEvaluationMapper(context: Mapping[str, ResultT] | None = None)[source]
class pymbolic.mapper.evaluator.CachedFloatEvaluationMapper(context=None)[source]
pymbolic.mapper.evaluator.evaluate(expression: Expression, context: Mapping[str, ResultT] | None = None, mapper_cls: type[EvaluationMapper[ResultT]] = <class 'pymbolic.mapper.evaluator.CachedEvaluationMapper'>) ResultT[source]
Parameters:

mapper_cls – A type of the evaluation mapper whose instance performs the evaluation.

pymbolic.mapper.evaluator.evaluate_kw(expression: Expression, mapper_cls: type[~pymbolic.mapper.evaluator.EvaluationMapper[~pymbolic.mapper.ResultT]] = <class 'pymbolic.mapper.evaluator.CachedEvaluationMapper'>, **context: ~pymbolic.mapper.ResultT) ResultT[source]
Parameters:

mapper_cls – A type of the evaluation mapper whose instance performs the evaluation.

pymbolic.mapper.evaluator.evaluate_to_float(expression, context=None, mapper_cls=<class 'pymbolic.mapper.evaluator.CachedFloatEvaluationMapper'>) float[source]
Parameters:

mapper_cls – A type of the evaluation mapper whose instance performs the evaluation.

class pymbolic.mapper.differentiator.DifferentiationMapper(variable, func_map=<function map_math_functions_by_name>, allowed_nonsmoothness=None)[source]

Example usage:

>>> import pymbolic.primitives as p
>>> x = p.Variable("x")
>>> expr = x*(x+5)**3/(x-1)**2

>>> from pymbolic import flatten
>>> from pymbolic.mapper.differentiator import DifferentiationMapper as DM
>>> print(flatten(DM(x)(expr)))
(((x + 5)**3 + x*3*(x + 5)**2)*(x + -1)**2 + (-1)*2*(x + -1)*x*(x + 5)**3) / (x + -1)**2**2
class pymbolic.mapper.distributor.DistributeMapper(collector=None, const_folder=None)[source]

Example usage:

>>> import pymbolic.primitives as p
>>> x = p.Variable("x")
>>> expr = (x+1)**7
>>> from pymbolic.mapper.distributor import DistributeMapper as DM
>>> print DM()(expr) 
7*x**6 + 21*x**5 + 21*x**2 + 35*x**3 + 1 + 35*x**4 + 7*x + x**7
pymbolic.mapper.distributor.distribute(expr: Expression, parameters=None, commutative=True) Expression[source]
class pymbolic.mapper.collector.TermCollector(parameters: Set[p.AlgebraicLeaf] | None = None)[source]

A term collector that assumes that multiplication is commutative.

Allows specifying parameters (a set of pymbolic.primitives.Variable instances) that are viewed as being coefficients and are not used for term collection.

class pymbolic.mapper.constant_folder.ConstantFoldingMapper[source]
class pymbolic.mapper.constant_folder.CommutativeConstantFoldingMapper[source]
class pymbolic.mapper.substitutor.SubstitutionMapper(subst_func: Callable[[AlgebraicLeaf], Expression | None])[source]
class pymbolic.mapper.substitutor.CachedSubstitutionMapper(subst_func: Callable[[AlgebraicLeaf], Expression | None])[source]
pymbolic.mapper.substitutor.make_subst_func(variable_assignments: SupportsGetItem[Any, Expression]) Callable[[AlgebraicLeaf], Expression | None][source]
pymbolic.mapper.substitutor.substitute(expression: Expression, variable_assignments: SupportsItems[AlgebraicLeaf | str, Expression] | None = None, mapper_cls=<class 'pymbolic.mapper.substitutor.CachedSubstitutionMapper'>, **kwargs: Expression)[source]
Parameters:

mapper_cls – A type of the substitution mapper whose instance applies the substitution.

class pymbolic.mapper.substitutor.Callable

References

class pymbolic.mapper.substitutor.SupportsGetItem

A protocol with a __getitem__ method.

Finding expression properties

class pymbolic.mapper.dependency.DependencyMapper(include_subscripts: bool = True, include_lookups: bool = True, include_calls: bool | Literal['descend_args'] = True, include_cses: bool = False, composite_leaves: bool | None = None)[source]

Maps an expression to the set of expressions it is based on. The include_* arguments to the constructor determine which types of objects occur in this output set. If all are False, only pymbolic.primitives.Variable instances are included.

class pymbolic.mapper.dependency.CachedDependencyMapper(include_subscripts: bool = True, include_lookups: bool = True, include_calls: bool | Literal['descend_args'] = True, include_cses: bool = False, composite_leaves: bool | None = None)[source]
class pymbolic.mapper.flop_counter.FlopCounter[source]
class pymbolic.mapper.flop_counter.CSEAwareFlopCounter[source]

A flop counter that only counts the contribution from common subexpressions once.

Warning

You must use a fresh mapper for each new evaluation operation for which reuse may take place.

Analysis tools

class pymbolic.mapper.analysis.NodeCountMapper[source]

Counts the number of nodes in an expression tree. Nodes that occur repeatedly as well as CommonSubexpression nodes are only counted once.

count

The number of nodes.

pymbolic.mapper.analysis.get_num_nodes(expr) int[source]

Returns the number of nodes in expr. Nodes that occur repeatedly as well as CommonSubexpression nodes are only counted once.

Simplification

class pymbolic.mapper.flattener.FlattenMapper[source]

Applies pymbolic.primitives.flattened_sum() to Sum” and pymbolic.primitives.flattened_product() to Product.” Also applies light-duty simplification to other operators.

This parallels what was done implicitly in the expression node constructors.

is_expr_integer_valued(expr: Expression) bool[source]

A user-supplied method to indicate whether a given expr is integer- valued. This enables additional simplifications that are not valid in general. The default implementation simply returns False.

Added in version 2024.1.

pymbolic.flatten(expr: ArithmeticOrExpressionT) ArithmeticOrExpressionT[source]