Skip to main content

numerics - Machine precision near zero: not fulfilled?


I am puzzled by the behavior of Mathematica machine precision with numbers approaching zero. This manifests itself, e.g., with FixedPoint and the like.


In the examples below I will use the following "service" function to take only a few values of long lists:


ClearAll[take];

take[n_Integer][li_List] := If[Length[li] >= Abs[n], Take[li, n], li];

Consider finding the solution of two different equations:


FindRoot[Sin[2.0 x] == x, {x, 1}]

FindRoot[Sin[0.5 x] == x, {x, 1}]

They return respectively:



{x -> 0.9477471335169905}



{x -> 2.6312502524050707*^-15}



where the second one is actually zero to machine precision. edit: no: where the second can be considered as zero in many machine precision computations, even if it is several orders of magnitude bigger than the smallest floating point number.


Now consider doing the same with FixedPoint:


a = FixedPoint[Sin[2.0 #] &, 1.]

b = FixedPoint[Sin[0.5 #] &, 1.]

The behavior of the functions is such that the two should converge to the respective solutions above. Actually both never end.


An analysis of the values obtained (with FixedPointList) shows that the problem with the first function is an oscillation in the last bit(s):



take[-5]@ FixedPointList[Sin[2.0 #] &, 1., 1000] // Differences


{-2.220446*^-16, 2.220446*^-16, -2.220446*^-16, 2.220446*^-16}



so that a real fixed point is never achieved. In this case, SameTest -> Equal is of help:


FixedPoint[Sin[2.0 #] &, 1., SameTest -> Equal]


0.9477471335169858




On the other hand, using SameTest -> Equal does not help with the other example, since:


FixedPoint[Sin[0.5 #] &, 1., SameTest -> Equal]

also never ends.


The same analysis as before, though, shows this:


take[-5]@ FixedPointList[Sin[0.5 #] &, 1., 10000] // Differences


{-3.7962812653512530891065876917712356`15.477468515471298*^-3010,



-1.8981406326756265445532938458856178`15.477468515471298*^-3010,


-9.490703163378132722766469229428089`15.477468515471298*^-3011,


-4.745351581689066361383234614714044`15.477468515471298*^-3011}



Actually there is no bottom! The negative exponents become arbitrarily large and two successive numbers are never seen to be equal to zero.


Now the question: is it reasonable that, having given as input MachinePrecision numbers, arbitrarily large exponents are not confined into the expected range? This is what Chop would do, but it is not applied and must be forced with a user-given SameTest, which seems a little unexpected here.


Why can MachinePrecision numbers have an arbitrary negative exponent?




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...

plotting - How to draw lines between specified dots on ListPlot?

I would like to create a plot where I have unconnected dots and some connected. So far, I have figured out how to draw the dots. My code is the following: ListPlot[{{1, 1}, {2, 2}, {3, 3}, {4, 4}, {1, 4}, {2, 5}, {3, 6}, {4, 7}, {1, 7}, {2, 8}, {3, 9}, {4, 10}, {1, 10}, {2, 11}, {3, 12}, {4,13}, {2.5, 7}}, Ticks -> {{1, 2, 3, 4}, None}, AxesStyle -> Thin, TicksStyle -> Directive[Black, Bold, 12], Mesh -> Full] I have thought using ListLinePlot command, but I don't know how to specify to the command to draw only selected lines between the dots. Do have any suggestions/hints on how to do that? Thank you. Answer One possibility would be to use Epilog with Line : ListPlot[ {{1, 1}, {2, 2}, {3, 3}, {4, 4}, {1, 4}, {2, 5}, {3, 6}, {4, 7}, {1, 7}, {2, 8}, {3, 9}, {4, 10}, {1, 10}, {2, 11}, {3, 12}, {4, 13}, {2.5, 7}}, Ticks -> {{1, 2, 3, 4}, None}, AxesStyle -> Thin, TicksStyle -> Directive[Black, Bold, 12], Mesh -> Full, Epilog -> { Line[ ...