Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

I would like to run a time consuming function:

TimeConstrained[f[x],maxseconds]

and be able to change maxseconds during running (increasing or decreasing max time) using a slider. Ideally when i decrease maxseconds below the time it has already consume it will stop.

I could implement such a functionality inside f but i would have to do this for all f i want to create , so this way is out of the question.

Thanks in advance,

Theodore.

share|improve this question
    
This is a tough one. Basically it boils down to the fact that once a long calculation is started, you cannot interrupt it programmatically from the outside (i.e. not from the inside as in case of e.g. EventMonitor:>If[aborted, Abort[]]) with any Abort[], even using a background scheduled task to monitor elapsed time. –  István Zachar Nov 29 '13 at 12:47
    
I understand your point. This is why I opened the bounty - in case there is a way of generalizing TimeConstrained maybe with some low level Java programming? –  tchronis Nov 29 '13 at 14:24
3  
Perhaps "EvaluatorAbort" could be used. –  Michael E2 Nov 29 '13 at 15:44
    
Thanks @MichaelE2 for the input! –  István Zachar Nov 29 '13 at 18:25
2  
Another completely different approach would be to abuse one of the parallel kernels to run the computation in a detached thread. After all, the parallel kernels are just simple kernels you can use for calculation. In this way you could work in the front end while your f[x] is calculated in the background and you can stop the calculation at any time. –  halirutan Nov 30 '13 at 2:55

1 Answer 1

up vote 10 down vote accepted
+50

Thanks to Michael E2's comment, the following approach is successful. The method sets up a scheduled task that (at certain resolution res) monitors the elapsed $time and compares it to the dynamic $max. If $time is more than allowed by $max, it calls the front-end "EvaluatorAbort".

Attributes[dynamicTimeConstrained] = {HoldAll};
dynamicTimeConstrained[expr_] := Module[{task, res = .1},
   $time = 0;
       task = RunScheduledTask[(
          $time = $time + res;
          If[$time >= $max,
           RemoveScheduledTask@task;
           FrontEndExecute@FrontEnd`CellPrint@Cell[
               "Aborted at "<>ToString@$time<>".", "Output"];
           FrontEndExecute@FrontEndToken@"EvaluatorAbort"
          ];
      ), {res, Infinity}];
   res = expr;
   RemoveScheduledTask@task;
   res
   ];

$time = 0;
$max = 3;
Dynamic@$time

(* set up slider to dynamically manipulate $max *)
    Slider[Dynamic@$max, {0.0001, 10}, Appearance -> "Labeled"]

(* simulate a long calculation by Pause *)
dynamicTimeConstrained[Do[Pause@1; Print[i];, {i, 5}]; 111]

Notice that the scheduled task is aware of the global value changes to both $time and $max, so the method works. May need a bit of fine tuning on the correct time-resolution as too fine a resolution might cause delayed abortion.

Here the default allotted time (3 sec) is extended, so the calculation terminates normally without abort:

enter image description here

Here the default time (3 sec again) is decreased and the job aborts as expected:

enter image description here

share|improve this answer
    
Great job! Glad the comment helped. :) –  Michael E2 Nov 29 '13 at 18:31
    
@tchronis Thanks for the accept and the bounty! I hope this method can be used in realistic situations as well. –  István Zachar Dec 13 '13 at 7:56

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.