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...."
The I do $ ./test_hang.sage
it 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.