5
$\begingroup$

Normally, in Global context, these 2 are equivalent

eqn = "r-x";
r = -2;
Plot[ToExpression[eqn], {x, -5, 5}]

and

eqn = r - x;
r = -2;
Plot[eqn, {x, -5, 5}]

But inside Manipulate (which is a DynamicModule) and assuming r is a control variable, then these are not equivalent. There is some context or scope change that is causing this which I do not fully understand. i.e. the following do not work the same way:

Manipulate[

 eqn = "r-x";
 Plot[ToExpression[eqn], {x, -5, 5}],
 {{r, -1, "r"}, -2, 2, .1, Appearance -> "Labeled"},
 TrackedSymbols :> {r}

 ]

and

Manipulate[

 eqn = r - x;
 Plot[eqn, {x, -5, 5}],
 {{r, -1, "r"}, -2, 2, .1, Appearance -> "Labeled"},
 TrackedSymbols :> {r}

 ]

The reason this would be useful, is that one can use an InputField, to enter an equation as a String, then convert it to an Expression and use it inside Manipulate, where the equation can have in it a variable which happens to be a control variable. Here is an example:

Manipulate[
 Plot[ToExpression[eqn], {x, -5, 5}],
 Grid[{
   {"r=", Control[{{r, -1, ""}, -2, 2, .1, Appearance -> "Labeled"}]},
   {"eqn", InputField[Dynamic[eqn], String], Dynamic[eqn]}
   }],
 {{r, -2}, None},
 {{eqn, "r-x"}, None}
 ]

enter image description here

The idea is that one can enter an expression in the InputField with r in it, and then change r using the slider afterwords.

The current solution to this is shown in this Prevent interdependence of controls but it is a work around and it helps if one understands better why the above example does not produce the same result when used inside Manipulate.

$\endgroup$

1 Answer 1

4
$\begingroup$

Any issues with this?

Manipulate[
 Plot[ReleaseHold[eqn /. Symbol[$Context <> "r"] :> r], {x, -5, 5}] //
   Dynamic, 
 Grid[{{"r=", 
    Control[{{r, -1, ""}, -2, 2, .1, 
      Appearance -> "Labeled"}]}, {"eqn", 
    InputField[Dynamic[eqn], Hold@Expression], 
    Dynamic[HoldForm @@ eqn]}}], {{r, -2}, None}, {{eqn, Null}, None},
 Initialization :> 
  ToExpression["r", InputForm, 
   Function[r, eqn = Hold[r + x], HoldFirst]]]

When you evaluate, for example

DynamicModule[{x = 0},
 Button["Increment", ++x]]

it does something similar to a Module except that the result is again wrapped in DynamicModule. So in this case it retuns (almost) the exact same expression, but in the process, the kernel creates a variable (like Module would) and stores it. Even though the front end "owns" x, the kernel has it's copy. And this copy has some local ugly unique name that guarantees no conflicts. In many dynamic updates, Mathematica simply assumes that the value the kernel has is correct, so it doesn't need to sync it and saves time. So, it just sends to the kernel the dynamic code with xs replaced by the corresponding FE`x$29whatever. Now, if your code has a line such as Symbol["x"], that won't be recognized as the symbol x until the kernel already has the code and is evaluating it. So, it simply becomes the variable x in the current context. In the version in this answer, that "r" in the current context is replaced by whatever local variable Mathematica automatically replaces r with.

Your original code had that problem.

Take

Module[{x = 8},
 ToExpression["x+8"]
 ]

Now, that returns x and not 8 It could be fixed with

Module[{x = 8},
 ToExpression["x+8"] /. Symbol["x"] -> x
 ]

16

Summary: important points

  • The kernel stores DynamicModule locals with a different name
  • The translation is done before the evaluation takes place. Otherwise it is simply not done
  • InputField doesn't do this translation
$\endgroup$
9
  • $\begingroup$ That's because it isn't initialized properly, it was meant to edit the input field $\endgroup$
    – Rojo
    Sep 28, 2012 at 15:53
  • $\begingroup$ I just edited... @NasserM.Abbasi $\endgroup$
    – Rojo
    Sep 28, 2012 at 15:54
  • $\begingroup$ As soon as you type a number in place of r, the control for r decouples from the rest and does not affect things any more. $\endgroup$ Sep 28, 2012 at 15:57
  • $\begingroup$ @LeonidShifrin, but if you type a number in place of r isn't it supposed to stop depending on r? If I type r back and press return it works again for me $\endgroup$
    – Rojo
    Sep 28, 2012 at 16:03
  • $\begingroup$ You may be right. Perhaps I interpreted the question differently,I just made it possible to control the value of r either in the InputField or by the slider - which is probably not what was asked. $\endgroup$ Sep 28, 2012 at 16:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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