Is Put - Get cycle in Mathematica always deterministic?

蓝咒 提交于 2019-12-05 18:45:41

问题


In Mathematica as in other systems of computer math the numbers are internally stored in binary form. However when exporting them with such functions as Put and PutAppend they are converted into approximate decimals. When you import them back with such functions as Get they are restored from this approximate decimal representation to binary form.

The question is whether the recovered number is always identical to the original binary number and, if not always, in which cases it is not and how large can be the difference? I am particularly interested in the Put - Get cycle (on the same computer system).

The following two simple experiments show that probably the Put - Get cycle in Mathematica always restores original numbers exactly even for arbitrary precision numbers:

In[1]:= list=RandomReal[{-10^6,10^6},10000];
Put[list,"test.txt"];
list2=Get["test.txt"];
Order[list,list2]===0
Order[Total@Abs[list-list2],0.]===0

Out[4]= True
Out[5]= True


In[6]:= list=SetPrecision[RandomReal[{-10^6,10^6},10000],50];
Put[list,"test.txt"];
list2=Get["test.txt"];
Order[list,list2]===0
Total@Abs[list-list2]//InputForm

Out[9]= True
Out[10]//InputForm=
0``39.999515496936205

But maybe I am missing something?


UPDATE

With more correct test code I have found that in reality these tests show only that restored numbers have identical binary RealDigits but their Precisions may differ even in Equal sense. Here are more correct tests:

test := (Put[list, "test.txt"];
  list2 = Get["test.txt"];
  {Order[list, list2] === 0,
   Order[Total@Abs[list - list2], 0.] === 0,
   Total[Order @@@ RealDigits[Transpose[{list, list2}], 2]],
   Total[Order @@@ Map[Precision, Transpose[{list, list2}], {-1}]],
   Total[1 - Boole[Equal @@@ Map[Precision, Transpose[{list, list2}], {-1}]]]})

In[8]:= list=RandomReal[NormalDistribution[],10000]^1001;
test
Out[9]= {False,True,0,1,3}
In[6]:= list=RandomReal[NormalDistribution[],10000,WorkingPrecision->50]^1001;
test
Out[7]= {False,False,0,-2174,1}

回答1:


I'm afraid I can't give a definitive answer. If you look into the text file you see it's stored as something like the InputForm of the values, including the precision indication for non-machine precision numbers.

Assuming that Get uses the same conversion routines as ImportString and ExportString your test can be sped up a tiny bit.

Monitor[
 Do[
  i = RandomReal[{$MinMachineNumber, 10 $MinMachineNumber}, 100000];
  If[i =!= 
    ToExpression[ImportString[ExportString[i, "Text"], "List"]], 
   Print[i]], {n, 100}
  ],
 n]

I have tested this for several hundreds of millions of numbers in various ranges between $MinMachineNumber and $MaxMachineNumber and I always get back the original numbers. It's no proof, of course, but it seems unlikely that you're going to see numbers for which this is not true if there are any (and in that case the difference would be so tiny as to be negligible).




回答2:


One important thing to know is that Put[] / Get[] doesn't keep packed arrays packed. You should check out DumpSave[]. It's much faster as it's a binary format and keeps arrays packed.



来源:https://stackoverflow.com/questions/6482607/is-put-get-cycle-in-mathematica-always-deterministic

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!