Suppose I have two sets of parameters. One set of parameters is defined in terms of the other, according to some rules. I'm interested in displaying an object, which may by manipulated by either set of parameters. The expression is a plot based on the latter set of parameters.
It's important for me to keep variables and rules aside, as I'll be dealing with a larger list of them, and each would additionally have their own initial values and min./max. range. Also, this information would be used elsewhere in the code - I don't want to go through my list of ~30 parameters (16 inner, 14 outer) everytime I want to display a different Manipulate control.
Intuitively, I'd use a nested Manipulate
expression to achieve this:
(* Two sets of parameters *)
vars1 = {a, b, c};
vars2 = {p, q, r};
(* One set is defined in terms of the other *)
rules = {
p -> a^2 + c,
q -> a*b,
r -> a + b + c
};
(* An object I'm interested in displaying *)
expr = Plot[p*x^2 + q*x + r, {x, 0, 1}];
(* Nested Manipulate *)
Apply[Manipulate, Join[
{Apply[Manipulate, Join[
{expr},
Map[{{#1[[1]], #1[[2]]}, 0, 4, Appearance -> "Open"} &, rules]
]]},
Map[{#1, 0, 1} &, vars1]
]]
This works as expected for the parameter values: when setting a
, b
or c
, the other set of variables resets to get their default values. However, the plot isn't displayed correctly:
I assume the cause for the empty plot, is that the Plot
gets evaluated out-of-context from the Manipulate
. Being somewhat new to Mathematica and its use of symbols and dynamic variables, I'm not quite sure how to proceed.
I want to keep my variables and rules aside, as I'll be dealing with a larger list of them, and each would additionally have their own initial values and min./max. range.
There's more than one question about using Manipulate
with a variable parameter list, and most answers point towards using Dynamic
(e.g. Manipulate with a variable number of sliders). I also thought Hold
and variants and/or Unevaluated
might help, but not sure how.
I tried using Dynamic
approach, and I thought Refresh
might be useful in setting the variables. Taking from the example in the documentation, I have this working:
DynamicModule[{a, p},
Column[{
Slider[Dynamic[a]],
Slider[Dynamic[p]],
(* Reset p according to a, when a is set *)
Dynamic[Refresh[p = a^2, TrackedSymbols -> {a}]],
(* Show values and plot some expression *)
Dynamic[{a, p}],
Dynamic[Plot[a*z^2 + p, {z, 0, 1}]]
}]
]
Here, p
is set according to a
(but not vice versa) and the plot is updated.
However, I don't know how to expand this to work on a predefined list of variables, such as is defined in vars1
, vars2
and rules
above.
The closest I got is the following code, but it produces errors and doesn't run after the first, initial run:
DynamicModule[Evaluate[Join[vars1, vars2]],
Column[
{
(* Create simple manipulators for each of the variables *)
Grid[
Join[
Map[{ToString[#1, TraditionalForm], Slider[Dynamic[#1], {0, 4}],
InputField[Dynamic[#1], FieldSize -> Tiny]} &, vars2],
Map[{ToString[#1, TraditionalForm], Slider[Dynamic[#1], {0, 1}],
InputField[Dynamic[#1], FieldSize -> Tiny]} &, vars1]
]
],
(* My honest attempt at reproducing the example with two *)
(* parameters to work with a list of variables. *)
Refresh[Map[#1[[1]] -> Dynamic[#1[[2]]] &, rules] /. Rule -> Set,
TrackedSymbols -> Map[Dynamic[#1] &, vars1]]
}
]
]
I'd appreciate any help getting this code to work in the manner I want. Thank you!