Пример #1
0
def evalf_subs(prec, subs):
    """ Change all Float entries in `subs` to have precision prec. """
    newsubs = {}
    for a, b in subs.items():
        b = S(b)
        if b.is_Float:
            b = b._eval_evalf(prec)
        newsubs[a] = b
    return newsubs
Пример #2
0
 def __new__(cls, p, q=None):
     if q is None:
         if isinstance(p, Rational):
            return p
         if isinstance(p, basestring):
             try:
                 # we might have a Real
                 neg_pow, digits, expt = decimal.Decimal(p).as_tuple()
                 p = [1, -1][neg_pow] * int("".join(str(x) for x in digits))
                 if expt > 0:
                     rv = Rational(p*Pow(10, expt), 1)
                 return Rational(p, Pow(10, -expt))
             except decimal.InvalidOperation:
                 import re
                 f = re.match(' *([-+]? *[0-9]+)( */ *)([0-9]+)', p)
                 if f:
                     p, _, q = f.groups()
                     return Rational(int(p), int(q))
                 else:
                     raise ValueError('invalid literal: %s' % p)
         elif not isinstance(p, Basic):
             return Rational(S(p))
         q = S.One
     if isinstance(q, Rational):
         p *= q.q
         q = q.p
     if isinstance(p, Rational):
         q *= p.q
         p = p.p
     p = int(p)
     q = int(q)
     if q == 0:
         if p == 0:
             if _errdict["divide"]:
                 raise ValueError("Indeterminate 0/0")
             else:
                 return S.NaN
         if p < 0:
             return S.NegativeInfinity
         return S.Infinity
     if q < 0:
         q = -q
         p = -p
     n = igcd(abs(p), q)
     if n > 1:
         p //= n
         q //= n
     if q == 1:
         return Integer(p)
     if p == 1 and q == 2:
         return S.Half
     obj = Expr.__new__(cls)
     obj.p = p
     obj.q = q
     #obj._args = (p, q)
     return obj
Пример #3
0
 def as_real_imag(self, deep=True):
     other = []
     coeff = S(1)
     for a in self.args:
         if a.is_real:
             coeff *= a
         else:
             other.append(a)
     m = Mul(*other)
     return (coeff * C.re(m), coeff * C.im(m))
Пример #4
0
    def _eval_power(b, e):
        if (e is S.NaN): return S.NaN
        if isinstance(e, Number):
            if isinstance(e, Real):
                return b._eval_evalf(e._prec)**e
            if e.is_negative:
                # (3/4)**-2 -> (4/3)**2
                ne = -e
                if (ne is S.One):
                    return Rational(b.q, b.p)
                if b < 0:
                    if e.q != 1:
                        return -(S.NegativeOne)**(
                            (e.p % e.q) / S(e.q)) * Rational(b.q, -b.p)**ne
                    else:
                        return S.NegativeOne**ne * Rational(b.q, -b.p)**ne
                else:
                    return Rational(b.q, b.p)**ne
            if (e is S.Infinity):
                if b.p > b.q:
                    # (3/2)**oo -> oo
                    return S.Infinity
                if b.p < -b.q:
                    # (-3/2)**oo -> oo + I*oo
                    return S.Infinity + S.Infinity * S.ImaginaryUnit
                return S.Zero
            if isinstance(e, Integer):
                # (4/3)**2 -> 4**2 / 3**2
                return Rational(b.p**e.p, b.q**e.p)
            if isinstance(e, Rational):
                if b.p != 1:
                    # (4/3)**(5/6) -> 4**(5/6) * 3**(-5/6)
                    return Integer(b.p)**e * Integer(b.q)**(-e)
                if b >= 0:
                    return Integer(b.q)**Rational(
                        e.p * (e.q - 1), e.q) / (Integer(b.q)**Integer(e.p))
                else:
                    return (-1)**e * (-b)**e

        c, t = b.as_coeff_terms()
        if e.is_even and isinstance(c, Number) and c < 0:
            return (-c * Mul(*t))**e

        return
Пример #5
0
    def _eval_power(b, e):
        """
        Tries to do some simplifications on b ** e, where b is
        an instance of Integer

        Returns None if no further simplifications can be done

        When exponent is a fraction (so we have for example a square root),
        we try to find a simpler representation by factoring the argument
        up to factors of 2**15, e.g.

          - 4**Rational(1,2) becomes 2
          - (-4)**Rational(1,2) becomes 2*I
          - (2**(3+7)*3**(6+7))**Rational(1,7) becomes 6*18**(3/7)

        Further simplification would require a special call to factorint on
        the argument which is not done here for sake of speed.

        """
        from sympy import perfect_power

        if e is S.NaN:
            return S.NaN
        if b is S.One:
            return S.One
        if b is S.NegativeOne:
            return
        if e is S.Infinity:
            if b > S.One:
                return S.Infinity
            if b is S.NegativeOne:
                return S.NaN
            # cases for 0 and 1 are done in their respective classes
            return S.Infinity + S.ImaginaryUnit * S.Infinity
        if not isinstance(e, Number):
            # simplify when exp is even
            # (-2) ** k --> 2 ** k
            c, t = b.as_coeff_mul()
            if e.is_even and isinstance(c, Number) and c < 0:
                return (-c*Mul(*t))**e
        if not isinstance(e, Rational):
            return
        if e is S.Half and b < 0:
            # we extract I for this special case since everyone is doing so
            return S.ImaginaryUnit*Pow(-b, e)
        if e < 0:
            # invert base and change sign on exponent
            ne = -e
            if b < 0:
                if e.q != 1:
                    return -(S.NegativeOne)**((e.p % e.q) /
                                             S(e.q)) * Rational(1, -b)**ne
                else:
                    return (S.NegativeOne)**ne*Rational(1, -b)**ne
            else:
                return Rational(1, b)**ne
        # see if base is a perfect root, sqrt(4) --> 2
        b_pos = int(abs(b))
        x, xexact = integer_nthroot(b_pos, e.q)
        if xexact:
            # if it's a perfect root we've finished
            result = Integer(x ** abs(e.p))
            if b < 0:
                result *= (-1)**e
            return result

        # The following is an algorithm where we collect perfect roots
        # from the factors of base.

        # if it's not an nth root, it still might be a perfect power
        p = perfect_power(b_pos)
        if p:
            dict = {p[0]: p[1]}
        else:
            dict = Integer(b_pos).factors(limit=2**15)

        # now process the dict of factors
        if b.is_negative:
            dict[-1] = 1
        out_int = 1
        sqr_int = 1
        sqr_gcd = 0
        sqr_dict = {}
        for prime, exponent in dict.iteritems():
            exponent *= e.p
            div_e, div_m = divmod(exponent, e.q)
            if div_e > 0:
                out_int *= prime**div_e
            if div_m > 0:
                sqr_dict[prime] = div_m
        for p, ex in sqr_dict.iteritems():
            if sqr_gcd == 0:
                sqr_gcd = ex
            else:
                sqr_gcd = igcd(sqr_gcd, ex)
        for k, v in sqr_dict.iteritems():
            sqr_int *= k**(v//sqr_gcd)
        if sqr_int == b and out_int == 1:
            result = None
        else:
            result = out_int*Pow(sqr_int , Rational(sqr_gcd, e.q))
        return result
Пример #6
0
 def _eval_expand_func(self, deep=True, **hints):
     return S.Half + S.Half*S.Sqrt(5)
Пример #7
0
    def _eval_power(b, e):
        """
        Tries to do some simplifications on b ** e, where b is
        an instance of Integer

        Returns None if no further simplifications can be done

        When exponent is a fraction (so we have for example a square root),
        we try to find the simplest possible representation, so that
          - 4**Rational(1,2) becomes 2
          - (-4)**Rational(1,2) becomes 2*I
        We will
        """
        if e is S.NaN: return S.NaN
        if b is S.One: return S.One
        if b is S.NegativeOne: return
        if e is S.Infinity:
            if b.p > S.One: return S.Infinity
            if b.p == -1: return S.NaN
            # cases 0, 1 are done in their respective classes
            return S.Infinity + S.ImaginaryUnit * S.Infinity
        if not isinstance(e, Number):
            # simplify when exp is even
            # (-2) ** k --> 2 ** k
            c, t = b.as_coeff_terms()
            if e.is_even and isinstance(c, Number) and c < 0:
                return (-c * Mul(*t))**e
        if not isinstance(e, Rational): return
        if e is S.Half and b < 0:
            # we extract I for this special case since everyone is doing so
            return S.ImaginaryUnit * Pow(-b, e)
        if e < 0:
            # invert base and change sign on exponent
            ne = -e
            if b < 0:
                if e.q != 1:
                    return -(S.NegativeOne)**(
                        (e.p % e.q) / S(e.q)) * Rational(1, -b)**ne
                else:
                    return (S.NegativeOne)**ne * Rational(1, -b)**ne
            else:
                return Rational(1, b.p)**ne
        # see if base is a perfect root, sqrt(4) --> 2
        x, xexact = integer_nthroot(abs(b.p), e.q)
        if xexact:
            # if it's a perfect root we've finished
            result = Integer(x**abs(e.p))
            if b < 0: result *= (-1)**e
            return result
        # The following is an algorithm where we collect perfect roots
        # from the factors of base
        if b > 4294967296:
            # Prevent from factorizing too big integers
            return None
        dict = b.factors()
        out_int = 1
        sqr_int = 1
        sqr_gcd = 0
        sqr_dict = {}
        for prime, exponent in dict.iteritems():
            exponent *= e.p
            div_e = exponent // e.q
            div_m = exponent % e.q
            if div_e > 0:
                out_int *= prime**div_e
            if div_m > 0:
                sqr_dict[prime] = div_m
        for p, ex in sqr_dict.iteritems():
            if sqr_gcd == 0:
                sqr_gcd = ex
            else:
                sqr_gcd = igcd(sqr_gcd, ex)
        for k, v in sqr_dict.iteritems():
            sqr_int *= k**(v // sqr_gcd)
        if sqr_int == b.p and out_int == 1:
            result = None
        else:
            result = out_int * Pow(sqr_int, Rational(sqr_gcd, e.q))
        return result