Ask Your Question
0

timeout does not work with maxima. Ok with others

asked 2018-06-18 12:24:39 +0100

Nasser gravatar image

updated 2018-06-18 12:48:55 +0100

This is using SageMath version 8.3.beta5, Release Date: 2018-06-09

I set a timeout using Python signal to put a limit on how long an integral can take (since as far as I know python itself does not have a timeout constraint support to use on a call to a function, so one must program this in)

If integrate takes more than some number of seconds, an exception is raised. This way my script does not hang on an integral.

I found it works with fricas, but not with maxima. i.e. when I set the algorithm to maxima, and pick an integral that takes too long and set the timeout to short time (10 seconds), the exception never fires. It means the signal was lost or ignored.

When I do the same thing, set the algorithm to fricas, and pick an integral that also takes long time for fricas to do, the timeout works.

Same exact code. Only difference is the algorithm used.

May be the way I am setting timer is not the best, and there are more robust ways to do this. But I do not understand now why it works with fricas and not with maxima. Here is an example. This is file called test_hanged.sag

#!/usr/bin/env sage

import sys, os, signal, time
from sage.all import *

class TimeoutError(Exception):
    pass

def handler(signum,frame):
    print("handler fired")
    raise TimeoutError()

signal.signal(signal.SIGALRM, handler)
signal.alarm(10) #10 seconds time out

try:            
    #this call will hang. Timer is either lost or ignored. Only with maxima
    integrate(sqrt(x^2 + 1)*arctan(x)^2,x, algorithm="maxima")

    #never reach here
    signal.alarm(0)
    print "Finished "

except Exception as e:
     #this never gets called. It is supposed to be called after 10 seconds
     print "exception=", type(e).__name__

print "finished...."

Then $ ./test_hang.sage just hangs. Now the following with fricas, works. Same code. Just changed the call to integrate

#!/usr/bin/env sage

import sys, os, signal, time
from sage.all import *

class TimeoutError(Exception):
    pass

def handler(signum,frame):
    print("handler fired")
    raise TimeoutError()

signal.signal(signal.SIGALRM, handler)
signal.alarm(10) #10 seconds time out

try:            
    #this call will hang or take too long if there is no timeout
    integrate((x+(1+x)^(1/2))^(1/2)/(x^2+1)/(1+x)^(1/2),x,algorithm="fricas")

    #never reach here, due to time out
    signal.alarm(0)
    print "Finished "

except Exception as e:
     #this is now called. So timer worked.
     print "exception=", type(e).__name__

print "finished...."

And now

./test_hang.sage
handler fired
exception= TimeoutError
finished....

Any idea why the above works with fricas and not with maxima? I need now to try to find better way to do timeouts, as the above does not work for all.

edit retag flag offensive close merge delete

1 Answer

Sort by ยป oldest newest most voted
3

answered 2018-06-18 18:03:19 +0100

nbruin gravatar image

When you use the "maxima" strategy. you're actually calling maxima_lib -- an instance of maxima/ECL that is running as a library inside the sage process. Upon entering the library, the signal handlers are adjusted to ECL's liking. Your python signal handler is therefore suspended, because it wouldn't be able to execute safely while ECL is in operation (yes, this is very non-thread-safe).

If you want to run the integration in a separate maxima process, use a maxima interface explicitly, e.g.

F=maxima(sqrt(x^2 + 1)*arctan(x)^2)
F.integrate(x)

In general maxima_lib has some distinct advantages, because it can convert expressions between sage and maxima in a more efficient way than just sending characters back and forth (maxima_lib shares memory with sage).

edit flag offensive delete link more

Comments

Thanks. But I am little confused on something. When I do

sage: F=maxima(sin(x))
sage: F.integrate(x)
-cos(_SAGE_VAR_x)

How to get it to look like -cos(x)? I tried adding var('x') before the first line above, but that did not change the result. _SAGE_VAR_x was still there. Is there an addition command to use to convert the output to sage normal looking output which is -cos(x) ?

Oh, I just found out! I just need to add .sage() to the last call to do the conversion. So I am all set. Thanks.

Nasser gravatar imageNasser ( 2018-06-19 00:26:25 +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: 2018-06-18 12:24:39 +0100

Seen: 453 times

Last updated: Jun 18 '18