TermCollector

class TermCollector(symbols_to_expressions: dict, R: MatrixBase, points: Iterable, point_names: Iterable[str])[source]

This class takes a mapping of symbols to expressions and provides methods to create an abstract ast.CodeBlock that contains a list of ast.Assignment objects. Those objects can be easily converted to real code.

symbols_to_expressions

symbols_to_expressions maps symbols to sympy expressions. Allowed symbols are:

  • sy.Symbol

  • sy.Function of R

  • sy.MatrixSymbol

  • sy.Indexed

  • sympy.matrices.expressions.matexpr.MatrixElement

Any sympy expression is allowed that has the same shape as the coresponding symbol.

Each point at which a sy.Function is evaluated, must be declared in the points argument.

Examples

The matrix M is expressed in terms of matrix T. For each matrix component an ast.Assignment is created. The assignments can be executed from the first one to the last one, because it is guaranteed that a dependent variable occurs after all its dependencies are computed.

>>> M = sy.MatrixSymbol("M", 2, 1)
>>> T = sy.MatrixSymbol("T", 2, 1)
>>> collector = TermCollector(
...     symbols_to_expressions={
...         M: 2 * T,
...         T[0]: 1,
...         T[1]: 1,
...     },
...     R=sy.Matrix([]),
...     points=[],
...     point_names=[]
... )
>>> collector.collect_assignments(
...     input_symbols=[],
...     result_symbol=M
... )
CodeBlock(
Assignment(T[0, 0], 1),
Assignment(M[0, 0], 2*T[0, 0]),
Assignment(T[1, 0], 1),
Assignment(M[1, 0], 2*T[1, 0])
)

Another example demonstrates the use of a sy.Function. The function is evaluated at r=0 and r=1. For this reason two points and point names are defined. The point names are used to define variable names for the function value at a specific point. E.g. g_at_p0 is the variable name of g(0).

>>> r, f, k, o, d = sy.symbols("r f k o d")
>>> g = sy.Function("g")
>>> collector = TermCollector(
...     symbols_to_expressions={
...         f: g(0) + k*(g(1) - g(0)),
...         k: g(1) - g(0),
...         g(r): o + d * r
...     },
...     R=sy.Matrix([r]),
...     points=[[0], [1]],
...     point_names=["p0", "p1"]
... )

Three input variables are defined. No assignments will be made to input variables, even if it would be possible. E.g. g_at_p0 is g(0) and could be expressed as g_at_p0=o.

>>> collector.collect_assignments(
...     input_symbols=[o, d, "g_at_p0"],
...     result_symbol=f,
...     cse=False
... )
CodeBlock(
Assignment(g_at_p1, d + o),
Assignment(k, -g_at_p0 + g_at_p1),
Assignment(f, g_at_p0 + k*(-g_at_p0 + g_at_p1))
)

Furthermore, the common subexpression elimination (cse) of sympy elimiates duplicate expressions. E.g.: -g_at_p0 + g_at_p1 is computed twice in the above example. Cse introduces a new variable (tmp0), instead.

>>> collector.to_assignments(input_symbols=[o, d, "g_at_p0", "g_at_p1"], cse=True)
CodeBlock(
Assignment(tmp0, -g_at_p0 + g_at_p1),
Assignment(k, tmp0),
Assignment(f, g_at_p0 + k*tmp0)
)
Parameters:
  • symbols_to_expressions – Dictionary mapping symbols to sympy expressions

  • R – sympy Matrix of shape (d,) containing symbolic reference space coordinates

  • points – Array of shape (p, d) containing points. Each point that is evalutated by a sy.Function in symbols_to_expressions object has to be declared.

  • point_names – Array of shape (p,) containing names of points defined in points.

Methods

__init__(symbols_to_expressions, R, points, ...)

This class takes a mapping of symbols to expressions and provides methods to create an abstract ast.CodeBlock that contains a list of ast.Assignment objects.

collect_assignments(input_symbols, result_symbol)

Collect all assignments needed to compute the result with the given input symbols.

collect_expressions_for_array(result_array)

Collect all assignments needed to compute the result_array.

collect_expressions_for_symbol(result)

Collect all assignments needed to compute the result.

reset()

Resets all collected assignments

to_assignments(input_symbols[, cse])

Create a code block with assignments.