Пример #1
0
def evalf_log(expr, prec, options):
    arg = expr.args[0]
    workprec = prec + 10
    xre, xim, xacc, _ = evalf(arg, workprec, options)

    if xim:
        # XXX: use get_abs etc instead
        re = evalf_log(C.log(C.Abs(arg, evaluate=False), evaluate=False), prec, options)
        im = mpf_atan2(xim, xre or fzero, prec)
        return re[0], im, re[2], prec

    imaginary_term = mpf_cmp(xre, fzero) < 0

    re = mpf_log(mpf_abs(xre), prec, rnd)
    size = fastlog(re)
    if prec - size > workprec:
        # We actually need to compute 1+x accurately, not x
        arg = C.Add(S.NegativeOne, arg, evaluate=False)
        xre, xim, _, _ = evalf_add(arg, prec, options)
        prec2 = workprec - fastlog(xre)
        re = mpf_log(mpf_add(xre, fone, prec2), prec, rnd)

    re_acc = prec

    if imaginary_term:
        return re, mpf_pi(prec), re_acc, prec
    else:
        return re, None, re_acc, None
Пример #2
0
 def _eval_is_real(self):
     real_b = self.base.is_real
     if real_b is None: return
     real_e = self.exp.is_real
     if real_e is None: return
     if real_b and real_e:
         if self.base.is_positive:
             return True
         else:  # negative or zero (or positive)
             if self.exp.is_integer:
                 return True
             elif self.base.is_negative:
                 if self.exp.is_Rational:
                     return False
     im_b = self.base.is_imaginary
     im_e = self.exp.is_imaginary
     if im_b:
         if self.exp.is_integer:
             if self.exp.is_even:
                 return True
             elif self.exp.is_odd:
                 return False
         elif (self.exp in [S.ImaginaryUnit, -S.ImaginaryUnit]
               and self.base in [S.ImaginaryUnit, -S.ImaginaryUnit]):
             return True
     if real_b and im_e:
         c = self.exp.coeff(S.ImaginaryUnit)
         if c:
             ok = (c * C.log(self.base) / S.Pi).is_Integer
             if ok is not None:
                 return ok
Пример #3
0
 def _eval_subs(self, old, new):
     if old.func is self.func and self.base == old.base:
         coeff1, terms1 = self.exp.as_independent(C.Symbol, as_Add=False)
         coeff2, terms2 = old.exp.as_independent(C.Symbol, as_Add=False)
         if terms1 == terms2:
             pow = coeff1/coeff2
             ok = False  # True if int(pow) == pow OR self.base.is_positive
             try:
                 pow = as_int(pow)
                 ok = True
             except ValueError:
                 ok = self.base.is_positive
             if ok:
                 # issue 2081
                 return Pow(new, pow)  # (x**(6*y)).subs(x**(3*y),z)->z**2
     if old.func is C.exp and self.exp.is_real and self.base.is_positive:
         coeff1, terms1 = old.args[0].as_independent(C.Symbol, as_Add=False)
         # we can only do this when the base is positive AND the exponent
         # is real
         coeff2, terms2 = (self.exp*C.log(self.base)).as_independent(
             C.Symbol, as_Add=False)
         if terms1 == terms2:
             pow = coeff1/coeff2
             if pow == int(pow) or self.base.is_positive:
                 return Pow(new, pow)  # (2**x).subs(exp(x*log(2)), z) -> z
Пример #4
0
 def _eval_subs(self, old, new):
     if old.func is self.func and self.base == old.base:
         coeff1, terms1 = self.exp.as_independent(C.Symbol, as_Add=False)
         coeff2, terms2 = old.exp.as_independent(C.Symbol, as_Add=False)
         if terms1 == terms2:
             pow = coeff1/coeff2
             ok = False  # True if int(pow) == pow OR self.base.is_positive
             try:
                 pow = as_int(pow)
                 ok = True
             except ValueError:
                 ok = self.base.is_positive
             if ok:
                 # issue 2081
                 return Pow(new, pow)  # (x**(6*y)).subs(x**(3*y),z)->z**2
     if old.func is C.exp and self.exp.is_real and self.base.is_positive:
         coeff1, terms1 = old.args[0].as_independent(C.Symbol, as_Add=False)
         # we can only do this when the base is positive AND the exponent
         # is real
         coeff2, terms2 = (self.exp*C.log(self.base)).as_independent(
             C.Symbol, as_Add=False)
         if terms1 == terms2:
             pow = coeff1/coeff2
             if pow == int(pow) or self.base.is_positive:
                 return Pow(new, pow)  # (2**x).subs(exp(x*log(2)), z) -> z
Пример #5
0
 def _eval_is_real(self):
     real_b = self.base.is_real
     if real_b is None: return
     real_e = self.exp.is_real
     if real_e is None: return
     if real_b and real_e:
         if self.base.is_positive:
             return True
         else:   # negative or zero (or positive)
             if self.exp.is_integer:
                 return True
             elif self.base.is_negative:
                 if self.exp.is_Rational:
                     return False
     im_b = self.base.is_imaginary
     im_e = self.exp.is_imaginary
     if im_b:
         if self.exp.is_integer:
             if self.exp.is_even:
                 return True
             elif self.exp.is_odd:
                 return False
         elif (self.exp in [S.ImaginaryUnit, -S.ImaginaryUnit] and
               self.base in [S.ImaginaryUnit, -S.ImaginaryUnit]):
             return True
     if real_b and im_e:
         c = self.exp.coeff(S.ImaginaryUnit)
         if c:
             ok = (c*C.log(self.base)/S.Pi).is_Integer
             if ok is not None:
                 return ok
Пример #6
0
def evalf_log(expr, prec, options):
    arg = expr.args[0]
    workprec = prec + 10
    xre, xim, xacc, _ = evalf(arg, workprec, options)

    if xim:
        # XXX: use get_abs etc instead
        re = evalf_log(C.log(C.Abs(arg, evaluate=False), evaluate=False), prec,
                       options)
        im = mpf_atan2(xim, xre or fzero, prec)
        return re[0], im, re[2], prec

    imaginary_term = (mpf_cmp(xre, fzero) < 0)

    re = mpf_log(mpf_abs(xre), prec, round_nearest)
    size = fastlog(re)
    if prec - size > workprec:
        # We actually need to compute 1+x accurately, not x
        arg = C.Add(S.NegativeOne, arg, evaluate=False)
        xre, xim, xre_acc, xim_acc = evalf_add(arg, prec, options)
        prec2 = workprec - fastlog(xre)
        re = mpf_log(mpf_add(xre, fone, prec2), prec, round_nearest)

    re_acc = prec

    if imaginary_term:
        return re, mpf_pi(prec), re_acc, prec
    else:
        return re, None, re_acc, None
Пример #7
0
 def _eval_subs(self, old, new):
     if old.func is self.func and self.base == old.base:
         coeff1, terms1 = self.exp.as_coeff_Mul()
         coeff2, terms2 = old.exp.as_coeff_Mul()
         if terms1 == terms2:
             pow = coeff1 / coeff2
             if pow == int(pow) or self.base.is_positive:
                 # issue 2081
                 return Pow(new, pow)  # (x**(6*y)).subs(x**(3*y),z)->z**2
     if old.func is C.exp and self.exp.is_real and self.base.is_positive:
         coeff1, terms1 = old.args[0].as_coeff_Mul()
         # we can only do this when the base is positive AND the exponent
         # is real
         coeff2, terms2 = (self.exp * C.log(self.base)).as_coeff_Mul()
         if terms1 == terms2:
             pow = coeff1 / coeff2
             if pow == int(pow) or self.base.is_positive:
                 return Pow(new, pow)  # (2**x).subs(exp(x*log(2)), z) -> z
Пример #8
0
 def _eval_subs(self, old, new):
     if self == old:
         return new
     if old.func is self.func and self.base == old.base:
         coeff1, terms1 = self.exp.as_coeff_mul()
         coeff2, terms2 = old.exp.as_coeff_mul()
         if terms1 == terms2:
             pow = coeff1/coeff2
             if pow.is_Integer or self.base.is_commutative:
                 return Pow(new, pow) # (x**(2*y)).subs(x**(3*y),z) -> z**(2/3)
     if old.func is C.exp:
         coeff1, terms1 = old.args[0].as_coeff_mul()
         coeff2, terms2 = (self.exp*C.log(self.base)).as_coeff_mul()
         if terms1 == terms2:
             pow = coeff1/coeff2
             if pow.is_Integer or self.base.is_commutative:
                 return Pow(new, pow) # (x**(2*y)).subs(x**(3*y),z) -> z**(2/3)
     return Pow(self.base._eval_subs(old, new), self.exp._eval_subs(old, new))
Пример #9
0
 def _eval_subs(self, old, new):
     if old.func is self.func and self.base == old.base:
         coeff1, terms1 = self.exp.as_coeff_Mul()
         coeff2, terms2 = old.exp.as_coeff_Mul()
         if terms1 == terms2:
             pow = coeff1/coeff2
             if pow == int(pow) or self.base.is_positive:
                 # issue 2081
                 return Pow(new, pow) # (x**(6*y)).subs(x**(3*y),z)->z**2
     if old.func is C.exp and self.exp.is_real and self.base.is_positive:
         coeff1, terms1 = old.args[0].as_coeff_Mul()
         # we can only do this when the base is positive AND the exponent
         # is real
         coeff2, terms2 = (self.exp*C.log(self.base)).as_coeff_Mul()
         if terms1 == terms2:
             pow = coeff1/coeff2
             if pow == int(pow) or self.base.is_positive:
                 return Pow(new, pow) # (2**x).subs(exp(x*log(2)), z) -> z
Пример #10
0
 def _eval_subs(self, old, new):
     if self == old:
         return new
     if old.func is self.func and self.base == old.base:
         coeff1, terms1 = self.exp.as_coeff_mul()
         coeff2, terms2 = old.exp.as_coeff_mul()
         if terms1 == terms2:
             pow = coeff1/coeff2
             if pow.is_Integer or self.base.is_commutative:
                 return Pow(new, pow) # (x**(2*y)).subs(x**(3*y),z) -> z**(2/3)
     if old.func is C.exp:
         coeff1, terms1 = old.args[0].as_coeff_mul()
         coeff2, terms2 = (self.exp*C.log(self.base)).as_coeff_mul()
         if terms1 == terms2:
             pow = coeff1/coeff2
             if pow.is_Integer or self.base.is_commutative:
                 return Pow(new, pow) # (x**(2*y)).subs(x**(3*y),z) -> z**(2/3)
     return Pow(self.base._eval_subs(old, new), self.exp._eval_subs(old, new))
Пример #11
0
 def _eval_subs(self, old, new):
     if self == old:
         return new
     if old.func is self.func and self.base == old.base:
         coeff1, terms1 = self.exp.as_coeff_mul()
         coeff2, terms2 = old.exp.as_coeff_mul()
         if terms1 == terms2:
             pow = coeff1/coeff2
             if pow.is_Integer or self.base.is_commutative:
                 return Pow(new, pow) # (x**(2*y)).subs(x**(3*y),z) -> z**(2/3)
     if old.func is C.exp:
         coeff1, terms1 = old.args[0].as_coeff_mul()
         coeff2, terms2 = (self.exp*C.log(self.base)).as_coeff_mul()
         if terms1 == terms2:
             pow = coeff1/coeff2
             if pow.is_Integer or self.base.is_commutative:
                 return Pow(new, pow) # (x**(2*y)).subs(x**(3*y),z) -> z**(2/3)
     b, e = self.base._eval_subs(old, new), self.exp._eval_subs(old, new)
     if not b and e.is_negative: # don't let subs create an infinity
         return S.NaN
     return Pow(b, e)
Пример #12
0
 def _eval_subs(self, old, new):
     if self == old:
         return new
     if old.func is self.func and self.base == old.base:
         coeff1, terms1 = self.exp.as_coeff_mul()
         coeff2, terms2 = old.exp.as_coeff_mul()
         if terms1 == terms2:
             pow = coeff1 / coeff2
             if pow.is_Integer or self.base.is_commutative:
                 return Pow(new,
                            pow)  # (x**(2*y)).subs(x**(3*y),z) -> z**(2/3)
     if old.func is C.exp:
         coeff1, terms1 = old.args[0].as_coeff_mul()
         coeff2, terms2 = (self.exp * C.log(self.base)).as_coeff_mul()
         if terms1 == terms2:
             pow = coeff1 / coeff2
             if pow.is_Integer or self.base.is_commutative:
                 return Pow(new,
                            pow)  # (x**(2*y)).subs(x**(3*y),z) -> z**(2/3)
     b, e = self.base._eval_subs(old, new), self.exp._eval_subs(old, new)
     if not b and e.is_negative:  # don't let subs create an infinity
         return S.NaN
     return Pow(b, e)
Пример #13
0
 def _eval_as_leading_term(self, x):
     if not self.exp.has(x):
         return Pow(self.base.as_leading_term(x), self.exp)
     return C.exp(self.exp * C.log(self.base)).as_leading_term(x)
Пример #14
0
 def _eval_derivative(self, s):
     dbase = self.base.diff(s)
     dexp = self.exp.diff(s)
     return self * (dexp * C.log(self.base) + dbase * self.exp / self.base)
Пример #15
0
 def _eval_as_leading_term(self, x):
     if not self.exp.has(x):
         return Pow(self.base.as_leading_term(x), self.exp)
     return C.exp(self.exp * C.log(self.base)).as_leading_term(x)
Пример #16
0
 def _eval_derivative(self, s):
     dbase = self.base.diff(s)
     dexp = self.exp.diff(s)
     return self * (dexp * C.log(self.base) + dbase * self.exp/self.base)