Skip to content

Commit 1cfb65c

Browse files
committed
Minor changes in import and code structuring
1 parent e133b0a commit 1cfb65c

File tree

1 file changed

+49
-18
lines changed

1 file changed

+49
-18
lines changed

integration_tests/gruntz_demo.py

Lines changed: 49 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -118,14 +118,14 @@
118118
"""
119119
from functools import reduce
120120

121-
from sympy.core import Basic, S, Mul, PoleError, expand_mul
121+
from sympy.core import Basic, S, Mul, PoleError, expand_mul, evaluate
122122
from sympy.core.cache import cacheit
123-
from sympy.core.intfunc import ilcm
124123
from sympy.core.numbers import I, oo
125-
from sympy.core.symbol import Dummy, Wild
124+
from sympy.core.symbol import Dummy, Wild, Symbol
126125
from sympy.core.traversal import bottom_up
126+
from sympy.core.sorting import ordered
127127

128-
from sympy.functions import log, exp, sign as _sign
128+
from sympy.functions import log, exp, sign, sin
129129
from sympy.series.order import Order
130130
from sympy.utilities.exceptions import SymPyDeprecationWarning
131131
from sympy.utilities.misc import debug_decorator as debug
@@ -142,7 +142,6 @@ def mrv(e, x):
142142
{x}
143143
144144
"""
145-
from ..functions import log
146145

147146
if not e.has(x):
148147
return set()
@@ -151,7 +150,7 @@ def mrv(e, x):
151150
if e.is_Mul or e.is_Add:
152151
a, b = e.as_two_terms()
153152
return mrv_max(mrv(a, x), mrv(b, x), x)
154-
if e.is_Exp:
153+
if e.func == exp:
155154
if e.exp == x:
156155
return {e}
157156
if any(a.is_infinite for a in Mul.make_args(limitinf(e.exp, x))):
@@ -161,11 +160,41 @@ def mrv(e, x):
161160
return mrv(e.base, x)
162161
if isinstance(e, log):
163162
return mrv(e.args[0], x)
164-
if e.is_Function and not isinstance(e.func, UndefinedFunction):
165-
return functools.reduce(lambda a, b: mrv_max(a, b, x),
166-
(mrv(a, x) for a in e.args))
163+
if e.is_Function:
164+
return reduce(lambda a, b: mrv_max(a, b, x), (mrv(a, x) for a in e.args))
167165
raise NotImplementedError(f"Can't calculate the MRV of {e}.")
168166

167+
def mrv_max(f, g, x):
168+
"""Compute the maximum of two MRV sets.
169+
170+
Examples
171+
========
172+
173+
>>> mrv_max({log(x)}, {x**5}, x)
174+
{x**5}
175+
176+
"""
177+
178+
if not f:
179+
return g
180+
if not g:
181+
return f
182+
if f & g:
183+
return f | g
184+
185+
a, b = map(next, map(iter, (f, g)))
186+
187+
# The log(exp(...)) must always be simplified here.
188+
la = a.exp if a.is_Exp else log(a)
189+
lb = b.exp if b.is_Exp else log(b)
190+
191+
c = limitinf(la/lb, x)
192+
if c.is_zero:
193+
return g
194+
if c.is_infinite:
195+
return f
196+
return f | g
197+
169198
def rewrite(e, x, w):
170199
r"""
171200
Rewrites the expression in terms of the MRV subexpression.
@@ -194,7 +223,6 @@ def rewrite(e, x, w):
194223
(log(x)/y, -x)
195224
196225
"""
197-
from ..functions import exp
198226

199227
Omega = mrv(e, x)
200228
if not Omega:
@@ -245,25 +273,24 @@ def mrv_leadterm(e, x):
245273
(-1, 0)
246274
247275
"""
248-
from ..functions import exp, log
249276

250277
if not e.has(x):
251278
return e, Integer(0)
252279

253280
# Rewrite to exp-log functions per Sec. 3.3 of thesis.
254281
e = e.replace(lambda f: f.is_Pow and f.exp.has(x),
255282
lambda f: exp(log(f.base)*f.exp))
256-
e = e.replace(lambda f: f.is_Mul and sum(a.is_Exp for a in f.args) > 1,
257-
lambda f: Mul(exp(Add(*(a.exp for a in f.args if a.is_Exp))),
258-
*(a for a in f.args if not a.is_Exp)))
283+
e = e.replace(lambda f: f.is_Mul and sum(a.func == exp for a in f.args) > 1,
284+
lambda f: Mul(exp(Add(*(a.exp for a in f.args if a.func == exp))),
285+
*(a for a in f.args if not a.func == exp)))
259286

260287
# The positive dummy, w, is used here so log(w*2) etc. will expand.
261288
# TODO: For limits of complex functions, the algorithm would have to
262289
# be improved, or just find limits of Re and Im components separately.
263290
w = Dummy('w', real=True, positive=True)
264291
e, logw = rewrite(e, x, w)
265292

266-
c0, e0 = f.leadterm(w, logx=logw)
293+
c0, e0 = e.leadterm(w, logx=logw)
267294
if c0.has(w):
268295
raise NotImplementedError(f'Cannot compute leadterm({e}, {x}). '
269296
'The coefficient should have been free of '
@@ -283,12 +310,11 @@ def signinf(e, x):
283310
large and zero if `e` is *constantly* zero for `x\to\infty`.
284311
285312
"""
286-
from ..functions import sign
287313

288314
if not e.has(x):
289315
return sign(e).simplify()
290316
if e == x or (e.is_Pow and signinf(e.base, x) == 1):
291-
return Integer(1)
317+
return S(1)
292318
if e.is_Mul:
293319
a, b = e.as_two_terms()
294320
return signinf(a, x)*signinf(b, x)
@@ -365,4 +391,9 @@ def gruntz(e, z, z0, dir="+"):
365391
# tractable functions in terms of familiar intractable ones.
366392
# It might be nicer to rewrite the exactly to what they were initially,
367393
# but that would take some work to implement.
368-
return r.rewrite('intractable', deep=True)
394+
return r.rewrite('intractable', deep=True)
395+
396+
# tests
397+
x = Symbol('x')
398+
ans = gruntz(sin(x)/x, x, 0)
399+
print(ans)

0 commit comments

Comments
 (0)