Ejemplo n.º 1
0
    def test_real_is_integer(self):
        self.assertTrue(Real.is_integer(-1.0))
        self.assertTrue(Real.is_integer(0.0))
        self.assertTrue(Real.is_integer(1.0))
        self.assertTrue(Real.is_integer(42.0))

        self.assertFalse(Real.is_integer(-0.5))
        self.assertFalse(Real.is_integer(4.2))
Ejemplo n.º 2
0
    def add_datapoint(self, value: Real, weighting: Real = 1.0):
        """Record a batch-level measurement of the metric.

        Parameters
        ----------
        value : Real
            The recorded value.
        weighting : Real
            The weight with which this recorded value will contribute
            to the epoch-level mean."""
        if isinstance(value, np.ndarray):
            value = value.item()

        self._batch_data_list.append(value)
        self._running_weighted_sum += weighting * value
        self._total_weighting += weighting
        self._cnt_since_epoch += 1
Ejemplo n.º 3
0
def sympify(a, locals=None, convert_xor=True):
    """Converts an arbitrary expression to a type that can be used
       inside sympy. For example, it will convert python int's into
       instance of sympy.Rational, floats into intances of sympy.Real,
       etc. It is also able to coerce symbolic expressions which does
       inherit after Basic. This can be useful in cooperation with SAGE.

       It currently accepts as arguments:
           - any object defined in sympy (except maybe matrices [TODO])
           - standard numeric python types: int, long, float, Decimal
           - strings (like "0.09" or "2e-19")
           - booleans (will leave them unchanged)

       If the argument is already a type that sympy understands, it will do
       nothing but return that value. This can be used at the begining of a
       function to ensure you are working with the correct type.

       >>> from sympy import *

       >>> sympify(2).is_integer
       True
       >>> sympify(2).is_real
       True

       >>> sympify(2.0).is_real
       True
       >>> sympify("2.0").is_real
       True
       >>> sympify("2e-45").is_real
       True

    """
    # XXX instead of duplicating _sympify it would be better to call _sympify
    # directly from here, but a lot of SymPy still calls sympify (no '_') and
    # this will add unneccesary overhead.
    #
    # When everything settles, let's refactor this.
    #                                      -- kirr
    if locals is None:
        locals = {}
    if isinstance(a, Basic):
        return a
    if isinstance(a, BasicType):
        return a
    elif isinstance(a, bool):
        return a
    elif isinstance(a, (int, long)):
        return Integer(a)
    elif isinstance(a, (float, decimal.Decimal)):
        return Real(a)
    elif isinstance(a, complex):
        real, imag = map(sympify, (a.real, a.imag))
        ireal, iimag = int(real), int(imag)

        if ireal + iimag * 1j == a:
            return ireal + iimag * S.ImaginaryUnit
        return real + S.ImaginaryUnit * imag
    elif isinstance(a, (list, tuple, set)):
        return type(a)([sympify(x) for x in a])

    # let's see if 'a' implements conversion methods such as '_sympy_' or
    # '__int__', that returns a SymPy (by definition) or SymPy compatible
    # expression, so we just use it
    for methname, conv in [
        ('_sympy_', None),
        ('__float__', Real),
        ('__int__', Integer),
    ]:
        meth = getattr(a, methname, None)
        if meth is None:
            continue

        # we have to be careful -- calling Class.__int__() almost always is not
        # a good idea
        try:
            v = meth()
        except TypeError:
            continue

        if conv is not None:
            v = conv(v)

        return v

    else:
        # XXX this is here because of cyclic-import issues
        from sympy.matrices import Matrix

        if isinstance(a, Matrix):
            raise NotImplementedError('matrix support')

        if not isinstance(a, str):
            # At this point we were given an arbitrary expression
            # which does not inherit from Basic and doesn't implement
            # _sympy_ (which is a canonical and robust way to convert
            # anything to SymPy expression).
            #
            # As a last chance, we try to take "a"'s  normal form via str()
            # and try to parse it. If it fails, then we have no luck and
            # return an exception
            a = str(a)

        if convert_xor:
            a = a.replace('^', '**')
        import ast_parser
        return ast_parser.parse_expr(a, locals)
    raise SympifyError("%r is NOT a valid SymPy expression" % a)
Ejemplo n.º 4
0
def _sympify(a):
    """short version of sympify for internal usage

       When adding and comparing symbolic expressions, it is unwise to allow
       e.g. strings to mixin. On the other hand Python integers and floats are
       allowed.

       So we don't use full-featured sympify in __add__ and __eq__ methods, but
       instead use this small-crafted function there instead.

       >>> Integer(1) == 1
       True

       >>> Integer(1) == '1'
       False

       >>> from sympy import Symbol
       >>> x = Symbol('x')
       >>> x + 1
       1 + x

       >>> x + '1'
       Traceback (most recent call last):
           ...
       TypeError: unsupported operand type(s) for +: 'Symbol' and 'str'

       see: sympify
    """
    if isinstance(a, Basic):
        return a
    if isinstance(a, BasicType):
        return a
    elif isinstance(a, (int, long)):
        return Integer(a)
    elif isinstance(a, (float, decimal.Decimal)):
        return Real(a)
    elif isinstance(a, complex):
        real, imag = map(sympify, (a.real, a.imag))
        ireal, iimag = int(real), int(imag)

        if ireal + iimag * 1j == a:
            return ireal + iimag * S.ImaginaryUnit
        return real + S.ImaginaryUnit * imag

    # let's see if 'a' implements conversion methods such as '_sympy_' or
    # '__int__', that returns a SymPy (by definition) or SymPy compatible
    # expression, so we just use it
    for methname, conv in [
        ('_sympy_', None),
        ('__float__', Real),
        ('__int__', Integer),
    ]:
        meth = getattr(a, methname, None)
        if meth is None:
            continue

        # we have to be careful -- calling Class.__int__() almost always is not
        # a good idea
        try:
            v = meth()
        except TypeError:
            continue

        if conv is not None:
            v = conv(v)

        return v

    raise SympifyError("%r is NOT a valid SymPy expression" % (a, ))
Ejemplo n.º 5
0
Archivo: mul.py Proyecto: pernici/sympy
    def flatten(cls, seq):

        # apply associativity, separate commutative part of seq
        c_part = []  # out: commutative factors
        nc_part = []  # out: non-commutative factors

        nc_seq = []

        coeff = S.One  # standalone term
        # e.g. 3 * ...

        c_powers = []  # (base,exp)      n
        # e.g. (x,n) for x

        num_exp = []  # (num-base, exp)           y
        # e.g.  (3, y)  for  ... * 3  * ...

        order_symbols = None

        # --- PART 1 ---
        #
        # "collect powers and coeff":
        #
        # o coeff
        # o c_powers
        # o num_exp
        #
        # NOTE: this is optimized for all-objects-are-commutative case

        for o in seq:
            # O(x)
            if o.is_Order:
                o, order_symbols = o.as_expr_variables(order_symbols)

            # Mul([...])
            if o.is_Mul:
                if o.is_commutative:
                    seq.extend(o.args)  # XXX zerocopy?

                else:
                    # NCMul can have commutative parts as well
                    for q in o.args:
                        if q.is_commutative:
                            seq.append(q)
                        else:
                            nc_seq.append(q)

                    # append non-commutative marker, so we don't forget to
                    # process scheduled non-commutative objects
                    seq.append(NC_Marker)

                continue

            # 3
            elif o.is_Number:
                if o is S.NaN or coeff is S.ComplexInfinity and o is S.Zero:
                    # we know for sure the result will be nan
                    return [S.NaN], [], None
                elif coeff.is_Number:  # it could be zoo
                    coeff *= o
                    if coeff is S.NaN:
                        # we know for sure the result will be nan
                        return [S.NaN], [], None
                continue

            elif o is S.ComplexInfinity:
                if not coeff or coeff is S.ComplexInfinity:
                    # we know for sure the result will be nan
                    return [S.NaN], [], None
                coeff = S.ComplexInfinity
                continue

            elif o.is_commutative:
                #      e
                # o = b
                b, e = o.as_base_exp()

                #  y
                # 3
                if o.is_Pow and b.is_Number:
                    # get all the factors with numeric base so they can be
                    # combined below, but don't combine negatives unless
                    # the exponent is an integer
                    if b.is_positive or e.is_integer:
                        num_exp.append((b, e))
                        continue

                #         n          n          n
                # (-3 + y)   ->  (-1)  * (3 - y)
                #
                # Give powers a chance to become a Mul if that's the
                # behavior obtained from Add._eval_power()
                if not Basic.keep_sign and b.is_Add and e.is_Number:
                    cb = b._eval_power(e, terms=True)
                    if cb:
                        c, b = cb
                        coeff *= c

                c_powers.append((b, e))

            # NON-COMMUTATIVE
            # TODO: Make non-commutative exponents not combine automatically
            else:
                if o is not NC_Marker:
                    nc_seq.append(o)

                # process nc_seq (if any)
                while nc_seq:
                    o = nc_seq.pop(0)
                    if not nc_part:
                        nc_part.append(o)
                        continue

                    #                             b    c       b+c
                    # try to combine last terms: a  * a   ->  a
                    o1 = nc_part.pop()
                    b1, e1 = o1.as_base_exp()
                    b2, e2 = o.as_base_exp()
                    new_exp = e1 + e2
                    # Only allow powers to combine if the new exponent is
                    # not an Add. This allow things like a**2*b**3 == a**5
                    # if a.is_commutative == False, but prohibits
                    # a**x*a**y and x**a*x**b from combining (x,y commute).
                    if b1 == b2 and (not new_exp.is_Add):
                        o12 = b1**new_exp

                        # now o12 could be a commutative object
                        if o12.is_commutative:
                            seq.append(o12)
                            continue
                        else:
                            nc_seq.insert(0, o12)

                    else:
                        nc_part.append(o1)
                        nc_part.append(o)

        # We do want a combined exponent if it would not be an Add, such as
        #  y    2y     3y
        # x  * x   -> x
        # We determine this if two exponents have the same term in as_coeff_mul
        #
        # Unfortunately, this isn't smart enough to consider combining into
        # exponents that might already be adds, so things like:
        #  z - y    y
        # x      * x  will be left alone.  This is because checking every possible
        # combination can slow things down.

        # gather exponents of common bases...
        # in c_powers
        new_c_powers = []
        common_b = {}  # b:e

        for b, e in c_powers:
            co = e.as_coeff_mul()
            common_b.setdefault(b, {}).setdefault(co[1], []).append(co[0])
        for b, d in common_b.items():
            for di, li in d.items():
                d[di] = Add(*li)

        for b, e in common_b.items():
            for t, c in e.items():
                new_c_powers.append((b, c * Mul(*t)))
        c_powers = new_c_powers

        # and in num_exp
        new_num_exp = []
        common_b = {}  # b:e

        for b, e in num_exp:
            co = e.as_coeff_mul()
            common_b.setdefault(b, {}).setdefault(co[1], []).append(co[0])
        for b, d in common_b.items():
            for di, li in d.items():
                d[di] = Add(*li)

        for b, e in common_b.items():
            for t, c in e.items():
                new_num_exp.append((b, c * Mul(*t)))
        num_exp = new_num_exp

        # --- PART 2 ---
        #
        # o process collected powers  (x**0 -> 1; x**1 -> x; otherwise Pow)
        # o combine collected powers  (2**x * 3**x -> 6**x)
        #   with numeric base

        # ................................
        # now we have:
        # - coeff:
        # - c_powers:    (b, e)
        # - num_exp:     (2, e)

        #  0             1
        # x  -> 1       x  -> x
        for b, e in c_powers:
            if e is S.Zero:
                continue

            if e is S.One:
                if b.is_Number:
                    coeff *= b
                else:
                    c_part.append(b)
            elif e.is_Integer and b.is_Number:
                coeff *= Pow(b, e)
            else:
                c_part.append(Pow(b, e))

        #  x    x     x
        # 2  * 3  -> 6
        inv_exp_dict = {}  # exp:Mul(num-bases)     x    x
        # e.g.  x:6  for  ... * 2  * 3  * ...
        for b, e in num_exp:
            inv_exp_dict.setdefault(e, []).append(b)
        for e, b in inv_exp_dict.items():
            inv_exp_dict[e] = Mul(*b)

        reeval = False

        for e, b in inv_exp_dict.items():
            if e is S.Zero:
                continue

            if e is S.One:
                if b.is_Number:
                    coeff *= b
                else:
                    c_part.append(b)
            elif e.is_Integer and b.is_Number:
                coeff *= Pow(b, e)
            else:
                obj = b**e
                if obj.is_Mul:
                    # We may have split out a number that needs to go in coeff
                    # e.g., sqrt(6)*sqrt(2) == 2*sqrt(3).  See issue 415.
                    reeval = True
                if obj.is_Number:
                    coeff *= obj
                else:
                    c_part.append(obj)

        # oo, -oo
        if (coeff is S.Infinity) or (coeff is S.NegativeInfinity):
            new_c_part = []
            coeff_sign = 1
            for t in c_part:
                if t.is_positive:
                    continue
                if t.is_negative:
                    coeff_sign *= -1
                    continue
                new_c_part.append(t)
            c_part = new_c_part
            new_nc_part = []
            for t in nc_part:
                if t.is_positive:
                    continue
                if t.is_negative:
                    coeff_sign *= -1
                    continue
                new_nc_part.append(t)
            nc_part = new_nc_part
            coeff *= coeff_sign

        # zoo
        if coeff is S.ComplexInfinity:
            # zoo might be
            #   unbounded_real + bounded_im
            #   bounded_real + unbounded_im
            #   unbounded_real + unbounded_im
            # and non-zero real or imaginary will not change that status.
            c_part = [
                c for c in c_part
                if not (c.is_nonzero and c.is_real is not None)
            ]
            nc_part = [
                c for c in nc_part
                if not (c.is_nonzero and c.is_real is not None)
            ]

        # 0
        elif coeff is S.Zero:
            # we know for sure the result will be 0
            return [coeff], [], order_symbols

        elif coeff.is_Real:
            if coeff == Real(0):
                c_part, nc_part = [coeff], []
            elif coeff == Real(1):
                # change it to One, so it doesn't get inserted to slot0
                coeff = S.One

        # order commutative part canonically
        c_part.sort(Basic.compare)

        # current code expects coeff to be always in slot-0
        if coeff is not S.One:
            c_part.insert(0, coeff)

        # we are done
        if len(c_part) == 2 and c_part[0].is_Number and c_part[1].is_Add:
            # 2*(1+a) -> 2 + 2 * a
            coeff = c_part[0]
            c_part = [Add(*[coeff * f for f in c_part[1].args])]

        if reeval:
            c_part, _, _ = Mul.flatten(c_part)
        return c_part, nc_part, order_symbols
Ejemplo n.º 6
0
    def flatten(cls, seq):

        # apply associativity, separate commutative part of seq
        c_part = []  # out: commutative factors
        nc_part = []  # out: non-commutative factors

        nc_seq = []

        coeff = S.One  # standalone term
        # e.g. 3 * ...

        c_powers = []  # (base,exp)      n
        # e.g. (x,n) for x

        num_exp = []  # (num-base, exp)           y
        # e.g.  (3, y)  for  ... * 3  * ...

        order_symbols = None

        # --- PART 1 ---
        #
        # "collect powers and coeff":
        #
        # o coeff
        # o c_powers
        # o num_exp
        #
        # NOTE: this is optimized for all-objects-are-commutative case

        for o in seq:
            # O(x)
            if o.is_Order:
                o, order_symbols = o.as_expr_symbols(order_symbols)

            # Mul([...])
            if o.is_Mul:
                if o.is_commutative:
                    seq.extend(o.args)  # XXX zerocopy?

                else:
                    # NCMul can have commutative parts as well
                    for q in o.args:
                        if q.is_commutative:
                            seq.append(q)
                        else:
                            nc_seq.append(q)

                    # append non-commutative marker, so we don't forget to
                    # process scheduled non-commutative objects
                    seq.append(NC_Marker)

                continue

            # 3
            elif o.is_Number:
                coeff *= o
                continue

            elif o.is_commutative:
                #      e
                # o = b
                b, e = o.as_base_exp()

                #  y
                # 3
                if o.is_Pow and b.is_Number:
                    # get all the factors with numeric base so they can be
                    # combined below
                    num_exp.append((b, e))
                    continue

                #         n          n          n
                # (-3 + y)   ->  (-1)  * (3 - y)
                if b.is_Add and e.is_Number:
                    #found factor (x+y)**number; split off initial coefficient
                    c, t = b.as_coeff_terms()
                    #last time I checked, Add.as_coeff_terms returns One or NegativeOne
                    #but this might change
                    if c.is_negative and not e.is_integer:
                        # extracting root from negative number: ignore sign
                        if c is not S.NegativeOne:
                            # make c positive (probably never occurs)
                            coeff *= (-c)**e
                            assert len(t) == 1, ` t `
                            b = -t[0]
                        #else: ignoring sign from NegativeOne: nothing to do!
                    elif c is not S.One:
                        coeff *= c**e
                        assert len(t) == 1, ` t `
                        b = t[0]
                    #else: c is One, so pass

                c_powers.append((b, e))

            # NON-COMMUTATIVE
            # TODO: Make non-commutative exponents not combine automatically
            else:
                if o is not NC_Marker:
                    nc_seq.append(o)

                # process nc_seq (if any)
                while nc_seq:
                    o = nc_seq.pop(0)
                    if not nc_part:
                        nc_part.append(o)
                        continue

                    #                             b    c       b+c
                    # try to combine last terms: a  * a   ->  a
                    o1 = nc_part.pop()
                    b1, e1 = o1.as_base_exp()
                    b2, e2 = o.as_base_exp()
                    if b1 == b2:
                        o12 = b1**(e1 + e2)

                        # now o12 could be a commutative object
                        if o12.is_commutative:
                            seq.append(o12)
                            continue

                        else:
                            nc_seq.insert(0, o12)

                    else:
                        nc_part.append(o1)
                        nc_part.append(o)
        # We do want a combined exponent if it would not be an Add, such as
        #  y    2y     3y
        # x  * x   -> x
        # We determine this if two exponents have the same term in as_coeff_terms
        #
        # Unfortunately, this isn't smart enough to consider combining into
        # exponents that might already be adds, so thing like:
        #  z - y    y
        # x      * x  will be left alone.  This is because checking every possible
        # combination can slow things down.
        new_c_powers = []
        common_b = {}  # b:e

        # First gather exponents of common bases
        for b, e in c_powers:
            co = e.as_coeff_terms()
            if b in common_b:
                if co[1] in common_b[b]:
                    common_b[b][co[1]] += co[0]
                else:
                    common_b[b][co[1]] = co[0]
            else:
                common_b[b] = {co[1]: co[0]}

        for b, e, in common_b.items():
            for t, c in e.items():
                new_c_powers.append((b, c * Mul(*t)))
        c_powers = new_c_powers

        # And the same for numeric bases
        new_num_exp = []
        common_b = {}  # b:e
        for b, e in num_exp:
            co = e.as_coeff_terms()
            if b in common_b:
                if co[1] in common_b[b]:
                    common_b[b][co[1]] += co[0]
                else:
                    common_b[b][co[1]] = co[0]
            else:
                common_b[b] = {co[1]: co[0]}

        for b, e, in common_b.items():
            for t, c in e.items():
                new_num_exp.append((b, c * Mul(*t)))
        num_exp = new_num_exp

        # --- PART 2 ---
        #
        # o process collected powers  (x**0 -> 1; x**1 -> x; otherwise Pow)
        # o combine collected powers  (2**x * 3**x -> 6**x)
        #   with numeric base

        # ................................
        # now we have:
        # - coeff:
        # - c_powers:    (b, e)
        # - num_exp:     (2, e)

        #  0             1
        # x  -> 1       x  -> x
        for b, e in c_powers:
            if e is S.Zero:
                continue

            if e is S.One:
                if b.is_Number:
                    coeff *= b
                else:
                    c_part.append(b)
            elif e.is_Integer and b.is_Number:
                coeff *= b**e
            else:
                c_part.append(Pow(b, e))

        #  x    x     x
        # 2  * 3  -> 6
        inv_exp_dict = {}  # exp:Mul(num-bases)     x    x
        # e.g.  x:6  for  ... * 2  * 3  * ...
        for b, e in num_exp:
            if e in inv_exp_dict:
                inv_exp_dict[e] *= b
            else:
                inv_exp_dict[e] = b

        for e, b in inv_exp_dict.items():
            if e is S.Zero:
                continue

            if e is S.One:
                if b.is_Number:
                    coeff *= b
                else:
                    c_part.append(b)
            elif e.is_Integer and b.is_Number:
                coeff *= b**e
            else:
                obj = b**e
                if obj.is_Number:
                    coeff *= obj
                else:
                    c_part.append(obj)

        # oo, -oo
        if (coeff is S.Infinity) or (coeff is S.NegativeInfinity):
            new_c_part = []
            for t in c_part:
                if t.is_positive:
                    continue
                if t.is_negative:
                    coeff = -coeff
                    continue
                new_c_part.append(t)
            c_part = new_c_part
            new_nc_part = []
            for t in nc_part:
                if t.is_positive:
                    continue
                if t.is_negative:
                    coeff = -coeff
                    continue
                new_nc_part.append(t)
            nc_part = new_nc_part

        # 0, nan
        elif (coeff is S.Zero) or (coeff is S.NaN):
            # we know for sure the result will be the same as coeff (0 or nan)
            return [coeff], [], order_symbols

        elif coeff.is_Real:
            if coeff == Real(0):
                c_part, nc_part = [coeff], []
            elif coeff == Real(1):
                # change it to One, so it doesn't get inserted to slot0
                coeff = S.One

        # order commutative part canonically
        c_part.sort(Basic.compare)

        # current code expects coeff to be always in slot-0
        if coeff is not S.One:
            c_part.insert(0, coeff)

        # we are done
        if len(c_part) == 2 and c_part[0].is_Number and c_part[1].is_Add:
            # 2*(1+a) -> 2 + 2 * a
            coeff = c_part[0]
            c_part = [Add(*[coeff * f for f in c_part[1].args])]

        return c_part, nc_part, order_symbols
Ejemplo n.º 7
0
 def is_right_unbounded(self):
     """Return ``True`` if the right endpoint is positive infinity. """
     return self.right is S.Infinity or self.right == Real("+inf")
Ejemplo n.º 8
0
 def is_left_unbounded(self):
     """Return ``True`` if the left endpoint is negative infinity. """
     return self.left is S.NegativeInfinity or self.left == Real("-inf")
from numbers import Real

from z3 import *

x = Real('x')
y = Real('y')
s = Solver()
s.add(x + y > 5, x > 1, y > 1)
print(s.check())
print(s.model())