Exemple #1
0
def union_sets(self, o):  # noqa:F811
    """ Returns the union of self and o
    for use with sympy.sets.Set, if possible. """

    from sympy.sets import Union, FiniteSet

    # if its a FiniteSet, merge any points
    # we contain and return a union with the rest
    if o.is_FiniteSet:
        other_points = [p for p in o if not self._contains(p)]
        if len(other_points) == len(o):
            return None
        return Union(self, FiniteSet(*other_points))
    if self._contains(o):
        return self
    return None
Exemple #2
0
def _set_pow(x, exponent):
    """
    Powers in interval arithmetic
    https://en.wikipedia.org/wiki/Interval_arithmetic
    """
    s1 = x.start**exponent
    s2 = x.end**exponent
    if ((s2 > s1) if exponent > 0 else (x.end > -x.start)) == True:
        left_open = x.left_open
        right_open = x.right_open
        # TODO: handle unevaluated condition.
        sleft = s2
    else:
        # TODO: `s2 > s1` could be unevaluated.
        left_open = x.right_open
        right_open = x.left_open
        sleft = s1

    if x.start.is_positive:
        return Interval(
            Min(s1, s2),
            Max(s1, s2), left_open, right_open)
    elif x.end.is_negative:
        return Interval(
            Min(s1, s2),
            Max(s1, s2), left_open, right_open)

    # Case where x.start < 0 and x.end > 0:
    if exponent.is_odd:
        if exponent.is_negative:
            if x.start.is_zero:
                return Interval(s2, oo, x.right_open)
            if x.end.is_zero:
                return Interval(-oo, s1, True, x.left_open)
            return Union(Interval(-oo, s1, True, x.left_open), Interval(s2, oo, x.right_open))
        else:
            return Interval(s1, s2, x.left_open, x.right_open)
    elif exponent.is_even:
        if exponent.is_negative:
            if x.start.is_zero:
                return Interval(s2, oo, x.right_open)
            if x.end.is_zero:
                return Interval(s1, oo, x.left_open)
            return Interval(0, oo)
        else:
            return Interval(S.Zero, sleft, S.Zero not in x, left_open)
Exemple #3
0
def test_booleans():
    """ test basic unions and intersections """
    half = Rational(1, 2)

    p1, p2, p3, p4 = map(Point, [(0, 0), (1, 0), (5, 1), (0, 1)])
    p5, p6, p7 = map(Point, [(3, 2), (1, -1), (0, 2)])
    l1 = Line(Point(0, 0), Point(1, 1))
    l2 = Line(Point(half, half), Point(5, 5))
    l3 = Line(p2, p3)
    l4 = Line(p3, p4)
    poly1 = Polygon(p1, p2, p3, p4)
    poly2 = Polygon(p5, p6, p7)
    poly3 = Polygon(p1, p2, p5)
    assert Union(l1, l2).equals(l1)
    assert Intersection(l1, l2).equals(l1)
    assert Intersection(l1, l4) == FiniteSet(Point(1, 1))
    assert Intersection(Union(l1, l4),
                        l3) == FiniteSet(Point(-S(1) / 3, -S(1) / 3),
                                         Point(5, 1))
    assert Intersection(l1, FiniteSet(Point(7, -7))) == EmptySet()
    assert Intersection(Circle(Point(0, 0), 3),
                        Line(p1, p2)) == FiniteSet(Point(-3, 0), Point(3, 0))
    assert Intersection(l1, FiniteSet(p1)) == FiniteSet(p1)
    assert Union(l1, FiniteSet(p1)) == l1

    fs = FiniteSet(Point(S(1) / 3, 1), Point(S(2) / 3, 0),
                   Point(S(9) / 5,
                         S(1) / 5), Point(S(7) / 3, 1))
    # test the intersection of polygons
    assert Intersection(poly1, poly2) == fs
    # make sure if we union polygons with subsets, the subsets go away
    assert Union(poly1, poly2, fs) == Union(poly1, poly2)
    # make sure that if we union with a FiniteSet that isn't a subset,
    # that the points in the intersection stop being listed
    assert Union(poly1, FiniteSet(Point(0, 0),
                                  Point(3,
                                        5))) == Union(poly1,
                                                      FiniteSet(Point(3, 5)))
    # intersect two polygons that share an edge
    assert Intersection(poly1, poly3) == Union(
        FiniteSet(Point(S(3) / 2, 1), Point(2, 1)),
        Segment(Point(0, 0), Point(1, 0)))
Exemple #4
0
def _solve_abs(f, symbol):
    """ Helper function to solve equation involving absolute value function """
    p, q, r = Wild('p'), Wild('q'), Wild('r')
    pattern_match = f.match(p*Abs(q) + r) or {}
    if not pattern_match.get(p, S.Zero).is_zero:
        f_p, f_q, f_r = pattern_match[p], pattern_match[q], pattern_match[r]
        q_pos_cond = solve_univariate_inequality(f_q >= 0, symbol,
                                                 relational=False)
        q_neg_cond = solve_univariate_inequality(f_q < 0, symbol,
                                                 relational=False)

        sols_q_pos = solveset_real(f_p*f_q + f_r,
                                           symbol).intersect(q_pos_cond)
        sols_q_neg = solveset_real(f_p*(-f_q) + f_r,
                                           symbol).intersect(q_neg_cond)
        return Union(sols_q_pos, sols_q_neg)
    else:
        return ConditionSet(symbol, Eq(f, 0), S.Complexes)
Exemple #5
0
def _invert_complex(f, g_ys, symbol):
    """ Helper function for invert_complex """

    if not f.has(symbol):
        raise ValueError("Inverse of constant function doesn't exist")

    if f is symbol:
        return (f, g_ys)

    n = Dummy('n')
    if f.is_Add:
        # f = g + h
        g, h = f.as_independent(symbol)
        if g != S.Zero:
            return _invert_complex(h, imageset(Lambda(n, n - g), g_ys), symbol)

    if f.is_Mul:
        # f = g*h
        g, h = f.as_independent(symbol)

        if g != S.One:
            return _invert_complex(h, imageset(Lambda(n, n / g), g_ys), symbol)

    if hasattr(f, 'inverse') and \
       not isinstance(f, TrigonometricFunction) and \
       not isinstance(f, exp):
        if len(f.args) > 1:
            raise ValueError("Only functions with one argument are supported.")
        return _invert_complex(f.args[0],
                               imageset(Lambda(n,
                                               f.inverse()(n)), g_ys), symbol)

    if isinstance(f, exp):
        if isinstance(g_ys, FiniteSet):
            exp_invs = Union(*[
                imageset(
                    Lambda(n,
                           I * (2 * n * pi + arg(g_y)) +
                           log(Abs(g_y))), S.Integers) for g_y in g_ys
                if g_y != 0
            ])
            return _invert_complex(f.args[0], exp_invs, symbol)
    return (f, g_ys)
Exemple #6
0
def test_booleans():
    """ test basic unions and intersections """
    assert Union(l1, l2).equals(l1)
    assert Intersection(l1, l2).equals(l1)
    assert Intersection(l1, l4) == FiniteSet(Point(1,1))
    assert Intersection(Union(l1, l4), l3) == FiniteSet(Point(-1/3, -1/3), Point(5, 1))
    assert Intersection(l1, FiniteSet(Point(7,-7))) == EmptySet()
    assert Intersection(Circle(Point(0,0), 3), Line(p1,p2)) == FiniteSet(Point(-3,0), Point(3,0))
    assert Intersection(l1, FiniteSet(p1)) == FiniteSet(p1)
    assert Union(l1, FiniteSet(p1)) == l1

    fs = FiniteSet(Point(1/3, 1), Point(2/3, 0), Point(9/5, 1/5), Point(7/3, 1))
    # test the intersection of polygons
    assert Intersection(poly1, poly2) == fs
    # make sure if we union polygons with subsets, the subsets go away
    assert Union(poly1, poly2, fs) == Union(poly1, poly2)
    # make sure that if we union with a FiniteSet that isn't a subset,
    # that the points in the intersection stop being listed
    assert Union(poly1, FiniteSet(Point(0,0), Point(3,5))) == Union(poly1, FiniteSet(Point(3,5)))
    # intersect two polygons that share an edge
    assert Intersection(poly1, poly3) == Union(FiniteSet(Point(3/2, 1), Point(2, 1)), Segment(Point(0, 0), Point(1, 0)))
Exemple #7
0
    def _intersect(self, o):
        """ Returns a sympy.sets.Set of intersection objects,
        if possible. """

        from sympy.sets import Set, FiniteSet, Union
        from sympy.geometry import Point

        try:
            inter = self.intersection(o)
        except NotImplementedError:
            # sympy.sets.Set.reduce expects None if an object
            # doesn't know how to simplify
            return None

        # put the points in a FiniteSet
        points = FiniteSet(*[p for p in inter if isinstance(p, Point)])
        non_points = [p for p in inter if not isinstance(p, Point)]

        return Union(*(non_points + [points]))
Exemple #8
0
def _solve_abs(f, symbol):
    """ Helper function to solve equation involving absolute value function """
    from sympy.solvers.inequalities import solve_univariate_inequality
    assert f.has(Abs)
    p, q, r = Wild('p'), Wild('q'), Wild('r')
    pattern_match = f.match(p*Abs(q) + r)
    if not pattern_match[p].is_zero:
        f_p, f_q, f_r = pattern_match[p], pattern_match[q], pattern_match[r]
        q_pos_cond = solve_univariate_inequality(f_q >= 0, symbol,
                                                 relational=False)
        q_neg_cond = solve_univariate_inequality(f_q < 0, symbol,
                                                 relational=False)

        sols_q_pos = solveset_real(f_p*f_q + f_r,
                                           symbol).intersect(q_pos_cond)
        sols_q_neg = solveset_real(f_p*(-f_q) + f_r,
                                           symbol).intersect(q_neg_cond)
        return Union(sols_q_pos, sols_q_neg)
    else:
        raise NotImplementedError
Exemple #9
0
def test_SetExpr_Interval_div():
    # TODO: some expressions cannot be calculated due to bugs (currently
    # commented):
    assert SetExpr(Interval(-3, -2))/SetExpr(Interval(-2, 1)) == SetExpr(Interval(-oo, oo))
    assert SetExpr(Interval(2, 3))/SetExpr(Interval(-2, 2)) == SetExpr(Interval(-oo, oo))

    assert SetExpr(Interval(-3, -2))/SetExpr(Interval(0, 4)) == SetExpr(Interval(-oo, Rational(-1, 2)))
    assert SetExpr(Interval(2, 4))/SetExpr(Interval(-3, 0)) == SetExpr(Interval(-oo, Rational(-2, 3)))
    assert SetExpr(Interval(2, 4))/SetExpr(Interval(0, 3)) == SetExpr(Interval(Rational(2, 3), oo))

    # assert SetExpr(Interval(0, 1))/SetExpr(Interval(0, 1)) == SetExpr(Interval(0, oo))
    # assert SetExpr(Interval(-1, 0))/SetExpr(Interval(0, 1)) == SetExpr(Interval(-oo, 0))
    assert SetExpr(Interval(-1, 2))/SetExpr(Interval(-2, 2)) == SetExpr(Interval(-oo, oo))

    assert 1/SetExpr(Interval(-1, 2)) == SetExpr(Union(Interval(-oo, -1), Interval(S.Half, oo)))

    assert 1/SetExpr(Interval(0, 2)) == SetExpr(Interval(S.Half, oo))
    assert (-1)/SetExpr(Interval(0, 2)) == SetExpr(Interval(-oo, Rational(-1, 2)))
    # assert 1/SetExpr(Interval(-oo, 0)) == SetExpr(Interval.open(-oo, 0))
    assert 1/SetExpr(Interval(-1, 0)) == SetExpr(Interval(-oo, -1))
Exemple #10
0
def _solve_real_trig(f, symbol):
    """ Helper to solve trigonometric equations """
    f = trigsimp(f)
    f = f.rewrite(exp)
    f = together(f)
    g, h = fraction(f)
    y = Dummy('y')
    g, h = g.expand(), h.expand()
    g, h = g.subs(exp(I * symbol), y), h.subs(exp(I * symbol), y)
    if g.has(symbol) or h.has(symbol):
        return ConditionSet(symbol, Eq(f, 0), S.Reals)

    solns = solveset_complex(g, y) - solveset_complex(h, y)

    if isinstance(solns, FiniteSet):
        return Union(
            *[invert_complex(exp(I * symbol), s, symbol)[1] for s in solns])
    elif solns is S.EmptySet:
        return S.EmptySet
    else:
        return ConditionSet(symbol, Eq(f, 0), S.Reals)
Exemple #11
0
def _solve_abs(f, symbol, domain):
    """ Helper function to solve equation involving absolute value function """
    if not domain.is_subset(S.Reals):
        raise ValueError(filldedent('''
            Absolute values cannot be inverted in the
            complex domain.'''))
    p, q, r = Wild('p'), Wild('q'), Wild('r')
    pattern_match = f.match(p*Abs(q) + r) or {}
    if not pattern_match.get(p, S.Zero).is_zero:
        f_p, f_q, f_r = pattern_match[p], pattern_match[q], pattern_match[r]
        q_pos_cond = solve_univariate_inequality(f_q >= 0, symbol,
                                                 relational=False)
        q_neg_cond = solve_univariate_inequality(f_q < 0, symbol,
                                                 relational=False)

        sols_q_pos = solveset_real(f_p*f_q + f_r,
                                           symbol).intersect(q_pos_cond)
        sols_q_neg = solveset_real(f_p*(-f_q) + f_r,
                                           symbol).intersect(q_neg_cond)
        return Union(sols_q_pos, sols_q_neg)
    else:
        return ConditionSet(symbol, Eq(f, 0), domain)
Exemple #12
0
def intersection_sets(self, o): # noqa:F811
    """ Returns a sympy.sets.Set of intersection objects,
    if possible. """

    from sympy.geometry.point import Point

    try:
        # if o is a FiniteSet, find the intersection directly
        # to avoid infinite recursion
        if o.is_FiniteSet:
            inter = FiniteSet(*(p for p in o if self.contains(p)))
        else:
            inter = self.intersection(o)
    except NotImplementedError:
        # sympy.sets.Set.reduce expects None if an object
        # doesn't know how to simplify
        return None

    # put the points in a FiniteSet
    points = FiniteSet(*[p for p in inter if isinstance(p, Point)])
    non_points = [p for p in inter if not isinstance(p, Point)]

    return Union(*(non_points + [points]))
Exemple #13
0
def _solve_as_poly(f, symbol, solveset_solver, invert_func):
    """
    Solve the equation using polynomial techniques if it already is a
    polynomial equation or, with a change of variables, can be made so.
    """
    result = None
    if f.is_polynomial(symbol):

        solns = roots(f,
                      symbol,
                      cubics=True,
                      quartics=True,
                      quintics=True,
                      domain='EX')
        num_roots = sum(solns.values())
        if degree(f, symbol) <= num_roots:
            result = FiniteSet(*solns.keys())
        else:
            poly = Poly(f, symbol)
            solns = poly.all_roots()
            if poly.degree() <= len(solns):
                result = FiniteSet(*solns)
            else:
                raise NotImplementedError("Couldn't find all roots "
                                          "of the equation %s" % f)
    else:
        poly = Poly(f)
        if poly is None:
            raise NotImplementedError("Could not convert %s to Poly" % f)
        gens = [g for g in poly.gens if g.has(symbol)]

        if len(gens) == 1:
            poly = Poly(poly, gens[0])
            gen = poly.gen
            deg = poly.degree()
            poly = Poly(poly.as_expr(), poly.gen, composite=True)
            poly_solns = FiniteSet(
                *roots(poly, cubics=True, quartics=True, quintics=True).keys())

            if len(poly_solns) < deg:
                raise NotImplementedError("Couldn't find all the roots of "
                                          "the equation %s" % f)

            if gen != symbol:
                y = Dummy('y')
                lhs, rhs_s = invert_func(gen, y, symbol)
                if lhs is symbol:
                    result = Union(*[rhs_s.subs(y, s) for s in poly_solns])
                else:
                    raise NotImplementedError("inversion of %s not handled" %
                                              gen)
        else:
            raise NotImplementedError("multiple generators not handled"
                                      " by solveset")

    if result is not None:
        if isinstance(result, FiniteSet):
            # this is to simplify solutions like -sqrt(-I) to sqrt(2)/2
            # - sqrt(2)*I/2. We are not expanding for solution with free
            # variables because that makes the solution more complicated. For
            # example expand_complex(a) returns re(a) + I*im(a)
            if all([
                    s.free_symbols == set() and not isinstance(s, RootOf)
                    for s in result
            ]):
                s = Dummy('s')
                result = imageset(Lambda(s, expand_complex(s)), result)
        return result
    else:
        raise NotImplementedError
Exemple #14
0
def _solve_as_poly(f, symbol, domain=S.Complexes):
    """
    Solve the equation using polynomial techniques if it already is a
    polynomial equation or, with a change of variables, can be made so.
    """
    result = None
    if f.is_polynomial(symbol):
        solns = roots(f, symbol, cubics=True, quartics=True,
                      quintics=True, domain='EX')
        num_roots = sum(solns.values())
        if degree(f, symbol) <= num_roots:
            result = FiniteSet(*solns.keys())
        else:
            poly = Poly(f, symbol)
            solns = poly.all_roots()
            if poly.degree() <= len(solns):
                result = FiniteSet(*solns)
            else:
                result = ConditionSet(symbol, Eq(f, 0), domain)
    else:
        poly = Poly(f)
        if poly is None:
            result = ConditionSet(symbol, Eq(f, 0), domain)
        gens = [g for g in poly.gens if g.has(symbol)]

        if len(gens) == 1:
            poly = Poly(poly, gens[0])
            gen = poly.gen
            deg = poly.degree()
            poly = Poly(poly.as_expr(), poly.gen, composite=True)
            poly_solns = FiniteSet(*roots(poly, cubics=True, quartics=True,
                                          quintics=True).keys())

            if len(poly_solns) < deg:
                result = ConditionSet(symbol, Eq(f, 0), domain)

            if gen != symbol:
                y = Dummy('y')
                inverter = invert_real if domain.is_subset(S.Reals) else invert_complex
                lhs, rhs_s = inverter(gen, y, symbol)
                if lhs == symbol:
                    result = Union(*[rhs_s.subs(y, s) for s in poly_solns])
                else:
                    result = ConditionSet(symbol, Eq(f, 0), domain)
        else:
            result = ConditionSet(symbol, Eq(f, 0), domain)

    if result is not None:
        if isinstance(result, FiniteSet):
            # this is to simplify solutions like -sqrt(-I) to sqrt(2)/2
            # - sqrt(2)*I/2. We are not expanding for solution with free
            # variables because that makes the solution more complicated. For
            # example expand_complex(a) returns re(a) + I*im(a)
            if all([s.free_symbols == set() and not isinstance(s, RootOf)
                    for s in result]):
                s = Dummy('s')
                result = imageset(Lambda(s, expand_complex(s)), result)
        if isinstance(result, FiniteSet):
            result = result.intersection(domain)
        return result
    else:
        return ConditionSet(symbol, Eq(f, 0), domain)
Exemple #15
0
def _invert_real(f, g_ys, symbol):
    """Helper function for _invert."""

    if f == symbol:
        return (f, g_ys)

    n = Dummy('n', real=True)

    if hasattr(f, 'inverse') and not isinstance(f, (
            TrigonometricFunction,
            HyperbolicFunction,
            )):
        if len(f.args) > 1:
            raise ValueError("Only functions with one argument are supported.")
        return _invert_real(f.args[0],
                            imageset(Lambda(n, f.inverse()(n)), g_ys),
                            symbol)

    if isinstance(f, Abs):
        pos = Interval(0, S.Infinity)
        neg = Interval(S.NegativeInfinity, 0)
        return _invert_real(f.args[0],
                    Union(imageset(Lambda(n, n), g_ys).intersect(pos),
                          imageset(Lambda(n, -n), g_ys).intersect(neg)), symbol)

    if f.is_Add:
        # f = g + h
        g, h = f.as_independent(symbol)
        if g is not S.Zero:
            return _invert_real(h, imageset(Lambda(n, n - g), g_ys), symbol)

    if f.is_Mul:
        # f = g*h
        g, h = f.as_independent(symbol)

        if g is not S.One:
            return _invert_real(h, imageset(Lambda(n, n/g), g_ys), symbol)

    if f.is_Pow:
        base, expo = f.args
        base_has_sym = base.has(symbol)
        expo_has_sym = expo.has(symbol)

        if not expo_has_sym:
            res = imageset(Lambda(n, real_root(n, expo)), g_ys)
            if expo.is_rational:
                numer, denom = expo.as_numer_denom()
                if numer == S.One or numer == - S.One:
                    return _invert_real(base, res, symbol)
                else:
                    if numer % 2 == 0:
                        n = Dummy('n')
                        neg_res = imageset(Lambda(n, -n), res)
                        return _invert_real(base, res + neg_res, symbol)
                    else:
                        return _invert_real(base, res, symbol)
            else:
                if not base.is_positive:
                    raise ValueError("x**w where w is irrational is not "
                                     "defined for negative x")
                return _invert_real(base, res, symbol)

        if not base_has_sym:
            return _invert_real(expo,
                imageset(Lambda(n, log(n)/log(base)), g_ys), symbol)

    if isinstance(f, TrigonometricFunction):
        if isinstance(g_ys, FiniteSet):
            def inv(trig):
                if isinstance(f, (sin, csc)):
                    F = asin if isinstance(f, sin) else acsc
                    return (lambda a: n*pi + (-1)**n*F(a),)
                if isinstance(f, (cos, sec)):
                    F = acos if isinstance(f, cos) else asec
                    return (
                        lambda a: 2*n*pi + F(a),
                        lambda a: 2*n*pi - F(a),)
                if isinstance(f, (tan, cot)):
                    return (lambda a: n*pi + f.inverse()(a),)

            n = Dummy('n', integer=True)
            invs = S.EmptySet
            for L in inv(f):
                invs += Union(*[imageset(Lambda(n, L(g)), S.Integers) for g in g_ys])
            return _invert_real(f.args[0], invs, symbol)

    return (f, g_ys)
Exemple #16
0
def _invert_real(f, g_ys, symbol):
    """ Helper function for invert_real """

    if not f.has(symbol):
        raise ValueError("Inverse of constant function doesn't exist")

    if f is symbol:
        return (f, g_ys)

    n = Dummy('n')
    if hasattr(f, 'inverse') and not isinstance(f, TrigonometricFunction) and \
            not isinstance(f, HyperbolicFunction):
        if len(f.args) > 1:
            raise ValueError("Only functions with one argument are supported.")
        return _invert_real(f.args[0], imageset(Lambda(n,
                                                       f.inverse()(n)), g_ys),
                            symbol)

    if isinstance(f, Abs):
        return _invert_real(
            f.args[0],
            Union(
                imageset(Lambda(n, n), g_ys).intersect(Interval(0, oo)),
                imageset(Lambda(n, -n), g_ys).intersect(Interval(-oo, 0))),
            symbol)

    if f.is_Add:
        # f = g + h
        g, h = f.as_independent(symbol)
        if g != S.Zero:
            return _invert_real(h, imageset(Lambda(n, n - g), g_ys), symbol)

    if f.is_Mul:
        # f = g*h
        g, h = f.as_independent(symbol)

        if g != S.One:
            return _invert_real(h, imageset(Lambda(n, n / g), g_ys), symbol)

    if f.is_Pow:
        base, expo = f.args
        base_has_sym = base.has(symbol)
        expo_has_sym = expo.has(symbol)

        if not expo_has_sym:
            res = imageset(Lambda(n, real_root(n, expo)), g_ys)
            if expo.is_rational:
                numer, denom = expo.as_numer_denom()
                if numer == S.One or numer == -S.One:
                    return _invert_real(base, res, symbol)
                else:
                    if numer % 2 == 0:
                        n = Dummy('n')
                        neg_res = imageset(Lambda(n, -n), res)
                        return _invert_real(base, res + neg_res, symbol)
                    else:
                        return _invert_real(base, res, symbol)
            else:
                if not base.is_positive:
                    raise ValueError("x**w where w is irrational is not "
                                     "defined for negative x")
                return _invert_real(base, res, symbol)

        if not base_has_sym:
            return _invert_real(expo,
                                imageset(Lambda(n,
                                                log(n) / log(base)), g_ys),
                                symbol)

    if isinstance(f, sin):
        n = Dummy('n')
        if isinstance(g_ys, FiniteSet):
            sin_invs = Union(*[imageset(Lambda(n, n*pi + (-1)**n*asin(g_y)), \
                                        S.Integers) for g_y in g_ys])
            return _invert_real(f.args[0], sin_invs, symbol)

    if isinstance(f, csc):
        n = Dummy('n')
        if isinstance(g_ys, FiniteSet):
            csc_invs = Union(*[imageset(Lambda(n, n*pi + (-1)**n*acsc(g_y)), \
                                        S.Integers) for g_y in g_ys])
            return _invert_real(f.args[0], csc_invs, symbol)

    if isinstance(f, cos):
        n = Dummy('n')
        if isinstance(g_ys, FiniteSet):
            cos_invs_f1 = Union(*[imageset(Lambda(n, 2*n*pi + acos(g_y)), \
                                        S.Integers) for g_y in g_ys])
            cos_invs_f2 = Union(*[imageset(Lambda(n, 2*n*pi - acos(g_y)), \
                                        S.Integers) for g_y in g_ys])
            cos_invs = Union(cos_invs_f1, cos_invs_f2)
            return _invert_real(f.args[0], cos_invs, symbol)

    if isinstance(f, sec):
        n = Dummy('n')
        if isinstance(g_ys, FiniteSet):
            sec_invs_f1 = Union(*[imageset(Lambda(n, 2*n*pi + asec(g_y)), \
                                        S.Integers) for g_y in g_ys])
            sec_invs_f2 = Union(*[imageset(Lambda(n, 2*n*pi - asec(g_y)), \
                                        S.Integers) for g_y in g_ys])
            sec_invs = Union(sec_invs_f1, sec_invs_f2)
            return _invert_real(f.args[0], sec_invs, symbol)

    if isinstance(f, tan) or isinstance(f, cot):
        n = Dummy('n')
        if isinstance(g_ys, FiniteSet):
            tan_cot_invs = Union(*[imageset(Lambda(n, n*pi + f.inverse()(g_y)), \
                                        S.Integers) for g_y in g_ys])
            return _invert_real(f.args[0], tan_cot_invs, symbol)
    return (f, g_ys)
Exemple #17
0
def solveset_complex(f, symbol):
    """ Solve a complex valued equation.

    Parameters
    ==========

    f : Expr
        The target equation
    symbol : Symbol
        The variable for which the equation is solved

    Returns
    =======

    Set
        A set of values for `symbol` for which `f` equal to
        zero. An `EmptySet` is returned if no solution is found.
        A `ConditionSet` is returned as an unsolved object if algorithms
        to evaluate complete solutions are not yet implemented.

    `solveset_complex` claims to be complete in the solution set that
    it returns.

    Raises
    ======

    NotImplementedError
        The algorithms to solve inequalities in complex domain  are
        not yet implemented.
    ValueError
        The input is not valid.
    RuntimeError
        It is a bug, please report to the github issue tracker.

    See Also
    ========

    solveset_real: solver for real domain

    Examples
    ========

    >>> from sympy import Symbol, exp
    >>> from sympy.solvers.solveset import solveset_complex
    >>> from sympy.abc import x, a, b, c
    >>> solveset_complex(a*x**2 + b*x +c, x)
    {-b/(2*a) - sqrt(-4*a*c + b**2)/(2*a), -b/(2*a) + sqrt(-4*a*c + b**2)/(2*a)}

    * Due to the fact that complex extension of my real valued functions are
      multivariate even some simple equations can have infinitely many
      solution.

    >>> solveset_complex(exp(x) - 1, x)
    ImageSet(Lambda(_n, 2*_n*I*pi), Integers())

    """
    if not symbol.is_Symbol:
        raise ValueError(" %s is not a symbol" % (symbol))

    f = sympify(f)
    original_eq = f
    if not isinstance(f, (Expr, Number)):
        raise ValueError(" %s is not a valid sympy expression" % (f))

    f = together(f)
    # Without this equations like a + 4*x**2 - E keep oscillating
    # into form  a/4 + x**2 - E/4 and (a + 4*x**2 - E)/4
    if not fraction(f)[1].has(symbol):
        f = expand(f)

    if f.is_zero:
        return S.Complexes
    elif not f.has(symbol):
        result = EmptySet()
    elif f.is_Mul and all([_is_finite_with_finite_vars(m) for m in f.args]):
        result = Union(*[solveset_complex(m, symbol) for m in f.args])
    else:
        lhs, rhs_s = invert_complex(f, 0, symbol)
        if lhs == symbol:
            result = rhs_s
        elif isinstance(rhs_s, FiniteSet):
            equations = [lhs - rhs for rhs in rhs_s]
            result = EmptySet()
            for equation in equations:
                if equation == f:
                    if any(
                            _has_rational_power(g, symbol)[0]
                            for g in equation.args):
                        result += _solve_radical(equation, symbol,
                                                 solveset_complex)
                    else:
                        result += _solve_as_rational(
                            equation,
                            symbol,
                            solveset_solver=solveset_complex,
                            as_poly_solver=_solve_as_poly_complex)
                else:
                    result += solveset_complex(equation, symbol)
        else:
            result = ConditionSet(symbol, Eq(f, 0), S.Complexes)

    if isinstance(result, FiniteSet):
        result = [
            s for s in result
            if isinstance(s, RootOf) or domain_check(original_eq, symbol, s)
        ]
        return FiniteSet(*result)
    else:
        return result
Exemple #18
0
def _(f, x):
    return Union(*(imageset(f, arg) for arg in x.args))
Exemple #19
0
def solveset_real(f, symbol):
    """ Solves a real valued equation.

    Parameters
    ==========

    f : Expr
        The target equation
    symbol : Symbol
        The variable for which the equation is solved

    Returns
    =======

    Set
        A set of values for `symbol` for which `f` is equal to
        zero. An `EmptySet` is returned if no solution is found.
        A `ConditionSet` is returned as unsolved object if algorithms
        to evaluate complete solutions are not yet implemented.

    `solveset_real` claims to be complete in the set of the solution it
    returns.

    Raises
    ======

    NotImplementedError
        Algorithms to solve inequalities in complex domain are
        not yet implemented.
    ValueError
        The input is not valid.
    RuntimeError
        It is a bug, please report to the github issue tracker.


    See Also
    =======

    solveset_complex : solver for complex domain

    Examples
    ========

    >>> from sympy import Symbol, exp, sin, sqrt, I
    >>> from sympy.solvers.solveset import solveset_real
    >>> x = Symbol('x', real=True)
    >>> a = Symbol('a', real=True, finite=True, positive=True)
    >>> solveset_real(x**2 - 1, x)
    {-1, 1}
    >>> solveset_real(sqrt(5*x + 6) - 2 - x, x)
    {-1, 2}
    >>> solveset_real(x - I, x)
    EmptySet()
    >>> solveset_real(x - a, x)
    {a}
    >>> solveset_real(exp(x) - a, x)
    {log(a)}

    * In case the equation has infinitely many solutions an infinitely indexed
      `ImageSet` is returned.

    >>> solveset_real(sin(x) - 1, x)
    ImageSet(Lambda(_n, 2*_n*pi + pi/2), Integers())

    * If the equation is true for any arbitrary value of the symbol a `S.Reals`
      set is returned.

    >>> solveset_real(x - x, x)
    (-oo, oo)

    """
    if not symbol.is_Symbol:
        raise ValueError(" %s is not a symbol" % (symbol))

    f = sympify(f)
    if not isinstance(f, (Expr, Number)):
        raise ValueError(" %s is not a valid sympy expression" % (f))

    original_eq = f
    f = together(f)

    # In this, unlike in solveset_complex, expression should only
    # be expanded when fraction(f)[1] does not contain the symbol
    # for which we are solving
    if not symbol in fraction(f)[1].free_symbols and f.is_rational_function():
        f = expand(f)

    if f.has(Piecewise):
        f = piecewise_fold(f)
    result = EmptySet()

    if f.expand().is_zero:
        return S.Reals
    elif not f.has(symbol):
        return EmptySet()
    elif f.is_Mul and all([_is_finite_with_finite_vars(m) for m in f.args]):
        # if f(x) and g(x) are both finite we can say that the solution of
        # f(x)*g(x) == 0 is same as Union(f(x) == 0, g(x) == 0) is not true in
        # general. g(x) can grow to infinitely large for the values where
        # f(x) == 0. To be sure that we are not silently allowing any
        # wrong solutions we are using this technique only if both f and g are
        # finite for a finite input.
        result = Union(*[solveset_real(m, symbol) for m in f.args])
    elif _is_function_class_equation(TrigonometricFunction, f, symbol) or \
            _is_function_class_equation(HyperbolicFunction, f, symbol):
        result = _solve_real_trig(f, symbol)
    elif f.is_Piecewise:
        result = EmptySet()
        expr_set_pairs = f.as_expr_set_pairs()
        for (expr, in_set) in expr_set_pairs:
            solns = solveset_real(expr, symbol).intersect(in_set)
            result = result + solns
    else:
        lhs, rhs_s = invert_real(f, 0, symbol)
        if lhs == symbol:
            result = rhs_s
        elif isinstance(rhs_s, FiniteSet):
            equations = [lhs - rhs for rhs in rhs_s]
            for equation in equations:
                if equation == f:
                    if any(
                            _has_rational_power(g, symbol)[0]
                            for g in equation.args):
                        result += _solve_radical(equation, symbol,
                                                 solveset_real)
                    elif equation.has(Abs):
                        result += _solve_abs(f, symbol)
                    else:
                        result += _solve_as_rational(
                            equation,
                            symbol,
                            solveset_solver=solveset_real,
                            as_poly_solver=_solve_as_poly_real)
                else:
                    result += solveset_real(equation, symbol)
        else:
            result = ConditionSet(symbol, Eq(f, 0), S.Reals)

    if isinstance(result, FiniteSet):
        result = [
            s for s in result
            if isinstance(s, RootOf) or domain_check(original_eq, symbol, s)
        ]
        return FiniteSet(*result).intersect(S.Reals)
    else:
        return result.intersect(S.Reals)
Exemple #20
0
def function_sets(f, x):
    return Union(imageset(f, arg) for arg in x.args)
Exemple #21
0
def test_SetExpr_Interval_pow():
    assert SetExpr(Interval(0, 2))**2 == SetExpr(Interval(0, 4))
    assert SetExpr(Interval(-1, 1))**2 == SetExpr(Interval(0, 1))
    assert SetExpr(Interval(1, 2))**2 == SetExpr(Interval(1, 4))
    assert SetExpr(Interval(-1, 2))**3 == SetExpr(Interval(-1, 8))
    assert SetExpr(Interval(-1, 1))**0 == SetExpr(FiniteSet(1))

    #assert SetExpr(Interval(1, 2))**(S(5)/2) == SetExpr(Interval(1, 4*sqrt(2)))
    #assert SetExpr(Interval(-1, 2))**(S.One/3) == SetExpr(Interval(-1, 2**(S.One/3)))
    #assert SetExpr(Interval(0, 2))**(S.One/2) == SetExpr(Interval(0, sqrt(2)))

    #assert SetExpr(Interval(-4, 2))**(S(2)/3) == SetExpr(Interval(0, 2*2**(S.One/3)))

    #assert SetExpr(Interval(-1, 5))**(S.One/2) == SetExpr(Interval(0, sqrt(5)))
    #assert SetExpr(Interval(-oo, 2))**(S.One/2) == SetExpr(Interval(0, sqrt(2)))
    #assert SetExpr(Interval(-2, 3))**(S(-1)/4) == SetExpr(Interval(0, oo))

    assert SetExpr(Interval(1, 5))**(-2) == SetExpr(Interval(S.One / 25, 1))
    assert SetExpr(Interval(-1, 3))**(-2) == SetExpr(Interval(0, oo))
    assert SetExpr(Interval(0, 2))**(-2) == SetExpr(Interval(S.One / 4, oo))
    assert SetExpr(Interval(-1, 2))**(-3) == SetExpr(
        Union(Interval(-oo, -1), Interval(S(1) / 8, oo)))
    assert SetExpr(Interval(-3, -2))**(-3) == SetExpr(
        Interval(S(-1) / 8, -S.One / 27))
    assert SetExpr(Interval(-3, -2))**(-2) == SetExpr(
        Interval(S.One / 9, S.One / 4))
    #assert SetExpr(Interval(0, oo))**(S.One/2) == SetExpr(Interval(0, oo))
    #assert SetExpr(Interval(-oo, -1))**(S.One/3) == SetExpr(Interval(-oo, -1))
    #assert SetExpr(Interval(-2, 3))**(-S.One/3) == SetExpr(Interval(-oo, oo))
    assert SetExpr(Interval(-oo, 0))**(-2) == SetExpr(Interval.open(0, oo))
    assert SetExpr(Interval(-2, 0))**(-2) == SetExpr(Interval(S.One / 4, oo))

    assert SetExpr(Interval(S.One / 3, S.One / 2))**oo == SetExpr(FiniteSet(0))
    assert SetExpr(Interval(0, S.One / 2))**oo == SetExpr(FiniteSet(0))
    assert SetExpr(Interval(S.One / 2, 1))**oo == SetExpr(Interval(0, oo))
    assert SetExpr(Interval(0, 1))**oo == SetExpr(Interval(0, oo))
    assert SetExpr(Interval(2, 3))**oo == SetExpr(FiniteSet(oo))
    assert SetExpr(Interval(1, 2))**oo == SetExpr(Interval(0, oo))
    assert SetExpr(Interval(S.One / 2, 3))**oo == SetExpr(Interval(0, oo))
    assert SetExpr(Interval(-S.One / 3,
                            -S.One / 4))**oo == SetExpr(FiniteSet(0))
    assert SetExpr(Interval(-1, -S.One / 2))**oo == SetExpr(Interval(-oo, oo))
    assert SetExpr(Interval(-3, -2))**oo == SetExpr(FiniteSet(-oo, oo))
    assert SetExpr(Interval(-2, -1))**oo == SetExpr(Interval(-oo, oo))
    assert SetExpr(Interval(-2, -S.One / 2))**oo == SetExpr(Interval(-oo, oo))
    assert SetExpr(Interval(-S.One / 2,
                            S.One / 2))**oo == SetExpr(FiniteSet(0))
    assert SetExpr(Interval(-S.One / 2, 1))**oo == SetExpr(Interval(0, oo))
    assert SetExpr(Interval(-S(2) / 3, 2))**oo == SetExpr(Interval(0, oo))
    assert SetExpr(Interval(-1, 1))**oo == SetExpr(Interval(-oo, oo))
    assert SetExpr(Interval(-1, S.One / 2))**oo == SetExpr(Interval(-oo, oo))
    assert SetExpr(Interval(-1, 2))**oo == SetExpr(Interval(-oo, oo))
    assert SetExpr(Interval(-2, S.One / 2))**oo == SetExpr(Interval(-oo, oo))

    assert (SetExpr(Interval(1, 2))**x).dummy_eq(
        SetExpr(ImageSet(Lambda(_d, _d**x), Interval(1, 2))))

    assert SetExpr(Interval(2, 3))**(-oo) == SetExpr(FiniteSet(0))
    assert SetExpr(Interval(0, 2))**(-oo) == SetExpr(Interval(0, oo))
    assert (SetExpr(Interval(-1, 2))**(-oo)).dummy_eq(
        SetExpr(ImageSet(Lambda(_d, _d**(-oo)), Interval(-1, 2))))
def _set_function(f, x):
    from sympy.functions.elementary.miscellaneous import Min, Max
    from sympy.solvers.solveset import solveset
    from sympy.core.function import diff, Lambda
    from sympy.series import limit
    from sympy.calculus.singularities import singularities
    from sympy.sets import Complement
    # TODO: handle functions with infinitely many solutions (eg, sin, tan)
    # TODO: handle multivariate functions

    expr = f.expr
    if len(expr.free_symbols) > 1 or len(f.variables) != 1:
        return
    var = f.variables[0]

    if expr.is_Piecewise:
        result = S.EmptySet
        domain_set = x
        for (p_expr, p_cond) in expr.args:
            if p_cond is true:
                intrvl = domain_set
            else:
                intrvl = p_cond.as_set()
                intrvl = Intersection(domain_set, intrvl)

            if p_expr.is_Number:
                image = FiniteSet(p_expr)
            else:
                image = imageset(Lambda(var, p_expr), intrvl)
            result = Union(result, image)

            # remove the part which has been `imaged`
            domain_set = Complement(domain_set, intrvl)
            if domain_set.is_EmptySet:
                break
        return result

    if not x.start.is_comparable or not x.end.is_comparable:
        return

    try:
        sing = [i for i in singularities(expr, var)
            if i.is_real and i in x]
    except NotImplementedError:
        return

    if x.left_open:
        _start = limit(expr, var, x.start, dir="+")
    elif x.start not in sing:
        _start = f(x.start)
    if x.right_open:
        _end = limit(expr, var, x.end, dir="-")
    elif x.end not in sing:
        _end = f(x.end)

    if len(sing) == 0:
        solns = list(solveset(diff(expr, var), var))

        extr = [_start, _end] + [f(i) for i in solns
                                 if i.is_real and i in x]
        start, end = Min(*extr), Max(*extr)

        left_open, right_open = False, False
        if _start <= _end:
            # the minimum or maximum value can occur simultaneously
            # on both the edge of the interval and in some interior
            # point
            if start == _start and start not in solns:
                left_open = x.left_open
            if end == _end and end not in solns:
                right_open = x.right_open
        else:
            if start == _end and start not in solns:
                left_open = x.right_open
            if end == _start and end not in solns:
                right_open = x.left_open

        return Interval(start, end, left_open, right_open)
    else:
        return imageset(f, Interval(x.start, sing[0],
                                    x.left_open, True)) + \
            Union(*[imageset(f, Interval(sing[i], sing[i + 1], True, True))
                    for i in range(0, len(sing) - 1)]) + \
            imageset(f, Interval(sing[-1], x.end, True, x.right_open))
def _set_function(f, x):
    return Union(imageset(f, arg) for arg in x.args)
Exemple #24
0
def dispatch_on_operation(x, y, op):
    return Union(*[dispatch_on_operation(i, y, op) for i in x])
Exemple #25
0
def _solveset(f, symbol, domain, _check=False):
    """Helper for solveset to return a result from an expression
    that has already been sympify'ed and is known to contain the
    given symbol."""
    # _check controls whether the answer is checked or not

    from sympy.simplify.simplify import signsimp
    orig_f = f
    f = together(f)
    if f.is_Mul:
        _, f = f.as_independent(symbol, as_Add=False)
    if f.is_Add:
        a, h = f.as_independent(symbol)
        m, h = h.as_independent(symbol, as_Add=False)
        f = a/m + h  # XXX condition `m != 0` should be added to soln
    f = piecewise_fold(f)

    # assign the solvers to use
    solver = lambda f, x, domain=domain: _solveset(f, x, domain)
    if domain.is_subset(S.Reals):
        inverter_func = invert_real
    else:
        inverter_func = invert_complex
    inverter = lambda f, rhs, symbol: inverter_func(f, rhs, symbol, domain)

    result = EmptySet()

    if f.expand().is_zero:
        return domain
    elif not f.has(symbol):
        return EmptySet()
    elif f.is_Mul and all(_is_finite_with_finite_vars(m, domain)
            for m in f.args):
        # if f(x) and g(x) are both finite we can say that the solution of
        # f(x)*g(x) == 0 is same as Union(f(x) == 0, g(x) == 0) is not true in
        # general. g(x) can grow to infinitely large for the values where
        # f(x) == 0. To be sure that we are not silently allowing any
        # wrong solutions we are using this technique only if both f and g are
        # finite for a finite input.
        result = Union(*[solver(m, symbol) for m in f.args])
    elif _is_function_class_equation(TrigonometricFunction, f, symbol) or \
            _is_function_class_equation(HyperbolicFunction, f, symbol):
        result = _solve_trig(f, symbol, domain)
    elif f.is_Piecewise:
        dom = domain
        result = EmptySet()
        expr_set_pairs = f.as_expr_set_pairs()
        for (expr, in_set) in expr_set_pairs:
            if in_set.is_Relational:
                in_set = in_set.as_set()
            if in_set.is_Interval:
                dom -= in_set
            solns = solver(expr, symbol, in_set)
            result += solns
    else:
        lhs, rhs_s = inverter(f, 0, symbol)
        if lhs == symbol:
            # do some very minimal simplification since
            # repeated inversion may have left the result
            # in a state that other solvers (e.g. poly)
            # would have simplified; this is done here
            # rather than in the inverter since here it
            # is only done once whereas there it would
            # be repeated for each step of the inversion
            if isinstance(rhs_s, FiniteSet):
                rhs_s = FiniteSet(*[Mul(*
                    signsimp(i).as_content_primitive())
                    for i in rhs_s])
            result = rhs_s
        elif isinstance(rhs_s, FiniteSet):
            for equation in [lhs - rhs for rhs in rhs_s]:
                if equation == f:
                    if any(_has_rational_power(g, symbol)[0]
                           for g in equation.args) or _has_rational_power(
                           equation, symbol)[0]:
                        result += _solve_radical(equation,
                                                 symbol,
                                                 solver)
                    elif equation.has(Abs):
                        result += _solve_abs(f, symbol, domain)
                    else:
                        result += _solve_as_rational(equation, symbol, domain)
                else:
                    result += solver(equation, symbol)
        else:
            result = ConditionSet(symbol, Eq(f, 0), domain)

    if _check:
        if isinstance(result, ConditionSet):
            # it wasn't solved or has enumerated all conditions
            # -- leave it alone
            return result

        # whittle away all but the symbol-containing core
        # to use this for testing
        fx = orig_f.as_independent(symbol, as_Add=True)[1]
        fx = fx.as_independent(symbol, as_Add=False)[1]

        if isinstance(result, FiniteSet):
            # check the result for invalid solutions
            result = FiniteSet(*[s for s in result
                      if isinstance(s, RootOf)
                      or domain_check(fx, symbol, s)])

    return result
Exemple #26
0
def _set_function(f, x):  # noqa:F811
    return Union(*(imageset(f, arg) for arg in x.args))
def test_SetExpr_Interval_pow():
    assert SetExpr(Interval(0, 2))**2 == SetExpr(Interval(0, 4))
    assert SetExpr(Interval(-1, 1))**2 == SetExpr(Interval(0, 1))
    assert SetExpr(Interval(1, 2))**2 == SetExpr(Interval(1, 4))
    assert SetExpr(Interval(-1, 2))**3 == SetExpr(Interval(-1, 8))
    assert SetExpr(Interval(-1, 1))**0 == SetExpr(FiniteSet(1))

    #assert SetExpr(Interval(1, 2))**Rational(5, 2) == SetExpr(Interval(1, 4*sqrt(2)))
    #assert SetExpr(Interval(-1, 2))**Rational(1, 3) == SetExpr(Interval(-1, 2**Rational(1, 3)))
    #assert SetExpr(Interval(0, 2))**S.Half == SetExpr(Interval(0, sqrt(2)))

    #assert SetExpr(Interval(-4, 2))**Rational(2, 3) == SetExpr(Interval(0, 2*2**Rational(1, 3)))

    #assert SetExpr(Interval(-1, 5))**S.Half == SetExpr(Interval(0, sqrt(5)))
    #assert SetExpr(Interval(-oo, 2))**S.Half == SetExpr(Interval(0, sqrt(2)))
    #assert SetExpr(Interval(-2, 3))**(Rational(-1, 4)) == SetExpr(Interval(0, oo))

    assert SetExpr(Interval(1,
                            5))**(-2) == SetExpr(Interval(Rational(1, 25), 1))
    assert SetExpr(Interval(-1, 3))**(-2) == SetExpr(Interval(0, oo))
    assert SetExpr(Interval(0,
                            2))**(-2) == SetExpr(Interval(Rational(1, 4), oo))
    assert SetExpr(Interval(-1, 2))**(-3) == SetExpr(
        Union(Interval(-oo, -1), Interval(Rational(1, 8), oo)))
    assert SetExpr(Interval(-3, -2))**(-3) == SetExpr(
        Interval(Rational(-1, 8), Rational(-1, 27)))
    assert SetExpr(Interval(-3, -2))**(-2) == SetExpr(
        Interval(Rational(1, 9), Rational(1, 4)))
    #assert SetExpr(Interval(0, oo))**S.Half == SetExpr(Interval(0, oo))
    #assert SetExpr(Interval(-oo, -1))**Rational(1, 3) == SetExpr(Interval(-oo, -1))
    #assert SetExpr(Interval(-2, 3))**(Rational(-1, 3)) == SetExpr(Interval(-oo, oo))
    assert SetExpr(Interval(-oo, 0))**(-2) == SetExpr(Interval.open(0, oo))
    assert SetExpr(Interval(-2,
                            0))**(-2) == SetExpr(Interval(Rational(1, 4), oo))

    assert SetExpr(Interval(Rational(1, 3),
                            S.Half))**oo == SetExpr(FiniteSet(0))
    assert SetExpr(Interval(0, S.Half))**oo == SetExpr(FiniteSet(0))
    assert SetExpr(Interval(S.Half, 1))**oo == SetExpr(Interval(0, oo))
    assert SetExpr(Interval(0, 1))**oo == SetExpr(Interval(0, oo))
    assert SetExpr(Interval(2, 3))**oo == SetExpr(FiniteSet(oo))
    assert SetExpr(Interval(1, 2))**oo == SetExpr(Interval(0, oo))
    assert SetExpr(Interval(S.Half, 3))**oo == SetExpr(Interval(0, oo))
    assert SetExpr(Interval(Rational(-1, 3),
                            Rational(-1, 4)))**oo == SetExpr(FiniteSet(0))
    assert SetExpr(Interval(-1, Rational(-1,
                                         2)))**oo == SetExpr(Interval(-oo, oo))
    assert SetExpr(Interval(-3, -2))**oo == SetExpr(FiniteSet(-oo, oo))
    assert SetExpr(Interval(-2, -1))**oo == SetExpr(Interval(-oo, oo))
    assert SetExpr(Interval(-2, Rational(-1,
                                         2)))**oo == SetExpr(Interval(-oo, oo))
    assert SetExpr(Interval(Rational(-1, 2),
                            S.Half))**oo == SetExpr(FiniteSet(0))
    assert SetExpr(Interval(Rational(-1, 2),
                            1))**oo == SetExpr(Interval(0, oo))
    assert SetExpr(Interval(Rational(-2, 3),
                            2))**oo == SetExpr(Interval(0, oo))
    assert SetExpr(Interval(-1, 1))**oo == SetExpr(Interval(-oo, oo))
    assert SetExpr(Interval(-1, S.Half))**oo == SetExpr(Interval(-oo, oo))
    assert SetExpr(Interval(-1, 2))**oo == SetExpr(Interval(-oo, oo))
    assert SetExpr(Interval(-2, S.Half))**oo == SetExpr(Interval(-oo, oo))

    assert (SetExpr(Interval(1, 2))**x).dummy_eq(
        SetExpr(ImageSet(Lambda(_d, _d**x), Interval(1, 2))))

    assert SetExpr(Interval(2, 3))**(-oo) == SetExpr(FiniteSet(0))
    assert SetExpr(Interval(0, 2))**(-oo) == SetExpr(Interval(0, oo))
    assert (SetExpr(Interval(-1, 2))**(-oo)).dummy_eq(
        SetExpr(ImageSet(Lambda(_d, _d**(-oo)), Interval(-1, 2))))
Exemple #28
0
def _invert_real(f, g_ys, symbol):
    """ Helper function for invert_real """

    if not f.has(symbol):
        raise ValueError("Inverse of constant function doesn't exist")

    if f is symbol:
        return (f, g_ys)

    n = Dummy('n')
    if hasattr(f, 'inverse') and not isinstance(f, TrigonometricFunction):
        if len(f.args) > 1:
            raise ValueError("Only functions with one argument are supported.")
        return _invert_real(f.args[0], imageset(Lambda(n,
                                                       f.inverse()(n)), g_ys),
                            symbol)

    if isinstance(f, Abs):
        g_ys = g_ys - FiniteSet(*[g_y for g_y in g_ys if g_y.is_negative])
        return _invert_real(f.args[0],
                            Union(g_ys, imageset(Lambda(n, -n), g_ys)), symbol)

    if f.is_Add:
        # f = g + h
        g, h = f.as_independent(symbol)
        if g != S.Zero:
            return _invert_real(h, imageset(Lambda(n, n - g), g_ys), symbol)

    if f.is_Mul:
        # f = g*h
        g, h = f.as_independent(symbol)

        if g != S.One:
            return _invert_real(h, imageset(Lambda(n, n / g), g_ys), symbol)

    if f.is_Pow:
        base, expo = f.args
        base_has_sym = base.has(symbol)
        expo_has_sym = expo.has(symbol)

        if not expo_has_sym:
            res = imageset(Lambda(n, Pow(n, 1 / expo)), g_ys)
            if expo.is_rational:
                numer, denom = expo.as_numer_denom()
                if numer == S.One or numer == -S.One:
                    return _invert_real(base, res, symbol)
                else:
                    if numer % 2 == 0:
                        n = Dummy('n')
                        neg_res = imageset(Lambda(n, -n), res)
                        return _invert_real(base, res + neg_res, symbol)
                    else:
                        return _invert_real(base, res, symbol)
            else:
                if not base.is_positive:
                    raise ValueError("x**w where w is irrational is not "
                                     "defined for negative x")
                return _invert_real(base, res, symbol)

        if not base_has_sym:
            return _invert_real(expo,
                                imageset(Lambda(n,
                                                log(n) / log(base)), g_ys),
                                symbol)

    if isinstance(f, tan) or isinstance(f, cot):
        n = Dummy('n')
        if isinstance(g_ys, FiniteSet):
            tan_cot_invs = Union(*[
                imageset(Lambda(n, n * pi + f.inverse()(g_y)), S.Integers)
                for g_y in g_ys
            ])
            return _invert_real(f.args[0], tan_cot_invs, symbol)

    return (f, g_ys)