예제 #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
예제 #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
예제 #3
0
    def _eval_power(b, e):
        """
        b is Real but not equal to rationals, integers, 0.5, oo, -oo, nan
        e is symbolic object but not equal to 0, 1

        (-p) ** r -> exp(r * log(-p)) -> exp(r * (log(p) + I*Pi)) ->
                  -> p ** r * (sin(Pi*r) + cos(Pi*r) * I)
        """
        if isinstance(e, Number):
            if isinstance(e, Integer):
                e = e.p
                return Real(decimal_math.pow(b.num, e))

            e2 = e._as_decimal()
            if b.is_negative and not e.is_integer:
                m = decimal_math.pow(-b.num, e2)
                a = decimal_math.pi() * e2
                s = m * decimal_math.sin(a)
                c = m * decimal_math.cos(a)
                return Real(s) + Real(c) * S.ImaginaryUnit
            return Real(decimal_math.pow(b.num, e2))
        return