-
-
Notifications
You must be signed in to change notification settings - Fork 4.8k
Open
Labels
Description
I'm trying to remove the dependency of the plotting module from experimental_lambdify
in favor of lambdify
. Unfortunately, it doesn't appear to be that simple when interval arithmetic is involved (used by plot_implicit
when adaptive=True
). Let's look at the following examples.
Correct result when using experimental_lambdify
from sympy import *
from sympy.plotting.experimental_lambdify import experimental_lambdify
from sympy.plotting.intervalmath import interval
var("x, y")
expr = Eq(y, sin(x)) & (y > 0)
f1 = experimental_lambdify((x, y), expr, use_interval=True)
xi, yi = interval(-4.999996, -4.687508), interval(-0.312501, 0.000005)
f1(xi, yi)
# Output: intervalMembership(False, True)
Wrong result when using lambdify
import sympy.plotting.intervalmath.lib_interval as li
# use the interval math functions with lambdify
keys = [t for t in dir(li) if ("__" not in t) and (t not in ["import_module", "interval"])]
vals = [getattr(li, k) for k in keys]
d = {k: v for k, v in zip(keys, vals)}
f2 = lambdify((x, y), expr, modules=d)
f2(xi, yi)
# Output: intervalMembership(None, True)
Debugging
Let's inspect the two functions:
print(f1.eval_str)
# Output: lambda x0, x1 : ( (x1 > 0) & (lambda x, y: x == y)(x1, imath.sin(x0)) )
Note the use of the operator &
.
import inspect
print(inspect.getsource(f2))
# Output:
# def _lambdifygenerated(x, y):
# return (y == sin(x)) and (y > 0)
Note the use of the operator and
.
Obviously, by modifying the second function to use &
we will get the correct result:
def func(x, y):
return (y == li.sin(x)) & (y > 0)
func(xi, yi)
# Output: intervalMembership(False, True)
Question
Is it possible to ask lambdify
to use &
instead of and
?