Skip to main content

What is and isn't a valid variable specification for Manipulate?


I have an expression whose terms have arguments (representing subscripts), like this:


myExpr = A[0] + V[1,T]

I would like to put it inside a Manipulate to see its value as I move around the parameters. (The goal is eventually to plot it wrt one of the variables inside.)


However, Mathematica complains when I set V[1,T] as a manipulated variable:


Manipulate[Evaluate[myExpr], {A[0], 0, 1}, {V[1, T], 0, 1}]

(*Manipulate::vsform: Manipulate argument {V[1,T],0,1} does not have the correct form for a variable specification. >> *)

As a workaround, if I get rid of the symbol T inside the argument, it works fine:


Manipulate[
Evaluate[myExpr /. T -> 15], {A[0], 0, 1}, {V[1, 15], 0, 1}]

Why this behavior? Can anyone point me to the documentation that says what counts as a valid variable? And is there a way to get Manpiulate to accept an expression with a symbolic argument as a variable?


Investigations I've done so far:



  • I tried using variableQ from this answer, but it says V[1,T] is fine as a valid variable.



  • And Plot works just fine with V[1,T] as the variable, as in:


    Plot[myExpr /. A[0] -> 2, {V[{1, T}], 1, 2}]





Answer



I suspect it's an internal decision by WRI to allow as variables only expressions of the form A[0, 1, 2], that is, a symbol with integer arguments. You could try reporting your desired functionality to WRI; maybe they will extend what expressions are allowed. Instead of being localized in the usual way, the expressions are remapped to Unique[] symbols. For instance, the expression A[0] would be mapped to a symbol like $101. In this scheme, almost any expression could be allowed as a variable, because it can be replaced by a valid variable name. One danger is that in an expression like V[1, T], the symbol T would not be localized, so if T changed value, one should expect a change in behavior. One could wish that V[0, T] were mapped to $102, but that would remove the dependency on T. From a programming point of view, this would be really bad. But if T in a user's program is an inert symbol, then from the user's point of view, it is a bit irritating not to be able to do it.


Well, with some hacking, you could do it like you want, but let me first suggest this:


Manipulate[{A[0], V1T}, {A[0], 0, 1}, {{V1T, 0, HoldForm@V[1, T]}, 0, 1}]


Mathematica graphics


Hack:


The check on what is a valid variable is performed Manipulate`Dump`extendedVariable. You can add your own allowed forms like this:


Internal`InheritedBlock[{Manipulate`Dump`extendedVariable},
Manipulate`Dump`extendedVariable[_Symbol[__]] := True;
Manipulate[{A[0], V[1, T]}, {A[0], 0, 1}, {V[1, T], 0, 1}]
]

Mathematica graphics


This would be a little safer, but I would still recommend the first approach above:



Internal`InheritedBlock[{Manipulate`Dump`extendedVariable},
Manipulate`Dump`extendedVariable[_Symbol[(_Integer | _String) ..]] := True;
Manipulate[{A[0], V[1, "T"]}, {A[0], 0, 1}, {V[1, "T"], 0, 1}]
]

Bug/Restriction (updated):


My point seemed to be lost in the simple example I originally gave, so I have changed it and added some explanation to try to clarify the issues. My claim was and is: I'm not sure why forms like A[0] are allowed. They don't work the way they do in normal Mathematica.


The point is that when expressions A[0] etc. are replaced by Unique[] symbols like $123, only the literal expressions like A[0] etc. are replaced in the Manipulate code by kernel, before the Manipulate is sent back to the front end for instantiation. An expression like A[n] that evaluates to A[0] at runtime will not be linked to the actual variable $123 being used to represent A[0].


Manipulate[{A[0], A[n]}, {A[0], 0, 1}, {n, 0, 1, 1}] // InputForm
(*

Manipulate[{$3340, A[n]}, (*$*)
{{$3340, 0, RawBoxes[RowBox[{"A", "[", "0", "]"}]]}, 0, 1}, (*$*)
{n, 0, 1, 1}]
*)

Mathematica graphics


A more complicated example, which might illustrate better a more practical use of A[n], is given below. But simplicity has advantages in an issue that is complicated and potentially confusing.


One reason for using variables like A[0], A[1], etc. is to be able to parametrize them by A[n]. Such functionality can often be accomplished with lists, which can be made to work in Manipulate, but that seems a separate issue. Workarounds are not an explanation. My point is that one of the basic uses of A[0] etc. cannot be implemented in Manipulate.


A more complicated example:


Manipulate[

With[{f = Sum[A[n] x^n, {n, 0, m}]},
Plot[f, {x, -1, 1}, PlotLabel -> f]
],
{A[0], 0, 1}, {A[1], 0, 1}, {A[2], 0, 1},
{m, 0, 2, 1}]

Mathematica graphics


Note that A[1], A[2], and A[3] in the list are not updated or connected to the controls. (This is because, while A[1] is remapped to $nnn, the expression A[n] is not!) My advice is to avoid them, and use


{{A0, 0, HoldForm@A[0]}, 0, 1}


instead.


A workaround for the last example, for those who like them:


Manipulate[
With[{f = Sum[A[n] x^n, {n, 0, m}] /. {A[n_] /; n == 0 :> A[0],
A[n_] /; n == 1 :> A[1], A[n_] /; n == 2 :> A[2]}},
Plot[f, {x, -1, 1}, PlotLabel -> f]
],
{A[0], 0, 1}, {A[1], 0, 1}, {A[2], 0, 1},
{m, 0, 2, 1}]


Mathematica graphics


The literal occurrences of A[0], A[1] and A[2] in the replacement rules are replaced by unique $nnn in the kernel:


{A[n_] /; n == 0 :> A[0], A[n_] /; n == 1 :> A[1], A[n_] /; n == 2 :> A[2]}}

At runtime the rules replace the evaluated A[n] by the corresponding $nnn variable. Such a set of rules has to be applied at all appropriate places in the code. For instance it cannot be applied to the whole body, because it has to be applied to f before Plot is evaluated. In a complicated piece of code, it would be a big pain. In such an application, it would be best to avoid them. After all, that is basically what Manipulate is doing already by rewriting them as simple variables (original example):


Manipulate[
Table[A[n], {n, 3}],
{A[1], 0, 1}, {A[2], 0, 1}, {A[3], 0, 1}] // InputForm
(*
Manipulate[Table[A[n], {n, 3}],

{{$3335, 0, RawBoxes[RowBox[{"A", "[", "1", "]"}]]}, 0, 1},
{{$3336, 0, RawBoxes[RowBox[{"A", "[", "2", "]"}]]}, 0, 1},
{{$3337, 0, RawBoxes[RowBox[{"A", "[", "3", "]"}]]}, 0, 1}]
*)

Comments

Popular posts from this blog

plotting - How to draw lines between specified dots on ListPlot?

I would like to create a plot where I have unconnected dots and some connected. So far, I have figured out how to draw the dots. My code is the following: ListPlot[{{1, 1}, {2, 2}, {3, 3}, {4, 4}, {1, 4}, {2, 5}, {3, 6}, {4, 7}, {1, 7}, {2, 8}, {3, 9}, {4, 10}, {1, 10}, {2, 11}, {3, 12}, {4,13}, {2.5, 7}}, Ticks -> {{1, 2, 3, 4}, None}, AxesStyle -> Thin, TicksStyle -> Directive[Black, Bold, 12], Mesh -> Full] I have thought using ListLinePlot command, but I don't know how to specify to the command to draw only selected lines between the dots. Do have any suggestions/hints on how to do that? Thank you. Answer One possibility would be to use Epilog with Line : ListPlot[ {{1, 1}, {2, 2}, {3, 3}, {4, 4}, {1, 4}, {2, 5}, {3, 6}, {4, 7}, {1, 7}, {2, 8}, {3, 9}, {4, 10}, {1, 10}, {2, 11}, {3, 12}, {4, 13}, {2.5, 7}}, Ticks -> {{1, 2, 3, 4}, None}, AxesStyle -> Thin, TicksStyle -> Directive[Black, Bold, 12], Mesh -> Full, Epilog -> { Line[ ...

equation solving - Invert and fit implicitly defined curve

I need to fit an implicitly defined curve. I thought I could get some data out of Solve , and then using FindFit . Therefore, I would like to find the relation the parametric curve defined by $F(x,y)=0$: Solve[-(1/2) + 1/2 (0.41202 BesselK[0, 0.1 Sqrt[x^2 + y^2]] + (0.101483 x BesselK[1, 0.1 Sqrt[x^2 + y^2]])/Sqrt[x^2 + y^2]) == 0, y] But I can't get an output: Solve was unable to solve the system with inexact coefficients or the system obtained by direct rationalization of inexact numbers present in the system. Since many of the methods used by Solve require exact input, providing Solve with an exact version of the system may help. >> Edit: In particular, I would like to fit the data coming from the curve with the expression of another curve, and not with a function $f(x)$. In particular, since this clearly looks like a cardioid , I would like it to fit to something like it. What other strategies could I try?

dynamic - How can I make a clickable ArrayPlot that returns input?

I would like to create a dynamic ArrayPlot so that the rectangles, when clicked, provide the input. Can I use ArrayPlot for this? Or is there something else I should have to use? Answer ArrayPlot is much more than just a simple array like Grid : it represents a ranged 2D dataset, and its visualization can be finetuned by options like DataReversed and DataRange . These features make it quite complicated to reproduce the same layout and order with Grid . Here I offer AnnotatedArrayPlot which comes in handy when your dataset is more than just a flat 2D array. The dynamic interface allows highlighting individual cells and possibly interacting with them. AnnotatedArrayPlot works the same way as ArrayPlot and accepts the same options plus Enabled , HighlightCoordinates , HighlightStyle and HighlightElementFunction . data = {{Missing["HasSomeMoreData"], GrayLevel[ 1], {RGBColor[0, 1, 1], RGBColor[0, 0, 1], GrayLevel[1]}, RGBColor[0, 1, 0]}, {GrayLevel[0], GrayLevel...