3
$\begingroup$

I have encountered unexpected behaviour when assigning variables in Manipulate. Consider an inverted parabola

y[x_, c_] := -x^2 + c

The following code finds the maximum of y and plots it

Manipulate[
    Grid[{
       { ymax = FindMaximum[{y[x, c], -1 <= x <= 1}, x] },
       { Plot[y[x, c], {x, -1, 1}] }
    }],
{c, -0.5, 0.5}]

which gives, for a the initial default value of c=-0.5,

 In[3]:= ymax
Out[3]:= {-0.5, {x -> -1.70726*10^-14}}

Now I would expect that when I re-use ymax to calculate the maximum with a different value of c=2, it would permanently change the state of ymax:

 In[4]:= ymax = FindMaximum[{y[x, 2], -1 <= x <= 1}, x]
Out[4]:= {2, {x -> -1.70726*10^-14}}

But it does not:

 In[5]:= ymax
Out[5]:= {-0.5, {x -> -1.70726*10^-14}}

It seems that the cell with Manipulate in it re-evaluates every time I evaluate any cell; for example when I try to start with a clean slate and run

ClearAll["Global`*"]

in a different cell, the cell with Manipulate throws a bunch of error messages (because I have cleared y[x,c] and so Manipulate tries to evaluate without that function defined).

My questions are: is this behaviour, re-evaluation of Manipulate when you evaluate, known behaviour? Is it useful in a different context? Can I avoid it if I really want to re-use the variable again outside Manipulate, for whatever reason?

(General tips also welcomed as I am (clearly) a Mathematica novice!)

$\endgroup$
7
$\begingroup$

Updated to handle $ showing from using module variable.

Add TrackedSymbols :> {c} and add Module

ClearAll[x,y,c];
y[x_,c_]:=-x^2+c

Manipulate[
Module[{ymax,x},
   ymax=FindMaximum[{y[x,c],-1<=x<=1},x];
   Grid[
   {
     {str[ymax]},
     {Plot[y[x,c],{x,-1,1}]}
   }
   ]
]
,
{c,-0.5,0.5},
TrackedSymbols:>{c}
]

(*this function to handle $ in local variable names *)
str[expr_]:=Module[{},
      StringReplace[ToString[expr,
        FormatType->TraditionalForm],
        c:LetterCharacter~~"$"~~DigitCharacter..:>c]];

Now

Mathematica graphics

Manipulate by default will track all symbols that shows inside it. So when you typed ymax, frontend tracked this symbols and Manipulate went and re-evaulated its expression again, and that is why you got 0.5.

As a rule of thumb, I always use TrackedSymbols. This keep things safe. Also use a Module inside Manipulate to add internal context. Like this:

So rules of thumbs

  1. Use Module inside Manipulate to hide any non-control variables used inside Manipulate. (in your example, these would be x and ymax.

  2. Use TrackedSymbols to explicitly list the symbols being tracked. In your case c.

This should eliminate most of the problems.

ps. the $ showing up attached to symbols, when printing/displaying expressions from inside module is common in Mathematica. See print-expressions-using-local-variables-in-module-without-dollar-sign-is-that-p

$\endgroup$
  • $\begingroup$ Thanks Nasser. Adding TrackedSymbols :> {c} as you suggested did not solve the problem; the behaviour remained as per my original post. Using Module did work and kept the scope of ymax to the Manipulate command. However inside the output cell the second output of FindMaximum had a dollar sign and a five digit number that seems to increase whenever it runs (what does this mean in Mathematica?!) i.e. {-0.5, {x$23166 -> -1.70726*10^-14}}. $\endgroup$ – jms547 Apr 26 '18 at 21:24
  • 1
    $\begingroup$ @jms547 Ok, for some reason it was working for me when I tried it. But ok, so you need Module. (I use Module any way all the time). I added also small function to remove the $ from the local variable names. This is common problem. When printing any symbol from module, it will have $ attached. Hopefully this version will work OK for you. $\endgroup$ – Nasser Apr 26 '18 at 23:27

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.