15
$\begingroup$

For my calculations, I need increased precision of parameter k in my Manipulate:

Manipulate[
 Plot[Cos[k x], {x, 0, 2 Pi}], {{k, 1}, 0, SetPrecision[4.0, 22], 
  SetPrecision[0.100, 22], Appearance -> "Labeled"}]

However, at the same time, for aesthetic reasons, I want the label to the right of the slider to display only couple of digits. How this could be done?

$\endgroup$
3
  • $\begingroup$ Good question, the long number also messes up the standard numeric display field (which is displayed by clicking on the "+" next to the slider). $\endgroup$
    – Yves Klett
    Aug 13, 2013 at 15:41
  • $\begingroup$ Would simply using SetPrecision[k,22] in place of k in the body of your Manipulate work? Positioning a slider with 22 digits precision is challenging and Table[k, {k, 0.0, SetPrecision[1, 22], SetPrecision[0.1, 22]}] == Table[SetPrecision[k, 22], {k, 0.0, 1.0, 0.1}] gives True. $\endgroup$ Aug 13, 2013 at 16:05
  • $\begingroup$ Related: (8671) $\endgroup$
    – Mr.Wizard
    Jun 1, 2017 at 20:48

6 Answers 6

10
$\begingroup$

Two, now three, ways: I think I'd recommend the first -- strike that -- maybe the third one at the end, but perhaps you have a reason for using SetPrecision, in which case, use the second.

This first one works as is. One caveat: if the label is used as an input field, the number k will be set to a machine-precision number.

Manipulate[
 Plot[Cos[k x], {x, 0, 2 Pi}],
 {{k, 1}, 0.`22, 4.`22, 0.1`22, Appearance -> "Labeled"}]

The second way is to make your own label. Here editing the label still maintains the desired precision.

Manipulate[
 Plot[Cos[k x], {x, 0, 2 Pi}],
 {{k, 1}, SetPrecision[0., 22], SetPrecision[4.0, 22], SetPrecision[0.100, 22], 
  Row[{Manipulator[##], "  ", 
     InputField[Dynamic[Round[k, 0.1], (k = SetPrecision[#, 22]) &], 
      Appearance -> "Frameless", BaseStyle -> "Label"]}] &}
 ]

Here is a variation with a non-editable label:

Manipulate[
 Plot[Cos[k x], {x, 0, 2 Pi}],
 {{k, 1}, SetPrecision[0., 22], SetPrecision[4.0, 22], SetPrecision[0.100, 22],
  Row[{Manipulator[##], "  ", Dynamic@Round[k, 0.1]}] &}]

Both look the same.

Mathematica graphics


There is a difference between setting the precision with SetPrecision and with a backtick:

x = SetPrecision[0.1, 22]
(* 0.1000000000000000055511 *)

y = 0.1`22
(* 0.1000000000000000000000 *)

Precision /@ {x, y}
(* {22., 22.} *)

x - y
(* 5.5511*10^-18 *)

Alternatively, you can use a dummy variable and convert it to the desired precision:

Manipulate[
 k = N[Round[k0, 1/10], 22];
 Plot[Cos[k x], {x, 0, 2 Pi}, PlotLabel -> k],
 {{k0, 1, "k"}, 0, 4, 0.1, Appearance -> "Labeled"},
 {k, None},
 TrackedSymbols :> {k0}]

(I included a plot label to verify that k has the proper precision.)

$\endgroup$
1
  • $\begingroup$ Yes, I use SetPrecision for good reason while I use global parameter to set/increase precision of calculations, which is not possible to do with backtick. Since you provided more alternatives, you get the accept! $\endgroup$
    – Cendo
    Aug 14, 2013 at 11:12
8
$\begingroup$

Because I'm new to Mathematica, I thought it may be helpful to newer people to answer this question the way a "new user" may think about the problem without the use of the more compact symbols. Obviously, MichaelE2 has covered the gambit of options already, and the solution below is negligibly different from his "non-editable label" solution.

To create the desired result, I used a Row[] construct that has the control's label k, the slider, some added space for aesthetic purposes, and the variable displayed as a numerical approximation all next to each other.

Manipulate[Plot[Cos[k x], {x, 0, 2 Pi}],
  Row[{Control[{{k, 1}, 0, SetPrecision[4.0, 22], 
    SetPrecision[0.100, 22]}], Spacer[5], Dynamic[N[k, 2]]}]
]

enter image description here

Whenever a control is placed in a row, it must be identified by wrapping it with the Control[] function. The numerical approximation must be wrapped in a Dynamic[] because it should be updated whenever the slider is moved. If you wanted to change the number of digits that was displayed, all you have to do is change the number in the second argument of N[].

$\endgroup$
2
  • $\begingroup$ This is a nice variant. +1. I learned how to massage controls in v6, before Control, and by habit I often neglect how useful it is. $\endgroup$
    – Michael E2
    Aug 13, 2013 at 23:18
  • $\begingroup$ Nice, your solution is even shorter than @Michael E2. $\endgroup$
    – Cendo
    Aug 14, 2013 at 11:13
4
$\begingroup$

You mean something like this?

Manipulate[
 Plot[Cos[k x], {x, 0, 2 Pi}, Frame -> True, Axes -> False, ImagePadding -> 30],

 Text[Style[

   Grid[{ {Style["k", Italic], Spacer[2],
      Manipulator[Dynamic[k, {k = SetPrecision[#, 22]} &], {0, to, del}, 
       ImageSize -> Tiny],

      Spacer[2],

      Dynamic[AccountingForm[k , (*choose how many digits to show*){23, 22}, NumberSigns -> {"", ""}, 
        NumberPadding -> {"0", "0"}, SignPadding -> True]]}},

     Spacings -> {0.1, .1}, Frame -> True, FrameStyle -> Directive[Thickness[.001], Gray]
    ],
   20]
  ],
 {{k, 1}, None},
 Initialization :>
  (
   to = SetPrecision[4.0, 22];
   del = SetPrecision[0.100, 22]
   )
 ]

enter image description here

$\endgroup$
3
$\begingroup$

Of course if you are going to have a high precision parameter and you want to vary it over an extended domain, then don't you want to precisely control all the digits of the number? The Presentations Application has a VernierSlider that allows you to do that. You can specify the beginning and end of the domain, the precision and accuracy. Then it provides a PopupMenu that allows you to pick any position in the number and a Slider that varies over 100 units about that position. Here is an example that follows the above with a precision of 22 and accuracy of 21. The PopupMenu label indicates the place being adjusted. The single displayed Slider is actually multiple Sliders, which are connected by the setx routine.

<< Presentations` 

DynamicModule[
 {k = 0, setx},
 setx[xx_] := k = xx;
 pagelet[
  VernierSlider[0, 4, 22, 21, setx],
  Dynamic[NumberForm[k, {22, 21}]],
  Dynamic@Plot[Cos[k x], {x, 0, 2 \[Pi]}]
  ]
 ]

enter image description here

Here is an example that varies k from 3 to 3.2 with a precision of 10 and accuracy of 9 and plots over a smaller domain so that one might see an effect.

DynamicModule[
 {k = 0, setx},
 setx[xx_] := k = xx;
 pagelet[
  VernierSlider[3, 3.2, 10, 9, setx],
  Dynamic[NumberForm[k, {10, 9}]],
  Dynamic@Plot[Cos[k x], {x, 1.6, 1.7}, PlotRange -> {0.2, 0.6}]
  ]
 ]

enter image description here

You can get fine control on a Slider by holding down Alt or Ctrl+Alt while moving the Slider, but if you need precise control of many digits, then the VernierSlider is useful. Presentations also has a MultiSlider in which a single Slider can be reused for various parameters with various domains. This allows complex dynamic displays that aren't completely filled with Sliders.

$\endgroup$
1
  • $\begingroup$ I didn't know about the fine control with alt and ctrl+alt, it's useful, thanks $\endgroup$
    – Rojo
    Aug 25, 2013 at 1:21
2
$\begingroup$

This works but it's a bit of a hack (i.e. I don't know how/if you can have the label the same side Appearance->"Labelled" would put it):

Manipulate[
 a = Round[k, .1];
 Plot[Cos[k x], {x, 0, 2 Pi}], {{k, 1, Dynamic@a}, 0, 
  SetPrecision[4.0, 22], SetPrecision[0.100, 22]}]
$\endgroup$
2
$\begingroup$
Manipulate[Plot[Cos[k x], {x, 0, 2 Pi}], 
          {{k, 0, Dynamic@Panel[Row[{Style["k=", Blue, 14], 
                                     Style[Round[k, 0.001], Blue, 14]
                                   }],
                                ImageSize -> {80, 40}]
           }, SetPrecision[0.100, 22], SetPrecision[4.0, 22]}]

enter image description here

??

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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