ASKSAGE: Sage Q&A Forum - RSS feedhttps://ask.sagemath.org/questions/Q&A Forum for SageenCopyright Sage, 2010. Some rights reserved under creative commons license.Fri, 05 Oct 2012 12:02:23 +0200Piece-wise functions and plottinghttps://ask.sagemath.org/question/9377/piece-wise-functions-and-plotting/Hi,
I have a piece-wise defined function that I want to plot (and potentially do other symbolic stuff with) and I was wondering how to do this. The problem is that I am defining my function as a Python function:
<pre>def F(x,y):
if( x <= y ):
return x*y
return x+y
</pre>
So I am gluing together two pieces, and I would like to be able to do
<pre>(x,y) = var('x,y')
contour_plot( F(x,y), (x,0,1), (y,0,1) )</pre>
But the problem is that this only plots the second part. This occurs because x <= y evaluates as false (they are variables) and F(x,y) is always evaluated as x+y. In Mathematica there is the <b>Which</b> function that works on symbolic expression to make piece-wise definitions. Is there an equivalent in Sage? Is there another way to do this? If I had a function (say, <i>delta</i>) that just evaluated as 1 if the symbolic expression was true, and 0 if not, I could craft the function as:
<pre>F(x,y) = delta( x<=y ) * (x*y) + delta( x>y ) * (x+y)</pre>
But as it is, I think there is no way to do this. Is there?
Thanks a lot for your help,
EdgarTue, 02 Oct 2012 11:20:42 +0200https://ask.sagemath.org/question/9377/piece-wise-functions-and-plotting/Comment by Edgar for <p>Hi,</p>
<p>I have a piece-wise defined function that I want to plot (and potentially do other symbolic stuff with) and I was wondering how to do this. The problem is that I am defining my function as a Python function:</p>
<pre>def F(x,y):
if( x <= y ):
return x*y
return x+y
</pre>
<p>So I am gluing together two pieces, and I would like to be able to do</p>
<pre>(x,y) = var('x,y')
contour_plot( F(x,y), (x,0,1), (y,0,1) )</pre>
<p>But the problem is that this only plots the second part. This occurs because x <= y evaluates as false (they are variables) and F(x,y) is always evaluated as x+y. In Mathematica there is the <b>Which</b> function that works on symbolic expression to make piece-wise definitions. Is there an equivalent in Sage? Is there another way to do this? If I had a function (say, <i>delta</i>) that just evaluated as 1 if the symbolic expression was true, and 0 if not, I could craft the function as:</p>
<pre>F(x,y) = delta( x<=y ) * (x*y) + delta( x>y ) * (x+y)</pre>
<p>But as it is, I think there is no way to do this. Is there?</p>
<p>Thanks a lot for your help,</p>
<p>Edgar</p>
https://ask.sagemath.org/question/9377/piece-wise-functions-and-plotting/?comment=18922#post-id-18922Also, I just found out that Sage has the kronecker_delta function, so one could rewrite the above example as a product of two pieces, however, in my case I actually have three pieces and I would still need to find an appropriate transformation to map the pieces to non-overlapping conditions where the delta function would be 1 for exactly one of them. While possible, this is really not elegant. Any other thoughts?Wed, 03 Oct 2012 10:06:31 +0200https://ask.sagemath.org/question/9377/piece-wise-functions-and-plotting/?comment=18922#post-id-18922Comment by kcrisman for <p>Hi,</p>
<p>I have a piece-wise defined function that I want to plot (and potentially do other symbolic stuff with) and I was wondering how to do this. The problem is that I am defining my function as a Python function:</p>
<pre>def F(x,y):
if( x <= y ):
return x*y
return x+y
</pre>
<p>So I am gluing together two pieces, and I would like to be able to do</p>
<pre>(x,y) = var('x,y')
contour_plot( F(x,y), (x,0,1), (y,0,1) )</pre>
<p>But the problem is that this only plots the second part. This occurs because x <= y evaluates as false (they are variables) and F(x,y) is always evaluated as x+y. In Mathematica there is the <b>Which</b> function that works on symbolic expression to make piece-wise definitions. Is there an equivalent in Sage? Is there another way to do this? If I had a function (say, <i>delta</i>) that just evaluated as 1 if the symbolic expression was true, and 0 if not, I could craft the function as:</p>
<pre>F(x,y) = delta( x<=y ) * (x*y) + delta( x>y ) * (x+y)</pre>
<p>But as it is, I think there is no way to do this. Is there?</p>
<p>Thanks a lot for your help,</p>
<p>Edgar</p>
https://ask.sagemath.org/question/9377/piece-wise-functions-and-plotting/?comment=18937#post-id-18937See http://trac.sagemath.org/sage_trac/ticket/11225. Unfortunately, no one has had the combination of time, expertise, and interest to update our piecewise functions from their original implementation - but there might be a helpful link for you there.Tue, 02 Oct 2012 11:42:49 +0200https://ask.sagemath.org/question/9377/piece-wise-functions-and-plotting/?comment=18937#post-id-18937Comment by Edgar for <p>Hi,</p>
<p>I have a piece-wise defined function that I want to plot (and potentially do other symbolic stuff with) and I was wondering how to do this. The problem is that I am defining my function as a Python function:</p>
<pre>def F(x,y):
if( x <= y ):
return x*y
return x+y
</pre>
<p>So I am gluing together two pieces, and I would like to be able to do</p>
<pre>(x,y) = var('x,y')
contour_plot( F(x,y), (x,0,1), (y,0,1) )</pre>
<p>But the problem is that this only plots the second part. This occurs because x <= y evaluates as false (they are variables) and F(x,y) is always evaluated as x+y. In Mathematica there is the <b>Which</b> function that works on symbolic expression to make piece-wise definitions. Is there an equivalent in Sage? Is there another way to do this? If I had a function (say, <i>delta</i>) that just evaluated as 1 if the symbolic expression was true, and 0 if not, I could craft the function as:</p>
<pre>F(x,y) = delta( x<=y ) * (x*y) + delta( x>y ) * (x+y)</pre>
<p>But as it is, I think there is no way to do this. Is there?</p>
<p>Thanks a lot for your help,</p>
<p>Edgar</p>
https://ask.sagemath.org/question/9377/piece-wise-functions-and-plotting/?comment=18923#post-id-18923Yes, for one-dimensional piecewise functions that would work, but for two-dimensional or more, it would not, I am afraid.Wed, 03 Oct 2012 10:06:23 +0200https://ask.sagemath.org/question/9377/piece-wise-functions-and-plotting/?comment=18923#post-id-18923Answer by achrzesz for <p>Hi,</p>
<p>I have a piece-wise defined function that I want to plot (and potentially do other symbolic stuff with) and I was wondering how to do this. The problem is that I am defining my function as a Python function:</p>
<pre>def F(x,y):
if( x <= y ):
return x*y
return x+y
</pre>
<p>So I am gluing together two pieces, and I would like to be able to do</p>
<pre>(x,y) = var('x,y')
contour_plot( F(x,y), (x,0,1), (y,0,1) )</pre>
<p>But the problem is that this only plots the second part. This occurs because x <= y evaluates as false (they are variables) and F(x,y) is always evaluated as x+y. In Mathematica there is the <b>Which</b> function that works on symbolic expression to make piece-wise definitions. Is there an equivalent in Sage? Is there another way to do this? If I had a function (say, <i>delta</i>) that just evaluated as 1 if the symbolic expression was true, and 0 if not, I could craft the function as:</p>
<pre>F(x,y) = delta( x<=y ) * (x*y) + delta( x>y ) * (x+y)</pre>
<p>But as it is, I think there is no way to do this. Is there?</p>
<p>Thanks a lot for your help,</p>
<p>Edgar</p>
https://ask.sagemath.org/question/9377/piece-wise-functions-and-plotting/?answer=14094#post-id-14094It seems that this version does not ignore the x*y case:
p=contour_plot(lambda x,y: F(x,y), (x,0,1), (y,0,1) )
p.show()
Lambda is not necessary:
def F(x,y):
if( x <= y ):
return x*y
return x+y
contour_plot( F, (x,0,1), (y,0,1) ).show()
Tue, 02 Oct 2012 15:27:54 +0200https://ask.sagemath.org/question/9377/piece-wise-functions-and-plotting/?answer=14094#post-id-14094Comment by achrzesz for <p>It seems that this version does not ignore the x*y case:</p>
<pre><code>p=contour_plot(lambda x,y: F(x,y), (x,0,1), (y,0,1) )
p.show()
</code></pre>
<p>Lambda is not necessary:</p>
<pre><code>def F(x,y):
if( x <= y ):
return x*y
return x+y
contour_plot( F, (x,0,1), (y,0,1) ).show()
</code></pre>
https://ask.sagemath.org/question/9377/piece-wise-functions-and-plotting/?comment=18917#post-id-18917Can you show a code snippet leading to performance degradationFri, 05 Oct 2012 12:02:23 +0200https://ask.sagemath.org/question/9377/piece-wise-functions-and-plotting/?comment=18917#post-id-18917Comment by kcrisman for <p>It seems that this version does not ignore the x*y case:</p>
<pre><code>p=contour_plot(lambda x,y: F(x,y), (x,0,1), (y,0,1) )
p.show()
</code></pre>
<p>Lambda is not necessary:</p>
<pre><code>def F(x,y):
if( x <= y ):
return x*y
return x+y
contour_plot( F, (x,0,1), (y,0,1) ).show()
</code></pre>
https://ask.sagemath.org/question/9377/piece-wise-functions-and-plotting/?comment=18936#post-id-18936Yes, lambdas will often work where nothing else does! Good answer.Tue, 02 Oct 2012 15:33:37 +0200https://ask.sagemath.org/question/9377/piece-wise-functions-and-plotting/?comment=18936#post-id-18936Comment by Edgar for <p>It seems that this version does not ignore the x*y case:</p>
<pre><code>p=contour_plot(lambda x,y: F(x,y), (x,0,1), (y,0,1) )
p.show()
</code></pre>
<p>Lambda is not necessary:</p>
<pre><code>def F(x,y):
if( x <= y ):
return x*y
return x+y
contour_plot( F, (x,0,1), (y,0,1) ).show()
</code></pre>
https://ask.sagemath.org/question/9377/piece-wise-functions-and-plotting/?comment=18919#post-id-18919Ah, thanks!... In my code, I had some nested transformations going on, so I didn't pass just the function handle. Now this works, unfortunately, it takes me back to the very poor performance which makes it impractical to put it in an @interact environmentFri, 05 Oct 2012 03:04:39 +0200https://ask.sagemath.org/question/9377/piece-wise-functions-and-plotting/?comment=18919#post-id-18919Comment by achrzesz for <p>It seems that this version does not ignore the x*y case:</p>
<pre><code>p=contour_plot(lambda x,y: F(x,y), (x,0,1), (y,0,1) )
p.show()
</code></pre>
<p>Lambda is not necessary:</p>
<pre><code>def F(x,y):
if( x <= y ):
return x*y
return x+y
contour_plot( F, (x,0,1), (y,0,1) ).show()
</code></pre>
https://ask.sagemath.org/question/9377/piece-wise-functions-and-plotting/?comment=18921#post-id-18921The proper syntax is:
p=contour_plot( P, (x,0,1), (y,0,1) );
p.show();Wed, 03 Oct 2012 13:38:08 +0200https://ask.sagemath.org/question/9377/piece-wise-functions-and-plotting/?comment=18921#post-id-18921Comment by Edgar for <p>It seems that this version does not ignore the x*y case:</p>
<pre><code>p=contour_plot(lambda x,y: F(x,y), (x,0,1), (y,0,1) )
p.show()
</code></pre>
<p>Lambda is not necessary:</p>
<pre><code>def F(x,y):
if( x <= y ):
return x*y
return x+y
contour_plot( F, (x,0,1), (y,0,1) ).show()
</code></pre>
https://ask.sagemath.org/question/9377/piece-wise-functions-and-plotting/?comment=18925#post-id-18925This is a good answer in that it works, the problem now is about efficiency. If I do this with my actual function (which is a bit more complicated that the one in the example) then it takes 30 seconds to render. If I try to get fancy and make:
P = lambda x,y: F(x,y); p=contour_plot( P(x,y), (x,0,1), (y,0,1) ); p.show();
Now it doesn't work again!Wed, 03 Oct 2012 09:44:10 +0200https://ask.sagemath.org/question/9377/piece-wise-functions-and-plotting/?comment=18925#post-id-18925