Ask Your Question
1

incorrect plot of simple defined function, but works with lambda

asked 2019-11-14 22:47:07 +0100

holistone gravatar image

updated 2019-11-15 03:49:47 +0100

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. image description

edit retag flag offensive close merge delete

1 Answer

Sort by ยป oldest newest most voted
1

answered 2019-11-15 07:10:09 +0100

Emmanuel Charpentier gravatar image

updated 2019-11-15 07:26:06 +0100

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,

edit flag offensive delete link more

Comments

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).

holistone gravatar imageholistone ( 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))
Juanjo gravatar imageJuanjo ( 2019-11-15 16:36:07 +0100 )edit

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

Emmanuel Charpentier gravatar imageEmmanuel Charpentier ( 2019-11-15 18:49:17 +0100 )edit

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

Question Tools

Stats

Asked: 2019-11-14 22:47:07 +0100

Seen: 727 times

Last updated: Nov 15 '19