4
$\begingroup$

I am trying to plot a polynomial inside Manipulate with indexed coefficients.

Surprisingly, only an empty plot is generated.

Any help welcome.

Block[{n = 3},
 Manipulate @@ {
 Column[{
  Sum[a[i] x^i, {i, 0, n}],
  Plot[Evaluate@Sum[a[i] x^i, {i, 0, n}], {x, -5, 5}]
 }],
 Sequence @@ Table[{{a[i], 0}, -2, 2}, {i, 0, n}]
}]

Regards Robert

$\endgroup$
3
  • 1
    $\begingroup$ Why are you using Manipulate @@? Because of this the Plot[...] evaluates early and Manipulate will never see the Plot command. $\endgroup$
    – Szabolcs
    Sep 4, 2017 at 12:25
  • $\begingroup$ @Szabolcs I am using Manipulate @@ to have an programmable number n of adjustable coefficients. $\endgroup$ Sep 4, 2017 at 12:46
  • $\begingroup$ Closely related: Manipulate with a variable number of sliders $\endgroup$
    – Kuba
    Sep 4, 2017 at 12:50

2 Answers 2

6
$\begingroup$

I couldn't do it with Manipulate[], so I used pure Dynamic[] constructs instead:

With[{nmax = 12},
     DynamicModule[{n = 3, cofs = ConstantArray[0, 4]},
                   Panel[Row[{Column[{Style["Degree:", Bold], 
                                      Slider[Dynamic[n, (n = #;
                                                     cofs = PadRight[cofs, n + 1, 0];) &],
                                             {1, nmax, 1}],
                                      Style["Coefficients:", Bold], 
                                      Dynamic[Multicolumn[
                                              Array[Row[{Subscript["c", # - 1],
                                              Spacer[5],
                                              Slider[Dynamic[cofs[[#]]], {-2, 2}, 
                                                     ImageSize -> Small]}] &, n + 1],
                                              {9, Automatic}]]}], 
                   Spacer[20], 
                   Dynamic[Column[{Pane[
                   Row[{"f(x) = ", TraditionalForm[Expand[
                                                   FromDigits[Reverse[cofs], x]]]}]], 
                   Panel[Plot[FromDigits[Reverse[cofs], x], {x, -5, 5}, 
                              Axes -> None, Frame -> True]]}]]}]]]]

For instance:

polynomial maker

$\endgroup$
1
  • $\begingroup$ thx, silver medal for your answer. $\endgroup$ Sep 5, 2017 at 13:24
6
$\begingroup$

I think what you are trying to accomplish is not easy. Both evaluation control and symbol localization can be tricky in Mathematica, and your code has subtle errors related to both.

First I will give a possible solution, then I will discuss the problems with your approach.

manip[n_] :=
 Block[{a,x}, (* prevent conflict with any global a, x *)
   With[{
     vars = Sequence @@ Table[{{a[i], 0}, -2, 2}, {i, 0, n}],
     poly = Sum[a[i] x^i, {i, 0, n}]
     },
    Manipulate[
     Column[{
       poly,
       Plot[poly, {x, -5, 5}]
       }],
     vars
    ]
   ]
 ]

Problems with your code:

  • Using Manipulate @@ {...} instead of Manipulate[...] prevents the HoldAll attribute of Manipulate from taking effect. You probably did this on purpose to allow the second argument to evaluate. But the first one evaluates too, including the Plot part. Manipulate will never have a chance to see the Plot command (only its empty result).

  • Block sets n only temporarily. This means that after evaluating the content of Block, the result must not contain any unevaluated n symbols. If it does, these will never get the value 3 again. This is in contradiction with the requirement not to evaluate Plot ...

  • When compound expressions are used as Manipulate variables, i.e. a[1], a[2], ..., they will internally be replaced by single symbols. In practice this means that each of a[1], a[2], ... must appear explicitly in the body of Manipulate. a[i], with i being substituted only during dynamic evaluation, will not work.

These difficulties are overcome by pre-generating both the variable list and the polynomial, and injecting them into a Manipulate.

Another note: Usually people recommend against using Subscript[a,1] instead of a[1]. I think in this case it's quite safe to use the subscript, as the computation will be done with replacement symbols anyway. The Manipulate interface will look better.

$\endgroup$
1
  • $\begingroup$ nice, thx. The problem with this kind of stuff is always that one knows well what is desired but it is difficult to tell MMA. Wouldn't it be easier to generate the code as a String and convert to an expression? $\endgroup$ Sep 4, 2017 at 14:36

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.