Message Boards Message Boards

0
|
7670 Views
|
12 Replies
|
4 Total Likes
View groups...
Share
Share this post:

Problem with SaveDefinitions in Manipulate

Posted 10 years ago

Here is a minimal example I don't really understand:

Manipulate[ x,{{x, 0.5}, 0, 1},SaveDefinitions -> True ]

When I run this code after using the variable x in other calculations, the initial value of x in the slider will be the one that comes from outside, not the 0.5 specified in the code. It is strange, because the variable x is localised inside the manipulate, the outside x does not change after running this code. But still, the outside x is used to initialize the slider. Any suggestions how to fix this?

POSTED BY: Ferenc Beleznay
12 Replies

Yes, we've given different approaches to the problem -- Mathematica gives one lots of choices!

One thing worth remembering is that Manipulate is a high level function whose purpose is to create a DynamicModule with a variety of option settings. The end result of executing a Manipulate is to create a DynamicModule expression internally (well, inside the cell it's a DynamicModuleBox...). When a Manipulate is executed with SaveDefinitions->True, the code first finds all symbols in the first argument, then it determines whether there are any preexisting definitions for those symbols. If there are any it then goes on to create a DynamicModule with those definitions within its Initialization option. When the DynamicModule is then executed, those Initializations are first executed. The result is the behavior that you notice in your simple example. At least that is roughly how it goes.

POSTED BY: David Reiss
Posted 10 years ago

Yes, I see this logic, but I still think that this is a bug in the way Manipulate is implemented. If the first argument is a Module, then the interpreter will not look for preexisting definitions for the symbols specified as local in that Module. Since the control symbols in Manipulate are also assumed to be local (at least this is my understanding), they should be treated the same way. Probably there is a good reson why they are not. Also, apparently the initial condition for the control variable is completely ignored if a value of the control symbol is found earlier. Again, probably there is a reason for this.

Since I now understand a bit better what is going on (from the users point of view), and there is an easy way around my problem, I think I will just let it go and let the developers think about the (probably good) reasons behind their approach.

POSTED BY: Ferenc Beleznay

You might want to look at these if you are interested in learning more about SaveDefinitions

the-dangers-of-savedefinitions-should-this-really-happen

savedefinitions-considered-dangerous

POSTED BY: Nasser M. Abbasi

Initialization :>{...} is convenient when there are relatively few functions to supply to Manipulate or DynamicModule. However when there there is more complex code to supply the development process becomes unwieldy. Then developing that code in the notebook elsewhere and then and using SaveDefinitions->True is a valuable approach.

Also, expanding on Nasser's comment, you can set the context properties for your notebook using the Evaluation>Notebook Default Context menu item and, for example, choose "Unique to this Notebook" or "Unique to each Cell Group" to isolate the contexts of symbols. Also, you can edit the specific Cell to set it's specific CellContext option.

POSTED BY: David Reiss

My only experience is with using Manipulate for demos. So I was thinking in that context. When making a demo, all the code used by the notebook demo, must be included in the demo notebook, and physically be part of it. So for a demo, I do not see the point of using SaveDefinitions vs. Initialization, as one can't load external functions when the demo is deployed anyway. What I end up doing, is copy other functions I wrote from one demo to the other manually. So now I have copies of the same function in more than one demo. It is not a good way to do things, but there is no other option. It will be nice if one can load a package from a demo, and this way, one can have the same code in the package, but used by different demo notebooks.

POSTED BY: Nasser M. Abbasi
Posted 10 years ago

Thank you both for your comments. However, both of you give different advices on how to localize the variable. But the variable is already localized by being a control variable inside Manipulate. I don't see why it needs to be localized again. SaveDefinition may save something, but it does not change the value of the outside x. I tried it. So the outside x is not the variable Manipulate works with. How come then it uses it's value? I still think this should not happen this way.

However I found a solution. Instead of giving the starting value of x in the controller definition (which as I see it should override everything, but apparently it does not), I initialize x in the initialization part of Manipulate. The following code works for me.

Manipulate[x, {x, 0, 1}, SaveDefinitions -> True,  Initialization :> (x = 0.5)]

The value of the outside x is not changed with this version of the code either.

POSTED BY: Ferenc Beleznay

But if you are using Initialization :> (x = 0.5)], what is point of using SaveDefinitions -> True ? Each time the Manipulate is run, x will be initialized to 0.5 before anything. I do not see the point of using SaveDefinitions and Initialization on the same symbol. Can you please explain the logic of this method?

POSTED BY: Nasser M. Abbasi
Posted 10 years ago

I use SaveDefinitions because I need it for the other variables. I did not include the rest of the code in the example, because that was not the problem. But there is no way to specify the scope of SaveDefinition (or at least I don't know how), so it includes the control variable, too.

POSTED BY: Ferenc Beleznay

This happens by definition. saveDefinitions means to use "saved" definitions of every symbol in Manipulate. So, when Manipulate runs, it "sees" x defined, so it uses its value. Manipulate does not know if this value came from after or before the notebook was opened, i.e. before or after current Manipulate ran. It has no time-line to know or time-stamp of each symbol.

It just sees "SaveDefinitions" there, and it also sees "x" defined, so it uses it.

I myself never use SaveDefinitions, as it causes more trouble for me than it is worth it and its semantics is fuzzy to me. I Simply use "Initialization :> (...)" in Manipulate.

POSTED BY: Nasser M. Abbasi

Something like this would work:

DynamicModule[{x},
 Manipulate[x, {{x, 0.5}, 0, 1}, SaveDefinitions -> True]
 ]
POSTED BY: David Reiss
Posted 10 years ago

Yes, it works, thank you. However I still don't understand why I need this. Isn't this something that should not happen? The variable is local, so how come it initializes with a value of another variable, especially when the initialization value is explicitly given in the code. Also, I would like to upload a demonstration to the Wolfram website, where it should be a single Manipulate. I would prefer a solution without an extra layer around it.

POSTED BY: Ferenc Beleznay

Also, I would like to upload a demonstration to the Wolfram website

But if you are doing a demo for WRI, then you have to use a demo style sheet. In that stylesheet, you can't have cell outside your own Manipulate cell and the definition/initialization cell that are part of the style sheet. So this issue will not happen. If you worried about clash from other open notebooks, then you can localized symbols per notebook level. i.e. you separate the "x" from notebook, from the "x" in your demo notebook.

see is-there-a-way-to-separate-variables-between-multiple-notebooks

POSTED BY: Nasser M. Abbasi
Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
Attachments
Remove
or Discard

Group Abstract Group Abstract