def _eval_nseries(self, x, n, logx):
        # NOTE Please see the comment at the beginning of this file, labelled
        #      IMPORTANT.
        from sympy import cancel
        if not logx:
            logx = log(x)
        if self.args[0] == x:
            return logx
        arg = self.args[0]
        k, l = Wild("k"), Wild("l")
        r = arg.match(k*x**l)
        if r is not None:
            #k = r.get(r, S.One)
            #l = r.get(l, S.Zero)
            k, l = r[k], r[l]
            if l != 0 and not l.has(x) and not k.has(x):
                r = log(k) + l*logx  # XXX true regardless of assumptions?
                return r

        # TODO new and probably slow
        s = self.args[0].nseries(x, n=n, logx=logx)
        while s.is_Order:
            n += 1
            s = self.args[0].nseries(x, n=n, logx=logx)
        a, b = s.leadterm(x)
        p = cancel(s/(a*x**b) - 1)
        g = None
        l = []
        for i in xrange(n + 2):
            g = log.taylor_term(i, p, g)
            g = g.nseries(x, n=n, logx=logx)
            l.append(g)
        return log(a) + b*logx + Add(*l) + C.Order(p**n, x)
Beispiel #2
0
    def _eval_nseries(self, x, n, logx, cdir=0):
        # NOTE Please see the comment at the beginning of this file, labelled
        #      IMPORTANT.
        from sympy import im, cancel, I, Order, logcombine
        if not logx:
            logx = log(x)
        if self.args[0] == x:
            return logx
        arg = self.args[0]
        k, l = Wild("k"), Wild("l")
        r = arg.match(k * x**l)
        if r is not None:
            k, l = r[k], r[l]
            if l != 0 and not l.has(x) and not k.has(x):
                r = log(k) + l * logx  # XXX true regardless of assumptions?
                return r

        # TODO new and probably slow
        try:
            a, b = arg.leadterm(x)
            s = arg.nseries(x, n=n + b, logx=logx)
        except (ValueError, NotImplementedError):
            s = arg.nseries(x, n=n, logx=logx)
            while s.is_Order:
                n += 1
                s = arg.nseries(x, n=n, logx=logx)
        a, b = s.removeO().leadterm(x)
        p = cancel(s / (a * x**b) - 1)
        if p.has(exp):
            p = logcombine(p)
        g = None
        l = []
        for i in range(n + 2):
            g = log.taylor_term(i, p, g)
            g = g.nseries(x, n=n, logx=logx)
            l.append(g)

        res = log(a) + b * logx
        if cdir != 0:
            cdir = self.args[0].dir(x, cdir)
        if a.is_real and a.is_negative and im(cdir) < 0:
            res -= 2 * I * S.Pi
        return res + Add(*l) + Order(p**n, x)
Beispiel #3
0
    def _eval_nseries(self, x, n, logx, cdir=0):
        # NOTE Please see the comment at the beginning of this file, labelled
        #      IMPORTANT.
        from sympy import im, cancel, I, Order, logcombine
        from itertools import product
        if not logx:
            logx = log(x)
        if self.args[0] == x:
            return logx
        arg = self.args[0]
        k, l = Wild("k"), Wild("l")
        r = arg.match(k * x**l)
        if r is not None:
            k, l = r[k], r[l]
            if l != 0 and not l.has(x) and not k.has(x):
                r = log(k) + l * logx  # XXX true regardless of assumptions?
                return r

        def coeff_exp(term, x):
            coeff, exp = S.One, S.Zero
            for factor in Mul.make_args(term):
                if factor.has(x):
                    base, exp = factor.as_base_exp()
                    if base != x:
                        try:
                            return term.leadterm(x)
                        except ValueError:
                            return term, S.Zero
                else:
                    coeff *= factor
            return coeff, exp

        # TODO new and probably slow
        try:
            a, b = arg.leadterm(x)
            s = arg.nseries(x, n=n + b, logx=logx)
        except (ValueError, NotImplementedError):
            s = arg.nseries(x, n=n, logx=logx)
            while s.is_Order:
                n += 1
                s = arg.nseries(x, n=n, logx=logx)
        a, b = s.removeO().leadterm(x)
        p = cancel(s / (a * x**b) - 1).expand().powsimp()
        if p.has(exp):
            p = logcombine(p)
        if isinstance(p, Order):
            n = p.getn()
        _, d = coeff_exp(p, x)
        if not d.is_positive:
            return log(a) + b * logx + Order(x**n, x)

        def mul(d1, d2):
            res = {}
            for e1, e2 in product(d1, d2):
                ex = e1 + e2
                if ex < n:
                    res[ex] = res.get(ex, S.Zero) + d1[e1] * d2[e2]
            return res

        pterms = {}

        for term in Add.make_args(p):
            co1, e1 = coeff_exp(term, x)
            pterms[e1] = pterms.get(e1, S.Zero) + co1.removeO()

        k = S.One
        terms = {}
        pk = pterms

        while k * d < n:
            coeff = -(-1)**k / k
            for ex in pk:
                terms[ex] = terms.get(ex, S.Zero) + coeff * pk[ex]
            pk = mul(pk, pterms)
            k += S.One

        res = log(a) + b * logx
        for ex in terms:
            res += terms[ex] * x**(ex)

        if cdir != 0:
            cdir = self.args[0].dir(x, cdir)
        if a.is_real and a.is_negative and im(cdir) < 0:
            res -= 2 * I * S.Pi
        return res + Order(x**n, x)
Beispiel #4
0
 def _eval_nseries(self, x, n):
     from sympy import powsimp
     arg = self.args[0]
     k, l = Wild("k"), Wild("l")
     r = arg.match(k*x**l)
     if r is not None:
         #k = r.get(r, S.One)
         #l = r.get(l, S.Zero)
         k, l = r[k], r[l]
         if l != 0 and not l.has(x) and not k.has(x):
             r = log(k) + l*log(x) # XXX true regardless of assumptions?
             return r
     order = C.Order(x**n, x)
     arg = self.args[0]
     use_lt = not C.Order(1, x).contains(arg)
     if not use_lt:
         arg0 = arg.limit(x, 0)
         use_lt = (arg0 is S.Zero)
     if use_lt: # singularity, #example: self = log(sin(x))
         # arg = (arg / lt) * lt
         lt = arg.as_leading_term(x) # arg = sin(x); lt = x
         a = powsimp((arg/lt).expand(), deep=True, combine='exp') # a = sin(x)/x
         # the idea is to recursively call log(a).series(), but one needs to
         # make sure that log(sin(x)/x) doesn't get "simplified" to
         # -log(x)+log(sin(x)) and an infinite recursion occurs, see also the
         # issue 252.
         obj = log(lt) + log(a).nseries(x, n=n)
     else:
         # arg -> arg0 + (arg - arg0) -> arg0 * (1 + (arg/arg0 - 1))
         z = (arg/arg0 - 1)
         o = C.Order(z, x)
         if o is S.Zero:
             return log(1 + z) + log(arg0)
         if o.expr.is_number:
             e = log(order.expr*x)/log(x)
         else:
             e = log(order.expr)/log(o.expr)
         n = e.limit(x, 0) + 1
         if n.is_unbounded:
             # requested accuracy gives infinite series,
             # order is probably nonpolynomial e.g. O(exp(-1/x), x).
             return log(1 + z) + log(arg0)
         # XXX was int or floor intended? int used to behave like floor
         try:
             n = int(n)
         except TypeError:
             #well, the n is something more complicated (like 1+log(2))
             n = int(n.evalf()) + 1 # XXX why is 1 being added?
         assert n>=0, `n`
         l = []
         g = None
         for i in xrange(n + 2):
             g = log.taylor_term(i, z, g)
             g = g.nseries(x, n=n)
             l.append(g)
         obj = Add(*l) + log(arg0)
     obj2 = expand_log(powsimp(obj, deep=True, combine='exp'))
     if obj2 != obj:
         r = obj2.nseries(x, n=n)
     else:
         r = obj
     if r == self:
         return self
     return r + order
Beispiel #5
0
 def _eval_nseries(self, x, n):
     from sympy import powsimp
     arg = self.args[0]
     k, l = Wild("k"), Wild("l")
     r = arg.match(k * x**l)
     if r is not None:
         #k = r.get(r, S.One)
         #l = r.get(l, S.Zero)
         k, l = r[k], r[l]
         if l != 0 and not l.has(x) and not k.has(x):
             r = log(k) + l * log(x)  # XXX true regardless of assumptions?
             return r
     order = C.Order(x**n, x)
     arg = self.args[0]
     use_lt = not C.Order(1, x).contains(arg)
     if not use_lt:
         arg0 = arg.limit(x, 0)
         use_lt = (arg0 is S.Zero)
     if use_lt:  # singularity, #example: self = log(sin(x))
         # arg = (arg / lt) * lt
         lt = arg.as_leading_term(x)  # arg = sin(x); lt = x
         a = powsimp((arg / lt).expand(), deep=True,
                     combine='exp')  # a = sin(x)/x
         # the idea is to recursively call log(a).series(), but one needs to
         # make sure that log(sin(x)/x) doesn't get "simplified" to
         # -log(x)+log(sin(x)) and an infinite recursion occurs, see also the
         # issue 252.
         obj = log(lt) + log(a).nseries(x, n=n)
     else:
         # arg -> arg0 + (arg - arg0) -> arg0 * (1 + (arg/arg0 - 1))
         z = (arg / arg0 - 1)
         o = C.Order(z, x)
         if o is S.Zero:
             return log(1 + z) + log(arg0)
         if o.expr.is_number:
             e = log(order.expr * x) / log(x)
         else:
             e = log(order.expr) / log(o.expr)
         n = e.limit(x, 0) + 1
         if n.is_unbounded:
             # requested accuracy gives infinite series,
             # order is probably nonpolynomial e.g. O(exp(-1/x), x).
             return log(1 + z) + log(arg0)
         # XXX was int or floor intended? int used to behave like floor
         try:
             n = int(n)
         except TypeError:
             #well, the n is something more complicated (like 1+log(2))
             n = int(n.evalf()) + 1  # XXX why is 1 being added?
         assert n >= 0, ` n `
         l = []
         g = None
         for i in xrange(n + 2):
             g = log.taylor_term(i, z, g)
             g = g.nseries(x, n=n)
             l.append(g)
         obj = Add(*l) + log(arg0)
     obj2 = expand_log(powsimp(obj, deep=True, combine='exp'))
     if obj2 != obj:
         r = obj2.nseries(x, n=n)
     else:
         r = obj
     if r == self:
         return self
     return r + order