# incorrect plot of simple defined function, but works with lambda

I am trying to produce a plot of a simple defined function with a single if statement. The function works correctly as demonstrated by numerical values, but the corresponding plot is incorrect.

If I create the plot using a lambda definition of the function, the plot is correct. The sample code follows:

def h(x):
if x<0: return x
return x^2
for k in (-2..2):
print "(%d,%d)"% (k,h(k)),
print 'sample h(x) vs. x pairs'
H = plot(h(x),(-1.5,1.5),linestyle='dotted',color='red',thickness=3)
L = plot(lambda x: x if x<0 else x^2,(-1.5,1.5),figsize=3)
H+L


The following image shows the code and output in a Sagemath notebook. As you can see the plot of h(x) does not properly evaluate the function if statement, but the lambda plot does.

edit retag close merge delete

Sort by » oldest newest most voted

Another classic Sage trap...

sage: def h(x):
....:     if x<0: return x
....:     return x^2
....:


What happens ?

• h is indeed a function:

sage: h
<function h at 0x7fdd6ede8d90>

• It works:

sage: h(-1.5)
-1.50000000000000

• But ... what is h(x) ?

sage: h(x)
x^2

• But why ?

Because:

sage: x<0
x < 0


When the Python variable x is bound to the symbolic variable x, the expression x<0evaluates to itself, which is neither False nor 0. Therefore, it is logically equivalent to True, and the if... statement of h evaluates to x^2.

Now, in the call plot(h(x),(-1.5,1.5)), the first argument is evaluated as the expression x^2, which is then evaluated for all values specified by the second argument (whether this one is (-1.5, 1.5) or (x, -1.5, 1.5)).

Oppose this to plot(h, (-1.5, 1.5)), where the first argument is evaluated to a function, which is then called for all the values specified by the second argument.

This is also true in the plot(lambda x: x if x<0 else x, (-1.5, 1.5)) call, whose first argument evaluates to a function:

sage: lambda x: x if x<0 else x^2
<function <lambda> at 0x7fdd67e2b9d8>


This trap is somewhat specific to Sage, since Python does not have evaluable symbolic expressions...

HTH,

more

Interesting. Is there a list of the "classic Sage traps"?

Coming from python, I would have expected some form of error message. Especially since the symbolic evaluation of h(x) as x^2 is not really correct.

If I change the definition to

def h(x):
return x^2*(x>=0)+x*(x<0)


which returns the same values, I now get an error with

print h(x)


and this is what I would have expected with the original definition of h(x).

( 2019-11-15 15:15:07 +0100 )edit

You can see Some common issues with functions. This kind of problem also affect built-in functions. For example, the command

plot(min(sin(x),cos(x)), (x,-2*pi,2*pi))


plots the sinus function. To really obtain the minimum of sin and cos, you can do this:

plot(lambda x: min(sin(x),cos(x)), (x,-2*pi,2*pi))

( 2019-11-15 16:36:07 +0100 )edit

Yon can also plot(min_symbolic(sin(x),cos(x)),(x,0,2*pi))...

( 2019-11-15 18:49:17 +0100 )edit