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