# Module inside of Manipulate Example

Here is a very nice example from The Student's Introduction to MATHEMATICA.

Manipulate[Module[{x, y},
ContourPlot[Exp[-x^2 - y^2] + x y, {x, -1, 1}, {y, -1, 1},
Contours -> 20,
Epilog ->
Dynamic[{Arrow[{pt,
pt + {y - 2 E^(-x^2 - y^2) x, x - 2 E^(-x^2 - y^2) y} /. {x ->
pt[], y -> pt[]}}]}]
]],
{{pt, {.5, .5}}, Locator,
Appearance -> Graphics[{Red, Disk[]}, ImageSize -> 5]}]


Which produces a wonderful demonstration. My next step was to try the following:

Clear[x, y, f];
f = E^(-x^2 - y^2) + x y;


Then in the next cell, I tried:

Manipulate[Module[{x, y},
ContourPlot[f, {x, -1, 1}, {y, -1, 1},
Contours -> 20,
Epilog ->
Dynamic[{Arrow[{pt,
pt + Grad[f, {x, y}] /. {x -> pt[], y -> pt[]}}]}]
]],
{{pt, {.5, .5}}, Locator,
Appearance -> Graphics[{Red, Disk[]}, ImageSize -> 5]}]


Which gave only this: I gave Evaluate a try but that didn't work. So I tried removing the Module.

Manipulate[
ContourPlot[f, {x, -1, 1}, {y, -1, 1},
Contours -> 20,
Epilog ->
Dynamic[{Arrow[{pt,
pt + Grad[f, {x, y}] /. {x -> pt[], y -> pt[]}}]}]
],
{{pt, {.5, .5}}, Locator,
Appearance -> Graphics[{Red, Disk[]}, ImageSize -> 5]}]


And that worked. But try typing

x=12


in the next cell and watch what happens to the arrow.

Finally I tried wrapping everything with a DynamicModule to see if it would prevent the x=12 issue in the notebook. First, this cell.

Clear[x, y, f];
f = E^(-x^2 - y^2) + x y;


Then:

DynamicModule[{x, y},
Manipulate[
ContourPlot[f, {x, -1, 1}, {y, -1, 1},
Contours -> 20,
Epilog ->
Dynamic[{Arrow[{pt,
pt + Grad[f, {x, y}] /. {x -> pt[], y -> pt[]}}]}]
],
{{pt, {.5, .5}}, Locator,
Appearance -> Graphics[{Red, Disk[]}, ImageSize -> 5]}]]


This only produced: As folks know, there has been a lot of discussion on not using Module inside of Manipulate and this is probably a good example of why not, but there is a lot of stuff happening here that I don't understand and could use some discussion explaining some of the issues:

1. Why does Dynamic in the first code just update the arrow and not the contour plot.

2. Why doesn't f = E^(-x^2 - y^2) + x y; and Grad[f, {x, y}]; work in the second piece of code?

3. Why doesn't DynamicModule work in the last piece of code?

4. And what is the best way to protect the arrow if a student type x=12 in their notebook?

Answers to Questions #3 and #4:

I should have defined the function f in the body of my dynamic module.

DynamicModule[{x, y, f},
f = E^(-x^2 - y^2) + x y;
Manipulate[
ContourPlot[f, {x, -1, 1}, {y, -1, 1}, Contours -> 20,
Epilog ->
Dynamic[{Arrow[{pt,
pt + Grad[f, {x, y}] /. {x -> pt[],
y -> pt[]}}]}]], {{pt, {.5, .5}}, Locator,
Appearance -> Graphics[{Red, Disk[]}, ImageSize -> 5]}]]


This works and x is protected.

• You can define f outside the module if you use f[x_,y_]:=Exp[...], and then use 'f[x,y]' inside the ContourPlot, and the Grad. – N.J.Evans Jul 30 '15 at 15:21
• @N.J.Evans. Sorry, that won't work in this situation. We're talking about having several Manipulate activities in a single notebook, not just one. And we need to protect the Manipulate activities from a host of static things inside the notebook. – David Jul 30 '15 at 18:56

Both Module and DynamicModule are shadowing the global variables x and y in the example in which you use them. The demonstration is best written without using either Module or DynamicModule.

Manipulate[
ContourPlot[f, {x, -1, 1}, {y, -1, 1}, Contours -> 20,
Epilog -> Dynamic[Arrow[{pt, pt + grad /. {x -> pt[], y -> pt[]}}]]],
{f, None},
{{pt, {.5, .5}}, Locator, Appearance -> Graphics[{Red, Disk[]}, ImageSize -> 5]},
TrackedSymbols :> {pt},
Initialization :> (
f = E^(-x^2 - y^2) + x y; ### Update

Sorry that I was careless about the testing of my code. The issue that you raise in your comment can be fixed by using pure functions. I do need to introduce Module in the fix.

My reworking of your example still keeps everything localized, Specifying controls that are non-functioning and invisible, like func and grad, is a useful trick for creating localized variables in Manipulate expressions,

x = 12; y = 42; func = 1; grad = 0;
Manipulate[
ContourPlot[func[x, y], {x, -1, 1}, {y, -1, 1},
Contours -> 20,
Epilog -> Dynamic[Arrow[{pt, pt + grad[pt[], pt[]]}]]],
{func, None},
{{pt, {.5, .5}}, Locator, Appearance -> Graphics[{Red, Disk[]}, ImageSize -> 5]},
TrackedSymbols :> {pt},
Initialization :> (
func = (E^(-#1^2 - #2^2) + #1 #2 &);
With[{
g = Module[{x, y},
Grad[func[x, y], {x, y}] /. {x -> #1, y -> #2}]},
Function[g]])]


The code taken from The Student's Introduction to MATHEMATICA works because it doesn't define functions, but uses expressions for both the function and the gradient. I don't like that approach because it is too rigidly coupled to a particular function. With my fixed code you only need to redefine func to introduce a new function. For example

Manipulate[
ContourPlot[func[x, y], {x, -1, 1}, {y, -1, 1},
Contours -> 20,
Epilog -> Dynamic[Arrow[{pt, pt + grad[pt[], pt[]]}]]],
{func, None},
{{pt, {0, .1}}, Locator, Appearance -> Graphics[{Red, Disk[]}, ImageSize -> 5]},
TrackedSymbols :> {pt},
Initialization :> (
func = (E^(#1^2 - #2^2) &);
With[{
g = Module[{x, y},
Grad[func[x, y], {x, y}] /. {x -> #1, y -> #2}]},
Function[g]])] • Sorry, it does not work. Put your code in a new notebook, quit the kernel, run your code, then in the next cell, type x=12 and run the cell. Watch what happens to the arrow. The Manipulate no longer runs properly. – David Jul 30 '15 at 3:00
• @David. I believe I have fixed the code so that no global variables can interfere with it. – m_goldberg Jul 30 '15 at 15:53

This is taking your first modification of the original code and just changing the way f is defined, then using that function inside the module. It seems to work fine for me.

Clear[x, y, f];
x = 10;(*Global values have no effect on Module...*)
y = 12;(*Global values have no effect on Module...*)
f[x_, y_] := E^(-x^2 - y^2) + x y;
Manipulate[
Module[
{x, y},
ContourPlot[f[x, y], {x, -1, 1}, {y, -1, 1}
, Contours -> 20
, Epilog -> Dynamic[{
Arrow[
{pt, pt + Grad[f[x, y], {x, y}] /. {x -> pt[], y -> pt[]}}
]
}]
]
]
, {{pt, {.5, .5}}
, Locator
, Appearance -> Graphics[{Red, Disk[]}, ImageSize -> 5]}
]

1. Your first piece of code does not update the contour plot because you set f in terms of the global variables x and y. Inside the module x and y are scoped uniquely so x becomes x\$1234, or something, and similar for y. Inside the module f is still a symbolic expression. This is why you should define f as a pure function, using set delayed.

2. Setting f as a pure function will allow you to write Grad[f[x,y],{x,y}], which will work, unless you've set a value for x. That value will be applied before grad evaluates. You have a few options there. You can use Unique[x] to generate a symbol with no definitions, and then use that in Grad, or just clear x explicitly before calling Grad. Or you can use a module to scope x and y for this particular calculation. Which is basically the same thing as using Unique, but MMA handles the scoping for you.

3. See 1. The symbols x and y are again localized to unique values within the dynamic module.

4. If you write the function as I have here global definitions of x have no effect on the code inside the module. And you don't have to worry about students defining values for x or y.

• Sorry, this does not work. Perform the following: (1) create a new notebook and quite the kernel. Copy your code into a cell and evaluate the cell. Then go to the next cell and enter the function f[x_, y_] := E^(x^2 - y^2) + x y; and evaluate this second cell. You will see that the image in your manipulate changes. – David Jul 30 '15 at 23:21
• If you keep moving the goal posts no one will ever answer your question. You listed four questions, I answered them. You should write another question about scoping that specifically addresses how to keep all symbols local, because that can be done. It's just not what you asked. – N.J.Evans Jul 31 '15 at 2:19