Esempio n. 1
0
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))
Esempio n. 2
0
def mrv2(expr, x, d, md):
    """
    Compute a set of most rapidly varying subexpressions of expr with respect to x.

    d = {}
    md = {}
    mrv2(x + exp(x),x,d) -> x+se, d={x:x, exp(x):se}, md={exp(x):se}
    """
    if d.has_key(expr): return d[expr]
    if not expr.has(x):
        return expr
    if expr==x:
        if not md: md[x] = x
        return x
    if isinstance(expr, (Basic.Add, Basic.Mul)):
        r = expr.__class__(*[mrv2(t, x, d, md) for t in expr])
        d[expr] = r
        return r
    log = Basic.log
    exp = Basic.exp
    if isinstance(expr, Basic.Pow):
        if not expr.exp.has(x):
            r = mrv2(expr.base, x, d, md)**expr.exp
        else:
            r = mrv2(exp(expr.exp * log(expr.base)), x, d, md)
        d[expr] = r
        return r
    if isinstance(expr, Basic.exp):
        e = expr[0]
        l = e.inflimit(x)
        r = exp(mrv2(e, x, d, md))
        if isinstance(l, Basic.Infinity):
            # e -> oo as x->oo
            en = e
        elif isinstance(l, Basic.NegativeInfinity):
            # e -> -oo as x->oo
            # rewrite to ensure that exp(e) -> oo
            en = -e
        else:
            # |e| < oo as x->oo
            d[expr] = r
            return r
        # normalize exp(2*e) -> exp(e)
        coeff, terms = en.as_coeff_terms()
        new_terms = []
        for t in terms:
            if t.has(x):
                pass
            elif t.is_positive:
                continue
            elif t.is_negative:
                coeff *= -1
                continue
            new_terms.append(t)
        terms = new_terms
        coeff = Basic.sign(coeff)
        if not isinstance(coeff, Basic.One):
            terms.insert(0,coeff)
        en = Basic.Mul(*terms)
        nexpr = exp(en)
        #print coeff,terms,nexpr
        if md.has_key(x):
            c = '>'
        else:
            lst = md.keys()
            lst.sort(cmp_ops_count)
            c = mrv_compare(nexpr, lst[0], x)
        if c !='<':
            if c=='>':
                md.clear()
            if md.has_key(nexpr):
                tmp = md[nexpr]
            else:
                tmp = Basic.Temporary()
                md[nexpr] = tmp
            r = expr.subs(nexpr, tmp)
        d[expr] = r
        return r
    if isinstance(expr, Basic.Function):
        r = expr.func(*[mrv2(a, x, d, md) for a in expr])
        d[expr] = r
        return r
    raise NotImplementedError("don't know how to find mrv2(%s,%s)" % (expr,x))