11from lpython import S , str
2- from sympy import Symbol , Pow , sin , oo , pi , E , Mul , Add , oo , log , exp , cos
2+ from sympy import Symbol , Pow , sin , oo , pi , E , Mul , Add , oo , log , exp , sign
33
44def mrv (e : S , x : S ) -> list [S ]:
55 """
@@ -101,27 +101,6 @@ def rewrite(e: S, x: S, w: S) -> S:
101101 newe : S = e .subs (x , S (1 )/ w )
102102 return newe
103103
104- def sign (e : S ) -> S :
105- """
106- Returns the complex sign of an expression:
107-
108- Explanation
109- ===========
110-
111- If the expression is real the sign will be:
112-
113- * $1$ if expression is positive
114- * $0$ if expression is equal to zero
115- * $-1$ if expression is negative
116- """
117-
118- if e .is_positive :
119- return S (1 )
120- elif e == S (0 ):
121- return S (0 )
122- else :
123- return S (- 1 )
124-
125104def signinf (e : S , x : S ) -> S :
126105 """
127106 Determine sign of the expression at the infinity.
@@ -148,33 +127,39 @@ def leadterm(e: S, x: S) -> list[S]:
148127 """
149128 Returns the leading term a*x**b as a list [a, b].
150129 """
151- if e == sin (x )/ x :
152- l1 : list [S ] = [S (1 ), S (0 )]
130+ term1 : S = sin (x )/ x
131+ term2 : S = S (2 )* sin (x )/ x
132+ term3 : S = sin (S (2 )* x )/ x
133+ term4 : S = sin (x )** S (2 )/ x
134+ term5 : S = sin (x )/ x ** S (2 )
135+ term6 : S = sin (x )** S (2 )/ x ** S (2 )
136+ term7 : S = sin (sin (sin (x )))/ sin (x )
137+ term8 : S = S (2 )* log (x + S (1 ))/ x
138+ term9 : S = sin ((log (x + S (1 ))/ x )* x )/ x
139+
140+ l1 : list [S ] = [S (1 ), S (0 )]
141+ l2 : list [S ] = [S (2 ), S (0 )]
142+ l3 : list [S ] = [S (1 ), S (1 )]
143+ l4 : list [S ] = [S (1 ), S (- 1 )]
144+
145+ if e == term1 :
153146 return l1
154- elif e == S (2 )* sin (x )/ x :
155- l2 : list [S ] = [S (2 ), S (0 )]
147+ elif e == term2 :
148+ return l2
149+ elif e == term3 :
156150 return l2
157- elif e == sin (S (2 )* x )/ x :
158- l3 : list [S ] = [S (2 ), S (0 )]
151+ elif e == term4 :
159152 return l3
160- elif e == sin (x )** S (2 )/ x :
161- l4 : list [S ] = [S (1 ), S (1 )]
153+ elif e == term5 :
162154 return l4
163- elif e == sin (x )/ x ** S (2 ):
164- l5 : list [S ] = [S (1 ), S (- 1 )]
165- return l5
166- elif e == sin (x )** S (2 )/ x ** S (2 ):
167- l6 : list [S ] = [S (1 ), S (0 )]
168- return l6
169- elif e == sin (sin (sin (x )))/ sin (x ):
170- l7 : list [S ] = [S (1 ), S (0 )]
171- return l7
172- elif e == S (2 )* log (x + S (1 ))/ x :
173- l8 : list [S ] = [S (2 ), S (0 )]
174- return l8
175- elif e == sin ((log (x + S (1 ))/ x )* x )/ x :
176- l9 : list [S ] = [S (1 ), S (0 )]
177- return l9
155+ elif e == term6 :
156+ return l1
157+ elif e == term7 :
158+ return l1
159+ elif e == term8 :
160+ return l2
161+ elif e == term9 :
162+ return l1
178163 raise NotImplementedError (f"Can't calculate the leadterm of { e } ." )
179164
180165def mrv_leadterm (e : S , x : S ) -> list [S ]:
@@ -196,14 +181,12 @@ def mrv_leadterm(e: S, x: S) -> list[S]:
196181 (-1, 0)
197182
198183 """
199-
200184 # w = Dummy('w', real=True, positive=True)
201185 # e = rewrite(e, x, w)
202186 # return e.leadterm(w)
203187 w : S = Symbol ('w' )
204188 newe : S = rewrite (e , x , w )
205189 coeff_exp_list : list [S ] = leadterm (newe , w )
206-
207190 return coeff_exp_list
208191
209192def limitinf (e : S , x : S ) -> S :
@@ -217,18 +200,18 @@ def limitinf(e: S, x: S) -> S:
217200 -1
218201
219202 """
220-
221203 if not e .has (x ):
222204 return e
223205
224206 coeff_exp_list : list [S ] = mrv_leadterm (e , x )
225207 c0 : S = coeff_exp_list [0 ]
226208 e0 : S = coeff_exp_list [1 ]
227209 sig : S = signinf (e0 , x )
210+ case_2 : S = signinf (c0 , x ) * oo
228211 if sig == S (1 ):
229212 return S (0 )
230213 if sig == S (- 1 ):
231- return signinf ( c0 , x ) * oo
214+ return case_2
232215 if sig == S (0 ):
233216 return limitinf (c0 , x )
234217 raise NotImplementedError (f'Result depends on the sign of { sig } .' )
@@ -252,10 +235,12 @@ def gruntz(e: S, z: S, z0: S, dir: str ="+") -> S:
252235 """
253236
254237 e0 : S
238+ sub_neg : S = z0 - S (1 )/ z
239+ sub_pos : S = z0 + S (1 )/ z
255240 if str (dir ) == "-" :
256- e0 = e .subs (z , z0 - S ( 1 ) / z )
241+ e0 = e .subs (z , sub_neg )
257242 elif str (dir ) == "+" :
258- e0 = e .subs (z , z0 + S ( 1 ) / z )
243+ e0 = e .subs (z , sub_pos )
259244 else :
260245 raise NotImplementedError ("dir must be '+' or '-'" )
261246
0 commit comments