Пример #1
0
        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)
Пример #2
0
        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)
Пример #3
0
    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)
Пример #4
0
        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))
Пример #5
0
from sage.sets.real_set import RealSet
from sage.structure.element import Matrix as MatrixClass
from sage.structure.factorization_integer import IntegerFactorization
from sage.symbolic.expression import Expression
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:
Пример #6
0
        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))
Пример #7
0
    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)