Форматирование чисел при записи в файлы в Mathematica - PullRequest
6 голосов
/ 10 февраля 2011

Это продолжение этого вопроса, касающегося форматирования чисел, и связанного с моим ранее вопросом о получении очень специфического вывода Mathematica в текстовые файлы.

Я частоприходится использовать высокую точность в Mathematica для генерации данных, но нужна только относительно низкая точность для целей визуализации.Я также хочу сохранить данные для последующего использования с сохранением всех имен символов и структур массива.Для этого я использовал Save[], но есть две связанные проблемы.

  1. Высокая точность «загрязняет» мои результаты лишними цифрами, от которых очень трудно избавиться:

    In[1]  := b = SetPrecision[7, 50]; a = Pi/b
    Out[1] := 0.44879895051282760549466334046850041202816705705358654585356351318683091518373`50.
    In[2]  := InputForm @ N[a, 6]
    Out[2] := 0.44879895051282760549466334046850041203`6.
    

    , где мне действительно нужно только 0,448799.

  2. Иногда даже число, указывающее на точность, искажается, и я получаю такие значения, как 4.72642364528438598726943'5.9999999999999999999999, где мне обычно не нужна точность и4.72642 было бы достаточно.

Оба этих параметра значительно увеличивают размер файла, и, хотя хранилище на жестком диске дешево, размер файла имеет огромное значение при последующей загрузке файлов обратно в Mathematica.

Итак, начиная с, например, aa, который содержит 50-значные числа произвольной точности в нерегулярном массиве, есть встроенный способ для меня получить текстовый файл, который будет читать что-то вроде этого

aa = {{2.0437`4, 4.7276`4, ...}, ...}

РЕДАКТИРОВАТЬ : Чтобы уточнить, у меня нет проблем с отображением чисел или с отслеживанием точности чисел или с изменением руточнение номеров.У меня проблемы с управлением записью числа в файл.

Использование N, NumberForm, OutputForm, InputForm, *Form и т. Д., Все не работаютправильно с SaveSave - единственный вариант экспорта, который я могу найти, который экспортирует символ и структуру массива.Export и Put* могут использоваться для лучшего управления форматированием, но они не включают символ (а в случае Export структура массива также теряется).

Ответы [ 4 ]

6 голосов
/ 10 февраля 2011

Тебе действительно нужны такие вещи, как 2.0437`4, или машины будет достаточно двойного 2.0437?Если последнее, то вы могли бы сделать что-то вроде

N[SetPrecision[values,6]]

, чтобы привести к машинным двойникам, которые будут (в основном) показывать шесть десятичных цифр.

Возможное преимущество заключается в его чтении.Ваш массив теперь будет двойником машин, следовательно, может быть упакован.Я не уверен, что Get или Import автоматически упакуют, но Developer`ToPackedArray сделает это.

--- edit 2011-02-11 ---

Теперь, когда я увидел, что может пойти не так ...

Вот пример, использующий ваш более поздний вклад и несколько других, которые, я надеюсь, будут репрезентативными.

aa = {7.469702041097916467293771347613073888816285869`15.\
  954589770191005*^-51, 5555.22222222222222222223,
  .00000000002222222222222222222222222227777777777777, N[E, 22]^33}

Первое преобразованиев строку.Это может быть действительно все, что вы действительно хотите, для сохранения в файл.Я использую NumberForm, но с настраиваемой функцией форматирования (по большей части взятой со страниц документации).

In[39]:= 
    InputForm[ToString[
      NumberForm[N[aa], 6, 
       NumberFormat :> (If[#3 != "", Row[{#1, "*^", #3}], #1] &)]]]

Out[39]//InputForm=
"{7.4697*^-51, 5555.22, 2.22222*^-11, 2.14644*^14}"

Обратите внимание, что преобразование выражений прекрасно работает на этом.

In[40]:=
    InputForm[ToExpression[
      ToString[NumberForm[N[aa], 6, 
       NumberFormat :> (If[#3 != "", Row[{#1, "*^", #3}], #1] &)]]]]

Out[40]//InputForm=
{7.4697*^-51, 5555.22, 2.22222*^-11, 2.14644*^14}

--- конец редактирования ---

Даниэль Лихтблау Вольфрам Исследования

3 голосов
/ 11 февраля 2011

Вот очень дурацкий способ делать то, что я хочу, т.е. заставлять Mathematica отбрасывать лишние цифры.

aa =  {7.469702041097916467293771347613073888816285869`15.954589770191005*^-51, ...};
list = RealDigits[N[aa, 6]];
bb = Thread @ #1*10.^(#2 - #3) &[FromDigits /@ First /@ list, 
                           Last /@ list, 
                           First /@ Dimensions /@ First /@ list];
InputForm @ bb

{7.469700000000001*^-51, ...}

Что уже является улучшением, но все еще имеет более чем вдвое большее число символов, чемнеобходимо.

РЕДАКТИРОВАТЬ: И у нас есть победитель:

list = Transpose @ {FromDigits /@ First /@ #, 
                    Last /@ #, 
                    First /@ Dimensions /@ First /@ #}& @ RealDigits[N[aa, 6]];
bb = ToExpression[ToString[#1] <> ".*^" <> ToString[#2 - #3]] & @@@ list;
InputForm @ bb

{7.4697`*^-51, ...}
0 голосов
/ 10 февраля 2011

У меня нет прямого решения вашей проблемы, но у меня есть предложение, которое может быть полезным в других отношениях.

Если вы заинтересованы в сохранении состояния и определений сеанса Mathematica, вам часто лучше использовать DumpSave вместо Save. Вы получаете какое-то двоичное изображение вместо простого текстового файла, и оно не только обычно занимает гораздо меньше места, но и загружается намного, намного, намного быстрее. Основным недостатком является то, что полученные файлы вообще не переносимы между версиями Mathematica, различными операционными системами или чем-то подобным, и, очевидно, они не читаются человеком.

Вы также можете подавить обратные помехи и точность, используя опцию NumberMarks с InputForm и др. Если вы действительно заинтересованы в снижении точности, я думаю, что использование N - это путь.

0 голосов
/ 10 февраля 2011

OutputForm ваш друг, чтобы избавиться от лишних цифр. Вы можете взломать его в строку, хотя это некрасиво

f[x_,n_]:=StringJoin[ToString[OutputForm[N[x,n]]],"`",ToString[Round[Precision[N[x,n]]]]];

В качестве альтернативы, если вам не нужны обратные метки или точность, простое решение:

FormatList[l_,n_]:=OutputForm[N[#,n]]&//@l;

Edit: второе решение не работает; временное исправление

FormatList[l_,n_]:=OutputForm[N[#,n]&//@l];
...