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
def calc_part(expr, nexpr): nint = int(to_int(nexpr, round_nearest)) expr = C.Add(expr, -nint, evaluate=False) x, _, x_acc, _ = evalf(expr, 10, options) check_target(expr, (x, None, x_acc, None), 3) nint += int(no * (mpf_cmp(x or fzero, fzero) == no)) nint = from_int(nint) return nint, fastlog(nint) + 10
def extract_multiplicatively(self, c): """Return None if it's not possible to make self in the form c * something in a nice way, i.e. preserving the properties of arguments of self. >>> from sympy import symbols, Rational >>> x, y = symbols('xy', real=True) >>> ((x*y)**3).extract_multiplicatively(x**2 * y) x*y**2 >>> ((x*y)**3).extract_multiplicatively(x**4 * y) >>> (2*x).extract_multiplicatively(2) x >>> (2*x).extract_multiplicatively(3) >>> (Rational(1,2)*x).extract_multiplicatively(3) x/6 """ c = sympify(c) if c is S.One: return self elif c == self: return S.One elif c.is_Mul: x = self.extract_multiplicatively(c.as_two_terms()[0]) if x != None: return x.extract_multiplicatively(c.as_two_terms()[1]) quotient = self / c if self.is_Number: if self is S.Infinity: if c.is_positive: return S.Infinity elif self is S.NegativeInfinity: if c.is_negative: return S.Infinity elif c.is_positive: return S.NegativeInfinity elif self is S.ComplexInfinity: if not c.is_zero: return S.ComplexInfinity elif self is S.NaN: return S.NaN elif self.is_Integer: if not quotient.is_Integer: return None elif self.is_positive and quotient.is_negative: return None else: return quotient elif self.is_Rational: if not quotient.is_Rational: return None elif self.is_positive and quotient.is_negative: return None else: return quotient elif self.is_Real: if not quotient.is_Real: return None elif self.is_positive and quotient.is_negative: return None else: return quotient elif self.is_NumberSymbol or self.is_Symbol or self is S.ImaginaryUnit: if quotient.is_Mul and len(quotient.args) == 2: if quotient.args[0].is_Integer and quotient.args[ 0].is_positive and quotient.args[1] == self: return quotient elif quotient.is_Integer: return quotient elif self.is_Add: newargs = [] for arg in self.args: newarg = arg.extract_multiplicatively(c) if newarg != None: newargs.append(newarg) else: return None return C.Add(*newargs) elif self.is_Mul: for i in xrange(len(self.args)): newargs = list(self.args) del (newargs[i]) tmp = C.Mul(*newargs).extract_multiplicatively(c) if tmp != None: return tmp * self.args[i] elif self.is_Pow: if c.is_Pow and c.base == self.base: new_exp = self.exp.extract_additively(c.exp) if new_exp != None: return self.base**(new_exp) elif c == self.base: new_exp = self.exp.extract_additively(1) if new_exp != None: return self.base**(new_exp)