When constructing a sympy.PIecewise object, it automatically calls piecewise_fold if it finds a Piecewise inside a condition. I would like to prevent this, because I’m using sympy for code generation and this auto-expansion is causing my expressions to explode exponentially.
Here is a simple example of this auto-substituion:
>>> import sympy as sym
>>> x = sym.Symbol(‘x’)
>>> y = sym.Piecewise((0,x<0),(x,True))
>>> sym.Piecewise((y,y<1),(1,True))
Piecewise((Piecewise((0, x < 0), (x, True)), x < 1), (1, True))
Note that the reference to y in the condition y<1 has been removed by the auto-folding. This is what I’m trying to prevent, because in my case it results in bigger and bigger expressions. Unfortunately this doesn’t work:
>>> sym.piecewise_fold(sym.Piecewise((y,sym.UnevaluatedExpr(y<1)),(1,True)))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/Users/ndv/Library/Python/3.6/lib/python/site-packages/sympy/functions/elementary/piecewise.py", line 129, in __new__
pair = ExprCondPair(*getattr(ec, 'args', ec))
File "/Users/ndv/Library/Python/3.6/lib/python/site-packages/sympy/functions/elementary/piecewise.py", line 31, in __new__
cond = cond.rewrite(ITE)
File "/Users/ndv/Library/Python/3.6/lib/python/site-packages/sympy/core/basic.py", line 1681, in rewrite
return self._eval_rewrite(None, rule, **hints)
File "/Users/ndv/Library/Python/3.6/lib/python/site-packages/sympy/core/basic.py", line 1589, in _eval_rewrite
rewritten = getattr(self, rule)(*args)
File "/Users/ndv/Library/Python/3.6/lib/python/site-packages/sympy/functions/elementary/piecewise.py", line 916, in _eval_rewrite_as_ITE
''' % func_name(b)))
TypeError:
Expecting Boolean or bool but got `UnevaluatedExpr`
And neither does this, which gives a fairly spectacular stack trace:
>>> sym.piecewise_fold(sym.Piecewise((y,sym.UnevaluatedExpr(y)<1),(1,True)))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/Users/ndv/Library/Python/3.6/lib/python/site-packages/sympy/functions/elementary/piecewise.py", line 138, in __new__
r = cls.eval(*newargs)
File "/Users/ndv/Library/Python/3.6/lib/python/site-packages/sympy/functions/elementary/piecewise.py", line 187, in eval
c = c.as_set().as_relational(x)
File "/Users/ndv/Library/Python/3.6/lib/python/site-packages/sympy/logic/boolalg.py", line 146, in as_set
if periodicity(r, x) not in (0, None):
File "/Users/ndv/Library/Python/3.6/lib/python/site-packages/sympy/calculus/util.py", line 456, in periodicity
return periodicity(g, symbol)
File "/Users/ndv/Library/Python/3.6/lib/python/site-packages/sympy/calculus/util.py", line 473, in periodicity
g_s = decompogen(f, symbol)
File "/Users/ndv/Library/Python/3.6/lib/python/site-packages/sympy/solvers/decompogen.py", line 57, in decompogen
result += [f1] + decompogen(f2, symbol)
File "/Users/ndv/Library/Python/3.6/lib/python/site-packages/sympy/solvers/decompogen.py", line 57, in decompogen
result += [f1] + decompogen(f2, symbol)
File "/Users/ndv/Library/Python/3.6/lib/python/site-packages/sympy/solvers/decompogen.py", line 57, in decompogen
result += [f1] + decompogen(f2, symbol)
[Previous line repeated 960 more times]
File "/Users/ndv/Library/Python/3.6/lib/python/site-packages/sympy/solvers/decompogen.py", line 51, in decompogen
fp = Poly(f)
File "/Users/ndv/Library/Python/3.6/lib/python/site-packages/sympy/polys/polytools.py", line 129, in __new__
return cls._from_expr(rep, opt)
File "/Users/ndv/Library/Python/3.6/lib/python/site-packages/sympy/polys/polytools.py", line 239, in _from_expr
rep, opt = _dict_from_expr(rep, opt)
File "/Users/ndv/Library/Python/3.6/lib/python/site-packages/sympy/polys/polyutils.py", line 368, in _dict_from_expr
rep, gens = _dict_from_expr_no_gens(expr, opt)
File "/Users/ndv/Library/Python/3.6/lib/python/site-packages/sympy/polys/polyutils.py", line 311, in _dict_from_expr_no_gens
(poly,), gens = _parallel_dict_from_expr_no_gens((expr,), opt)
File "/Users/ndv/Library/Python/3.6/lib/python/site-packages/sympy/polys/polyutils.py", line 274, in _parallel_dict_from_expr_no_gens
gens = _sort_gens(gens, opt=opt)
File "/Users/ndv/Library/Python/3.6/lib/python/site-packages/sympy/polys/polyutils.py", line 106, in _sort_gens
gens = sorted(gens, key=order_key)
File "/Users/ndv/Library/Python/3.6/lib/python/site-packages/sympy/polys/polyutils.py", line 78, in order_key
gen = str(gen)
File "/Users/ndv/Library/Python/3.6/lib/python/site-packages/sympy/core/basic.py", line 412, in __str__
return sstr(self, order=None)
File "/Users/ndv/Library/Python/3.6/lib/python/site-packages/sympy/printing/str.py", line 847, in sstr
s = p.doprint(expr)
File "/Users/ndv/Library/Python/3.6/lib/python/site-packages/sympy/printing/printer.py", line 249, in doprint
return self._str(self._print(expr))
File "/Users/ndv/Library/Python/3.6/lib/python/site-packages/sympy/printing/printer.py", line 287, in _print
return getattr(self, printmethod)(expr, **kwargs)
File "/Users/ndv/Library/Python/3.6/lib/python/site-packages/sympy/printing/str.py", line 558, in _print_UnevaluatedExpr
return self._print(expr.args[0])
File "/Users/ndv/Library/Python/3.6/lib/python/site-packages/sympy/printing/printer.py", line 287, in _print
return getattr(self, printmethod)(expr, **kwargs)
RecursionError: maximum recursion depth exceeded
>>> sym.Piecewise((y,sym.UnevaluatedExpr(y)<1),(1,True))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/Users/ndv/Library/Python/3.6/lib/python/site-packages/sympy/functions/elementary/piecewise.py", line 138, in __new__
r = cls.eval(*newargs)
File "/Users/ndv/Library/Python/3.6/lib/python/site-packages/sympy/functions/elementary/piecewise.py", line 187, in eval
c = c.as_set().as_relational(x)
File "/Users/ndv/Library/Python/3.6/lib/python/site-packages/sympy/logic/boolalg.py", line 146, in as_set
if periodicity(r, x) not in (0, None):
File "/Users/ndv/Library/Python/3.6/lib/python/site-packages/sympy/calculus/util.py", line 456, in periodicity
return periodicity(g, symbol)
File "/Users/ndv/Library/Python/3.6/lib/python/site-packages/sympy/calculus/util.py", line 473, in periodicity
g_s = decompogen(f, symbol)
File "/Users/ndv/Library/Python/3.6/lib/python/site-packages/sympy/solvers/decompogen.py", line 57, in decompogen
result += [f1] + decompogen(f2, symbol)
File "/Users/ndv/Library/Python/3.6/lib/python/site-packages/sympy/solvers/decompogen.py", line 57, in decompogen
result += [f1] + decompogen(f2, symbol)
File "/Users/ndv/Library/Python/3.6/lib/python/site-packages/sympy/solvers/decompogen.py", line 57, in decompogen
result += [f1] + decompogen(f2, symbol)
[Previous line repeated 960 more times]
File "/Users/ndv/Library/Python/3.6/lib/python/site-packages/sympy/solvers/decompogen.py", line 51, in decompogen
fp = Poly(f)
File "/Users/ndv/Library/Python/3.6/lib/python/site-packages/sympy/polys/polytools.py", line 129, in __new__
return cls._from_expr(rep, opt)
File "/Users/ndv/Library/Python/3.6/lib/python/site-packages/sympy/polys/polytools.py", line 239, in _from_expr
rep, opt = _dict_from_expr(rep, opt)
File "/Users/ndv/Library/Python/3.6/lib/python/site-packages/sympy/polys/polyutils.py", line 368, in _dict_from_expr
rep, gens = _dict_from_expr_no_gens(expr, opt)
File "/Users/ndv/Library/Python/3.6/lib/python/site-packages/sympy/polys/polyutils.py", line 311, in _dict_from_expr_no_gens
(poly,), gens = _parallel_dict_from_expr_no_gens((expr,), opt)
File "/Users/ndv/Library/Python/3.6/lib/python/site-packages/sympy/polys/polyutils.py", line 274, in _parallel_dict_from_expr_no_gens
gens = _sort_gens(gens, opt=opt)
File "/Users/ndv/Library/Python/3.6/lib/python/site-packages/sympy/polys/polyutils.py", line 106, in _sort_gens
gens = sorted(gens, key=order_key)
File "/Users/ndv/Library/Python/3.6/lib/python/site-packages/sympy/polys/polyutils.py", line 78, in order_key
gen = str(gen)
File "/Users/ndv/Library/Python/3.6/lib/python/site-packages/sympy/core/basic.py", line 412, in __str__
return sstr(self, order=None)
File "/Users/ndv/Library/Python/3.6/lib/python/site-packages/sympy/printing/str.py", line 847, in sstr
s = p.doprint(expr)
File "/Users/ndv/Library/Python/3.6/lib/python/site-packages/sympy/printing/printer.py", line 249, in doprint
return self._str(self._print(expr))
File "/Users/ndv/Library/Python/3.6/lib/python/site-packages/sympy/printing/printer.py", line 287, in _print
return getattr(self, printmethod)(expr, **kwargs)
File "/Users/ndv/Library/Python/3.6/lib/python/site-packages/sympy/printing/str.py", line 558, in _print_UnevaluatedExpr
return self._print(expr.args[0])
File "/Users/ndv/Library/Python/3.6/lib/python/site-packages/sympy/printing/printer.py", line 287, in _print
return getattr(self, printmethod)(expr, **kwargs)
RecursionError: maximum recursion depth exceeded
Is there some way that I can do this, i.e. keep the unevaluated Piecewise inside a cond of another piecewise?
Best regards
Nathaniel