Skip to main content

Why does a variable become real when using the second argument of Dynamic?


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.


enter image description here


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

Popular posts from this blog

front end - keyboard shortcut to invoke Insert new matrix

I frequently need to type in some matrices, and the menu command Insert > Table/Matrix > New... allows matrices with lines drawn between columns and rows, which is very helpful. I would like to make a keyboard shortcut for it, but cannot find the relevant frontend token command (4209405) for it. Since the FullForm[] and InputForm[] of matrices with lines drawn between rows and columns is the same as those without lines, it's hard to do this via 3rd party system-wide text expanders (e.g. autohotkey or atext on mac). How does one assign a keyboard shortcut for the menu item Insert > Table/Matrix > New... , preferably using only mathematica? Thanks! Answer In the MenuSetup.tr (for linux located in the $InstallationDirectory/SystemFiles/FrontEnd/TextResources/X/ directory), I changed the line MenuItem["&New...", "CreateGridBoxDialog"] to read MenuItem["&New...", "CreateGridBoxDialog", MenuKey["m", Modifiers-...

How to thread a list

I have data in format data = {{a1, a2}, {b1, b2}, {c1, c2}, {d1, d2}} Tableform: I want to thread it to : tdata = {{{a1, b1}, {a2, b2}}, {{a1, c1}, {a2, c2}}, {{a1, d1}, {a2, d2}}} Tableform: And I would like to do better then pseudofunction[n_] := Transpose[{data2[[1]], data2[[n]]}]; SetAttributes[pseudofunction, Listable]; Range[2, 4] // pseudofunction Here is my benchmark data, where data3 is normal sample of real data. data3 = Drop[ExcelWorkBook[[Column1 ;; Column4]], None, 1]; data2 = {a #, b #, c #, d #} & /@ Range[1, 10^5]; data = RandomReal[{0, 1}, {10^6, 4}]; Here is my benchmark code kptnw[list_] := Transpose[{Table[First@#, {Length@# - 1}], Rest@#}, {3, 1, 2}] &@list kptnw2[list_] := Transpose[{ConstantArray[First@#, Length@# - 1], Rest@#}, {3, 1, 2}] &@list OleksandrR[list_] := Flatten[Outer[List, List@First[list], Rest[list], 1], {{2}, {1, 4}}] paradox2[list_] := Partition[Riffle[list[[1]], #], 2] & /@ Drop[list, 1] RM[list_] := FoldList[Transpose[{First@li...

functions - Get leading series expansion term?

Given a function f[x] , I would like to have a function leadingSeries that returns just the leading term in the series around x=0 . For example: leadingSeries[(1/x + 2)/(4 + 1/x^2 + x)] x and leadingSeries[(1/x + 2 + (1 - 1/x^3)/4)/(4 + x)] -(1/(16 x^3)) Is there such a function in Mathematica? Or maybe one can implement it efficiently? EDIT I finally went with the following implementation, based on Carl Woll 's answer: lds[ex_,x_]:=( (ex/.x->(x+O[x]^2))/.SeriesData[U_,Z_,L_List,Mi_,Ma_,De_]:>SeriesData[U,Z,{L[[1]]},Mi,Mi+1,De]//Quiet//Normal) The advantage is, that this one also properly works with functions whose leading term is a constant: lds[Exp[x],x] 1 Answer Update 1 Updated to eliminate SeriesData and to not return additional terms Perhaps you could use: leadingSeries[expr_, x_] := Normal[expr /. x->(x+O[x]^2) /. a_List :> Take[a, 1]] Then for your examples: leadingSeries[(1/x + 2)/(4 + 1/x^2 + x), x] leadingSeries[Exp[x], x] leadingSeries[(1/x + 2 + (1 - 1/x...