# 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 +0200 )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 +0200 )edit

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

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