示例#1
0
 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))
示例#2
0
文件: add.py 项目: msgoff/sympy
    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
示例#3
0
文件: add.py 项目: aprasanna/sympy
 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))
示例#4
0
 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
示例#5
0
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
示例#6
0
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
示例#7
0
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