34
$\begingroup$

Is it possible to find the values of variables of a running Mathematica evaluation, without interrupting it? For example, suppose I do:

Do[Pause[1]; a++, {50}]

and then afterwards realize that the code is taking a long time. If I had realized before the computation started that it would be slow, I could have initially evaluated Dynamic[a], and then run the computation. Is there any way to do something similar after the computation has started, without interrupting the computation?

$\endgroup$
30
$\begingroup$

For simplistic purposes there is Evaluate in Subsession which is in the Evaluation menu, and has the shortcut key F7 under Windows & Linux (and alt+shift+enter under macOS).

Simply make a new Cell while the evaluation is running, containing e.g. a, make sure the cell has focus, and press F7; Mathematica evaluates this and returns the current value of a, and continues the computation.

If you prefer an ongoing count you can put e.g. Dynamic[a] in the new cell.

enter image description here

$\endgroup$
  • 2
    $\begingroup$ Wow, that's easy. Great to know! (I allowed myself to add the macOS shortcut.) $\endgroup$ – Henrik Schumacher Jul 23 '18 at 13:18
  • $\begingroup$ @Henrik Glad I could help. :-) Thank you for adding that; I don't like to write platform-dependent answers. $\endgroup$ – Mr.Wizard Jul 23 '18 at 22:17
  • 2
    $\begingroup$ I like this answer, but note the update to my answer that gives a situation where using multiple kernels might be better. $\endgroup$ – Carl Woll Jul 24 '18 at 4:34
  • $\begingroup$ @CarlWoll I am honored by your Accepting my answer. :-) $\endgroup$ – Mr.Wizard Jul 24 '18 at 4:36
30
$\begingroup$

Update

The other answers provide a good way to add dynamic monitoring using a single kernel when access to the front end is available. The method I proposed using multiple kernels will work even when the front end is not accessible. So, you might ask, when would the front end not be available?

Suppose you have a remote machine, with two kernels, a master/monitor kernel, and a slave/working kernel. It is possible to communicate with the master kernel using the Channel framework. In this situation, one might want to ask the master kernel to check on the status of the slave kernel, and report back diagnostic information. This is in fact a situation that I currently use, and one where I don't think the other answers will work.

I had a stylesheet approach that is not nearly as effective as MrWizard's answer, so I have removed that part of my original answer.

Original answer

Yes, this is possible. First, you need to make sure that your version of Mathematica has multiple kernels defined. Then, you can use Dynamic (or other symbols that take an Evaluator option, e.g., Button or Cell) to display the value of a symbol in another kernel.

Multiple kernels

You can create additional kernels using the Evaluation | Kernel Configuration Options menu item. Another method is to use CurrentValue. For instance, the following returns the list of evaluators that have been defined:

CurrentValue[$FrontEnd, EvaluatorNames]

{"Local" -> {"AutoStartOnLaunch" -> True}, "Local 2" -> {}}

Let's add a new evaluator:

CurrentValue[$FrontEnd, {EvaluatorNames, "Debug"}] = {"AppendNameToCellLabel"->True}

{"AppendNameToCellLabel" -> True}

Check:

CurrentValue[$FrontEnd, EvaluatorNames]

{"Local" -> {"AutoStartOnLaunch" -> True}, "Local 2" -> {}, "Debug" -> {"AppendNameToCellLabel" -> True}}

Dynamic

With multiple kernels, you can use Dynamic with the Evaluator option to display the value of a symbol in a different kernel. For example, suppose you have a running computation in kernel "Local". Then, in a notebook running the kernel "Debug", you can evaluate:

Dynamic[a, Evaluator->"Local"]

to display the value of the symbol a in kernel "Local".

For example, in the following animation, I create two notebooks, one using the kernel "Local", and the other using the kernel "Debug". Then, I start a computation in the "Local" notebook. Subsequently, in the "Debug" notebook, I execute the Dynamic expression above, which displays the value of a in the "Local" kernel:

enter image description here

$\endgroup$
18
$\begingroup$

Here is a quick solution in case you do not want / can not play with additional Kernels.

Steps

Assuming, the calculation already started:

  • create e.g. an input cell, just by typing below

  • Show cell expression Ctrl+Shift+E

  • Replace cell expression with:

    Cell[BoxData[ DynamicBox[ToBoxes[$CellContext`a, StandardForm]  ]]]
    
  • Switch back Ctrl+Shift+E

enter image description here

Why does it work?

Shortly, by default Dynamic content is evaluated via preemtive link which means that this evaluation can interrupt main link evaluations (our Do loop).

See: tutorial/AdvancedDynamicFunctionality#1938125129

We just need DynamicBox to appear in the notebook structure without using kernel.

We are editing cell expressions manually in the front end, the kernel is not needed. Once we finish the front end will try to handle our cell.

$\endgroup$
  • $\begingroup$ This is a neat trick, but is there a reason to prefer it over the more direct approach shown in my answer? $\endgroup$ – Mr.Wizard Jul 23 '18 at 12:37
  • 1
    $\begingroup$ @Mr.Wizard It is most useful when one does not know F7 solution. :) Your solution is the way to go here, even documentation says that. $\endgroup$ – Kuba Jul 23 '18 at 12:42
  • $\begingroup$ I'm surprised you didn't know of F7, but I'm glad I could introduce you to it. :-) $\endgroup$ – Mr.Wizard Jul 23 '18 at 13:01
  • 1
    $\begingroup$ I like this idea, as it doesn't involve any evaluations. $\endgroup$ – Carl Woll Jul 24 '18 at 4:35
  • $\begingroup$ @CarlWoll Strictly speaking doesn't DynamicBox entail evaluation? Nevertheless I think I know what you mean. $\endgroup$ – Mr.Wizard Jul 24 '18 at 4:39

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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