19
$\begingroup$

I am now struggling to understand code that contains the following (simplified) Manipulate structure.

Manipulate[
    complexparts[E^(I Pi t)],
 {{t, 1/4.}, 0., 2},
 {{complexparts, {Re[#], Im[#]} &}, None}]

I am having difficulty with the last line: {{complexparts, {Re[#], Im[#]}&}, None}. Somehow, this creates a "pure function" with a name "complexparts," which is then used above in the line

complexparts[E^(I Pi t)]

I tried to execute these independently outside the body of code so I could watch them do what they do, but without success. I evaluated:

{{complexparts, {Re[#], Im[#]} &}, None}

and then:

complexparts[x+Iy]

But my output was just:

complexparts(x+I y)

Can I get some help in understanding how {{complexparts, {Re[#], Im[#]} &}, None} works? And what does the word None do?

$\endgroup$

3 Answers 3

26
$\begingroup$

What the first part of the variable declaration does

Manipulate initializes complexparts to {Re[#], Im[#]} & when it executes. (In general, a declaration of the form {{var, expr},...} in a Manipulate results in the local variable var being initialized to expr.) To use complexparts outside of the Manipulate, do this:

complexparts = {Re[#], Im[#]} &;
With[{θ = 0.25, b = 0.5 + 0.2 I},
 complexparts /@ {E^(I π θ), b E^(-I π θ), 
   E^(I π θ) + b E^(-I π θ), 0}]

(* {{0.707107, 0.707107}, {0.494975, -0.212132}, {1.20208, 0.494975}, {0, 0}} *)

Addendum 1 -- What "None" does

To illustrate @Mr.Wizard's remark about Initialization, one could modify @David's code above as follows:

Manipulate[
 complexparts[E^(I Pi t)],
 {{t, 1/4.}, 0., 2},
 {complexparts, None},
 Initialization :> (complexparts = {Re[#], Im[#]} &)
]

The declaration {complexparts, None} declares complexparts to be a local variable of the DynamicModule that is created by the Manipulate command. Whether complexparts needs to be declared local or not doesn't seem important in such an example. Generally I try to localize variables whenever possible, especially in Manipulate, as it saves headaches if you're doing scratch work in the same kernel that the Manipulate uses. Since the intended scope of complexparts is entire body of the Manipulate (and furthermore, it never changes), declaring it as a variable in a Manipulate seems appropriate. It hardly matters here, but in some cases it can make a big difference.

Update -- Reference to the manual

I have found a passage in the manual which I believe documents the usage of None. There are two alternatives for specifying a control type

{u, ..., ControlType -> type}

or more briefly

(u, ..., type}

This last one is not described but is used frequently in the examples. Technically it has the form

{u, ..., func}

where func is a function that constructs the control; however, since None is not a function, one can object that None must be treated as a special case. On the other hand, the reference page state

Possible control types include: Animator.... None can also be used.

The effect of a variable declaration is described thus:

Manipulate generates a DynamicModule object, with the variables u, v, etc. specified as local.

While the manual does not clearly state that {u,..., None} is accepted usage, it does state that what is practically equivalent, {u,..., ControlType -> None} is:

Use ControlType to specify the type of control to use, including None:

Manipulate[u, {u, 0, 1}, ControlType -> None]

Addendum 2 -- "None" and other alternatives

In response to the updated title for @David's question, as well as to some of the comments, the following might be worth studying to see the differences.

Problem. We need the variable var to be local. It takes a long time to compute its value. It won't change its value, but we need to dynamically access the value (or parts of the value).

As an example, var is to be a list of squares and the "long time" is simulated by Pause[0.2]. We wish to display part n of var with the slider for n. The solutions below all do the "same" thing. But there are differences in how each works. Depending on what one is trying to do, the differences can be significant. In my opinion, #1 is the best; the others can be fine in appropriate situations. I'll explain below.

(* 1 *)
Manipulate[
 var[[n]],
 {n, 1, 10, 1},
 {{var, Table[Pause[0.2]; n^2, {n, 10}]}, None}
]

(* 2 *)
Manipulate[
 var[[n]],
 {n, 1, 10, 1},
 {var, None},
 Initialization :> (var = Table[Pause[0.2]; n^2, {n, 10}])
]

(* 3 *)
Module[{var = Table[Pause[0.2]; n^2, {n, 10}]},
 Manipulate[
  var[[n]],
  {n, 1, 10, 1}
  ]
]

(* 4 *)
Manipulate[
 Module[{var = Table[Pause[0.2]; n^2, {n, 10}]},
  var[[n]]],
 {n, 1, 10, 1}
 ]

enter image description here

The most important thing to ask is when is var calculated in each solution above:

  1. Once when the input cell is first evaluated.

  2. Every time the Manipulate output is (re)activated. For instance, every time the notebook is opened.

  3. Once when the input cell is first evaluated. (Same as #1.)

  4. Every time n changes value. This is terrible.

The second question is where is var stored:

  1. In the output cell (in the notebook) and loaded into the kernel. Can make a very big notebook file, but the data is persistent.

  2. In the output cell l (in the notebook) as in 1 (and overwritten by the Initialization code). Correction due to @unlikely.

  3. Just in the kernel, when the input cell is evaluated. (Note the difference in #1.)

  4. In the kernel, after recalculation.

Next, does the output work when the notebook is reopened? Will it work as a CDF? As a Wolfram Demonstration? (Each has the same answer for a given solution):

1, 2, 4: Yes. 3: No. (Even if var were made global, a Demonstration must have Manipulate as the outside function.)

So in summary,

  1. Fast, fast on re-open of notebook, quick start-up in a CDF.

  2. Fast, slow on re-open, slow start-up in a CDF. (Change pause to 5 seconds, and you'll see a problem.)

  3. Fast, won't work on reopen, won't work in a CDF.

  4. Super slow all the time.

Now what's going on?

In #1, the data is computed first and fed to Manipulate, which stores in the output. That's what happens in {{var, initial_value},..}.

In #2, the Initialization code is stored unevaluated in the output. Every time the output cell is activated (by opening the notebook and scrolling to the cell), the Initialization code is evaluated.

In #3, a local variable is first created in the kernel and initialized; the local id for var is stored in the Manipulate output. When the notebook is reopened, this id is invalid. You have to reevaluate the input again to get it to work.

In #4, a new local variable is created every time the Manipulate is updated (on start-up and every time a control is moved or a tracked variable changes); the variable is then initialized, so this can cost a lot a time. When the initialization time is short, you won't really notice the difference between #1, #2, and #4.

$\endgroup$
10
  • $\begingroup$ @Artes, Thanks for the edit. How do you get the Greek letters? $\endgroup$
    – Michael E2
    Dec 31, 2012 at 0:09
  • 1
    $\begingroup$ Take a look at aswers to this question : mathematica.stackexchange.com/questions/1137/… In case that doesn't work or, you can always copy/paste Greek letters from other posts. $\endgroup$
    – Artes
    Dec 31, 2012 at 0:19
  • 1
    $\begingroup$ @Mr.Wizard Thanks. To be complete, I should have discussed what happens if you replace Module by DynamicModule -- #3 becomes like #1, except #3 still won't be acceptable as a Demonstration, but it adds a level of localization someone might desire. #4 stays essentially the same, except some stuff gets stored in the front-end. $\endgroup$
    – Michael E2
    Jan 1, 2013 at 18:01
  • $\begingroup$ @MichaelE2 Hello Michael, it was nice to meet you. Pity that only once. Hope to see you next time too. :) $\endgroup$
    – Kuba
    Oct 25, 2014 at 17:04
  • $\begingroup$ @Kuba Hi, it was nice to meet you, too, and too bad it was so brief. Next time we should have an SE dinner or something. :) $\endgroup$
    – Michael E2
    Oct 25, 2014 at 20:46
9
$\begingroup$

I'm not surprised you're having trouble as {{complexparts, {Re[#], Im[#]} &}, None} is (to the best of my knowledge) a nonstandard "hack" and not part of the documented standard uses. I have used it myself but I still don't recommend it. Usually you can use the Initialization option instead.

Evaluating {{complexparts, {Re[#], Im[#]} &}, None} by itself outside of Manipulate doesn't do anything. Rather, this is part of the syntax of Manipulate describing a parameter complexparts with a starting value of {Re[#], Im[#]} & and no control (None).

$\endgroup$
3
  • $\begingroup$ The use of {var, None} in Manipulate was taught to me by a Wolfram Demonstrations editor back in Mma V6. Manipulate creates a DynamicModule with all the local variables declared at the end of the Manipulate, with controls attached to them unless you say None. They sometimes seemed to prefer local variables to be used within a Manipulate to be declared that way. The use of None is undocumented, but perhaps not nonstandard. One can't always accomplish the same thing with Initialization. $\endgroup$
    – Michael E2
    Dec 31, 2012 at 0:30
  • $\begingroup$ @Michael Alright, that adds to the validity of the practice, and I agree that it is sometimes hard to do without (see linked answer). $\endgroup$
    – Mr.Wizard
    Dec 31, 2012 at 0:33
  • $\begingroup$ I have added an argument to my answer that this use of None was intended. Not exactly a watertight argument, but add to it that the usage works in practice, and I think it has some weight. $\endgroup$
    – Michael E2
    May 12, 2013 at 13:38
2
$\begingroup$

That code you're pulling out of the Manipulate is just a list. complexparts is a blank symbol -- it's meaningless on its own. You may as well just type {1, 2, 3, 4}. The reason that code acquires meaning is because the Manipulate function chooses to interpret that list in a certain way. In other words, check the documentation for Manipulate to understand what that list means (within Mathematica, click on Manipulate and hit F1). That same list will mean something different in another context.

In this case remove the None and you'll see that the list is a manipulator/variable specification for Manipulate. The None is a meaningless symbol that Manipulate chooses to interpret to mean "don't show this control." So basically that list is just a weird way of declaring a variable within Manipulate. A variable that happens to be a function.

I'm not sure why that code is like that. You should just declare functions at the top or within a Module. Here's a simplified version of the code:

ReIm[c_] := {Re[c], Im[c]};

Manipulate[
 b = Complex @@ bmanipulate;

 Show[
  Graphics[GraphicsComplex[
    ReIm /@ {E^(I π θ), b E^(-I π θ), E^(I π θ) + b E^(-I π θ), 0},{
     Circle[4], {Red, Circle[4, Norm[b]]}, Arrow[{4, 1}],
     {Red, Arrow[{4, 2}]}, Line[{1, 3, 2}], {Dashed, Line[{4, 3}]}
     }], PlotRange -> 2, Axes -> True],

  ParametricPlot[
   ReIm[E^(I π t) + b E^(-I π t)], {t, 0, θ + 10^-6}], 
  ImageSize -> 250],

 {{ θ, 1/4.}, 0., 2},
 {{bmanipulate, {0.5, 0}}, {-1, -1}, {1, 1}, ControlPlacement -> Left}]

I'm not sure that the mathematical stuff stayed correct after I redid it, but in terms of the code it should be easier to follow.

(Small note. b here is a global variable because it's no longer a Manipulate variable. If you don't want variables leaking then use Module or With).

$\endgroup$
4
  • $\begingroup$ Why should one declare functions at the top or within a Module? Do you think that rule applies only to functions or to other variables that are local, or constant, or something else? $\endgroup$
    – Michael E2
    Dec 31, 2012 at 0:45
  • $\begingroup$ By the way, the statement b = Complex @@ bmanipulate makes the output depend on both b and bmanipulate. When bmanipulate is changed, the output is updated, which changes b, and in turn that triggers a second update. Doesn't matter much when the output is computed as fast this one, but it makes the demonstration run half as fast. $\endgroup$
    – Michael E2
    Dec 31, 2012 at 3:49
  • $\begingroup$ @MichaelE2 thanks, that's pretty subtle. A better version would declare the b within Module or With. And regarding functions, I just mean that generally you should declare things before using them, for the purposes of readability. That's all. $\endgroup$
    – amr
    Dec 31, 2012 at 4:32
  • $\begingroup$ Yes, it's odd that the variables in Manipulate, as well as the Initialiation code, come after use, whereas in Module etc. they come before. $\endgroup$
    – Michael E2
    Dec 31, 2012 at 5:28

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.