2
$\begingroup$

I am trying to define multiple functions with the same set of parameters and then put them in a Manipulate to simulate their behavior.

Ideally it should be something like that:

par={a,b,c};
f[q_,a_,b_,c_]:=q+a+b+c;
g[q_,a_,b_,c_]:=q-a-b-c;

Then afterwards I would like to have something like

Manipulate[
  Plot[f[q-5, par] + g[q+5, par], {q,0,10}],
  {{a,0},-1,1},{{b,0},-1,1},{{c,0},-1,1}]

I know that I can use the Apply command and write something like

f @@ par

The problem is that then I don't know how to still operate on the q parameter and, in addition, even if I add the q parameter in par and then write f@@par, the Manipulate does not work anymore.

Is it possible to solve this issue or I have to stick with this piece of code?

Manipulate[Plot[f[q-5,a,b,c] + g[q+5,a,b,c], {q,0,10}],{{a,0},-1,1},{{b,0},-1,1},{{c,0},-1,1}]
$\endgroup$
  • $\begingroup$ Welcome to Mathematica.SE! I suggest the following: 1) As you receive help, try to give it too, by answering questions in your area of expertise. 2) Take the tour! 3) When you see good questions and answers, vote them up by clicking the gray triangles, because the credibility of the system is based on the reputation gained by users sharing their knowledge. Also, please remember to accept the answer, if any, that solves your problem, by clicking the checkmark sign! $\endgroup$ – Michael E2 Feb 2 '16 at 13:17
  • $\begingroup$ The problem you're having is because Manipulate localizes its variables, while the symbols in par are global (in the "Global`" context). Your workaround seems reasonable. There's also the option LocalizeVariables -> False, but on the face of it, I prefer your workaround. $\endgroup$ – Michael E2 Feb 2 '16 at 13:21
  • $\begingroup$ Because I am dealing with a large number of parameters and functions I actually prefer your LocalizeVariables -> False workaround that would keep my code way more smooth. The problem is that it does not seem to work even with a single function like f@@par. $\endgroup$ – Gabriele De Luca Feb 2 '16 at 13:29
  • 1
    $\begingroup$ Oh my lord but it took me forever to realize that your manipulate function was independent of the values of a, b, and c, and that that is the expected behavior. $\endgroup$ – Jason B. Feb 2 '16 at 13:33
  • $\begingroup$ @JasonB Yeah, I changed it to f[q - 5, Sequence @@ par]^2 + g[q + 5, Sequence @@ par] so I could see whether a solution was working. :) $\endgroup$ – Michael E2 Feb 2 '16 at 13:35
2
$\begingroup$

One problem you're having is that because Manipulate localizes its variables, while the symbols in par are global (in the "Global`" context), the letters a, b, c inside the Manipulate do not refer to the variables in par. Your workaround seems reasonable. There's also the option LocalizeVariables, which can be set to False to make the Manipulate parameters global. But on the face of it, I prefer your workaround. Having global variables under the control of Manipulate has caused me headaches in the past.

Another potential solution is to localize par inside Manipulate and use Sequence to feed the arguments to f and g:

Manipulate[
 With[{par = {a, b, c}}, 
  Plot[f[q - 5, Sequence @@ par] + g[q + 5, Sequence @@ par], {q, 0, 10}]
  ],
 {{a, 0}, -1, 1}, {{b, 0}, -1, 1}, {{c, 0}, -1, 1}]

You could also inject the symbols into Manipulate before the code is passed to Manipulate for localization:

With[{par = par},
 Manipulate[
  Plot[f[q - 5, Sequence @@ par] + g[q + 5, Sequence @@ par], {q, 0,
     10}],
  {{a, 0}, -1, 1}, {{b, 0}, -1, 1}, {{c, 0}, -1, 1}]
 ]

One could also define your functions as a function of a list like this

f[q_, {a_, b_, c_}] := q + a + b + c;

and call the function like this

f[q - 5, par]
$\endgroup$
  • $\begingroup$ I was not aware of the command With: I can solve my issue with the combination of With and Sequence as in your first code example. I anyway find the definition of function of a list even more clear but I cannot really make it working. Do I have to declare par in a particular way? $\endgroup$ – Gabriele De Luca Feb 2 '16 at 13:46
  • $\begingroup$ @GabrieleDeLuca You'll still have to use With (but not Sequence). -- Thanks for the accept. It might be better to wait a while (like a day). Sometimes a better answer comes along, especially if when the question is not marked answered on the front page. $\endgroup$ – Michael E2 Feb 2 '16 at 13:52
1
$\begingroup$

There is really no need to gather the parameters into a list. You can do it with this simple approach.

DynamicModule[{f, g},
  f[q_, a_, b_, c_] := q + 2 a + 3 b + 4 c;
  g[q_, u_, v_, w_] := q - u/2 - v/3 - w/4;
  Manipulate[
    Plot[f[q - 5, a, b, c]^2 + g[q + 5, a, b, c]^2, {q, 0, 10}],
    {{a, 0}, -1, 1},
    {{b, 0}, -1, 1},
    {{c, 0}, -1, 1}]]

It does not matter at all what the formal arguments in a function definitions is named. I changed the name of some them in the definition of g to demonstrate that.

What matters in the Manipulate is that the actual arguments used in the plotted expression correspond by name and position in the two function calls.

$\endgroup$
  • $\begingroup$ This is another nice approach but then one still has to write down the arguments needed by the function, although with another name, while calling the list with With resembles more what I was looking for. $\endgroup$ – Gabriele De Luca Feb 2 '16 at 14:21

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.