def restriction(cls, self, parameters, variable, restricted_domain): """ Restrict the domain INPUT: - ``restricted_domain`` -- a :class:`~sage.sets.real_set.RealSet` or something that defines one. OUTPUT: A new piecewise function obtained by restricting the domain. EXAMPLES:: sage: f = piecewise([((-oo, oo), x)]); f piecewise(x|-->x on (-oo, +oo); x) sage: f.restriction([[-1,1], [3,3]]) piecewise(x|-->x on [-1, 1] + {3}; x) """ restricted_domain = RealSet(*restricted_domain) new_param = [] for domain, func in parameters: domain = domain.intersection(restricted_domain) new_param.append((domain, func)) return piecewise(new_param, var=variable)
def domain(cls, self, parameters, variable): """ Return the domain OUTPUT: The union of the domains of the individual pieces as a :class:`~sage.sets.real_set.RealSet`. EXAMPLES:: sage: f = piecewise([([0,0], sin(x)), ((0,2), cos(x))]); f piecewise(x|-->sin(x) on {0}, x|-->cos(x) on (0, 2); x) sage: f.domain() [0, 2) """ intervals = [] for domain, func in parameters: intervals += list(domain) return RealSet(*intervals)
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: checks.append(lvl[:])
def __call__(self, function_pieces, **kwds): r""" Piecewise functions INPUT: - ``function_pieces`` -- a list of pairs consisting of a domain and a symbolic function. - ``var=x`` -- a symbolic variable or ``None`` (default). The real variable in which the function is piecewise in. OUTPUT: A piecewise-defined function. A ``ValueError`` will be raised if the domains of the pieces are not pairwise disjoint. EXAMPLES:: sage: my_abs = piecewise([((-1, 0), -x), ([0, 1], x)], var=x); my_abs piecewise(x|-->-x on (-1, 0), x|-->x on [0, 1]; x) sage: [ my_abs(i/5) for i in range(-4, 5)] [4/5, 3/5, 2/5, 1/5, 0, 1/5, 2/5, 3/5, 4/5] TESTS:: sage: piecewise([([-1, 0], -x), ([0, 1], x)], var=x) Traceback (most recent call last): ... ValueError: domains must be pairwise disjoint sage: step = piecewise([((-1, 0), -1), ([0, 0], 0), ((0, 1), 1)], var=x); step piecewise(x|-->-1 on (-1, 0), x|-->0 on {0}, x|-->1 on (0, 1); x) sage: step(-1/2), step(0), step(1/2) (-1, 0, 1) """ from types import FunctionType var = kwds.pop('var', None) parameters = [] domain_list = [] for piece in function_pieces: domain, function = piece if not isinstance(domain, RealSet): domain = RealSet(domain) if domain.is_empty(): continue if isinstance(function, FunctionType): if var is None: var = SR.var('x') if function.func_code.co_argcount == 0: function = function() else: function = function(var) function = SR(function) if var is None and len(function.variables()) > 0: var = function.variables()[0] parameters.append((domain, function)) domain_list.append(domain) if not RealSet.are_pairwise_disjoint(*domain_list): raise ValueError('domains must be pairwise disjoint') if var is None: var = self.default_variable() parameters = SR._force_pyobject(tuple(parameters), recursive=False) return BuiltinFunction.__call__(self, parameters, var, **kwds)