(self, sym, a, b, targetcond=None)
return int_expr
Determine what intervals the expr, cond pairs affect.

        1) If cond is True, then log it as default
        1.1) Currently if cond can't be evaluated, throw NotImplementedError.
        2) For each inequality, if previous cond defines part of the interval
           update the new conds interval.
           -  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

        Under normal use, we return the expr,cond pairs in increasing order
        along the real axis corresponding to the symbol sym.  If targetcond
        is given, we return a list of (lowerbound, upperbound) pairs for
        this condition.
Determine what intervals the expr, cond pairs affect.
Determine what intervals the expr cond pairs affect .
def _sort_expr_cond(self, sym, a, b, targetcond=None):
        """Determine what intervals the expr, cond pairs affect.

        1) If cond is True, then log it as default
        1.1) Currently if cond can't be evaluated, throw NotImplementedError.
        2) For each inequality, if previous cond defines part of the interval
           update the new conds interval.
           -  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

        Under normal use, we return the expr,cond pairs in increasing order
        along the real axis corresponding to the symbol sym.  If targetcond
        is given, we return a list of (lowerbound, upperbound) pairs for
        this condition."""
        from sympy.solvers.inequalities import _solve_inequality
        default = None
        int_expr = []
        expr_cond = []
        or_cond = False
        or_intervals = []
        independent_expr_cond = []
        for expr, cond in self.args:
            if isinstance(cond, Or):
                for cond2 in sorted(cond.args, key=default_sort_key):
                    expr_cond.append((expr, cond2))
            else:
                expr_cond.append((expr, cond))
            if cond == True:
                break
        for expr, cond in expr_cond:
            if cond == True:
                independent_expr_cond.append((expr, cond))
                default = self.func(*independent_expr_cond)
                break
            orig_cond = cond
            if sym not in cond.free_symbols:
                independent_expr_cond.append((expr, cond))
                continue
            elif isinstance(cond, Equality):
                continue
            elif isinstance(cond, And):
                lower = S.NegativeInfinity
                upper = S.Infinity
                for cond2 in cond.args:
                    if sym not in [cond2.lts, cond2.gts]:
                        cond2 = _solve_inequality(cond2, sym)
                    if cond2.lts == sym:
                        upper = Min(cond2.gts, upper)
                    elif cond2.gts == sym:
                        lower = Max(cond2.lts, lower)
                    else:
                        raise NotImplementedError(
                            "Unable to handle interval evaluation of expression.")
            else:
                if sym not in [cond.lts, cond.gts]:
                    cond = _solve_inequality(cond, sym)
                lower, upper = cond.lts, cond.gts  # part 1: initialize with givens
                if cond.lts == sym:                # part 1a: expand the side ...
                    lower = S.NegativeInfinity   # e.g. x <= 0 ---> -oo <= 0
                elif cond.gts == sym:            # part 1a: ... that can be expanded
                    upper = S.Infinity           # e.g. x >= 0 --->  oo >= 0
                else:
                    raise NotImplementedError(
                        "Unable to handle interval evaluation of expression.")

            # part 1b: Reduce (-)infinity to what was passed in.
            lower, upper = Max(a, lower), Min(b, upper)

            for n in xrange(len(int_expr)):
                # Part 2: remove any interval overlap.  For any conflicts, the
                # iterval already there wins, and the incoming interval updates
                # its bounds accordingly.
                if self.__eval_cond(lower < int_expr[n][1]) and \
                        self.__eval_cond(lower >= int_expr[n][0]):
                    lower = int_expr[n][1]
                elif len(int_expr[n][1].free_symbols) and \
                        self.__eval_cond(lower >= int_expr[n][0]):
                    if self.__eval_cond(lower == int_expr[n][0]):
                        lower = int_expr[n][1]
                    else:
                        int_expr[n][1] = Min(lower, int_expr[n][1])
                elif len(int_expr[n][0].free_symbols) and \
                        self.__eval_cond(upper == int_expr[n][1]):
                    upper = Min(upper, int_expr[n][0])
                elif len(int_expr[n][1].free_symbols) and \
                        (lower >= int_expr[n][0]) != True and \
                        (int_expr[n][1] == Min(lower, upper)) != True:
                    upper = Min(upper, int_expr[n][0])
                elif self.__eval_cond(upper > int_expr[n][0]) and \
                        self.__eval_cond(upper <= int_expr[n][1]):
                    upper = int_expr[n][0]
                elif len(int_expr[n][0].free_symbols) and \
                        self.__eval_cond(upper < int_expr[n][1]):
                    int_expr[n][0] = Max(upper, int_expr[n][0])

            if self.__eval_cond(lower >= upper) != True:  # Is it still an interval?
                int_expr.append([lower, upper, expr])
            if orig_cond == targetcond:
                return [(lower, upper, None)]
            elif isinstance(targetcond, Or) and cond in targetcond.args:
                or_cond = Or(or_cond, cond)
                or_intervals.append((lower, upper, None))
                if or_cond == targetcond:
                    or_intervals.sort(key=lambda x: x[0])
                    return or_intervals

        int_expr.sort(key=lambda x: x[1].sort_key(
        ) if x[1].is_number else S.NegativeInfinity.sort_key())
        int_expr.sort(key=lambda x: x[0].sort_key(
        ) if x[0].is_number else S.Infinity.sort_key())

        for n in xrange(len(int_expr)):
            if len(int_expr[n][0].free_symbols) or len(int_expr[n][1].free_symbols):
                if isinstance(int_expr[n][1], Min) or int_expr[n][1] == b:
                    newval = Min(*int_expr[n][:-1])
                    if n > 0 and int_expr[n][0] == int_expr[n - 1][1]:
                        int_expr[n - 1][1] = newval
                    int_expr[n][0] = newval
                else:
                    newval = Max(*int_expr[n][:-1])
                    if n < len(int_expr) - 1 and int_expr[n][1] == int_expr[n + 1][0]:
                        int_expr[n + 1][0] = newval
                    int_expr[n][1] = newval

        # Add holes to list of intervals if there is a default value,
        # otherwise raise a ValueError.
        holes = []
        curr_low = a
        for int_a, int_b, expr in int_expr:
            if (curr_low < int_a) == True:
                holes.append([curr_low, Min(b, int_a), default])
            elif (curr_low >= int_a) != True:
                holes.append([curr_low, Min(b, int_a), default])
            curr_low = Min(b, int_b)
        if (curr_low < b) == True:
            holes.append([Min(b, curr_low), b, default])
        elif (curr_low >= b) != True:
            holes.append([Min(b, curr_low), b, default])

        if holes and default is not None:
            int_expr.extend(holes)
            if targetcond == True:
                return [(h[0], h[1], None) for h in holes]
        elif holes and default is None:
            raise ValueError("Called interval evaluation over piecewise "
                             "function on undefined intervals %s" %
                             ", ".join([str((h[0], h[1])) for h in holes]))

        return int_expr
def _sort_expr_cond ( self , sym , a , b , targetcond = None ) : from sympy . solvers . inequalities import _solve_inequality default = None int_expr = [ ] expr_cond = [ ] or_cond = False or_intervals = [ ] independent_expr_cond = [ ] for expr , cond in self . args : if isinstance ( cond , Or ) : for cond2 in sorted ( cond . args , key = default_sort_key ) : expr_cond . append ( ( expr , cond2 ) ) else : expr_cond . append ( ( expr , cond ) ) if cond == True : break for expr , cond in expr_cond : if cond == True : independent_expr_cond . append ( ( expr , cond ) ) default = self . func ( * independent_expr_cond ) break orig_cond = cond if sym not in cond . free_symbols : independent_expr_cond . append ( ( expr , cond ) ) continue elif isinstance ( cond , Equality ) : continue elif isinstance ( cond , And ) : lower = S . NegativeInfinity upper = S . Infinity for cond2 in cond . args : if sym not in [ cond2 . lts , cond2 . gts ] : cond2 = _solve_inequality ( cond2 , sym ) if cond2 . lts == sym : upper = Min ( cond2 . gts , upper ) elif cond2 . gts == sym : lower = Max ( cond2 . lts , lower ) else : raise NotImplementedError ( "Unable to handle interval evaluation of expression." ) else : if sym not in [ cond . lts , cond . gts ] : cond = _solve_inequality ( cond , sym ) lower , upper = cond . lts , cond . gts # part 1: initialize with givens if cond . lts == sym : # part 1a: expand the side ... lower = S . NegativeInfinity # e.g. x <= 0 ---> -oo <= 0 elif cond . gts == sym : # part 1a: ... that can be expanded upper = S . Infinity # e.g. x >= 0 --->  oo >= 0 else : raise NotImplementedError ( "Unable to handle interval evaluation of expression." ) # part 1b: Reduce (-)infinity to what was passed in. lower , upper = Max ( a , lower ) , Min ( b , upper ) for n in xrange ( len ( int_expr ) ) : # Part 2: remove any interval overlap.  For any conflicts, the # iterval already there wins, and the incoming interval updates # its bounds accordingly. if self . __eval_cond ( lower < int_expr [ n ] [ 1 ] ) and self . __eval_cond ( lower >= int_expr [ n ] [ 0 ] ) : lower = int_expr [ n ] [ 1 ] elif len ( int_expr [ n ] [ 1 ] . free_symbols ) and self . __eval_cond ( lower >= int_expr [ n ] [ 0 ] ) : if self . __eval_cond ( lower == int_expr [ n ] [ 0 ] ) : lower = int_expr [ n ] [ 1 ] else : int_expr [ n ] [ 1 ] = Min ( lower , int_expr [ n ] [ 1 ] ) elif len ( int_expr [ n ] [ 0 ] . free_symbols ) and self . __eval_cond ( upper == int_expr [ n ] [ 1 ] ) : upper = Min ( upper , int_expr [ n ] [ 0 ] ) elif len ( int_expr [ n ] [ 1 ] . free_symbols ) and ( lower >= int_expr [ n ] [ 0 ] ) != True and ( int_expr [ n ] [ 1 ] == Min ( lower , upper ) ) != True : upper = Min ( upper , int_expr [ n ] [ 0 ] ) elif self . __eval_cond ( upper > int_expr [ n ] [ 0 ] ) and self . __eval_cond ( upper <= int_expr [ n ] [ 1 ] ) : upper = int_expr [ n ] [ 0 ] elif len ( int_expr [ n ] [ 0 ] . free_symbols ) and self . __eval_cond ( upper < int_expr [ n ] [ 1 ] ) : int_expr [ n ] [ 0 ] = Max ( upper , int_expr [ n ] [ 0 ] ) if self . __eval_cond ( lower >= upper ) != True : # Is it still an interval? int_expr . append ( [ lower , upper , expr ] ) if orig_cond == targetcond : return [ ( lower , upper , None ) ] elif isinstance ( targetcond , Or ) and cond in targetcond . args : or_cond = Or ( or_cond , cond ) or_intervals . append ( ( lower , upper , None ) ) if or_cond == targetcond : or_intervals . sort ( key = lambda x : x [ 0 ] ) return or_intervals int_expr . sort ( key = lambda x : x [ 1 ] . sort_key ( ) if x [ 1 ] . is_number else S . NegativeInfinity . sort_key ( ) ) int_expr . sort ( key = lambda x : x [ 0 ] . sort_key ( ) if x [ 0 ] . is_number else S . Infinity . sort_key ( ) ) for n in xrange ( len ( int_expr ) ) : if len ( int_expr [ n ] [ 0 ] . free_symbols ) or len ( int_expr [ n ] [ 1 ] . free_symbols ) : if isinstance ( int_expr [ n ] [ 1 ] , Min ) or int_expr [ n ] [ 1 ] == b : newval = Min ( * int_expr [ n ] [ : - 1 ] ) if n > 0 and int_expr [ n ] [ 0 ] == int_expr [ n - 1 ] [ 1 ] : int_expr [ n - 1 ] [ 1 ] = newval int_expr [ n ] [ 0 ] = newval else : newval = Max ( * int_expr [ n ] [ : - 1 ] ) if n < len ( int_expr ) - 1 and int_expr [ n ] [ 1 ] == int_expr [ n + 1 ] [ 0 ] : int_expr [ n + 1 ] [ 0 ] = newval int_expr [ n ] [ 1 ] = newval # Add holes to list of intervals if there is a default value, # otherwise raise a ValueError. holes = [ ] curr_low = a for int_a , int_b , expr in int_expr : if ( curr_low < int_a ) == True : holes . append ( [ curr_low , Min ( b , int_a ) , default ] ) elif ( curr_low >= int_a ) != True : holes . append ( [ curr_low , Min ( b , int_a ) , default ] ) curr_low = Min ( b , int_b ) if ( curr_low < b ) == True : holes . append ( [ Min ( b , curr_low ) , b , default ] ) elif ( curr_low >= b ) != True : holes . append ( [ Min ( b , curr_low ) , b , default ] ) if holes and default is not None : int_expr . extend ( holes ) if targetcond == True : return [ ( h [ 0 ] , h [ 1 ] , None ) for h in holes ] elif holes and default is None : raise ValueError ( "Called interval evaluation over piecewise " "function on undefined intervals %s" % ", " . join ( [ str ( ( h [ 0 ] , h [ 1 ] ) ) for h in holes ] ) ) return int_expr