Exemplo n.º 1
0
def test_fuzzy_group():
    from sympy.utilities.iterables import cartes
    v = [T, F, U]
    for i in cartes(*[v]*3):
        assert _fuzzy_group(i) is (None if None in i else
                                   (True if all(j for j in i) else False))
        assert _fuzzy_group(i, quick_exit=True) is \
            (None if (i.count(False) > 1) else
             (None if None in i else (True if all(j for j in i) else False)))
    it = (True if (i == 0) else None for i in range(2))
    assert _torf(it) is None
    it = (True if (i == 1) else None for i in range(2))
    assert _torf(it) is None
Exemplo n.º 2
0
class MinMaxBase(Expr, LatticeOp):
    def __new__(cls, *args, **assumptions):
        if not args:
            raise ValueError("The Max/Min functions must have arguments.")

        args = (sympify(arg) for arg in args)

        # first standard filter, for cls.zero and cls.identity
        # also reshape Max(a, Max(b, c)) to Max(a, b, c)
        try:
            _args = frozenset(cls._new_args_filter(args))
        except ShortCircuit:
            return cls.zero

        # second filter
        # variant I: remove ones which can be removed
        # args = cls._collapse_arguments(set(_args), **assumptions)

        # variant II: find local zeros
        args = cls._find_localzeros(set(_args), **assumptions)

        if not args:
            return cls.identity
        elif len(args) == 1:
            return args.pop()
        else:
            # base creation
            # XXX should _args be made canonical with sorting?
            _args = frozenset(args)
            obj = Expr.__new__(cls, _args, **assumptions)
            obj._argset = _args
            return obj

    def _eval_simplify(self, ratio, measure):
        # simplify Min(foo, y, Max(foo, x)) to Min(foo, y)
        # Like And/Or, anything in common between the two
        # is cause to eliminate the opposite arg.
        cls = self.func
        if cls == Min:
            op = Max
        elif cls == Max:
            op = Min
        else:
            op = None
        if op:
            unnested = set()
            nested = []
            remove = []
            for a in self.args:
                if isinstance(a, op):
                    nested.append(a)
                else:
                    unnested.add(a)
            N = len(nested) - 1
            for i, n in enumerate(reversed(nested)):
                if set(n.args) & unnested:
                    nested.pop(N - i)
            return cls(*(list(unnested) + nested))

    @classmethod
    def _new_args_filter(cls, arg_sequence):
        """
        Generator filtering args.

        first standard filter, for cls.zero and cls.identity.
        Also reshape Max(a, Max(b, c)) to Max(a, b, c),
        and check arguments for comparability
        """
        for arg in arg_sequence:

            # pre-filter, checking comparability of arguments
            if (not isinstance(arg, Expr)) or (arg.is_real is False) or (
                    arg is S.ComplexInfinity):
                raise ValueError("The argument '%s' is not comparable." % arg)

            if arg == cls.zero:
                raise ShortCircuit(arg)
            elif arg == cls.identity:
                continue
            elif arg.func == cls:
                for x in arg.args:
                    yield x
            else:
                yield arg

    @classmethod
    def _find_localzeros(cls, values, **options):
        """
        Sequentially allocate values to localzeros.

        When a value is identified as being more extreme than another member it
        replaces that member; if this is never true, then the value is simply
        appended to the localzeros.
        """
        localzeros = set()
        for v in values:
            is_newzero = True
            localzeros_ = list(localzeros)
            for z in localzeros_:
                if id(v) == id(z):
                    is_newzero = False
                else:
                    con = cls._is_connected(v, z)
                    if con:
                        is_newzero = False
                        if con is True or con == cls:
                            localzeros.remove(z)
                            localzeros.update([v])
            if is_newzero:
                localzeros.update([v])
        return localzeros

    @classmethod
    def _is_connected(cls, x, y):
        """
        Check if x and y are connected somehow.
        """
        from sympy.core.exprtools import factor_terms

        def hit(v, t, f):
            if not v.is_Relational:
                return t if v else f

        for i in range(2):
            if x == y:
                return True
            r = hit(x >= y, Max, Min)
            if r is not None:
                return r
            r = hit(y <= x, Max, Min)
            if r is not None:
                return r
            r = hit(x <= y, Min, Max)
            if r is not None:
                return r
            r = hit(y >= x, Min, Max)
            if r is not None:
                return r
            # simplification can be expensive, so be conservative
            # in what is attempted
            x = factor_terms(x - y)
            y = S.Zero

        return False

    def _eval_derivative(self, s):
        # f(x).diff(s) -> x.diff(s) * f.fdiff(1)(s)
        i = 0
        l = []
        for a in self.args:
            i += 1
            da = a.diff(s)
            if da is S.Zero:
                continue
            try:
                df = self.fdiff(i)
            except ArgumentIndexError:
                df = Function.fdiff(self, i)
            l.append(df * da)
        return Add(*l)

    def evalf(self, prec=None, **options):
        return self.func(*[a.evalf(prec, **options) for a in self.args])

    n = evalf

    _eval_is_algebraic = lambda s: _torf(i.is_algebraic for i in s.args)
    _eval_is_antihermitian = lambda s: _torf(i.is_antihermitian
                                             for i in s.args)
    _eval_is_commutative = lambda s: _torf(i.is_commutative for i in s.args)
    _eval_is_complex = lambda s: _torf(i.is_complex for i in s.args)
    _eval_is_composite = lambda s: _torf(i.is_composite for i in s.args)
    _eval_is_even = lambda s: _torf(i.is_even for i in s.args)
    _eval_is_finite = lambda s: _torf(i.is_finite for i in s.args)
    _eval_is_hermitian = lambda s: _torf(i.is_hermitian for i in s.args)
    _eval_is_imaginary = lambda s: _torf(i.is_imaginary for i in s.args)
    _eval_is_infinite = lambda s: _torf(i.is_infinite for i in s.args)
    _eval_is_integer = lambda s: _torf(i.is_integer for i in s.args)
    _eval_is_irrational = lambda s: _torf(i.is_irrational for i in s.args)
    _eval_is_negative = lambda s: _torf(i.is_negative for i in s.args)
    _eval_is_noninteger = lambda s: _torf(i.is_noninteger for i in s.args)
    _eval_is_nonnegative = lambda s: _torf(i.is_nonnegative for i in s.args)
    _eval_is_nonpositive = lambda s: _torf(i.is_nonpositive for i in s.args)
    _eval_is_nonzero = lambda s: _torf(i.is_nonzero for i in s.args)
    _eval_is_odd = lambda s: _torf(i.is_odd for i in s.args)
    _eval_is_polar = lambda s: _torf(i.is_polar for i in s.args)
    _eval_is_positive = lambda s: _torf(i.is_positive for i in s.args)
    _eval_is_prime = lambda s: _torf(i.is_prime for i in s.args)
    _eval_is_rational = lambda s: _torf(i.is_rational for i in s.args)
    _eval_is_real = lambda s: _torf(i.is_real for i in s.args)
    _eval_is_transcendental = lambda s: _torf(i.is_transcendental
                                              for i in s.args)
    _eval_is_zero = lambda s: _torf(i.is_zero for i in s.args)
Exemplo n.º 3
0
def test_torf():
    from sympy.utilities.iterables import cartes
    v = [T, F, U]
    for i in cartes(*[v]*3):
        assert _torf(i) is (True if all(j for j in i) else
                            (False if all(j is False for j in i) else None))