details:   http://hg.sympy.org/sympy/rev/95089a89cabd
changeset: 1846:95089a89cabd
user:      Andy R. Terrel <[EMAIL PROTECTED]>
date:      Wed Oct 22 22:13:34 2008 +0200
description:
Adding ExprCondPair data structure to piecewise objects and cleaning code.

diffs (151 lines):

diff -r d072a7ea3a52 -r 95089a89cabd sympy/functions/elementary/piecewise.py
--- a/sympy/functions/elementary/piecewise.py   Wed Oct 22 22:13:18 2008 +0200
+++ b/sympy/functions/elementary/piecewise.py   Wed Oct 22 22:13:34 2008 +0200
@@ -1,9 +1,30 @@
 
 from sympy.core.basic import Basic, S
-from sympy.core.function import Function, FunctionClass, diff
+from sympy.core.function import Function, diff
 from sympy.core.numbers import Number
 from sympy.core.relational import Relational
 from sympy.core.sympify import sympify
+
+class ExprCondPair(Basic):
+    """Represents an expression, condition pair."""
+
+    def __new__(cls, expr, cond, **assumptions):
+        expr = sympify(expr)
+        cond = sympify(cond)
+        return Basic.__new__(cls, expr, cond, **assumptions)
+
+    @property
+    def expr(self):
+        return self.args[0]
+
+    @property
+    def cond(self):
+        return self.args[1]
+
+    def __iter__(self):
+        yield self.expr
+        yield self.cond
+
 
 class Piecewise(Function):
     """
@@ -36,13 +57,21 @@
     nargs=None
 
     def __new__(cls, *args, **options):
-        for opt in ["nargs", "dummy", "comparable", "noncommutative", 
"commutative"]:
-            if opt in options:
-                del options[opt]
-        r = cls.canonize(*args)
+        # Check types first
+        for ec in args:
+            if not isinstance(ec, tuple) or len(ec) != 2:
+                raise TypeError, "args may only include (expr, cond) pairs"
+            cond_type = type(ec[1])
+            if not (cond_type is bool or issubclass(cond_type, Relational) or \
+                    issubclass(cond_type, Number)):
+                raise TypeError, \
+                    "Cond %s is of type %s, but must be a bool," \
+                    " Relational or Number" % (ec[1], cond_type)
 
         # sympify args
-        args = map(lambda x:(sympify(x[0]), sympify(x[1])), args)
+        args = map(lambda x:ExprCondPair(*x), args)
+
+        r = cls.canonize(*args)
 
         if r is None:
             return Basic.__new__(cls, *args, **options)
@@ -51,18 +80,6 @@
 
     @classmethod
     def canonize(cls, *args):
-        # Check types first
-        for ec in args:
-            if (not isinstance(ec, tuple)) or len(ec)!=2:
-                raise TypeError, "args may only include (expr, cond) pairs"
-        for expr, cond in args:
-            cond_type = type(ec[1])
-            if cond_type != bool and not issubclass(cond_type, Relational) and\
-                    not issubclass(cond_type, Number):
-                raise TypeError, \
-                    "Cond %s is of type %s, but must be a bool,"\
-                    " Relational or Number" % (cond, cond_type)
-
         # Check for situations where we can evaluate the Piecewise object.
         # 1) Hit an unevaluatable cond (e.g. x<1) -> keep object
         # 2) Hit a true condition -> return that expr
@@ -117,7 +134,7 @@
         #    -  eg x < 1, x < 3 -> [oo,1],[1,3] instead of [oo,1],[oo,3]
         # 3) Sort the intervals to make it easier to find correct exprs
         for expr, cond in self.args:
-            if issubclass(type(cond),Number):
+            if cond.is_Number:
                 if cond:
                     default = expr
                     break
@@ -130,9 +147,9 @@
                 curr[1] = S.Infinity
             else:
                 raise NotImplementedError, \
-                    "Currently only supporting evaluation with only "\
-                    "sym on one side fo the relation."
-            curr = [max(a,curr[0]),min(b,curr[1])]
+                    "Currently only supporting evaluation with only " \
+                    "sym on one side of the relation."
+            curr = [max(a, curr[0]), min(b, curr[1])]
             for n in xrange(len(int_expr)):
                 if self.__eval_cond(curr[0] < int_expr[n][1]) and \
                         self.__eval_cond(curr[0] >= int_expr[n][0]):
@@ -141,7 +158,7 @@
                         self.__eval_cond(curr[1] <= int_expr[n][1]):
                     curr[1] = int_expr[n][0]
             if self.__eval_cond(curr[0] < curr[1]):
-                int_expr.append(curr+[expr])
+                int_expr.append(curr + [expr])
         int_expr.sort(key=lambda x:x[0])
 
         # Add holes to list of intervals if there is a default value,
@@ -150,16 +167,16 @@
         curr_low = a
         for int_a, int_b, expr in int_expr:
             if curr_low < int_a:
-                holes.append([curr_low, min(b,int_a), default])
+                holes.append([curr_low, min(b, int_a), default])
             curr_low = int_b
             if curr_low > b:
                 break
         if holes and default != None:
             int_expr.extend(holes)
         elif holes and default == None:
-            raise ValueError, "Called interval evaluation over piecewise "\
-                              "function on undefined intervals %s" %\
-                              ", ".join([str((h[0],h[1])) for h in holes])
+            raise ValueError, "Called interval evaluation over piecewise " \
+                              "function on undefined intervals %s" % \
+                              ", ".join([str((h[0], h[1])) for h in holes])
 
         # Finally run through the intervals and sum the evaluation.
         # TODO: Either refactor this code or Integral.doit to call 
_eval_interval
@@ -190,13 +207,8 @@
     @classmethod
     def __eval_cond(cls, cond):
         """Returns S.One if True, S.Zero if False, or None if undecidable."""
-        if issubclass(type(cond), Number) or type(cond) == bool:
+        if type(cond) == bool or cond.is_Number:
             return sympify(bool(cond))
-        arg0 = cond.args[0]
-        arg1 = cond.args[1]
-        if isinstance(arg0, FunctionClass) or isinstance(arg1, FunctionClass):
-            return None
-        if not issubclass(type(arg0.evalf()), Number) or \
-                not issubclass(type(arg1.evalf()), Number):
-            return None
-        return sympify(bool(cond))
+        if cond.args[0].is_Number and cond.args[1].is_Number:
+            return sympify(bool(cond))
+        return None

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"sympy-commits" group.
To post to this group, send email to sympy-commits@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/sympy-commits?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to