Skip to main content

Adding Trace produces error messages


This is very strange. As I was trying to debug this problem, I noticed when I add Trace then I get lots of internal errors generated. This also happens the first time after the kernel is started. So, with new fresh kernel, typing


vars = {a, b, c, d};
x = Times @@ vars;
$Assumptions = x > 0;
Trace[Simplify[1 == Sqrt[x] Sqrt[1/x]], TraceInternal -> True]

Gives


Mathematica graphics


But that is not all. Now with fresh kernel again, just adding one more variable to the list above, to make it 5 variables now, instead of 4, i.e. like this



vars = {a, b, c, d, e};
x = Times @@ vars;
$Assumptions = x > 0;
Trace[Simplify[1 == Sqrt[x] Sqrt[1/x]], TraceInternal -> True]

Now there is no error ! (make sure the kernel is fresh one before).


So it only happens when there are 4 variables in the list. Not 3 and not 5 and not 6. Only 4 !


Why does it fail when there are only 4 variables in the list? What is so special about the number 4?


Mathematica graphics



Answer




Short Version


The ultimate cause of this problem is an evaluation leak that occurs when an expression of the form MakeBoxes[StringForm[...]] is evaluated.


Longer Version


MakeBoxes has the attribute HoldAllComplete. This allows it to create the box representation of any expression without evaluating it. For example:


MakeBoxes[1 + 1]
(* RowBox[{"1", "+", "1"}] *)

MakeBoxes[Print[1]]
(* RowBox[{"Print", "[", "1", "]"}] *)


Apparently, StringForm gets special treatment by MakeBoxes:


MakeBoxes[StringForm["Hello, ``", "World"]]
(*
InterpretationBox["\"Hello, World\"",
StringForm["Hello, ``","World"], Editable -> False]]
*)

Notice how the StringForm[...] expression has been evaluated to produce the label for the InterpretationBox, in addition to the unevaluated expression that serves as the content of that box.


This is all well and good when the StringForm expression stands alone, but what about when it is an expression awaiting the values of local variables, like this:


MakeBoxes[StringForm[x, y]]

(*
During evaluation of In[20]:= StringForm::string: String expected at position 1
in StringForm[x,y]. >>

RowBox[{StringForm,[,RowBox[{x,,,y}],]}]
*)

Here we see a message very much like the one exhibited in the question. A simple RowBox is still generated, despite the message.


Isn't it invalid to have a free-standing StringForm expression like that? Yes, but we must remember that MakeBoxes is invoked recursively on all of its subexpressions. So we get an unexpected message when we try to generate boxes for a perfectly valid definition like this:


MakeBoxes[zot[x_, y_] := StringForm[x, y]]


(*
During evaluation of In[26]:= StringForm::string: String expected at position 1
in StringForm[x,y]. >>

RowBox[{RowBox[{"zot", "[", RowBox[{"x_", ",", "y_"}], "]"}], ":=",
RowBox[{"StringForm", "[", RowBox[{"x", ",", "y"}], "]"}]}]
*)

The StringForm did not start out to be an invalid free-standing expression, but the recursive action of MakeBoxes made it so.



More Gory Details


How do we know that StringForm is to blame?


If we evaluate the expressions from the question with the debugger turned on and message breaks enabled, we see this stack trace:


stack trace screenshot


We can see that StringForm triggered the first error, and we can see all of the behaviour described above in the preceding stack frames.


Why does the error only occur the first time the expression is evaluated?


The first time that the expression is evaluated, a great many packages are auto-loaded. Normally, this loading process is not shown by Trace. But because the example in the question uses TraceInternal, all of these internal activities are shown in the trace.


The first message is generated when MakeBoxes is called upon an auto-loaded definition that looks like this (in outline):


Parallel`Debug`Private`tracePrint[...] /; MemberQ[...] := 
CheckAbort[

Print[..., StringForm[Parallel`Debug`Private`sf, Parallel`Debug`Private`args]]
, Abort[]
]

In subsequent evaluations, these auto-loads do not occur so neither does the problem. Also, if we turn off TraceInternal, then the problem does not occur on even the first evaluation since none of the auto-load expressions appear in the trace.


Are all the messages due to this one problem?


No. Some of the messages are knock-on effects of this first message. Others are due to further occurrences of StringForm. And yet others appear to be due to similar evaluation leaks in other components.


Why does the problem only appear when there are four variables instead of three?


I'm not sure, but I have a guess. Observe the size of the trace output for each of the following variable counts:


1 variable: 2.9 meg

2 variables: 65 meg (error occurs)
3 variables: 1.5 meg
4 variables: 64 meg (error occurs)
5 variables: 7.0 meg
6 variables: 7.5 meg
12 variables: 10.6 meg

Note correlation of error occurrence with the spike in the output size for quadratic and quartic equations. I speculate that Simplify uses much more elaborate techniques for equations of this kind. Perhaps part of that elaboration involves loading special libraries... and at least one of those extra libraries ends up loading the troublesome Parallel`Debug definition. Or it may be simply that the enormous size of the trace output crosses a magic array size threshold, triggering the parallel computation machinery.


Comments

Popular posts from this blog

plotting - Plot 4D data with color as 4th dimension

I have a list of 4D data (x position, y position, amplitude, wavelength). I want to plot x, y, and amplitude on a 3D plot and have the color of the points correspond to the wavelength. I have seen many examples using functions to define color but my wavelength cannot be expressed by an analytic function. Is there a simple way to do this? Answer Here a another possible way to visualize 4D data: data = Flatten[Table[{x, y, x^2 + y^2, Sin[x - y]}, {x, -Pi, Pi,Pi/10}, {y,-Pi,Pi, Pi/10}], 1]; You can use the function Point along with VertexColors . Now the points are places using the first three elements and the color is determined by the fourth. In this case I used Hue, but you can use whatever you prefer. Graphics3D[ Point[data[[All, 1 ;; 3]], VertexColors -> Hue /@ data[[All, 4]]], Axes -> True, BoxRatios -> {1, 1, 1/GoldenRatio}]

plotting - Filling between two spheres in SphericalPlot3D

Manipulate[ SphericalPlot3D[{1, 2 - n}, {θ, 0, Pi}, {ϕ, 0, 1.5 Pi}, Mesh -> None, PlotPoints -> 15, PlotRange -> {-2.2, 2.2}], {n, 0, 1}] I cant' seem to be able to make a filling between two spheres. I've already tried the obvious Filling -> {1 -> {2}} but Mathematica doesn't seem to like that option. Is there any easy way around this or ... Answer There is no built-in filling in SphericalPlot3D . One option is to use ParametricPlot3D to draw the surfaces between the two shells: Manipulate[ Show[SphericalPlot3D[{1, 2 - n}, {θ, 0, Pi}, {ϕ, 0, 1.5 Pi}, PlotPoints -> 15, PlotRange -> {-2.2, 2.2}], ParametricPlot3D[{ r {Sin[t] Cos[1.5 Pi], Sin[t] Sin[1.5 Pi], Cos[t]}, r {Sin[t] Cos[0 Pi], Sin[t] Sin[0 Pi], Cos[t]}}, {r, 1, 2 - n}, {t, 0, Pi}, PlotStyle -> Yellow, Mesh -> {2, 15}]], {n, 0, 1}]

plotting - Mathematica: 3D plot based on combined 2D graphs

I have several sigmoidal fits to 3 different datasets, with mean fit predictions plus the 95% confidence limits (not symmetrical around the mean) and the actual data. I would now like to show these different 2D plots projected in 3D as in but then using proper perspective. In the link here they give some solutions to combine the plots using isometric perspective, but I would like to use proper 3 point perspective. Any thoughts? Also any way to show the mean points per time point for each series plus or minus the standard error on the mean would be cool too, either using points+vertical bars, or using spheres plus tubes. Below are some test data and the fit function I am using. Note that I am working on a logit(proportion) scale and that the final vertical scale is Log10(percentage). (* some test data *) data = Table[Null, {i, 4}]; data[[1]] = {{1, -5.8}, {2, -5.4}, {3, -0.8}, {4, -0.2}, {5, 4.6}, {1, -6.4}, {2, -5.6}, {3, -0.7}, {4, 0.04}, {5, 1.0}, {1, -6.8}, {2, -4.7}, {3, -1....