Example #1
0
    def _eval_power(b, e):
        if isinstance(e, Number):
            if isinstance(e, NaN): return S.NaN
            if isinstance(e, Real):
                return Real(decimal_math.pow(b._as_decimal(), e.num))
            if e.is_negative:
                # (3/4)**-2 -> (4/3)**2
                ne = -e
                if isinstance(ne, One):
                    return Rational(1, b.p)
                return Rational(1, b.p) ** ne
            if isinstance(e, Infinity):
                if b.p > 1:
                    # (3)**oo -> oo
                    return S.Infinity
                if b.p < -1:
                    # (-3)**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 Integer(b.p ** e.p)
            if isinstance(e, Rational):
                if b == -1:  # any one has tested this ???
                    # calculate the roots of -1
                    if e.q.is_odd:
                        return -1
                    r = cos(pi/e.q) + S.ImaginaryUnit*sin(pi/e.q)
                    return r**e.p
                if b >= 0:
                    x, xexact = integer_nthroot(b.p, e.q)
                    if xexact:
                        res = Integer(x ** abs(e.p))
                        if e >= 0:
                            return res
                        else:
                            return 1/res
                    # Now check also devisors of the exponents denominator
                    # TODO: Check if this slows down to much.
                    for i in xrange(2, e.q/2 + 1):
                        if e.q % i == 0:
                            x, xexact = integer_nthroot(b.p, i)
                            if xexact:
                                return Integer(x)**(e * i)
                    # Try to get some part of the base out, if exponent > 1
                    if e.p > e.q:
                        i = e.p / e.q
                        r = e.p % e.q
                        return b**i * b**Rational(r, e.q)

                else:
                    return (-1)**e * (-b)**e

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

        return
Example #2
0
    def _eval_power(b, e):
        if isinstance(e, Number):
            if isinstance(e, NaN): return S.NaN
            if isinstance(e, Real):
                return Real(decimal_math.pow(b._as_decimal(), e.num))
            if e.is_negative:
                # (3/4)**-2 -> (4/3)**2
                ne = -e
                if isinstance(ne, One):
                    return Rational(b.q, b.p)
                return Rational(b.q, b.p) ** ne
            if isinstance(e, 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:
                    x, xexact = integer_nthroot(b.p, e.q)
                    y, yexact = integer_nthroot(b.q, e.q)
                    if xexact and yexact:
                        res = Rational(x ** abs(e.p), y ** abs(e.p))
                        if e >= 0:
                            return res
                        else:
                            return 1/res
                    # Now check also devisors of the exponents denominator
                    # TODO: Check if this slows down to much.
                    for i in xrange(2, e.q/2 + 1):
                        if e.q % i == 0:
                            x, xexact = integer_nthroot(b.p, i)
                            y, yexact = integer_nthroot(b.q, i)
                            if xexact and yexact:
                                return Rational(x, y)**Rational(e.p, e.q/i)
                    else:
                        # Try to get some part of the base out, if exp > 1
                        if e.p > e.q:
                            i = e.p / e.q
                            r = e.p % e.q
                            return b**i * b**Rational(r, e.q)
                else:
                    return (-1)**e * (-b)**e

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

        return
Example #3
0
    def _eval_power(base, exp):
        """
        Tries to do some simplifications on base ** exp, where base is
        an instance of Rational

        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
        """

        MAX_INT_FACTOR = 4294967296 # Prevent from factorizing too big integers
        if not isinstance(exp, Number):
            c,t = base.as_coeff_terms()
            if exp.is_even and isinstance(c, Number) and c < 0:
                return (-c * Mul(*t)) ** exp
        if exp is S.NaN: return S.NaN
        if isinstance(exp, Real):
            return base._eval_evalf(exp._prec) ** exp
        if exp.is_negative:
            # (3/4)**-2 -> (4/3)**2
            ne = -exp
            if ne is S.One:
                return Rational(1, base.p)
            return Rational(1, base.p) ** ne
        if exp is S.Infinity:
            if base.p > 1:
                # (3)**oo -> oo
                return S.Infinity
            if base.p < -1:
                # (-3)**oo -> oo + I*oo
                return S.Infinity + S.Infinity * S.ImaginaryUnit
            return S.Zero
        if isinstance(exp, Integer):
            # (4/3)**2 -> 4**2 / 3**2
            return Integer(base.p ** exp.p)
        if exp == S.Half and base.is_negative:
            # sqrt(-2) -> I*sqrt(2)
            return S.ImaginaryUnit * ((-base)**exp)
        if isinstance(exp, Rational):
            # 4**Rational(1,2) -> 2
            result = None
            x, xexact = integer_nthroot(abs(base.p), exp.q)
            if xexact:
                res = Integer(x ** abs(exp.p))
                if exp >= 0:
                    result = res
                else:
                    result = 1/res
            else:
                if base > MAX_INT_FACTOR:
                    for i in xrange(2, exp.q//2 + 1): #OLD CODE
                        if exp.q % i == 0:
                            x, xexact = integer_nthroot(abs(base.p), i)
                            if xexact:
                                result = Integer(x)**(exp * i)
                                break
                    # Try to get some part of the base out, if exponent > 1
                    if exp.p > exp.q:
                        i = exp.p // exp.q
                        r = exp.p % exp.q
                        result = base**i * base**Rational(r, exp.q)

                    return

                dict = base.factors()
                out_int = 1
                sqr_int = 1
                sqr_gcd = 0
                sqr_dict = {}
                for prime,exponent in dict.iteritems():
                    exponent *= exp.p
                    div_e = exponent // exp.q
                    div_m = exponent % exp.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 == base.p and out_int == 1:
                    result = None
                else:
                    result = out_int * Pow(sqr_int , Rational(sqr_gcd, exp.q))

            if result is not None:
                if base.is_positive:
                    return result
                elif exp.q == 2:
                    return result * S.ImaginaryUnit
                else:
                    return result * ((-1)**exp)
            else:
                if exp == S.Half and base.is_negative:
                    return S.ImaginaryUnit * Pow(-base, exp)
Example #4
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
Example #5
0
File: numbers.py Project: NO2/sympy
    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
Example #6
0
    def _eval_power(base, exp):
        """
        Tries to do some simplifications on base ** exp, where base 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 exp is S.NaN: return S.NaN
        if base is S.One: return S.One
        if base is S.NegativeOne: return
        if exp is S.Infinity:
            if base.p > S.One: return S.Infinity
            if base.p == -1: return S.NaN
            # cases 0, 1 are done in their respective classes
            return S.Infinity + S.ImaginaryUnit * S.Infinity
        if not isinstance(exp, Number):
            # simplify when exp is even
            # (-2) ** k --> 2 ** k
            c,t = base.as_coeff_terms()
            if exp.is_even and isinstance(c, Number) and c < 0:
                return (-c * Mul(*t)) ** exp
        if not isinstance(exp, Rational): return
        if exp is S.Half and base < 0:
            # we extract I for this special case since everyone is doing so
            return S.ImaginaryUnit * Pow(-base, exp)
        if exp < 0:
            # invert base and change sign on exponent
            if base < 0:
                return -(S.NegativeOne) ** ((exp.p % exp.q) / S(exp.q)) * Rational(1, -base) ** (-exp)
            else:
                return Rational(1, base.p) ** (-exp)
        # see if base is a perfect root, sqrt(4) --> 2
        x, xexact = integer_nthroot(abs(base.p), exp.q)
        if xexact:
            # if it's a perfect root we've finished
            result = Integer(x ** abs(exp.p))
            if exp < 0: result = 1/result
            if base < 0: result *= (-1)**exp
            return result
        # The following is an algorithm where we collect perfect roots
        # from the factors of base
        if base > 4294967296:
            # Prevent from factorizing too big integers
            return None
        dict = base.factors()
        out_int = 1
        sqr_int = 1
        sqr_gcd = 0
        sqr_dict = {}
        for prime,exponent in dict.iteritems():
            exponent *= exp.p
            div_e = exponent // exp.q
            div_m = exponent % exp.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 == base.p and out_int == 1:
            result = None
        else:
            result = out_int * Pow(sqr_int , Rational(sqr_gcd, exp.q))
        return result
Example #7
0
    def _eval_power(base, exp):
        """
        Tries to do some simplifications on base ** exp, where base is
        an instance of Rational

        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
        """

        MAX_INT_FACTOR = 4294967296  # Prevent from factorizing too big integers
        if not isinstance(exp, Number):
            c, t = base.as_coeff_terms()
            if exp.is_even and isinstance(c, Number) and c < 0:
                return (-c * Mul(*t))**exp
        if exp is S.NaN: return S.NaN
        if isinstance(exp, Real):
            return base._eval_evalf(exp._prec)**exp
        if exp.is_negative:
            # (3/4)**-2 -> (4/3)**2
            ne = -exp
            if ne is S.One:
                return Rational(1, base.p)
            return Rational(1, base.p)**ne
        if exp is S.Infinity:
            if base.p > 1:
                # (3)**oo -> oo
                return S.Infinity
            if base.p < -1:
                # (-3)**oo -> oo + I*oo
                return S.Infinity + S.Infinity * S.ImaginaryUnit
            return S.Zero
        if isinstance(exp, Integer):
            # (4/3)**2 -> 4**2 / 3**2
            return Integer(base.p**exp.p)
        if exp == S.Half and base.is_negative:
            # sqrt(-2) -> I*sqrt(2)
            return S.ImaginaryUnit * ((-base)**exp)
        if isinstance(exp, Rational):
            # 4**Rational(1,2) -> 2
            result = None
            x, xexact = integer_nthroot(abs(base.p), exp.q)
            if xexact:
                res = Integer(x**abs(exp.p))
                if exp >= 0:
                    result = res
                else:
                    result = 1 / res
            else:
                if base > MAX_INT_FACTOR:
                    for i in xrange(2, exp.q // 2 + 1):  #OLD CODE
                        if exp.q % i == 0:
                            x, xexact = integer_nthroot(abs(base.p), i)
                            if xexact:
                                result = Integer(x)**(e * i)
                                break
                    # Try to get some part of the base out, if exponent > 1
                    if exp.p > exp.q:
                        i = exp.p // exp.q
                        r = exp.p % exp.q
                        result = base**i * b**Rational(r, exp.q)
                    return

                dict = base.factors()
                out_int = 1
                sqr_int = 1
                sqr_gcd = 0
                sqr_dict = {}
                for prime, exponent in dict.iteritems():
                    exponent *= exp.p
                    div_e = exponent // exp.q
                    div_m = exponent % exp.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 == base.p and out_int == 1:
                    result = None
                else:
                    result = out_int * Pow(sqr_int, Rational(sqr_gcd, exp.q))

            if result is not None:
                if base.is_positive:
                    return result
                elif exp.q == 2:
                    return result * S.ImaginaryUnit
                else:
                    return result * ((-1)**exp)
            else:
                if exp == S.Half and base.is_negative:
                    return S.ImaginaryUnit * Pow(-base, exp)