Version 9, on Windows 7.
Please compare these 2 very simple examples
Manipulate[
x,
Row[{Manipulator[Dynamic[x], {0, 10, 1/100}]}],
{{x, 1}, None}
]
and
Manipulate[
x,
Row[{Manipulator[Dynamic[x, (x = #) &], {0, 10, 1/100}]}],
{{x, 1}, None}
]
Would you not expect them to work the same way?
But in the second case, x becomes real, while in the first case it remains rational as expected.

Any one knows the reasoning for this? I read about the second argument of Dynamic, but do not see something obvious. I did not read everything about it. But the above behaviour is surprising.
The fix is easy:
Manipulate[
x,
Row[{Manipulator[
Dynamic[x, (x = Rationalize[#]) &], {0, 10, 1/100}]}],
{{x, 1}, None}
]
I am only asking why it happens, so I can learn more.
Answer
This is not an answer but it's too long for a comment. Also please remember that all the following are just guesses.
My first observation is that the simplified
Slider[Dynamic[x, (x=#)&], {0, 1, 1/10}]
can reproduce the problem.
We know that some variables (in particular DynamicModule variables) are owned by the Front End, not the Kernel, and can be directly set using GUI elements (such as Slider) without needing any kernel interaction. It is reasonable to assume that the Front End is only able to do computations with machine level data types like integers and reals, but not arbitrary precision numbers or Rationals. Why this might have an effect in this particular example, I do not know.
But let us take a look at what sort of box forms (which are handled by the front end) are generated for different variations of Slider:
1. First, the basic Dynamic with a Real step size:
Slider[Dynamic[x], {0, 1, 0.1}]
Cell[BoxData[
SliderBox[Dynamic[$CellContext`x], {0, 1, 0.1}]], "Output"]
This is a simple box form that maps to the input expression directly.
2. Now let's try a Rational step size:
Slider[Dynamic[x], {0, 1, 1/10}]
Cell[BoxData[
SliderBox[Dynamic[
BoxForm`RemapVariable[$CellContext`x, {0, 1, Rational[1, 10]}],
BoxForm`RemapValue[#, $CellContext`x, {0, 1, Rational[1, 10]}]& ],
{0, 10, 1}]], "Output"
]
Here I see something new (and to me unfamiliar): RemapValue and RemapVariable. Is this maybe used to ask the kernel to do computations? The slider range and step size are now all integers and are remapped using a (possibly kernel evaluated function) to rationals.
3. Let's try Dynamic with a second argument and a Rational step size:
Slider[Dynamic[x, (x = #) &], {0, 1, 1/10}]
Cell[BoxData[
SliderBox[Dynamic[$CellContext`x, ($CellContext`x = #)& ], {0, 1, Rational[1, 10]}]],
"Output"]
The RemapValue is gone now!
Can we add the second argument of Dynamic back to the RemapValue version of the box form? Note that Dynamic already has two arguments there, so it should be grafted onto the RemapValue function somehow.
Comments
Post a Comment