Ask Your Question
0

Piece-wise functions and plotting

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

Edgar gravatar image

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

FrédéricC gravatar image

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:

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,

Edgar

edit retag flag offensive close merge delete

Comments

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

kcrisman gravatar imagekcrisman ( 2012-10-02 11:42:49 +0100 )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 +0100 )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 +0100 )edit

1 Answer

Sort by » oldest newest most voted
3

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

achrzesz gravatar image

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

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

Comments

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

kcrisman gravatar imagekcrisman ( 2012-10-02 15:33:37 +0100 )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) ); p.show(); Now it doesn't work again!

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

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

achrzesz gravatar imageachrzesz ( 2012-10-03 13:38:08 +0100 )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 +0100 )edit

Can you show a code snippet leading to performance degradation

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

Stats

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

Seen: 2,363 times

Last updated: Oct 03 '12