I am mystified as to why a minus sign changes bottom_up behavior when applying evalf.
(I have modified bottom_up only by getting rid of the condition "if args != rv.args:" as otherwise it won't evalf integers. See below)
With the function
def initial_evalf(w):
try:
return w.evalf()
except:
return w
With a plus sign, the constant factor e^(1) is evaluated as a float.
In [47]: bottom_up(sympify("1+exp(3*z+1)"), initial_evalf, atoms=True)
Out[47]: 2.71828182845905*exp(3.0*z) + 1.0
With a minus sign, the constant factor stays as e^(1.0).
In [48]: bottom_up(sympify("1-exp(3*z+1)"), initial_evalf, atoms=True)
Out[48]: -1.0*exp(3.0*z + 1.0) + 1.0
I can't figure out what is making the difference. I'm trying to normalize expressions to be the same format, but I haven't figured out how to get the same behavior here.
Thanks,
Duane
Here's my modification of bottom_up with the one condition deleted:
def bottom_up(rv, F, atoms=False, nonbasic=False):
"""Apply ``F`` to all expressions in an expression tree from the
bottom up. If ``atoms`` is True, apply ``F`` even if there are no args;
if ``nonbasic`` is True, try to apply ``F`` to non-Basic objects.
"""
try:
if rv.args:
args = tuple([bottom_up(a, F, atoms, nonbasic)
for a in rv.args])
rv = rv.func(*args)
rv = F(rv)
elif atoms:
rv = F(rv)
except AttributeError:
if nonbasic:
try:
rv = F(rv)
except TypeError:
pass
return rv