Пример #1
0
def test_rel_ne():
    assert Relational(x, y, '!=') == Ne(x, y)

    # issue 6116
    p = Symbol('p', positive=True)
    assert Ne(p, 0) is S.true
Пример #2
0
def piecewise_eval(cls, *_args):
    if not _args:
        return

    if len(_args) == 1 and _args[0][-1] == True:
        return _args[0][0]

    newargs = []  # the unevaluated conditions
    current_cond = set()  # the conditions up to a given e, c pair
    # make conditions canonical
    args = []
    for e, c in _args:
        if not c.is_Atom and not isinstance(c, Relational):
            free = c.expr_free_symbols
            if len(free) == 1:
                funcs = [
                    i for i in c.atoms(Function) if not isinstance(i, Boolean)
                ]
                if len(funcs) == 1 and len(
                        c.xreplace({
                            list(funcs)[0]: Dummy()
                        }).free_symbols) == 1:
                    # we can treat function like a symbol
                    free = funcs
                _c = c
                x = free.pop()
                try:
                    c = c.as_set().as_relational(x)
                except NotImplementedError:
                    pass
                else:
                    reps = {}
                    for i in c.atoms(Relational):
                        ic = i.canonical
                        if ic.rhs in (S.Infinity, S.NegativeInfinity):
                            if not _c.has(ic.rhs):
                                # don't accept introduction of
                                # new Relationals with +/-oo
                                reps[i] = S.true
                            elif ('=' not in ic.rel_op and c.xreplace(
                                {x: i.rhs}) != _c.xreplace({x: i.rhs})):
                                reps[i] = Relational(i.lhs, i.rhs,
                                                     i.rel_op + '=')
                    c = c.xreplace(reps)
        args.append((e, _canonical(c)))

    for expr, cond in args:
        # Check here if expr is a Piecewise and collapse if one of
        # the conds in expr matches cond. This allows the collapsing
        # of Piecewise((Piecewise((x,x<0)),x<0)) to Piecewise((x,x<0)).
        # This is important when using piecewise_fold to simplify
        # multiple Piecewise instances having the same conds.
        # Eventually, this code should be able to collapse Piecewise's
        # having different intervals, but this will probably require
        # using the new assumptions.
        if isinstance(expr, sympy.functions.elementary.piecewise.Piecewise):
            unmatching = []
            for i, (e, c) in enumerate(expr.args):
                if c in current_cond:
                    # this would already have triggered
                    continue
                if c == cond:
                    if c != True:
                        # nothing past this condition will ever
                        # trigger and only those args before this
                        # that didn't match a previous condition
                        # could possibly trigger
                        if unmatching:
                            expr = sympy.functions.elementary.piecewise.Piecewise(
                                *(unmatching + [(e, c)]))
                        else:
                            expr = e
                    break
                else:
                    unmatching.append((e, c))

        # check for condition repeats
        got = False
        # -- if an And contains a condition that was
        #    already encountered, then the And will be
        #    False: if the previous condition was False
        #    then the And will be False and if the previous
        #    condition is True then then we wouldn't get to
        #    this point. In either case, we can skip this condition.
        for i in ([cond] + (list(cond.args) if isinstance(cond, And) else [])):
            if i in current_cond:
                got = True
                break
        if got:
            continue

        # -- if not(c) is already in current_cond then c is
        #    a redundant condition in an And. This does not
        #    apply to Or, however: (e1, c), (e2, Or(~c, d))
        #    is not (e1, c), (e2, d) because if c and d are
        #    both False this would give no results when the
        #    true answer should be (e2, True)
        if isinstance(cond, And):
            nonredundant = []
            for c in cond.args:
                if (isinstance(c, Relational)
                        and (~c).canonical in current_cond):
                    continue
                nonredundant.append(c)
            cond = cond.func(*nonredundant)
        elif isinstance(cond, Relational):
            if (~cond).canonical in current_cond:
                cond = S.true

        current_cond.add(cond)

        # collect successive e,c pairs when exprs or cond match
        if newargs:
            if newargs[-1].expr == expr:
                orcond = Or(cond, newargs[-1].cond)
                if isinstance(orcond, (And, Or)):
                    orcond = distribute_and_over_or(orcond)
                newargs[
                    -1] = sympy.functions.elementary.piecewise.ExprCondPair(
                        expr, orcond)
                continue
            elif newargs[-1].cond == cond:
                orexpr = Or(expr, newargs[-1].expr)
                if isinstance(orexpr, (And, Or)):
                    orexpr = distribute_and_over_or(orexpr)
                newargs[
                    -1] = sympy.functions.elementary.piecewise.ExprCondPair(
                        orexpr, cond)
                continue

        newargs.append(
            sympy.functions.elementary.piecewise.ExprCondPair(expr, cond))

    # some conditions may have been redundant
    missing = len(newargs) != len(_args)
    # some conditions may have changed
    same = all(a == b for a, b in zip(newargs, _args))
    # if either change happened we return the expr with the
    # updated args
    if not newargs:
        raise ValueError(
            filldedent('''
            There are no conditions (or none that
            are not trivially false) to define an
            expression.'''))
    if missing or not same:
        return cls(*newargs)
Пример #3
0
def reduce_abs_inequality(expr, rel, gen):
    """Reduce an inequality with nested absolute values.

    Examples
    ========

    >>> from sympy import Abs, Symbol
    >>> from sympy.solvers.inequalities import reduce_abs_inequality
    >>> x = Symbol('x', real=True)

    >>> reduce_abs_inequality(Abs(x - 5) - 3, '<', x)
    (2 < x) & (x < 8)

    >>> reduce_abs_inequality(Abs(x + 2)*3 - 13, '<', x)
    (-19/3 < x) & (x < 7/3)

    See Also
    ========

    reduce_abs_inequalities
    """
    if gen.is_real is False:
        raise TypeError(
            filldedent('''
            can't solve inequalities with absolute values containing
            non-real variables.
            '''))

    def _bottom_up_scan(expr):
        exprs = []

        if expr.is_Add or expr.is_Mul:
            op = expr.func

            for arg in expr.args:
                _exprs = _bottom_up_scan(arg)

                if not exprs:
                    exprs = _exprs
                else:
                    args = []

                    for expr, conds in exprs:
                        for _expr, _conds in _exprs:
                            args.append((op(expr, _expr), conds + _conds))

                    exprs = args
        elif expr.is_Pow:
            n = expr.exp
            if not n.is_Integer:
                raise ValueError("Only Integer Powers are allowed on Abs.")

            _exprs = _bottom_up_scan(expr.base)

            for expr, conds in _exprs:
                exprs.append((expr**n, conds))
        elif isinstance(expr, Abs):
            _exprs = _bottom_up_scan(expr.args[0])

            for expr, conds in _exprs:
                exprs.append((expr, conds + [Ge(expr, 0)]))
                exprs.append((-expr, conds + [Lt(expr, 0)]))
        else:
            exprs = [(expr, [])]

        return exprs

    exprs = _bottom_up_scan(expr)

    mapping = {'<': '>', '<=': '>='}
    inequalities = []

    for expr, conds in exprs:
        if rel not in mapping.keys():
            expr = Relational(expr, 0, rel)
        else:
            expr = Relational(-expr, 0, mapping[rel])

        inequalities.append([expr] + conds)

    return reduce_rational_inequalities(inequalities, gen)
Пример #4
0
def test_new_relational():
    x = Symbol('x')

    assert Eq(x, 0) == Relational(x, 0)       # None ==> Equality
    assert Eq(x, 0) == Relational(x, 0, '==')
    assert Eq(x, 0) == Relational(x, 0, 'eq')
    assert Eq(x, 0) == Equality(x, 0)

    assert Eq(x, 0) != Relational(x, 1)       # None ==> Equality
    assert Eq(x, 0) != Relational(x, 1, '==')
    assert Eq(x, 0) != Relational(x, 1, 'eq')
    assert Eq(x, 0) != Equality(x, 1)

    assert Eq(x, -1) == Relational(x, -1)       # None ==> Equality
    assert Eq(x, -1) == Relational(x, -1, '==')
    assert Eq(x, -1) == Relational(x, -1, 'eq')
    assert Eq(x, -1) == Equality(x, -1)
    assert Eq(x, -1) != Relational(x, 1)       # None ==> Equality
    assert Eq(x, -1) != Relational(x, 1, '==')
    assert Eq(x, -1) != Relational(x, 1, 'eq')
    assert Eq(x, -1) != Equality(x, 1)

    assert Ne(x, 0) == Relational(x, 0, '!=')
    assert Ne(x, 0) == Relational(x, 0, '<>')
    assert Ne(x, 0) == Relational(x, 0, 'ne')
    assert Ne(x, 0) == Unequality(x, 0)
    assert Ne(x, 0) != Relational(x, 1, '!=')
    assert Ne(x, 0) != Relational(x, 1, '<>')
    assert Ne(x, 0) != Relational(x, 1, 'ne')
    assert Ne(x, 0) != Unequality(x, 1)

    assert Ge(x, 0) == Relational(x, 0, '>=')
    assert Ge(x, 0) == Relational(x, 0, 'ge')
    assert Ge(x, 0) == GreaterThan(x, 0)
    assert Ge(x, 1) != Relational(x, 0, '>=')
    assert Ge(x, 1) != Relational(x, 0, 'ge')
    assert Ge(x, 1) != GreaterThan(x, 0)
    assert (x >= 1) == Relational(x, 1, '>=')
    assert (x >= 1) == Relational(x, 1, 'ge')
    assert (x >= 1) == GreaterThan(x, 1)
    assert (x >= 0) != Relational(x, 1, '>=')
    assert (x >= 0) != Relational(x, 1, 'ge')
    assert (x >= 0) != GreaterThan(x, 1)

    assert Le(x, 0) == Relational(x, 0, '<=')
    assert Le(x, 0) == Relational(x, 0, 'le')
    assert Le(x, 0) == LessThan(x, 0)
    assert Le(x, 1) != Relational(x, 0, '<=')
    assert Le(x, 1) != Relational(x, 0, 'le')
    assert Le(x, 1) != LessThan(x, 0)
    assert (x <= 1) == Relational(x, 1, '<=')
    assert (x <= 1) == Relational(x, 1, 'le')
    assert (x <= 1) == LessThan(x, 1)
    assert (x <= 0) != Relational(x, 1, '<=')
    assert (x <= 0) != Relational(x, 1, 'le')
    assert (x <= 0) != LessThan(x, 1)

    assert Gt(x, 0) == Relational(x, 0, '>')
    assert Gt(x, 0) == Relational(x, 0, 'gt')
    assert Gt(x, 0) == StrictGreaterThan(x, 0)
    assert Gt(x, 1) != Relational(x, 0, '>')
    assert Gt(x, 1) != Relational(x, 0, 'gt')
    assert Gt(x, 1) != StrictGreaterThan(x, 0)
    assert (x > 1) == Relational(x, 1, '>')
    assert (x > 1) == Relational(x, 1, 'gt')
    assert (x > 1) == StrictGreaterThan(x, 1)
    assert (x > 0) != Relational(x, 1, '>')
    assert (x > 0) != Relational(x, 1, 'gt')
    assert (x > 0) != StrictGreaterThan(x, 1)

    assert Lt(x, 0) == Relational(x, 0, '<')
    assert Lt(x, 0) == Relational(x, 0, 'lt')
    assert Lt(x, 0) == StrictLessThan(x, 0)
    assert Lt(x, 1) != Relational(x, 0, '<')
    assert Lt(x, 1) != Relational(x, 0, 'lt')
    assert Lt(x, 1) != StrictLessThan(x, 0)
    assert (x < 1) == Relational(x, 1, '<')
    assert (x < 1) == Relational(x, 1, 'lt')
    assert (x < 1) == StrictLessThan(x, 1)
    assert (x < 0) != Relational(x, 1, '<')
    assert (x < 0) != Relational(x, 1, 'lt')
    assert (x < 0) != StrictLessThan(x, 1)

    # finally, some fuzz testing
    from random import randint
    from sympy.core.compatibility import unichr
    for i in range(100):
        while 1:
            strtype, length = (unichr, 65535) if randint(0, 1) else (chr, 255)
            relation_type = strtype(randint(0, length))
            if randint(0, 1):
                relation_type += strtype(randint(0, length))
            if relation_type not in ('==', 'eq', '!=', '<>', 'ne', '>=', 'ge',
                                     '<=', 'le', '>', 'gt', '<', 'lt', ':=',
                                     '+=', '-=', '*=', '/=', '%='):
                break

        raises(ValueError, lambda: Relational(x, 1, relation_type))
    assert all(Relational(x, 0, op).rel_op == '==' for op in ('eq', '=='))
    assert all(Relational(x, 0, op).rel_op == '!='
               for op in ('ne', '<>', '!='))
    assert all(Relational(x, 0, op).rel_op == '>' for op in ('gt', '>'))
    assert all(Relational(x, 0, op).rel_op == '<' for op in ('lt', '<'))
    assert all(Relational(x, 0, op).rel_op == '>=' for op in ('ge', '>='))
    assert all(Relational(x, 0, op).rel_op == '<=' for op in ('le', '<='))
Пример #5
0
def reduce_rational_inequalities(exprs, gen, relational=True):
    """Reduce a system of rational inequalities with rational coefficients.

    Examples
    ========

    >>> from sympy import Poly, Symbol
    >>> from sympy.solvers.inequalities import reduce_rational_inequalities

    >>> x = Symbol('x', real=True)

    >>> reduce_rational_inequalities([[x**2 <= 0]], x)
    Eq(x, 0)

    >>> reduce_rational_inequalities([[x + 2 > 0]], x)
    (-2 < x) & (x < oo)
    >>> reduce_rational_inequalities([[(x + 2, ">")]], x)
    (-2 < x) & (x < oo)
    >>> reduce_rational_inequalities([[x + 2]], x)
    Eq(x, -2)
    """
    exact = True
    eqs = []
    solution = S.Reals if exprs else S.EmptySet
    for _exprs in exprs:
        _eqs = []

        for expr in _exprs:
            if isinstance(expr, tuple):
                expr, rel = expr
            else:
                if expr.is_Relational:
                    expr, rel = expr.lhs - expr.rhs, expr.rel_op
                else:
                    expr, rel = expr, '=='

            if expr is S.true:
                numer, denom, rel = S.Zero, S.One, '=='
            elif expr is S.false:
                numer, denom, rel = S.One, S.One, '=='
            else:
                numer, denom = expr.together().as_numer_denom()

            try:
                (numer, denom), opt = parallel_poly_from_expr((numer, denom),
                                                              gen)
            except PolynomialError:
                raise PolynomialError(
                    filldedent('''
                    only polynomials and rational functions are
                    supported in this context.
                    '''))

            if not opt.domain.is_Exact:
                numer, denom, exact = numer.to_exact(), denom.to_exact(), False

            domain = opt.domain.get_exact()

            if not (domain.is_ZZ or domain.is_QQ):
                expr = numer / denom
                expr = Relational(expr, 0, rel)
                solution &= solve_univariate_inequality(expr,
                                                        gen,
                                                        relational=False)
            else:
                _eqs.append(((numer, denom), rel))

        if _eqs:
            eqs.append(_eqs)

    if eqs:
        solution &= solve_rational_inequalities(eqs)
        exclude = solve_rational_inequalities([[((d, d.one), '==') for i in eqs
                                                for ((n, d), _) in i
                                                if d.has(gen)]])
        solution -= exclude

    if not exact and solution:
        solution = solution.evalf()

    if relational:
        solution = solution.as_relational(gen)

    return solution
Пример #6
0
def solve_poly_inequality(poly, rel):
    """Solve a polynomial inequality with rational coefficients.

    Examples
    ========

    >>> from sympy import Poly
    >>> from sympy.abc import x
    >>> from sympy.solvers.inequalities import solve_poly_inequality

    >>> solve_poly_inequality(Poly(x, x, domain='ZZ'), '==')
    [{0}]

    >>> solve_poly_inequality(Poly(x**2 - 1, x, domain='ZZ'), '!=')
    [Interval.open(-oo, -1), Interval.open(-1, 1), Interval.open(1, oo)]

    >>> solve_poly_inequality(Poly(x**2 - 1, x, domain='ZZ'), '==')
    [{-1}, {1}]

    See Also
    ========
    solve_poly_inequalities
    """
    if not isinstance(poly, Poly):
        raise ValueError(
            'For efficiency reasons, `poly` should be a Poly instance')
    if poly.is_number:
        t = Relational(poly.as_expr(), 0, rel)
        if t is S.true:
            return [S.Reals]
        elif t is S.false:
            return [S.EmptySet]
        else:
            raise NotImplementedError("could not determine truth value of %s" %
                                      t)

    reals, intervals = poly.real_roots(multiple=False), []

    if rel == '==':
        for root, _ in reals:
            interval = Interval(root, root)
            intervals.append(interval)
    elif rel == '!=':
        left = S.NegativeInfinity

        for right, _ in reals + [(S.Infinity, 1)]:
            interval = Interval(left, right, True, True)
            intervals.append(interval)
            left = right
    else:
        if poly.LC() > 0:
            sign = +1
        else:
            sign = -1

        eq_sign, equal = None, False

        if rel == '>':
            eq_sign = +1
        elif rel == '<':
            eq_sign = -1
        elif rel == '>=':
            eq_sign, equal = +1, True
        elif rel == '<=':
            eq_sign, equal = -1, True
        else:
            raise ValueError("'%s' is not a valid relation" % rel)

        right, right_open = S.Infinity, True

        for left, multiplicity in reversed(reals):
            if multiplicity % 2:
                if sign == eq_sign:
                    intervals.insert(
                        0, Interval(left, right, not equal, right_open))

                sign, right, right_open = -sign, left, not equal
            else:
                if sign == eq_sign and not equal:
                    intervals.insert(0, Interval(left, right, True,
                                                 right_open))
                    right, right_open = left, True
                elif sign != eq_sign and equal:
                    intervals.insert(0, Interval(left, left))

        if sign == eq_sign:
            intervals.insert(
                0, Interval(S.NegativeInfinity, right, True, right_open))

    return intervals
Пример #7
0
def test_rel_ne():
    Relational(x, y, '!=')  # this used to raise
Пример #8
0
def reduce_abs_inequality(expr, rel, gen, assume=True):
    """Reduce an inequality with nested absolute values.

    Examples
    ========

    >>> from sympy import Q, Abs
    >>> from sympy.abc import x
    >>> from sympy.solvers.inequalities import reduce_abs_inequality

    >>> reduce_abs_inequality(Abs(x - 5) - 3, '<', x, assume=Q.real(x))
    And(2 < x, x < 8)

    >>> reduce_abs_inequality(Abs(x + 2)*3 - 13, '<', x, assume=Q.real(x))
    And(-19/3 < x, x < 7/3)

    See Also
    ========
    reduce_abs_inequalities
    """
    if not ask(Q.real(gen), assumptions=assume):
        raise NotImplementedError(
            "can't solve inequalities with absolute values of a complex variable"
        )

    def _bottom_up_scan(expr):
        exprs = []

        if expr.is_Add or expr.is_Mul:
            op = expr.__class__

            for arg in expr.args:
                _exprs = _bottom_up_scan(arg)

                if not exprs:
                    exprs = _exprs
                else:
                    args = []

                    for expr, conds in exprs:
                        for _expr, _conds in _exprs:
                            args.append((op(expr, _expr), conds + _conds))

                    exprs = args
        elif expr.is_Pow:
            n = expr.exp

            if not n.is_Integer or n < 0:
                raise ValueError(
                    "only non-negative integer powers are allowed")

            _exprs = _bottom_up_scan(expr.base)

            for expr, conds in _exprs:
                exprs.append((expr**n, conds))
        elif isinstance(expr, Abs):
            _exprs = _bottom_up_scan(expr.args[0])

            for expr, conds in _exprs:
                exprs.append((expr, conds + [Ge(expr, 0)]))
                exprs.append((-expr, conds + [Lt(expr, 0)]))
        else:
            exprs = [(expr, [])]

        return exprs

    exprs = _bottom_up_scan(expr)

    mapping = {'<': '>', '<=': '>='}
    inequalities = []

    for expr, conds in exprs:
        if rel not in mapping.keys():
            expr = Relational(expr, 0, rel)
        else:
            expr = Relational(-expr, 0, mapping[rel])

        inequalities.append([expr] + conds)

    return reduce_rational_inequalities(inequalities, gen, assume)
Пример #9
0
def test_rel_ne():
    assert Relational(x, y, '!=') == Ne(x, y)
Пример #10
0
def trim(f, *symbols, **flags):
    """Cancel common factors in a given formal rational expression.

       Given an arbitrary expression, map all functional components
       to temporary symbols, rewriting this expression to rational
       function form and perform cancelation of common factors.

       When given a rational function or a list of symbols discards
       all functional components, then this procedure is equivalent
       to cancel().

       Note that this procedure can thread over composite objects
       like big operators, matrices, relational operators etc. It
       can be also called recursively (to change this behaviour
       unset 'recursive' flag).

       >>> from sympy import *

       >>> x,y = symbols('xy')
       >>> f = Function('f')

       >>> trim((f(x)**2+f(x))/f(x))
       1 + f(x)

       >>> trim((x**2+x)/x)
       1 + x

       Recursively simplify expressions:

       >>> trim(sin((f(x)**2+f(x))/f(x)))
       sin(1 + f(x))

    """
    f = sympify(f)

    if isinstance(f, Relational):
        return Relational(trim(f.lhs, *symbols, **flags),
                          trim(f.rhs, *symbols, **flags), f.rel_op)
    #elif isinstance(f, Matrix):
    #    return f.applyfunc(lambda g: trim(g, *symbols, **flags))
    else:
        recursive = flags.get('recursive', True)

        def is_functional(g):
            return not (g.is_Atom or g.is_number) \
                and (not symbols or g.has(*symbols))

        def components(g):
            result = set()

            if is_functional(g):
                if g.is_Add or g.is_Mul:
                    args = []

                    for h in g.args:
                        h, terms = components(h)

                        result |= terms
                        args.append(h)

                    g = g.__class__(*args)
                elif g.is_Pow:
                    if recursive:
                        base = trim(g.base, *symbols, **flags)
                    else:
                        base = g.base

                    if g.exp.is_Rational:
                        if g.exp.is_Integer:
                            if g.exp is S.NegativeOne:
                                h, terms = components(base)
                                return h**S.NegativeOne, terms
                            else:
                                h = base
                        else:
                            h = base**Rational(1, g.exp.q)

                        g = base**g.exp
                    else:
                        if recursive:
                            h = g = base**trim(g.exp, *symbols, **flags)
                        else:
                            h = g = base**g.exp

                    if is_functional(h):
                        result.add(h)
                else:
                    if not recursive:
                        result.add(g)
                    else:
                        g = g.__class__(*[trim(h, *symbols,
                            **flags) for h in g.args])

                        if is_functional(g):
                            result.add(g)

            return g, result

        if f.is_number or not f.has_any_symbols(*symbols):
            return f

        f = together(f.expand())
        f, terms = components(f)

        if not terms:
            return Poly.cancel(f, *symbols)
        else:
            mapping, reverse = {}, {}

            for g in terms:
                mapping[g] = Temporary()
                reverse[mapping[g]] = g

            p, q = f.as_numer_denom()
            f = p.expand()/q.expand()

            if not symbols:
                symbols = tuple(f.atoms(Symbol))

            symbols = tuple(mapping.values()) + symbols

            H = Poly.cancel(f.subs(mapping), *symbols)

            if not flags.get('extract', True):
                return H.subs(reverse)
            else:
                def extract(f):
                    p = f.args[0]

                    for q in f.args[1:]:
                        p = gcd(p, q, *symbols)

                        if p.is_number:
                            return S.One, f

                    return p, Add(*[quo(g, p, *symbols) for g in f.args])

                P, Q = H.as_numer_denom()

                if P.is_Add:
                    GP, P = extract(P)
                else:
                    GP = S.One

                if Q.is_Add:
                    GQ, Q = extract(Q)
                else:
                    GQ = S.One

                return ((GP*P)/(GQ*Q)).subs(reverse)
Пример #11
0
def reduce_abs_inequality(expr, rel, gen, assume=True):
    """Reduce an inequality with nested absolute values. """
    if not ask(Q.real(gen), assumptions=assume):
        raise NotImplementedError(
            "can't solve inequalities with absolute values of a complex variable"
        )

    def bottom_up_scan(expr):
        exprs = []

        if expr.is_Add or expr.is_Mul:
            op = expr.__class__

            for arg in expr.args:
                _exprs = bottom_up_scan(arg)

                if not exprs:
                    exprs = _exprs
                else:
                    args = []

                    for expr, conds in exprs:
                        for _expr, _conds in _exprs:
                            args.append((op(expr, _expr), conds + _conds))

                    exprs = args
        elif expr.is_Pow:
            n = expr.exp

            if not n.is_Integer or n < 0:
                raise ValueError(
                    "only non-negative integer powers are allowed")

            _exprs = bottom_up_scan(expr.base)

            for expr, conds in _exprs:
                exprs.append((expr**n, conds))
        elif isinstance(expr, Abs):
            _exprs = bottom_up_scan(expr.args[0])

            for expr, conds in _exprs:
                exprs.append((expr, conds + [Ge(expr, 0)]))
                exprs.append((-expr, conds + [Lt(expr, 0)]))
        else:
            exprs = [(expr, [])]

        return exprs

    exprs = bottom_up_scan(expr)

    mapping = {'<': '>', '<=': '>='}
    inequalities = []

    for expr, conds in exprs:
        if rel not in mapping.keys():
            expr = Relational(expr, 0, rel)
        else:
            expr = Relational(-expr, 0, mapping[rel])

        inequalities.append([expr] + conds)

    return reduce_poly_inequalities(inequalities, gen, assume)
Пример #12
0
def test_new_relational():
    x = Symbol('x')

    assert Eq(x) == Relational(x, 0)  # None ==> Equality
    assert Eq(x) == Relational(x, 0, '==')
    assert Eq(x) == Relational(x, 0, 'eq')
    assert Eq(x) == Equality(x, 0)
    assert Eq(x, -1) == Relational(x, -1)  # None ==> Equality
    assert Eq(x, -1) == Relational(x, -1, '==')
    assert Eq(x, -1) == Relational(x, -1, 'eq')
    assert Eq(x, -1) == Equality(x, -1)
    assert Eq(x) != Relational(x, 1)  # None ==> Equality
    assert Eq(x) != Relational(x, 1, '==')
    assert Eq(x) != Relational(x, 1, 'eq')
    assert Eq(x) != Equality(x, 1)
    assert Eq(x, -1) != Relational(x, 1)  # None ==> Equality
    assert Eq(x, -1) != Relational(x, 1, '==')
    assert Eq(x, -1) != Relational(x, 1, 'eq')
    assert Eq(x, -1) != Equality(x, 1)

    assert Ne(x, 0) == Relational(x, 0, '!=')
    assert Ne(x, 0) == Relational(x, 0, '<>')
    assert Ne(x, 0) == Relational(x, 0, 'ne')
    assert Ne(x, 0) == Unequality(x, 0)
    assert Ne(x, 0) != Relational(x, 1, '!=')
    assert Ne(x, 0) != Relational(x, 1, '<>')
    assert Ne(x, 0) != Relational(x, 1, 'ne')
    assert Ne(x, 0) != Unequality(x, 1)

    assert Ge(x, 0) == Relational(x, 0, '>=')
    assert Ge(x, 0) == Relational(x, 0, 'ge')
    assert Ge(x, 0) == GreaterThan(x, 0)
    assert Ge(x, 1) != Relational(x, 0, '>=')
    assert Ge(x, 1) != Relational(x, 0, 'ge')
    assert Ge(x, 1) != GreaterThan(x, 0)
    assert (x >= 1) == Relational(x, 1, '>=')
    assert (x >= 1) == Relational(x, 1, 'ge')
    assert (x >= 1) == GreaterThan(x, 1)
    assert (x >= 0) != Relational(x, 1, '>=')
    assert (x >= 0) != Relational(x, 1, 'ge')
    assert (x >= 0) != GreaterThan(x, 1)

    assert Le(x, 0) == Relational(x, 0, '<=')
    assert Le(x, 0) == Relational(x, 0, 'le')
    assert Le(x, 0) == LessThan(x, 0)
    assert Le(x, 1) != Relational(x, 0, '<=')
    assert Le(x, 1) != Relational(x, 0, 'le')
    assert Le(x, 1) != LessThan(x, 0)
    assert (x <= 1) == Relational(x, 1, '<=')
    assert (x <= 1) == Relational(x, 1, 'le')
    assert (x <= 1) == LessThan(x, 1)
    assert (x <= 0) != Relational(x, 1, '<=')
    assert (x <= 0) != Relational(x, 1, 'le')
    assert (x <= 0) != LessThan(x, 1)

    assert Gt(x, 0) == Relational(x, 0, '>')
    assert Gt(x, 0) == Relational(x, 0, 'gt')
    assert Gt(x, 0) == StrictGreaterThan(x, 0)
    assert Gt(x, 1) != Relational(x, 0, '>')
    assert Gt(x, 1) != Relational(x, 0, 'gt')
    assert Gt(x, 1) != StrictGreaterThan(x, 0)
    assert (x > 1) == Relational(x, 1, '>')
    assert (x > 1) == Relational(x, 1, 'gt')
    assert (x > 1) == StrictGreaterThan(x, 1)
    assert (x > 0) != Relational(x, 1, '>')
    assert (x > 0) != Relational(x, 1, 'gt')
    assert (x > 0) != StrictGreaterThan(x, 1)

    assert Lt(x, 0) == Relational(x, 0, '<')
    assert Lt(x, 0) == Relational(x, 0, 'lt')
    assert Lt(x, 0) == StrictLessThan(x, 0)
    assert Lt(x, 1) != Relational(x, 0, '<')
    assert Lt(x, 1) != Relational(x, 0, 'lt')
    assert Lt(x, 1) != StrictLessThan(x, 0)
    assert (x < 1) == Relational(x, 1, '<')
    assert (x < 1) == Relational(x, 1, 'lt')
    assert (x < 1) == StrictLessThan(x, 1)
    assert (x < 0) != Relational(x, 1, '<')
    assert (x < 0) != Relational(x, 1, 'lt')
    assert (x < 0) != StrictLessThan(x, 1)

    # finally, some fuzz testing
    from random import randint
    for i in range(100):
        while 1:
            strtype, length = (unichr, 65535) if randint(0, 1) else (chr, 255)
            relation_type = strtype(randint(0, length))
            if randint(0, 1):
                relation_type += strtype(randint(0, length))
            if relation_type not in ('==', 'eq', '!=', '<>', 'ne', '>=', 'ge',
                                     '<=', 'le', '>', 'gt', '<', 'lt'):
                break

        raises(ValueError, "Relational(x, 1, relation_type)")
Пример #13
0
def test_new_relational():
    x = Symbol("x")

    assert Eq(x, 0) == Relational(x, 0)  # None ==> Equality
    assert Eq(x, 0) == Relational(x, 0, "==")
    assert Eq(x, 0) == Relational(x, 0, "eq")
    assert Eq(x, 0) == Equality(x, 0)

    assert Eq(x, 0) != Relational(x, 1)  # None ==> Equality
    assert Eq(x, 0) != Relational(x, 1, "==")
    assert Eq(x, 0) != Relational(x, 1, "eq")
    assert Eq(x, 0) != Equality(x, 1)

    assert Eq(x, -1) == Relational(x, -1)  # None ==> Equality
    assert Eq(x, -1) == Relational(x, -1, "==")
    assert Eq(x, -1) == Relational(x, -1, "eq")
    assert Eq(x, -1) == Equality(x, -1)
    assert Eq(x, -1) != Relational(x, 1)  # None ==> Equality
    assert Eq(x, -1) != Relational(x, 1, "==")
    assert Eq(x, -1) != Relational(x, 1, "eq")
    assert Eq(x, -1) != Equality(x, 1)

    assert Ne(x, 0) == Relational(x, 0, "!=")
    assert Ne(x, 0) == Relational(x, 0, "<>")
    assert Ne(x, 0) == Relational(x, 0, "ne")
    assert Ne(x, 0) == Unequality(x, 0)
    assert Ne(x, 0) != Relational(x, 1, "!=")
    assert Ne(x, 0) != Relational(x, 1, "<>")
    assert Ne(x, 0) != Relational(x, 1, "ne")
    assert Ne(x, 0) != Unequality(x, 1)

    assert Ge(x, 0) == Relational(x, 0, ">=")
    assert Ge(x, 0) == Relational(x, 0, "ge")
    assert Ge(x, 0) == GreaterThan(x, 0)
    assert Ge(x, 1) != Relational(x, 0, ">=")
    assert Ge(x, 1) != Relational(x, 0, "ge")
    assert Ge(x, 1) != GreaterThan(x, 0)
    assert (x >= 1) == Relational(x, 1, ">=")
    assert (x >= 1) == Relational(x, 1, "ge")
    assert (x >= 1) == GreaterThan(x, 1)
    assert (x >= 0) != Relational(x, 1, ">=")
    assert (x >= 0) != Relational(x, 1, "ge")
    assert (x >= 0) != GreaterThan(x, 1)

    assert Le(x, 0) == Relational(x, 0, "<=")
    assert Le(x, 0) == Relational(x, 0, "le")
    assert Le(x, 0) == LessThan(x, 0)
    assert Le(x, 1) != Relational(x, 0, "<=")
    assert Le(x, 1) != Relational(x, 0, "le")
    assert Le(x, 1) != LessThan(x, 0)
    assert (x <= 1) == Relational(x, 1, "<=")
    assert (x <= 1) == Relational(x, 1, "le")
    assert (x <= 1) == LessThan(x, 1)
    assert (x <= 0) != Relational(x, 1, "<=")
    assert (x <= 0) != Relational(x, 1, "le")
    assert (x <= 0) != LessThan(x, 1)

    assert Gt(x, 0) == Relational(x, 0, ">")
    assert Gt(x, 0) == Relational(x, 0, "gt")
    assert Gt(x, 0) == StrictGreaterThan(x, 0)
    assert Gt(x, 1) != Relational(x, 0, ">")
    assert Gt(x, 1) != Relational(x, 0, "gt")
    assert Gt(x, 1) != StrictGreaterThan(x, 0)
    assert (x > 1) == Relational(x, 1, ">")
    assert (x > 1) == Relational(x, 1, "gt")
    assert (x > 1) == StrictGreaterThan(x, 1)
    assert (x > 0) != Relational(x, 1, ">")
    assert (x > 0) != Relational(x, 1, "gt")
    assert (x > 0) != StrictGreaterThan(x, 1)

    assert Lt(x, 0) == Relational(x, 0, "<")
    assert Lt(x, 0) == Relational(x, 0, "lt")
    assert Lt(x, 0) == StrictLessThan(x, 0)
    assert Lt(x, 1) != Relational(x, 0, "<")
    assert Lt(x, 1) != Relational(x, 0, "lt")
    assert Lt(x, 1) != StrictLessThan(x, 0)
    assert (x < 1) == Relational(x, 1, "<")
    assert (x < 1) == Relational(x, 1, "lt")
    assert (x < 1) == StrictLessThan(x, 1)
    assert (x < 0) != Relational(x, 1, "<")
    assert (x < 0) != Relational(x, 1, "lt")
    assert (x < 0) != StrictLessThan(x, 1)

    # finally, some fuzz testing
    from random import randint
    from sympy.core.compatibility import unichr

    for i in range(100):
        while 1:
            strtype, length = (unichr, 65535) if randint(0, 1) else (chr, 255)
            relation_type = strtype(randint(0, length))
            if randint(0, 1):
                relation_type += strtype(randint(0, length))
            if relation_type not in (
                "==",
                "eq",
                "!=",
                "<>",
                "ne",
                ">=",
                "ge",
                "<=",
                "le",
                ">",
                "gt",
                "<",
                "lt",
                ":=",
                "+=",
                "-=",
                "*=",
                "/=",
                "%=",
            ):
                break

        raises(ValueError, lambda: Relational(x, 1, relation_type))
    assert all(Relational(x, 0, op).rel_op == "==" for op in ("eq", "=="))
    assert all(Relational(x, 0, op).rel_op == "!=" for op in ("ne", "<>", "!="))
    assert all(Relational(x, 0, op).rel_op == ">" for op in ("gt", ">"))
    assert all(Relational(x, 0, op).rel_op == "<" for op in ("lt", "<"))
    assert all(Relational(x, 0, op).rel_op == ">=" for op in ("ge", ">="))
    assert all(Relational(x, 0, op).rel_op == "<=" for op in ("le", "<="))