from sage.symbolic.relation import solve from sage.symbolic.ring import SR pair_keep = staticmethod(lambda i, j: (i, j)) pair_swap = staticmethod(lambda i, j: (j, i)) CHECK_LEVELS = 4 INTERVAL = { (True, True): RealSet.closed, (True, False): RealSet.closed_open, (True, None): lambda l, u: RealSet.unbounded_above_closed(l), (False, True): RealSet.open_closed, (False, False): RealSet.open, (False, None): lambda l, u: RealSet.unbounded_above_open(l), (None, True): lambda l, u: RealSet.unbounded_below_closed(u), (None, False): lambda l, u: RealSet.unbounded_below_open(u), (None, None): lambda l, u: RealSet().complement() } def checklist(checks, inherit=None): """ Initialize the list of feasibility checking functions and return a decorator for the functions. """ if inherit is None: for i in range(CHECK_LEVELS): checks.append([]) else: for lvl in inherit:
def piecewise_add(cls, self, parameters, variable, other): """ Return a new piecewise function with domain the union of the original domains and functions summed. Undefined intervals in the union domain get function value `0`. EXAMPLES:: sage: f = piecewise([([0,1], 1), ((2,3), x)]) sage: g = piecewise([((1/2, 2), x)]) sage: f.piecewise_add(g).unextend_zero() piecewise(x|-->1 on (0, 1/2], x|-->x + 1 on (1/2, 1], x|-->x on (1, 2) + (2, 3); x) """ points = ([minus_infinity] + sorted(set(self.end_points() + other.end_points())) + [infinity]) domain = [] funcs = [] contains_lower = False contains_upper = False for i in range(len(points)-1): try: contains_lower = (self.domain().contains(points[i]) or other.domain().contains(points[i])) and not contains_upper contains_upper = (self.domain().contains(points[i+1]) or other.domain().contains(points[i+1])) if contains_lower: if contains_upper: rs = RealSet.closed(points[i],points[i+1]) else: rs = RealSet.closed_open(points[i],points[i+1]) else: if contains_upper: rs = RealSet.open_closed(points[i],points[i+1]) else: rs = RealSet.open(points[i],points[i+1]) point = (points[i+1] + points[i])/2 except ValueError: if points[i] == minus_infinity and points[i+1] == infinity: rs = RealSet.open(minus_infinity, infinity) point = 0 elif points[i] == minus_infinity: if contains_lower: rs = RealSet.unbounded_below_closed(points[i+1]) else: rs = RealSet.unbounded_below_open(points[i+1]) point = points[i+1]-1 elif points[i+1] == infinity: if contains_upper: rs = RealSet.unbounded_above_closed(points[i]) else: rs = RealSet.unbounded_above_open(points[i]) point = points[i]+1 else: raise try: ex1 = self.expression_at(point) except ValueError: ex1 = 0 try: ex2 = other.expression_at(point) except ValueError: ex2 = 0 ex = ex1 + ex2 if i>0 and funcs[-1] == ex: # extend the previous domain rs += domain[-1] domain[-1] = rs else: domain += rs funcs.append(ex) return piecewise(zip(domain, funcs))
def piecewise_add(cls, self, parameters, variable, other): """ Return a new piecewise function with domain the union of the original domains and functions summed. Undefined intervals in the union domain get function value `0`. EXAMPLES:: sage: f = piecewise([([0,1], 1), ((2,3), x)]) sage: g = piecewise([((1/2, 2), x)]) sage: f.piecewise_add(g).unextend_zero() piecewise(x|-->1 on (0, 1/2], x|-->x + 1 on (1/2, 1], x|-->x on (1, 2) + (2, 3); x) """ points = ([minus_infinity] + sorted(set(self.end_points() + other.end_points())) + [infinity]) domain = [] funcs = [] contains_lower = False contains_upper = False for i in range(len(points) - 1): try: contains_lower = (self.domain().contains(points[i]) or other.domain().contains( points[i])) and not contains_upper contains_upper = (self.domain().contains(points[i + 1]) or other.domain().contains(points[i + 1])) if contains_lower: if contains_upper: rs = RealSet.closed(points[i], points[i + 1]) else: rs = RealSet.closed_open(points[i], points[i + 1]) else: if contains_upper: rs = RealSet.open_closed(points[i], points[i + 1]) else: rs = RealSet.open(points[i], points[i + 1]) point = (points[i + 1] + points[i]) / 2 except ValueError: if points[i] == minus_infinity and points[i + 1] == infinity: rs = RealSet.open(minus_infinity, infinity) point = 0 elif points[i] == minus_infinity: if contains_lower: rs = RealSet.unbounded_below_closed(points[i + 1]) else: rs = RealSet.unbounded_below_open(points[i + 1]) point = points[i + 1] - 1 elif points[i + 1] == infinity: if contains_upper: rs = RealSet.unbounded_above_closed(points[i]) else: rs = RealSet.unbounded_above_open(points[i]) point = points[i] + 1 else: raise try: ex1 = self.expression_at(point) except ValueError: ex1 = 0 try: ex2 = other.expression_at(point) except ValueError: ex2 = 0 ex = ex1 + ex2 if i > 0 and funcs[-1] == ex: # extend the previous domain rs += domain[-1] domain[-1] = rs else: domain += rs funcs.append(ex) return piecewise(zip(domain, funcs))