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
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
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))
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
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_expand_func(self, deep=True, **hints): return S.Half + S.Half*S.Sqrt(5)
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