Wierd behaviour of plot() and sqrt()

51 views
Skip to first unread message

Anthony Wickstead

unread,
Jul 26, 2012, 10:47:34 AM7/26/12
to sage-...@googlegroups.com
I don't think I am doing anything stupid, but I am fairly new to Sage.

I am using Sage 5.0 (Ubuntu 12.04 64 bit, running under Virtualbox) but the same behaviour occurs with Sage 4.7 running under Debian (not sure of version). I am trying to plot the graph of h(a,x) fo a range of values of a.

def h(a,x):
    if x<=a:
         return 2-sqrt(1-(1-x/a)^4)
     else:
         return sqrt(1-((x-a)/(2-a))^6)
plot(sqrt(x),(x,0,1))                            #Works fine
[h(.5,x) for x in [0..2,step=.1]]            #Returns plausible looking list
plot(h(.5,x),(x,0,2))


Anthony Wickstead

unread,
Jul 26, 2012, 10:50:50 AM7/26/12
to sage-...@googlegroups.com
Earlier post sent prematurely by acciident, sorry!
plot(h(.5,x),(x,0,2))                            #shows a horizontal straight line graph (approximately zero) 
plot(sqrt(x),(x,0,1)                                #another straight line, approximately sqrt(2)

Is this a weird bug or am I doing something wrong?

Tony Wickstead
 

P Purkayastha

unread,
Jul 26, 2012, 12:29:39 PM7/26/12
to sage-...@googlegroups.com
On 07/26/2012 10:50 PM, Anthony Wickstead wrote:
> Earlier post sent prematurely by acciident, sorry!
>
> On Thursday, July 26, 2012 3:47:34 PM UTC+1, Anthony Wickstead wrote:
>
> I don't think I am doing anything stupid, but I am fairly new to Sage.
>
> I am using Sage 5.0 (Ubuntu 12.04 64 bit, running under Virtualbox)
> but the same behaviour occurs with Sage 4.7 running under Debian
> (not sure of version). I am trying to plot the graph of h(a,x) fo a
> range of values of a.
>
> def h(a,x):
> if x<=a:
> return 2-sqrt(1-(1-x/a)^4)
> else:
> return sqrt(1-((x-a)/(2-a))^6)
> plot(sqrt(x),(x,0,1)) #Works fine
> [h(.5,x) for x in [0..2,step=.1]] #Returns plausible looking list
> plot(h(.5,x),(x,0,2)) #shows a horizontal straight line graph
> (approximately zero)

This is not the right way to plot h(.5,x). You should use it like this
(at least on the command line or notebook cell):
g(x) = h(.5,x)
plot(g(x), (x,0,1))


> plot(sqrt(x),(x,0,1) #another straight line, approximately sqrt(2)

I get the correct plot of sqrt with this, as long as I use g(x).


>
> Is this a weird bug or am I doing something wrong?
>
> Tony Wickstead
>
> --
> --
> To post to this group, send an email to sage-...@googlegroups.com
> To unsubscribe from this group, send an email to
> sage-devel+...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/sage-devel
> URL: http://www.sagemath.org
>
>
>


Robert Bradshaw

unread,
Jul 26, 2012, 10:18:18 PM7/26/12
to sage-...@googlegroups.com
You're assigning x to several values in your list comprehension.

sage: type(x)
<type 'sage.symbolic.expression.Expression'>
sage: plot(sqrt(x),(x,0,1)) #Works fine
sage: [sqrt(x) for x in [0..2,step=.1]]
[0.000000000000000 ... 1.41421356237310]
sage: x
2.00000000000000
sage: type(x)
<type 'sage.rings.real_mpfr.RealNumber'>
sage: sqrt(x)
1.41421356237310
sage: plot(sqrt(x),(x,0,1) # plotting sqrt(2)
sage: x = var('x')
sage: plot(sqrt(x),(x,0,1)) #Works fine

- Robert

Keshav Kini

unread,
Jul 27, 2012, 12:01:03 AM7/27/12
to sage-...@googlegroups.com
Robert Bradshaw <robe...@math.washington.edu> writes:
> You're assigning x to several values in your list comprehension.

By the way, in Python 3, list comprehensions will have nested scope:

[2] fs@boone ~ $ python2 -c 'x = 2; print(x); print([x**2 for x in range(5)]); print(x)'
2
[0, 1, 4, 9, 16]
4
[2] fs@boone ~ $ python3 -c 'x = 2; print(x); print([x**2 for x in range(5)]); print(x)'
2
[0, 1, 4, 9, 16]
2

-Keshav

----
Join us in #sagemath on irc.freenode.net !

Anthony Wickstead

unread,
Jul 27, 2012, 3:58:50 AM7/27/12
to sage-...@googlegroups.com
Thanks to everyone for the replies here and the direct emails from Rob McMahon and Juan Arias de Reyna. I was trying to isolate my problem and only succeeded in introducing more confusion. My background is that I have been using Mathematica for teaching for the past 20+ years and find it difficult to shake of that background. The construction for creating a list there uses a dummy variable that does not alter the correspondng global variable, which is why creating the table of values in Sage messed things up unexpectedly, to me. The nature of my function, where one alternative was not real for part of the domain also caused me confusion.

I think that I now understand what my problem is, namely that a function created using if:... else: within a def (or inside a lambda function definition) can, it seems, only be used for returning numerical values. Any attempt to use it symbolically just returns the else: alternative.

E.g.
def f(x):
    if x<0:
        return x^2
    else:
        return x

After that, f(-1) returns 1 alright, but f(x) returns x, rather than some version of the function defined. That is why plot(f,(-1,1)) works fine but plot(f(x),(x,-1,1)) draws a straight line.
The same kind of thing happens using h=lambda x: x^2 if x<0 else x

Is there somewhere in the documentation that spells out this limitation of the various if...else  constructions?

Given my background coming from years of use of Mathematica, this seems like a major drawback of Sage.

kcrisman

unread,
Jul 27, 2012, 10:40:02 AM7/27/12
to sage-...@googlegroups.com

I think that I now understand what my problem is, namely that a function created using if:... else: within a def (or inside a lambda function definition) can, it seems, only be used for returning numerical values. Any attempt to use it symbolically just returns the else: alternative.

E.g.
def f(x):
    if x<0:
        return x^2
    else:
        return x

After that, f(-1) returns 1 alright, but f(x) returns x, rather than some version of the function defined. That is why plot(f,(-1,1)) works fine but plot(f(x),(x,-1,1)) draws a straight line.

Correct.
 
The same kind of thing happens using h=lambda x: x^2 if x<0 else x


Note that this will also happen with y

var('y')
f(y)

returns 

y

The 'x' in your function definition is indeed a dummy variable!  In particular, it's not a SYMBOLIC variable - maybe in Mathematica all variables are also mathematical?   Anyway, you put something in it that isn't less than 0, so it will just return that!  And the "x" you put in (or the "y" I put in) certainly isn't less than zero, or greater than zero, or equal to zero; it's a symbolic variable.
 
Is there somewhere in the documentation that spells out this limitation of the various if...else  constructions?


Well, this is Python, not Sage per se.  Presumably there are lots of things like this.  It's not really a limitation, it's a different language.  
 
Given my background coming from years of use of Mathematica, this seems like a major drawback of Sage.


We do have (limited) piecewise function support, which might clear up your current problem.  This is the best I could come up with - again, the piecewise support is rudimentary, dating from when it was the ONLY function type we really had in 2006 or so.  There are lots of other things you might have tried that wouldn't quite work for various reasons.

def f(a):
    return Piecewise([[(0,a),2-sqrt(1-(1-x/a)^4)],[(a,2),sqrt(1-((x-a)/(2-a))^6)]])

f(.5).plot()
Reply all
Reply to author
Forward
0 new messages