2

I would like to write a procedure with the signature:

Foo[vars, params]

which produces a Manipulate object. The procedure will dress up the vars into sliders of the form:

{{a, a0, "DisplayName"}, min, max, Appearance->"Labeled"}

and will produce a Plot, depending on both the params and vars. (The default value a0 and the other slider properties are generated in a particular manner from a.)

The issue I'm running into is that Manipulate requires all of its vars to be explicitly listed. I looked at the related question Proper way to handle free variables in manipulate/plot? to no avail (I couldn't get With to do what I want).

So how does one procedurally generate the commands of Manipulate? I am constrained to use Manipulate as opposed to Dynamic or other more advanced features.


Concrete Example:

Manipulate[
    Plot[
        c0 + c1 x + c2 x^2,
        {x,0,1}
    ],
    {{c0, 0},-1, 1},
    {{c1, 1}, 0, 2},
    {{c2, 2}, 1, 3},
]

Then the goal would be to replace the 2 with an n, i.e. to write a function Poly[n] which returns a manipulatable polynomial with coefficients c_i centered around i.

pre-kidney
  • 693
  • 3
  • 9
  • "The default value a0 and the other slider properties are generated in a particular manner from a." This is quite vague. Without some idea of what you need it is hard to provide a recommendation. – Mr.Wizard Jan 30 '15 at 07:04
  • Okay I'll write up a more concrete mwe. – pre-kidney Jan 30 '15 at 07:07
  • I do not think it is possible to do what you want. i.e. call a function to generate the controls, since the controls have to be set before evaluation. The closest you can do, is use With to help reduce duplicate code. Please see injecting-list-of-controls-into-manipulate which is pretty much asking the same thing, and the discussion and links there. – Nasser Jan 30 '15 at 07:10
  • @pre-kidney Please see the linked Q&A in Nasser's comment; do you think this question is a duplicate of that one, and if not, why not? – Mr.Wizard Jan 30 '15 at 07:15

1 Answers1

2

Please tell me if this does what you want:

poly[n_Integer?Positive] :=
 {
   Array[{{\[FormalC][#], #}, # - 1, # + 1} &, n + 1, 0],
   Sum[\[FormalC][i] \[FormalX]^i, {i, 0, n}]
 } /. {{var__}, expr_} :>
        Manipulate[Plot[expr, {\[FormalX], 0, 1}], var]

poly[4]

enter image description here

Mr.Wizard
  • 271,378
  • 34
  • 587
  • 1,371
  • This approach seems like it will work well for me, but I'm running into a couple hurdles. First of all, my Plot function relies on several other procedures, and I am having issues porting it to work with your code. I will add it to an edit of the question. – pre-kidney Jan 30 '15 at 09:42
  • I thought I understood the foo /. bar :> baz construction but after some fiddling it appears I was mistaken. Is it the bar :> baz that specifies the lazy replacement rule, which is then applied to foo? – pre-kidney Jan 30 '15 at 09:52
  • The Manipulate is continuously running. I am on V 10.02. typing poly[4] shows the right side is solid black all the time, which means it is running all the time. To see this more clearly, I added DateString[] call, poly[n_Integer?Positive] := {Array[{{\[FormalC][#], #}, # - 1, # + 1} &, n + 1, 0], Sum[\[FormalC][i] \[FormalX]^i, {i, 0, n}]} /. {{var__}, expr_} :> Manipulate[Row[{DateString[], Plot[expr, {\[FormalX], 0, 1}]}], var] and the clock is updating all the time. – Nasser Jan 30 '15 at 10:04
  • @pre-kidney I'm heading for bed so I'll have to address the update tomorrow. Regarding the second point please see (1937) and (8399) which hopefully give a foundation for my use of replacement here. If not I'll try to explain tomorrow. – Mr.Wizard Jan 30 '15 at 10:05
  • @Nasser I hadn't noticed. I'll explore that tomorrow too. – Mr.Wizard Jan 30 '15 at 10:07
  • Thank you both for your extensive help today. It has been wonderful learning more about Mathematica. – pre-kidney Jan 30 '15 at 10:07
  • @Nasser It seems the constant updating is due to the use of \[FormalX] in Plot, but I'm not going further tonight. – Mr.Wizard Jan 30 '15 at 10:12
  • TrackedSymbols :> Manipulate keeps the tracking confined to the vars. No further explanation at this point. – Michael E2 Jan 30 '15 at 13:57
  • This causes continual updating: Protect[y]; Dynamic[{Block[{y = 1}, y], Block[{y = 2}, y]}]. Perhaps it's the clearing of the Attributes by Block? – Michael E2 Jan 30 '15 at 14:16
  • Any workarounds? – pre-kidney Jan 30 '15 at 20:04
  • @pre-kidney Adding the option TrackedSymbols :> Manipulate to Manipulate is a workaround. So is Manipulate[Block[{\[FormalX]}, Plot[expr, {\[FormalX], 0, 1}]], var]. But maybe someone will figure out a more elegant one. – Michael E2 Jan 30 '15 at 23:38
  • 1
    @pre-kidney I've been busy today. The code from the first version of my answer with manual Hold and ReleaseHold does not seem to have that problem. I intend to come back to this but I don't have time now. Sorry. – Mr.Wizard Jan 31 '15 at 01:13
  • Your first revision appears to solve my problem better. At the moment, I am fine with littering my code with Holds all over the place, so it looks like I will use that version. Thanks! – pre-kidney Jan 31 '15 at 05:44