É colocado - Get ciclo no Mathematica sempre determinista?

9

Em Mathematica como em outros sistemas de computação matemática, os números são armazenados internamente em forma binária. No entanto, ao exportá-los com funções como Put e PutAppend , eles são convertidos em decimais aproximados. Quando você os importa de volta com funções como Get , eles são restaurados dessa representação decimal aproximada para a forma binária.

A questão é se o número recuperado é sempre idêntico ao número binário original e, se não sempre, em que casos não é e quão grande pode ser a diferença? Estou particularmente interessado no ciclo Put - Get (no mesmo sistema de computador).

Os dois experimentos simples a seguir mostram que provavelmente o ciclo Put - Get em Mathematica sempre restaura números originais exatamente mesmo para números de precisão arbitrária:

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

Mas talvez eu esteja perdendo alguma coisa?

UPDATE

Com o código de teste mais correto, descobri que, na realidade, esses testes mostram apenas que os números restaurados têm% binário RealDigits idêntico, mas que seus Precision s podem diferir mesmo em Equal sense. Aqui estão mais testes corretos:

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}
    
por Alexey Popkov 26.06.2011 в 09:01
fonte

2 respostas

5

Eu tenho medo de não dar uma resposta definitiva. Se você olhar para o arquivo de texto que você vê, ele é armazenado como algo como o InputForm dos valores, incluindo a indicação de precisão para números de precisão que não são da máquina.

Assumindo que Get use as mesmas rotinas de conversão que ImportString e ExportString , seu teste pode ser acelerado um pouquinho.

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

Eu testei isso por várias centenas de milhões de números em vários intervalos entre $ MinMachineNumber e $ MaxMachineNumber e sempre recebo os números originais. Não é uma prova, é claro, mas parece improvável que você veja números para os quais isso não é verdade se houver algum (e, nesse caso, a diferença seria tão pequena a ponto de ser insignificante).

    
por Sjoerd C. de Vries 26.06.2011 / 23:57
fonte
0

Uma coisa importante a saber é que Put [] / Get [] não mantém as matrizes compactadas compactadas. Você deve verificar DumpSave []. É muito mais rápido, pois é um formato binário e mantém os arrays compactados.

    
por Joshua Martell 27.06.2011 / 05:50
fonte