ASKSAGE: Sage Q&A Forum - Individual question feedhttp://ask.sagemath.org/questions/Q&A Forum for SageenCopyright Sage, 2010. Some rights reserved under creative commons license.Tue, 31 Jan 2012 06:46:41 -0600plot issue with a self-defined piecewise functionhttp://ask.sagemath.org/question/8643/plot-issue-with-a-self-defined-piecewise-function/The following code produces an error:
def f(x):
if x>3:
return(x^2)
if x<=3:
return(3*x)
plot(f(x),(x,0,5))
BUT, the code below works.
def f(x):
if x>3:
return(x^2)
if x<=3:
return(3*x)
plot(lambda x: f(x),(x,0,5))
So, my questions are:
(1) why do you need the lambda function? and
(2) when do you have to do this?
Wed, 18 Jan 2012 09:10:48 -0600http://ask.sagemath.org/question/8643/plot-issue-with-a-self-defined-piecewise-function/Answer by Jason Grout for <p>The following code produces an error:</p>
<pre><code>def f(x):
if x>3:
return(x^2)
if x<=3:
return(3*x)
plot(f(x),(x,0,5))
</code></pre>
<p>BUT, the code below works.</p>
<pre><code>def f(x):
if x>3:
return(x^2)
if x<=3:
return(3*x)
plot(lambda x: f(x),(x,0,5))
</code></pre>
<p>So, my questions are:
(1) why do you need the lambda function? and
(2) when do you have to do this?</p>
http://ask.sagemath.org/question/8643/plot-issue-with-a-self-defined-piecewise-function/?answer=13219#post-id-13219To answer the 3d plot question, again, you need to make the functions calculate their values when the plotting routine is actually getting points, not before the plotting routine is called:
Y=parametric_plot3d([lambda s,t: (2+sin(s))*sin(t*f(s)),lambda s,t: cos(s),lambda s,t: (2+sin(s))*cos(t*f(s))],(s,0,2*pi),(t,-1,1))
Tue, 31 Jan 2012 06:46:41 -0600http://ask.sagemath.org/question/8643/plot-issue-with-a-self-defined-piecewise-function/?answer=13219#post-id-13219Answer by MathLynx for <p>The following code produces an error:</p>
<pre><code>def f(x):
if x>3:
return(x^2)
if x<=3:
return(3*x)
plot(f(x),(x,0,5))
</code></pre>
<p>BUT, the code below works.</p>
<pre><code>def f(x):
if x>3:
return(x^2)
if x<=3:
return(3*x)
plot(lambda x: f(x),(x,0,5))
</code></pre>
<p>So, my questions are:
(1) why do you need the lambda function? and
(2) when do you have to do this?</p>
http://ask.sagemath.org/question/8643/plot-issue-with-a-self-defined-piecewise-function/?answer=13213#post-id-13213Toward a related issue - how do I incorporate such a conditional in a 3d plot? Consider the following.
s,t=var('s,t')
def f(x):
if x<pi:
return(arccos(-2/(2+sin(x))))
if x>=pi:
return(pi)
plot(f,(x,0,2*pi)) --- to check that the function is properly defined
X=parametric_plot3d([(2+sin(s))*sin(t),cos(s),(2+sin(s))*cos(t)],(s,0,2*pi),(t,0,2*pi)) --- to produce a torus
X.show(aspect_ratio=[1,1,1])
Y=parametric_plot3d([(2+sin(s))*sin(t*f(s)),cos(s),(2+sin(s))*cos(t*f(s))],(s,0,2*pi),(t,-1,1)) --- to produce the part of the torus above the z=-2 plane
Y.show(aspect_ratio=[1,1,1])
This fails. Any hints?
Sun, 29 Jan 2012 11:58:41 -0600http://ask.sagemath.org/question/8643/plot-issue-with-a-self-defined-piecewise-function/?answer=13213#post-id-13213Comment by Jason Grout for <p>Toward a related issue - how do I incorporate such a conditional in a 3d plot? Consider the following.</p>
<pre><code>s,t=var('s,t')
def f(x):
if x<pi:
return(arccos(-2/(2+sin(x))))
if x>=pi:
return(pi)
plot(f,(x,0,2*pi)) --- to check that the function is properly defined
X=parametric_plot3d([(2+sin(s))*sin(t),cos(s),(2+sin(s))*cos(t)],(s,0,2*pi),(t,0,2*pi)) --- to produce a torus
X.show(aspect_ratio=[1,1,1])
Y=parametric_plot3d([(2+sin(s))*sin(t*f(s)),cos(s),(2+sin(s))*cos(t*f(s))],(s,0,2*pi),(t,-1,1)) --- to produce the part of the torus above the z=-2 plane
Y.show(aspect_ratio=[1,1,1])
</code></pre>
<p>This fails. Any hints?</p>
http://ask.sagemath.org/question/8643/plot-issue-with-a-self-defined-piecewise-function/?comment=20375#post-id-20375To post code, highlight the code and click the "code" button (the button that has 1010 on it). Or just indent each line 4 spaces or so.Tue, 31 Jan 2012 06:41:26 -0600http://ask.sagemath.org/question/8643/plot-issue-with-a-self-defined-piecewise-function/?comment=20375#post-id-20375Answer by kcrisman for <p>The following code produces an error:</p>
<pre><code>def f(x):
if x>3:
return(x^2)
if x<=3:
return(3*x)
plot(f(x),(x,0,5))
</code></pre>
<p>BUT, the code below works.</p>
<pre><code>def f(x):
if x>3:
return(x^2)
if x<=3:
return(3*x)
plot(lambda x: f(x),(x,0,5))
</code></pre>
<p>So, my questions are:
(1) why do you need the lambda function? and
(2) when do you have to do this?</p>
http://ask.sagemath.org/question/8643/plot-issue-with-a-self-defined-piecewise-function/?answer=13145#post-id-13145Another option is to use the (not very powerful) `Piecewise` class. You could at least do some basic calculus with it as well, then. However, you'd have to define endpoints.
sage: g = Piecewise([[(-10,1),x], [(1,10),x^2]], x)
sage: derivative(g)
Piecewise defined function with 2 parts, [[(-10, 1), x |--> 1], [(1, 10), x |--> 2*x]]
sage: integrate(g)
Piecewise defined function with 2 parts, [[(-10, 1), x |--> 1/2*x^2 - 50], [(1, 10), x |--> 1/3*x^3 - 299/6]]
sage: plot(g)
So it works. But see [ticket 11225](http://trac.sagemath.org/sage_trac/ticket/11225) for a nice list of ways in which piecewise plotting could be improved. For instance, with infinite endpoints, although it does math, it won't plot. Perhaps that makes sense, since we wouldn't see infinity anyway...
sage: f = Piecewise([[(-oo,1),x], [(1,oo),x^2]], x)
sage: f(-10^6)
-1000000
sage: plot(f)
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
ValueError: cannot convert float NaN to integerWed, 18 Jan 2012 09:35:17 -0600http://ask.sagemath.org/question/8643/plot-issue-with-a-self-defined-piecewise-function/?answer=13145#post-id-13145Answer by Jason Grout for <p>The following code produces an error:</p>
<pre><code>def f(x):
if x>3:
return(x^2)
if x<=3:
return(3*x)
plot(f(x),(x,0,5))
</code></pre>
<p>BUT, the code below works.</p>
<pre><code>def f(x):
if x>3:
return(x^2)
if x<=3:
return(3*x)
plot(lambda x: f(x),(x,0,5))
</code></pre>
<p>So, my questions are:
(1) why do you need the lambda function? and
(2) when do you have to do this?</p>
http://ask.sagemath.org/question/8643/plot-issue-with-a-self-defined-piecewise-function/?answer=13144#post-id-13144The problem in your first example is that when you do `f(x)`, it is actually calling f and returning a value. However, you want to plot the *function*, not the return value from one call. So you should do this:
def f(x):
if x>3:
return(x^2)
if x<=3:
return(3*x)
plot(f,(x,0,5))
Notice that now, I haven't called the function. Instead, I'm just passing the function into plot, and *plot* will call the function with different values.
Your lambda function trick works because it is passing a function into plot. plot then calls the lambda function, which in turn calls the f function. But I think it's easier to what I did above.Wed, 18 Jan 2012 09:22:35 -0600http://ask.sagemath.org/question/8643/plot-issue-with-a-self-defined-piecewise-function/?answer=13144#post-id-13144Comment by Jason Grout for <p>The problem in your first example is that when you do <code>f(x)</code>, it is actually calling f and returning a value. However, you want to plot the <em>function</em>, not the return value from one call. So you should do this:</p>
<pre><code>def f(x):
if x>3:
return(x^2)
if x<=3:
return(3*x)
plot(f,(x,0,5))
</code></pre>
<p>Notice that now, I haven't called the function. Instead, I'm just passing the function into plot, and <em>plot</em> will call the function with different values.</p>
<p>Your lambda function trick works because it is passing a function into plot. plot then calls the lambda function, which in turn calls the f function. But I think it's easier to what I did above.</p>
http://ask.sagemath.org/question/8643/plot-issue-with-a-self-defined-piecewise-function/?comment=20498#post-id-20498I asked Jeff to post these to ask.sagemath.org so that others could see the answers.Wed, 18 Jan 2012 11:12:15 -0600http://ask.sagemath.org/question/8643/plot-issue-with-a-self-defined-piecewise-function/?comment=20498#post-id-20498Comment by kcrisman for <p>The problem in your first example is that when you do <code>f(x)</code>, it is actually calling f and returning a value. However, you want to plot the <em>function</em>, not the return value from one call. So you should do this:</p>
<pre><code>def f(x):
if x>3:
return(x^2)
if x<=3:
return(3*x)
plot(f,(x,0,5))
</code></pre>
<p>Notice that now, I haven't called the function. Instead, I'm just passing the function into plot, and <em>plot</em> will call the function with different values.</p>
<p>Your lambda function trick works because it is passing a function into plot. plot then calls the lambda function, which in turn calls the f function. But I think it's easier to what I did above.</p>
http://ask.sagemath.org/question/8643/plot-issue-with-a-self-defined-piecewise-function/?comment=20497#post-id-20497Sorry, I meant that @calc314 asked me to answer them, and I said to put it on this site so *I* could answer it ;-)Wed, 18 Jan 2012 13:22:06 -0600http://ask.sagemath.org/question/8643/plot-issue-with-a-self-defined-piecewise-function/?comment=20497#post-id-20497Comment by kcrisman for <p>The problem in your first example is that when you do <code>f(x)</code>, it is actually calling f and returning a value. However, you want to plot the <em>function</em>, not the return value from one call. So you should do this:</p>
<pre><code>def f(x):
if x>3:
return(x^2)
if x<=3:
return(3*x)
plot(f,(x,0,5))
</code></pre>
<p>Notice that now, I haven't called the function. Instead, I'm just passing the function into plot, and <em>plot</em> will call the function with different values.</p>
<p>Your lambda function trick works because it is passing a function into plot. plot then calls the lambda function, which in turn calls the f function. But I think it's easier to what I did above.</p>
http://ask.sagemath.org/question/8643/plot-issue-with-a-self-defined-piecewise-function/?comment=20502#post-id-20502Hmm, @calc314 originally asked me to answer this offline ... But good answer, and it should be available to all.Wed, 18 Jan 2012 09:28:31 -0600http://ask.sagemath.org/question/8643/plot-issue-with-a-self-defined-piecewise-function/?comment=20502#post-id-20502Comment by calc314 for <p>The problem in your first example is that when you do <code>f(x)</code>, it is actually calling f and returning a value. However, you want to plot the <em>function</em>, not the return value from one call. So you should do this:</p>
<pre><code>def f(x):
if x>3:
return(x^2)
if x<=3:
return(3*x)
plot(f,(x,0,5))
</code></pre>
<p>Notice that now, I haven't called the function. Instead, I'm just passing the function into plot, and <em>plot</em> will call the function with different values.</p>
<p>Your lambda function trick works because it is passing a function into plot. plot then calls the lambda function, which in turn calls the f function. But I think it's easier to what I did above.</p>
http://ask.sagemath.org/question/8643/plot-issue-with-a-self-defined-piecewise-function/?comment=20490#post-id-20490I have a follow up question, since I know that I will be asked this by students and colleagues. Why does a self-defined function attempt to evaluate f(x) when you give the command plot(f(x), (x,0,5)), but yet when you define a function as below it works?
f(x) = x^2
plot(f(x),(x,-3,3))Thu, 19 Jan 2012 03:52:42 -0600http://ask.sagemath.org/question/8643/plot-issue-with-a-self-defined-piecewise-function/?comment=20490#post-id-20490Comment by calc314 for <p>The problem in your first example is that when you do <code>f(x)</code>, it is actually calling f and returning a value. However, you want to plot the <em>function</em>, not the return value from one call. So you should do this:</p>
<pre><code>def f(x):
if x>3:
return(x^2)
if x<=3:
return(3*x)
plot(f,(x,0,5))
</code></pre>
<p>Notice that now, I haven't called the function. Instead, I'm just passing the function into plot, and <em>plot</em> will call the function with different values.</p>
<p>Your lambda function trick works because it is passing a function into plot. plot then calls the lambda function, which in turn calls the f function. But I think it's easier to what I did above.</p>
http://ask.sagemath.org/question/8643/plot-issue-with-a-self-defined-piecewise-function/?comment=20501#post-id-20501Thanks for all of the help! I think I get it now.Wed, 18 Jan 2012 09:39:32 -0600http://ask.sagemath.org/question/8643/plot-issue-with-a-self-defined-piecewise-function/?comment=20501#post-id-20501Comment by Jason Grout for <p>The problem in your first example is that when you do <code>f(x)</code>, it is actually calling f and returning a value. However, you want to plot the <em>function</em>, not the return value from one call. So you should do this:</p>
<pre><code>def f(x):
if x>3:
return(x^2)
if x<=3:
return(3*x)
plot(f,(x,0,5))
</code></pre>
<p>Notice that now, I haven't called the function. Instead, I'm just passing the function into plot, and <em>plot</em> will call the function with different values.</p>
<p>Your lambda function trick works because it is passing a function into plot. plot then calls the lambda function, which in turn calls the f function. But I think it's easier to what I did above.</p>
http://ask.sagemath.org/question/8643/plot-issue-with-a-self-defined-piecewise-function/?comment=20452#post-id-20452I typed something, but it was confusing, and kcrisman's answer is better.Mon, 23 Jan 2012 06:43:58 -0600http://ask.sagemath.org/question/8643/plot-issue-with-a-self-defined-piecewise-function/?comment=20452#post-id-20452Comment by kcrisman for <p>The problem in your first example is that when you do <code>f(x)</code>, it is actually calling f and returning a value. However, you want to plot the <em>function</em>, not the return value from one call. So you should do this:</p>
<pre><code>def f(x):
if x>3:
return(x^2)
if x<=3:
return(3*x)
plot(f,(x,0,5))
</code></pre>
<p>Notice that now, I haven't called the function. Instead, I'm just passing the function into plot, and <em>plot</em> will call the function with different values.</p>
<p>Your lambda function trick works because it is passing a function into plot. plot then calls the lambda function, which in turn calls the f function. But I think it's easier to what I did above.</p>
http://ask.sagemath.org/question/8643/plot-issue-with-a-self-defined-piecewise-function/?comment=20487#post-id-20487Yup! Basically, to see why, just type 'f' and 'f(x)' in Sage and see what you get. 'f(x)' still gives a symbolic expression in one variable, which can be plotted.Thu, 19 Jan 2012 13:43:43 -0600http://ask.sagemath.org/question/8643/plot-issue-with-a-self-defined-piecewise-function/?comment=20487#post-id-20487