def _eval_power(self, e): if e.is_Rational and self.is_number: from sympy.core.evalf import pure_complex from sympy.core.mul import _unevaluated_Mul from sympy.core.exprtools import factor_terms from sympy.core.function import expand_multinomial from sympy.functions.elementary.complexes import sign from sympy.functions.elementary.miscellaneous import sqrt ri = pure_complex(self) if ri: r, i = ri if e.q == 2: D = sqrt(r**2 + i**2) if D.is_Rational: # (r, i, D) is a Pythagorean triple root = sqrt(factor_terms((D - r) / 2))**e.p return root * expand_multinomial(( # principle value (D + r) / abs(i) + sign(i) * S.ImaginaryUnit)**e.p) elif e == -1: return _unevaluated_Mul(r - i * S.ImaginaryUnit, 1 / (r**2 + i**2))
def _eval_power(self, e): if e.is_Rational and self.is_number: from sympy.core.evalf import pure_complex from sympy.core.mul import _unevaluated_Mul from sympy.core.exprtools import factor_terms from sympy.core.function import expand_multinomial from sympy.functions.elementary.complexes import sign from sympy.functions.elementary.miscellaneous import sqrt ri = pure_complex(self) if ri: r, i = ri if e.q == 2: D = sqrt(r**2 + i**2) if D.is_Rational: # (r, i, D) is a Pythagorean triple root = sqrt(factor_terms((D - r) / 2))**e.p return root * expand_multinomial(( # principle value (D + r) / abs(i) + sign(i) * S.ImaginaryUnit)**e.p) elif e == -1: return _unevaluated_Mul(r - i * S.ImaginaryUnit, 1 / (r**2 + i**2)) elif e.is_Number and abs(e) != 1: # handle the Float case: (2.0 + 4*x)**e -> 4**e*(0.5 + x)**e c, m = zip(*[i.as_coeff_Mul() for i in self.args]) if any(i.is_Float for i in c): # XXX should this always be done? big = -1 for i in c: if abs(i) >= big: big = abs(i) if big > 0 and big != 1: from sympy.functions.elementary.complexes import sign bigs = (big, -big) c = [sign(i) if i in bigs else i / big for i in c] addpow = Add(*[c * m for c, m in zip(c, m)])**e return big**e * addpow
def _eval_power(self, e): if e.is_Rational and self.is_number: from sympy.core.evalf import pure_complex from sympy.core.mul import _unevaluated_Mul from sympy.core.exprtools import factor_terms from sympy.core.function import expand_multinomial from sympy.functions.elementary.complexes import sign from sympy.functions.elementary.miscellaneous import sqrt ri = pure_complex(self) if ri: r, i = ri if e.q == 2: D = sqrt(r**2 + i**2) if D.is_Rational: # (r, i, D) is a Pythagorean triple root = sqrt(factor_terms((D - r)/2))**e.p return root*expand_multinomial(( # principle value (D + r)/abs(i) + sign(i)*S.ImaginaryUnit)**e.p) elif e == -1: return _unevaluated_Mul( r - i*S.ImaginaryUnit, 1/(r**2 + i**2))
def _eval_power(self, e): if e.is_Rational and self.is_number: from sympy.core.evalf import pure_complex from sympy.core.mul import _unevaluated_Mul from sympy.core.exprtools import factor_terms from sympy.core.function import expand_multinomial from sympy.functions.elementary.complexes import sign from sympy.functions.elementary.miscellaneous import sqrt ri = pure_complex(self) if ri: r, i = ri if e.q == 2: D = sqrt(r**2 + i**2) if D.is_Rational: # (r, i, D) is a Pythagorean triple root = sqrt(factor_terms((D - r) / 2))**e.p return root * expand_multinomial(( # principle value (D + r) / abs(i) + sign(i) * S.ImaginaryUnit)**e.p) elif e == -1: return _unevaluated_Mul(r - i * S.ImaginaryUnit, 1 / (r**2 + i**2)) elif e.is_Number and abs(e) != 1: # handle the Float case: (2.0 + 4*x)**e -> 2.**e*(1 + 2.0*x)**e c, m = zip(*[i.as_coeff_Mul() for i in self.args]) big = 0 float = False s = dict() for i in c: float = float or i.is_Float if abs(i) >= big: big = 1.0 * abs(i) s[i] = -1 if i < 0 else 1 if float and big and big != 1: addpow = Add(*[(s[c[i]] if abs(c[i]) == big else c[i] / big) * m[i] for i in range(len(c))])**e return big**e * addpow
def _construct_simple(coeffs, opt): """Handle simple domains, e.g.: ZZ, QQ, RR and algebraic domains. """ rationals = reals = gaussians = algebraics = False if opt.extension is True: is_algebraic = lambda coeff: coeff.is_number and coeff.is_algebraic else: is_algebraic = lambda coeff: False for coeff in coeffs: if coeff.is_Rational: if not coeff.is_Integer: rationals = True elif coeff.is_Float: if algebraics or gaussians: # there are both reals and algebraics -> EX return False else: reals = True else: is_complex = pure_complex(coeff) if is_complex: # there are both reals and algebraics -> EX if reals: return False x, y = is_complex if x.is_Rational and y.is_Rational: gaussians = True if not (x.is_Integer and y.is_Integer): rationals = True continue if is_algebraic(coeff): if not reals: algebraics = True else: # there are both algebraics and reals -> EX return False else: # this is a composite domain, e.g. ZZ[X], EX return None if algebraics: domain, result = _construct_algebraic(coeffs, opt) else: if reals: # Use the maximum precision of all coefficients for the RR's # precision max_prec = max([c._prec for c in coeffs]) domain = RealField(prec=max_prec) else: if opt.field or rationals: domain = QQ_I if gaussians else QQ else: domain = ZZ_I if gaussians else ZZ result = [] for coeff in coeffs: result.append(domain.from_sympy(coeff)) return domain, result
def _construct_composite(coeffs, opt): """Handle composite domains, e.g.: ZZ[X], QQ[X], ZZ(X), QQ(X). """ numers, denoms = [], [] for coeff in coeffs: numer, denom = coeff.as_numer_denom() numers.append(numer) denoms.append(denom) polys, gens = parallel_dict_from_basic(numers + denoms) # XXX: sorting if not gens: return None if opt.composite is None: if any(gen.is_number and gen.is_algebraic for gen in gens): return None # generators are number-like so lets better use EX all_symbols = set([]) for gen in gens: symbols = gen.free_symbols if all_symbols & symbols: return None # there could be algebraic relations between generators else: all_symbols |= symbols n = len(gens) k = len(polys)//2 numers = polys[:k] denoms = polys[k:] if opt.field: fractions = True else: fractions, zeros = False, (0,)*n for denom in denoms: if len(denom) > 1 or zeros not in denom: fractions = True break coeffs = set([]) if not fractions: for numer, denom in zip(numers, denoms): denom = denom[zeros] for monom, coeff in numer.items(): coeff /= denom coeffs.add(coeff) numer[monom] = coeff else: for numer, denom in zip(numers, denoms): coeffs.update(list(numer.values())) coeffs.update(list(denom.values())) rationals = reals = gaussians = False for coeff in coeffs: if coeff.is_Rational: if not coeff.is_Integer: rationals = True elif coeff.is_Float: reals = True break else: is_complex = pure_complex(coeff) if is_complex is not None: x, y = is_complex if x.is_Rational and y.is_Rational: if not (x.is_Integer and y.is_Integer): rationals = True gaussians = True else: pass # XXX: CC? if reals: max_prec = max([c._prec for c in coeffs]) ground = RealField(prec=max_prec) elif gaussians: if rationals: ground = QQ_I else: ground = ZZ_I elif rationals: ground = QQ else: ground = ZZ result = [] if not fractions: domain = ground.poly_ring(*gens) for numer in numers: for monom, coeff in numer.items(): numer[monom] = ground.from_sympy(coeff) result.append(domain(numer)) else: domain = ground.frac_field(*gens) for numer, denom in zip(numers, denoms): for monom, coeff in numer.items(): numer[monom] = ground.from_sympy(coeff) for monom, coeff in denom.items(): denom[monom] = ground.from_sympy(coeff) result.append(domain((numer, denom))) return domain, result
def _construct_simple(coeffs, opt): """Handle simple domains, e.g.: ZZ, QQ, RR and algebraic domains. """ rationals = floats = complexes = algebraics = False float_numbers = [] if opt.extension is True: is_algebraic = lambda coeff: coeff.is_number and coeff.is_algebraic else: is_algebraic = lambda coeff: False for coeff in coeffs: if coeff.is_Rational: if not coeff.is_Integer: rationals = True elif coeff.is_Float: if algebraics: # there are both reals and algebraics -> EX return False else: floats = True float_numbers.append(coeff) else: is_complex = pure_complex(coeff) if is_complex: complexes = True x, y = is_complex if x.is_Rational and y.is_Rational: if not (x.is_Integer and y.is_Integer): rationals = True continue else: floats = True if x.is_Float: float_numbers.append(x) if y.is_Float: float_numbers.append(y) elif is_algebraic(coeff): if floats: # there are both algebraics and reals -> EX return False algebraics = True else: # this is a composite domain, e.g. ZZ[X], EX return None # Use the maximum precision of all coefficients for the RR or CC # precision max_prec = max(c._prec for c in float_numbers) if float_numbers else 53 if algebraics: domain, result = _construct_algebraic(coeffs, opt) else: if floats and complexes: domain = ComplexField(prec=max_prec) elif floats: domain = RealField(prec=max_prec) elif rationals or opt.field: domain = QQ_I if complexes else QQ else: domain = ZZ_I if complexes else ZZ result = [domain.from_sympy(coeff) for coeff in coeffs] return domain, result