Skip to content

lambdify - differences between and and & #23010

@Davide-sd

Description

@Davide-sd

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?

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions