[3/6] let's remove multiple inheritance (NoRelMeths)
[sympy.git] / sympy / series / limits.py
blob7104db35159f67f314430c0bbfd3ab2f3cbe849c
1 from sympy.core import S, Add, sympify, Basic
2 from sympy.core.methods import RelMeths, ArithMeths
3 from gruntz import gruntz
5 def limit(e, z, z0, dir="+"):
6 """
7 Compute the limit of e(z) at the point z0.
9 z0 can be any expression, including oo and -oo.
11 For dir="+" (default) it calculates the limit from the right
12 (z->z0+) and for dir="-" the limit from the left (z->z0-). For infinite z0
13 (oo or -oo), the dir argument doesn't matter.
15 Examples:
17 >>> limit(sin(x)/x, x, 0)
19 >>> limit(1/x, x, 0, dir="+")
21 >>> limit(1/x, x, 0, dir="-")
22 -oo
23 >>> limit(1/x, x, oo)
26 Strategy:
28 First we try some heuristics for easy and frequent cases like "x", "1/x",
29 "x**2" and similar, so that it's fast. For all other cases, we use the
30 Gruntz algorithm (see the gruntz() function).
31 """
32 e = sympify(e)
33 z = sympify(z)
34 z0 = sympify(z0)
36 if e == z:
37 return z0
39 if e.is_Rational:
40 return e
42 if e.is_Pow:
43 if e.args[0] == z:
44 if e.args[1].is_Rational:
45 if e.args[1] > 0:
46 return z0**e.args[1]
47 else:
48 if z0 == 0:
49 if dir == "+":
50 return S.Infinity
51 else:
52 return -S.Infinity
53 else:
54 return z0**e.args[1]
55 if e.args[1].is_number:
56 if e.args[1].evalf() > 0:
57 return S.Zero
58 else:
59 if dir == "+":
60 return S.Infinity
61 else:
62 return -S.Infinity
64 if e.is_Add:
65 if e.is_polynomial():
66 return Add(*[limit(term, z, z0, dir) for term in e.args])
67 else:
68 # this is a case like limit(x*y+x*z, z, 2) == x*y+2*x
69 # but we need to make sure, that the general gruntz() algorithm is
70 # executed for a case like "limit(sqrt(x+1)-sqrt(x),x,oo)==0"
71 r = e.subs(z, z0)
72 if r is not S.NaN:
73 return r
75 return gruntz(e, z, z0, dir)
77 class Limit(Basic, RelMeths, ArithMeths):
78 """Represents unevaluated limit.
80 Examples:
82 >>> Limit(sin(x)/x, x, 0)
83 Limit(1/x*sin(x), x, 0, dir='+')
84 >>> Limit(1/x, x, 0, dir="-")
85 Limit(1/x, x, 0, dir='-')
86 """
88 def __new__(cls, e, z, z0, dir="+"):
89 e = sympify(e)
90 z = sympify(z)
91 z0 = sympify(z0)
92 obj = Basic.__new__(cls)
93 obj._args = (e, z, z0, dir)
94 return obj
96 def doit(self):
97 e, z, z0, dir = self.args
98 return limit(e, z, z0, dir)