sympy/sympy — pull request #1009 by flacjacket (2012-01-22 04:41:52+00:00)
Title: Addressing Piecewise issues (opened for comments)

I'm opening this pull request to get feedback on some things I've been playing with in Piecwise.

This push is to address a couple open issues with Piecewise and its syntax. The first commit leaves the syntax mostly unchanged, with the exception of changing some things for otherwise syntax. Other major changes with this commit are getting rid of the ExprCondPair class and changing how evaluate=False is handled (both True and False conds are kept, they are stored as a sentinel value which are Dummy's). The second commit changes the syntax much more, basically moving what was the args to a Tuple as the first arg and making the second arg a boolean sentinel for evaluate. This allows for things like subs to recreate the piecewise function without forcing evaluate if the function was initially created with evaluate=False. It introduces a new syntax, but this syntax isn't really meant to be used outside of the re-creation of the object using its args. See the tests for an XFAIL test introduced in the first commit which passes after the changes in the second commit.

Any comments on any of the changes here would be greatly appreciated.

**The first commit:**

Piecewise syntax is changed to allow for a more sensible definition of the otherwise condition. Before, an expr/cond pair was specified where cond was given as True. Now, otherwise can either be passed as the final argument after a sequence of expr/cond 2-tuples or otherwise can be passed as a 1-tuple as the final argument of expr/cond 2-tuples.

The ExprCondPair class is removed in favor of Tuples to store the expr/cond pairs. With this, sentinal variables for both True and False, previously in ExprCondPair, are implemented in Piecewise, allowing all args to be Basic. With this, Piecewise should no longer perform things such as 'symplify()', as args should be subclasses of Basic.

Additionally, Piecewise no longer accepts an Interval as a condition. To implement the same functionality, either the '.as_relational()' or '.contains()' methods of Interval can be used.

The properties '.ecs' and '.otherwise' are implemented to easily access the expr/cond pairs and otherwise statement, respectively.

When a Piecewise is evaluated at a point where all the conditions are False and no otherwise expression is given, the function now return NaN instead of raising a ValueError.

**The second commit:**

Internally, Piecewise uses a new cannonical argument syntax. This is that the args have length 2, the first element is a Tuple consisting of expr/cond pairs and the otherwise expression, if given. This Tuple is
the same as the args were previously. The second element of the args is a sentinel for True or False denoting whether or not the Piecewise function should call 'eval()'. This allows for operations such as
'subs()' to be called without forcing the evaluation of Piecewise.

**This addresses the following issues:**

[2101](http://code.google.com/p/sympy/issues/detail?id=1216) latex printing with piecewise function : reversed expr and cond

[2567](http://code.google.com/p/sympy/issues/detail?id=2567) Piecewise does not work when not given an "otherwise" condition

[2626](http://code.google.com/p/sympy/issues/detail?id=2626) Piecewise should use a different syntax for "otherwise"

[2710](http://code.google.com/p/sympy/issues/detail?id=2710) Cannot simplify Piecewise

[2726](http://code.google.com/p/sympy/issues/detail?id=2726) Piecewise((1,Interval(0,1,False,True)),(0,True)) syntax should not be allowed

Also, the following also seems like it has been handled, but not closed:

[1216](http://code.google.com/p/sympy/issues/detail?id=1216) series expansion of piecewise fails