Ask Your Question

Piece-wise functions and plotting

asked 2012-10-02 11:20:42 +0200

Edgar gravatar image

updated 2015-01-14 12:20:27 +0200

FrédéricC gravatar image


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:

def F(x,y):
    if( x <= y ):
        return x*y
    return x+y

So I am gluing together two pieces, and I would like to be able to do

(x,y) = var('x,y')
contour_plot( F(x,y), (x,0,1), (y,0,1) )

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 Which 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, delta) that just evaluated as 1 if the symbolic expression was true, and 0 if not, I could craft the function as:

F(x,y) = delta( x<=y ) * (x*y) + delta( x>y ) * (x+y)

But as it is, I think there is no way to do this. Is there?

Thanks a lot for your help,


edit retag flag offensive close merge delete


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

kcrisman gravatar imagekcrisman ( 2012-10-02 11:42:49 +0200 )edit

Yes, for one-dimensional piecewise functions that would work, but for two-dimensional or more, it would not, I am afraid.

Edgar gravatar imageEdgar ( 2012-10-03 10:06:23 +0200 )edit

Also, 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?

Edgar gravatar imageEdgar ( 2012-10-03 10:06:31 +0200 )edit

1 Answer

Sort by » oldest newest most voted

answered 2012-10-02 15:27:54 +0200

achrzesz gravatar image

updated 2012-10-03 15:50:16 +0200

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

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()
edit flag offensive delete link more


Yes, lambdas will often work where nothing else does! Good answer.

kcrisman gravatar imagekcrisman ( 2012-10-02 15:33:37 +0200 )edit

This 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) );; Now it doesn't work again!

Edgar gravatar imageEdgar ( 2012-10-03 09:44:10 +0200 )edit

The proper syntax is: p=contour_plot( P, (x,0,1), (y,0,1) );;

achrzesz gravatar imageachrzesz ( 2012-10-03 13:38:08 +0200 )edit

Ah, 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 environment

Edgar gravatar imageEdgar ( 2012-10-05 03:04:39 +0200 )edit

Can you show a code snippet leading to performance degradation

achrzesz gravatar imageachrzesz ( 2012-10-05 12:02:23 +0200 )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

1 follower


Asked: 2012-10-02 11:20:42 +0200

Seen: 2,206 times

Last updated: Oct 03 '12