Beispiel #1
0
 def _eval_nseries(self, x, x0, n):
     assert len(self.args) == 1
     arg = self.args[0]
     arg0 = arg.limit(x, 0)
     from sympy import oo
     if arg0 in [-oo, oo]:
         raise PoleError("Cannot expand around %s" % (arg))
     if arg0 is not S.Zero:
         e = self.func(arg)
         e1 = e.expand()
         if e == e1:
             #for example when e = sin(x+1) or e = sin(cos(x))
             #let's try the general algorithm
             term = e.subs(x, S.Zero)
             series = term
             fact = S.One
             for i in range(n - 1):
                 i += 1
                 fact *= Rational(i)
                 e = e.diff(x)
                 term = e.subs(x, S.Zero) * (x**i) / fact
                 term = term.expand()
                 series += term
             return series + C.Order(x**n, x)
         return self.nseries(x, x0, n)
     l = []
     g = None
     for i in xrange(n + 2):
         g = self.taylor_term(i, arg, g)
         g = g.nseries(x, x0, n)
         l.append(g)
     return Add(*l) + C.Order(x**n, x)
Beispiel #2
0
    def extract_leading_order(self, *symbols):
        """
        Returns the leading term and it's order.

        Examples:

        >>> (x+1+1/x**5).extract_leading_order(x)
        ((1/x**5, O(1/x**5)),)
        >>> (1+x).extract_leading_order(x)
        ((1, O(1, x)),)
        >>> (x+x**2).extract_leading_order(x)
        ((x, O(x)),)
        """
        lst = []
        seq = [(f, C.Order(f, *symbols)) for f in self.args]
        for ef,of in seq:
            for e,o in lst:
                if o.contains(of) and o != of:
                    of = None
                    break
            if of is None:
                continue
            new_lst = [(ef,of)]
            for e,o in lst:
                if of.contains(o) and o != of:
                    continue
                new_lst.append((e,o))
            lst = new_lst
        return tuple(lst)
Beispiel #3
0
    def _eval_as_leading_term(self, x):
        """General method for the leading term"""
        arg = self.args[0].as_leading_term(x)

        if C.Order(1, x).contains(arg):
            return arg
        else:
            return self.func(arg)
Beispiel #4
0
 def _eval_as_leading_term(self, x):
     coeff, factors = self.as_coeff_factors(x)
     has_unbounded = bool([f for f in self.args if f.is_unbounded])
     if has_unbounded:
         if isinstance(factors, Basic):
             factors = factors.args
         factors = [f for f in factors if not f.is_bounded]
     if coeff is not S.Zero:
         o = C.Order(x)
     else:
         o = C.Order(factors[0]*x,x)
     n = 1
     s = self.nseries(x, 0, n)
     while s.is_Order:
         n +=1
         s = self.nseries(x, 0, n)
     if s.is_Add:
         s = s.removeO()
     if s.is_Add:
         lst = s.extract_leading_order(x)
         return Add(*[e for (e,f) in lst])
     return s.as_leading_term(x)
Beispiel #5
0
    def __new__(cls, *args, **assumptions):
        if assumptions.get('evaluate') is False:
            return Basic.__new__(cls, *map(_sympify, args), **assumptions)
        if len(args)==0:
            return cls.identity()
        if len(args)==1:
            return _sympify(args[0])
        c_part, nc_part, order_symbols = cls.flatten(map(_sympify, args))
        if len(c_part) + len(nc_part) <= 1:
            if c_part: obj = c_part[0]
            elif nc_part: obj = nc_part[0]
            else: obj = cls.identity()
        else:
            obj = Basic.__new__(cls, *(c_part + nc_part), **assumptions)
            obj.is_commutative = not nc_part

        if order_symbols is not None:
            obj = C.Order(obj, *order_symbols)
        return obj
Beispiel #6
0
    def _eval_nseries(self, x, x0, n):
        def geto(e):
            "Returns the O(..) symbol, or None if there is none."
            if e.is_Order:
                return e
            if e.is_Add:
                for x in e.args:
                    if x.is_Order:
                        return x

        def getn(e):
            """
            Returns the order of the expression "e".

            The order is determined either from the O(...) term. If there
            is no O(...) term, it returns None.

            Example:
            >>> getn(1+x+O(x**2))
            2
            >>> getn(1+x)
            >>>
            """
            o = geto(e)
            if o is None:
                return None
            else:
                o = o.expr
                if o.is_Symbol:
                    return Integer(1)
                if o.is_Pow:
                    return o.args[1]
                n, d = o.as_numer_denom()
                if isinstance(d, log):
                    # i.e. o = x**2/log(x)
                    if n.is_Symbol:
                        return Integer(1)
                    if n.is_Pow:
                        return n.args[1]

            raise Exception("Unimplemented")

        base, exp = self.args
        if exp.is_Integer:
            if exp > 0:
                # positive integer powers are easy to expand, e.g.:
                # sin(x)**4 = (x-x**3/3+...)**4 = ...
                return (base.nseries(x, x0, n) ** exp).expand()
            elif exp == -1:
                # this is also easy to expand using the formula:
                # 1/(1 + x) = 1 + x + x**2 + x**3 ...
                # so we need to rewrite base to the form "1+x"
                from sympy import log
                if base.has(log(x)):
                    # we need to handle the log(x) singularity:
                    assert x0 == 0
                    y = Symbol("y", dummy=True)
                    p = self.subs(log(x), -1/y)
                    if not p.has(x):
                        p = p.nseries(y, x0, n)
                        p = p.subs(y, -1/log(x))
                        return p
                base = base.nseries(x, x0, n)
                if base.has(log(x)):
                    # we need to handle the log(x) singularity:
                    assert x0 == 0
                    y = Symbol("y", dummy=True)
                    self0 = 1/base
                    p = self0.subs(log(x), -1/y)
                    if not p.has(x):
                        p = p.nseries(y, x0, n)
                        p = p.subs(y, -1/log(x))
                        return p
                prefactor = base.as_leading_term(x)
                # express "rest" as: rest = 1 + k*x**l + ... + O(x**n)
                rest = ((base-prefactor)/prefactor).expand()
                if rest == 0:
                    # if prefactor == w**4 + x**2*w**4 + 2*x*w**4, we need to
                    # factor the w**4 out using collect:
                    from sympy import collect
                    return 1/collect(prefactor, x)
                if rest.is_Order:
                    return ((1+rest)/prefactor).expand()
                if not rest.has(x):
                    return 1/(prefactor*(rest+1))
                n2 = getn(rest)
                if n2 is not None:
                    n = n2
                term2 = rest.as_leading_term(x)
                k, l = Wild("k"), Wild("l")
                r = term2.match(k*x**l)
                k, l = r[k], r[l]
                if l.is_Integer:
                    l = int(l)
                elif l.is_number:
                    l = float(l)
                else:
                    raise Exception("Not implemented")

                s = 1
                m = 1
                while l * m < n:
                    s += ((-rest)**m).expand()
                    m += 1
                r = (s/prefactor).expand()
                if n2 is None:
                    # Append O(...) because it is not included in "r"
                    from sympy import O
                    r += O(x**n)
                return r
            else:
                # negative powers are rewritten to the cases above, for example:
                # sin(x)**(-4) = 1/( sin(x)**4) = ...
                # and expand the denominator:
                denominator = (base**(-exp)).nseries(x, x0, n)
                if 1/denominator == self:
                    return self
                # now we have a type 1/f(x), that we know how to expand
                return (1/denominator).nseries(x, x0, n)

        if exp.has(x):
            import sympy
            return sympy.exp(exp*sympy.log(base)).nseries(x, x0, n)

        if base == x:
            return self

        order = C.Order(x**n, x)
        x = order.symbols[0]
        e = self.exp
        b = self.base
        ln = C.log
        exp = C.exp
        if e.has(x):
            return exp(e * ln(b)).nseries(x, x0, n)
        if b==x: return self
        b0 = b.limit(x,0)
        if b0 is S.Zero or b0.is_unbounded:
            lt = b.as_leading_term(x)
            o = order * lt**(1-e)
            bs = b.nseries(x, x0, n-e)
            if bs.is_Add:
                bs = bs.removeO()
            if bs.is_Add:
                # bs -> lt + rest -> lt * (1 + (bs/lt - 1))
                return (lt**e * ((bs/lt).expand()**e).nseries(x,
                        x0, n-e)).expand() + order
            return bs**e+order
        o2 = order * (b0**-e)
        # b -> b0 + (b-b0) -> b0 * (1 + (b/b0-1))
        z = (b/b0-1)
        #r = self._compute_oseries3(z, o2, self.taylor_term)
        x = o2.symbols[0]
        ln = C.log
        o = C.Order(z, x)
        if o is S.Zero:
            r = (1+z)
        else:
            if o.expr.is_number:
                e2 = ln(o2.expr*x)/ln(x)
            else:
                e2 = ln(o2.expr)/ln(o.expr)
            n = e2.limit(x,0) + 1
            if n.is_unbounded:
                # requested accuracy gives infinite series,
                # order is probably nonpolynomial e.g. O(exp(-1/x), x).
                r = (1+z)
            else:
                try:
                    n = int(n)
                except TypeError:
                    #well, the n is something more complicated (like 1+log(2))
                    n = int(n.evalf()) + 1
                assert n>=0,`n`
                l = []
                g = None
                for i in xrange(n+2):
                    g = self.taylor_term(i, z, g)
                    g = g.nseries(x, x0, n)
                    l.append(g)
                r = Add(*l)
        return r * b0**e + order
Beispiel #7
0
 def _eval_order(self, *symbols):
     # Order(5, x, y) -> Order(1,x,y)
     return C.Order(S.One, *symbols)