modelparameters.sympy.strategies package¶
Subpackages¶
Submodules¶
modelparameters.sympy.strategies.core module¶
Generic SymPy-Independent Strategies
- modelparameters.sympy.strategies.core.chain(*rules)[source]¶
Compose a sequence of rules so that they apply to the expr sequentially
- modelparameters.sympy.strategies.core.condition(cond, rule)[source]¶
Only apply rule if condition is true
- modelparameters.sympy.strategies.core.debug(rule, file=None)[source]¶
Print out before and after expressions each time rule is used
- modelparameters.sympy.strategies.core.do_one(*rules)[source]¶
Try each of the rules until one works. Then stop.
- modelparameters.sympy.strategies.core.exhaust(rule)[source]¶
Apply a rule repeatedly until it has no effect
- modelparameters.sympy.strategies.core.identity(x)¶
- modelparameters.sympy.strategies.core.minimize(*rules, **kwargs)[source]¶
Select result of rules that minimizes objective
>>> from ..strategies import minimize >>> inc = lambda x: x + 1 >>> dec = lambda x: x - 1 >>> rl = minimize(inc, dec) >>> rl(4) 3
>>> rl = minimize(inc, dec, objective=lambda x: -x) # maximize >>> rl(4) 5
- modelparameters.sympy.strategies.core.null_safe(rule)[source]¶
Return original expr if rule returns None
modelparameters.sympy.strategies.rl module¶
Generic Rules for SymPy
This file assumes knowledge of Basic and little else.
- modelparameters.sympy.strategies.rl.distribute(A, B)[source]¶
Turns an A containing Bs into a B of As
where A, B are container types
>>> from ..strategies import distribute >>> from .. import Add, Mul, symbols >>> x, y = symbols('x,y') >>> dist = distribute(Mul, Add) >>> expr = Mul(2, x+y, evaluate=False) >>> expr 2*(x + y) >>> dist(expr) 2*x + 2*y
- modelparameters.sympy.strategies.rl.flatten(expr, new=<function Basic.__new__>)[source]¶
Flatten T(a, b, T(c, d), T2(e)) to T(a, b, c, d, T2(e))
- modelparameters.sympy.strategies.rl.glom(key, count, combine)[source]¶
Create a rule to conglomerate identical args
>>> from ..strategies import glom >>> from .. import Add >>> from ..abc import x
>>> key = lambda x: x.as_coeff_Mul()[1] >>> count = lambda x: x.as_coeff_Mul()[0] >>> combine = lambda cnt, arg: cnt * arg >>> rl = glom(key, count, combine)
>>> rl(Add(x, -x, 3*x, 2, 3, evaluate=False)) 3*x + 5
Wait, how are key, count and combine supposed to work?
>>> key(2*x) x >>> count(2*x) 2 >>> combine(2, x) 2*x
- modelparameters.sympy.strategies.rl.rebuild(expr)[source]¶
Rebuild a SymPy tree
This function recursively calls constructors in the expression tree. This forces canonicalization and removes ugliness introduced by the use of Basic.__new__
- modelparameters.sympy.strategies.rl.rm_id(isid, new=<function Basic.__new__>)[source]¶
Create a rule to remove identities
isid - fn :: x -> Bool — whether or not this element is an identity
>>> from ..strategies import rm_id >>> from .. import Basic >>> remove_zeros = rm_id(lambda x: x==0) >>> remove_zeros(Basic(1, 0, 2)) Basic(1, 2) >>> remove_zeros(Basic(0, 0)) # If only identites then we keep one Basic(0)
See also
unpack
modelparameters.sympy.strategies.tools module¶
- modelparameters.sympy.strategies.tools.canon(*rules, **kwargs)[source]¶
Strategy for canonicalization
Apply each rule in a bottom_up fashion through the tree. Do each one in turn. Keep doing this until there is no change.
- modelparameters.sympy.strategies.tools.subs(d, **kwargs)[source]¶
Full simultaneous exact substitution
Examples
>>> from .tools import subs >>> from .. import Basic >>> mapping = {1: 4, 4: 1, Basic(5): Basic(6, 7)} >>> expr = Basic(1, Basic(2, 3), Basic(4, Basic(5))) >>> subs(mapping)(expr) Basic(4, Basic(2, 3), Basic(1, Basic(6, 7)))
- modelparameters.sympy.strategies.tools.typed(ruletypes)[source]¶
Apply rules based on the expression type
- inputs:
ruletypes – a dict mapping {Type: rule}
>>> from ..strategies import rm_id, typed >>> from .. import Add, Mul >>> rm_zeros = rm_id(lambda x: x==0) >>> rm_ones = rm_id(lambda x: x==1) >>> remove_idents = typed({Add: rm_zeros, Mul: rm_ones})
modelparameters.sympy.strategies.traverse module¶
Strategies to Traverse a Tree.
- modelparameters.sympy.strategies.traverse.bottom_up(rule, fns={'children': <function <lambda>>, 'leaf': <function <lambda>>, 'new': <function Basic.__new__>, 'op': <class 'type'>})[source]¶
Apply a rule down a tree running it on the bottom nodes first.
- modelparameters.sympy.strategies.traverse.bottom_up_once(rule, fns={'children': <function <lambda>>, 'leaf': <function <lambda>>, 'new': <function Basic.__new__>, 'op': <class 'type'>})[source]¶
Apply a rule up a tree - stop on success.
- modelparameters.sympy.strategies.traverse.sall(rule, fns={'children': <function <lambda>>, 'leaf': <function <lambda>>, 'new': <function Basic.__new__>, 'op': <class 'type'>})[source]¶
Strategic all - apply rule to args.
modelparameters.sympy.strategies.tree module¶
- modelparameters.sympy.strategies.tree.allresults(tree, leaf=<function yieldify>)[source]¶
Execute a strategic tree. Return all possibilities.
Returns a lazy iterator of all possible results
Exhaustiveness¶
This is an exhaustive algorithm. In the example
([a, b], [c, d])
All of the results from
(a, c), (b, c), (a, d), (b, d)
are returned. This can lead to combinatorial blowup.
See sympy.strategies.greedy for details on input
- modelparameters.sympy.strategies.tree.greedy(tree, objective=<function <lambda>>, **kwargs)[source]¶
Execute a strategic tree. Select alternatives greedily
Trees¶
Nodes in a tree can be either
function - a leaf list - a selection among operations tuple - a sequence of chained operations
Textual examples¶
Text: Run f, then run g, e.g.
lambda x: g(f(x))
Code:(f, g)
Text: Run either f or g, whichever minimizes the objective Code:
[f, g]
Textx: Run either f or g, whichever is better, then run h Code:
([f, g], h)
Text: Either expand then simplify or try factor then foosimp. Finally print Code:
([(expand, simplify), (factor, foosimp)], print)
Objective¶
“Better” is determined by the objective keyword. This function makes choices to minimize the objective. It defaults to the identity.
Examples
>>> from .tree import greedy >>> inc = lambda x: x + 1 >>> dec = lambda x: x - 1 >>> double = lambda x: 2*x
>>> tree = [inc, (dec, double)] # either inc or dec-then-double >>> fn = greedy(tree) >>> fn(4) # lowest value comes from the inc 5 >>> fn(1) # lowest value comes from dec then double 0
This function selects between options in a tuple. The result is chosen that minimizes the objective function.
>>> fn = greedy(tree, objective=lambda x: -x) # maximize >>> fn(4) # highest value comes from the dec then double 6 >>> fn(1) # highest value comes from the inc 2
Greediness¶
This is a greedy algorithm. In the example:
([a, b], c) # do either a or b, then do c
the choice between running
a
orb
is made without foresight to c
- modelparameters.sympy.strategies.tree.identity(x)¶
- modelparameters.sympy.strategies.tree.treeapply(tree, join, leaf=<function <lambda>>)[source]¶
Apply functions onto recursive containers (tree)
- join - a dictionary mapping container types to functions
e.g.
{list: minimize, tuple: chain}
Keys are containers/iterables. Values are functions [a] -> a.
Examples
>>> from .tree import treeapply >>> tree = [(3, 2), (4, 1)] >>> treeapply(tree, {list: max, tuple: min}) 2
>>> add = lambda *args: sum(args) >>> def mul(*args): ... total = 1 ... for arg in args: ... total *= arg ... return total >>> treeapply(tree, {list: mul, tuple: add}) 25
modelparameters.sympy.strategies.util module¶
Module contents¶
Rewrite Rules
DISCLAIMER: This module is experimental. The interface is subject to change.
A rule is a function that transforms one expression into another
Rule :: Expr -> Expr
A strategy is a function that says how a rule should be applied to a syntax tree. In general strategies take rules and produce a new rule
Strategy :: [Rules], Other-stuff -> Rule
This allows developers to separate a mathematical transformation from the algorithmic details of applying that transformation. The goal is to separate the work of mathematical programming from algorithmic programming.
Submodules
strategies.rl - some fundamental rules strategies.core - generic non-SymPy specific strategies strategies.traverse - strategies that traverse a SymPy tree strategies.tools - some conglomerate strategies that do depend on SymPy