def mrv_inflimit(expr, x, _cache = {}): if _cache.has_key((expr, x)): raise RuntimeError('Detected recursion while computing mrv_inflimit(%s, %s)' % (expr, x)) _cache[(expr, x)] = 1 expr_map = {} mrv_map = {} newexpr = mrv2(expr, x, expr_map, mrv_map) if mrv_map.has_key(x): t = Basic.Temporary(unbounded=True, positive=True) r = mrv_inflimit(expr.subs(Basic.log(x), t).subs(x, Basic.exp(t)).subs(t, x), x) del _cache[(expr, x)] return r w = Basic.Symbol('w_0',dummy=True, positive=True, infinitesimal=True) germ, new_mrv_map = rewrite_mrv_map(mrv_map, x, w) new_expr = rewrite_expr(newexpr, germ, new_mrv_map, w) lt = new_expr.as_leading_term(w) if germ is not None: lt = lt.subs(Basic.log(w), -germ[0]) c,e = lt.as_coeff_exponent(w) assert not c.has(w),`c` if e==0: r = c.inflimit(x) del _cache[(expr, x)] return r if e.is_positive: del _cache[(expr, x)] return S.Zero if e.is_negative: del _cache[(expr, x)] return Basic.sign(c) * S.Infinity raise RuntimeError('Failed to compute mrv_inflimit(%s, %s), got lt=%s' % (self, x, lt))
def __new__(cls, expr, x): expr = orig_expr = Basic.sympify(expr) orig_x = Basic.sympify(x) assert isinstance(orig_x,Basic.Symbol),`orig_x` # handle trivial results if orig_expr==orig_x: return S.Infinity elif not orig_expr.has(orig_x): return orig_expr x = InfLimit.limit_process_symbol() if not orig_expr.has(x): expr = orig_expr.subs(orig_x, x) elif orig_x==x: expr = orig_expr else: x = Basic.Symbol(orig_x.name + '_oo', dummy=True, unbounded=True, positive=True) expr = orig_expr.subs(orig_x, x) result = None if hasattr(expr,'_eval_inflimit'): # support for callbacks result = getattr(expr,'_eval_inflimit')(x) elif isinstance(expr, Basic.Add): result, factors = expr.as_coeff_factors(x) for f in factors: result += f.inflimit(x) if isinstance(result, Basic.NaN): result = None break elif isinstance(expr, Basic.Mul): result, terms = expr.as_coeff_terms(x) for t in terms: result *= t.inflimit(x) if isinstance(result, Basic.NaN): result = None break elif isinstance(expr, Basic.Pow): if not expr.exp.has(x): result = expr.base.inflimit(x) ** expr.exp elif not expr.base.has(x): result = expr.base ** expr.exp.inflimit(x) else: result = Basic.exp(expr.exp * Basic.log(expr.base)).inflimit(x) elif isinstance(expr, Basic.Function): # warning: assume that # lim_x f(g1(x),g2(x),..) = f(lim_x g1(x), lim_x g2(x)) # if this is incorrect, one must define f._eval_inflimit(x) method result = expr.func(*[a.inflimit(x) for a in expr]) if result is None: result = mrv_inflimit(expr, x) return result