First time here? Check out the FAQ!

Ask Your Question
1

incorrect plot of simple defined function, but works with lambda

asked 5 years ago

holistone gravatar image

updated 5 years ago

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

Preview: (hide)

1 Answer

Sort by » oldest newest most voted
1

answered 5 years ago

Emmanuel Charpentier gravatar image

updated 5 years ago

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,

Preview: (hide)
link

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 ( 5 years ago )

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 ( 5 years ago )

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

Emmanuel Charpentier gravatar imageEmmanuel Charpentier ( 5 years ago )

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: 5 years ago

Seen: 891 times

Last updated: Nov 15 '19