2011-02-10 9 views
6

これは数字書式に関する質問で、先にquestionという非常に特殊なMathematicaの出力をテキストファイルとして取得することに関するものです。Mathematicaでファイルに書き込むときの数値の書式設定

Mathematicaでデータ生成に高精度を頻繁に使用する必要がありますが、視覚化の目的では精度が比較的低いだけです。また、すべてのSymbol名と配列構造をそのまま使用して後で使用できるようにデータを保存したいと考えています。このため私はSave[]を使っていますが、2つの関連する問題があります。私は実際には0.448799を必要

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. 

  1. 高い精度が非常に困難であり、余分な数字と私の結果はを取り除くために「汚染します」。

  2. 場合によっては、精度を示す数値も壊れていて、一般的には精度が不要で、4.72642とすれば十分です。4.72642364528438598726943'5.9999999999999999999999のような値が得られることがあります。

これらの両方がファイルサイズに重大なオーバーヘッドをもたらし、ハードディスクストレージは安価ですが、後でファイルをMathematicaに戻すときにファイルサイズが大きく変わります。

ので、始まる、例えば、aa、私はこの

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

のようなものを読んでいましたテキストファイルを取得するための方法で構築されている不規則な配列に50桁の任意精度数値が含まれていますEDIT:明確にするために、数値の表示や数値の精度の追跡、数値の精度の変更に問題はありません。私が問題を抱えているのは、数値がファイルに書き込まれる方法を制御することです。などNNumberFormOutputFormInputForm*Formを使用

、すべてがSaveで正しく動作しません。そしてSaveは、シンボルと配列の構造体をエクスポートできる唯一のエクスポートオプションです。 ExportPut*は、フォーマットをよりよく制御するために使用できますが、シンボルは含まれません(Exportの場合は配列構造も失われます)。

答えて

6

あなたは本当に2.0437`4のようなものを必要としますか、またはマシンの倍の2.0437で十分でしょうか?後者の場合、あなたは(ほとんど)6桁が表示されます機械のダブルスに強制する

N[SetPrecision[values,6]] 

ような何かを行うことができます。

考えられる利点は、それを読み返すことです。あなたの配列は今ではマシン倍になり、したがってパッケージ化可能になります。 GetやImportが自動的にパックされているのかどうかはわかりませんが、Developer`ToPackedArrayはそれを行います。

---編集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} 

---エンド編集---

ダニエルLichtblau Wolfram Researchの

+0

私は精度情報は必要ありませんが、削除することは非常に困難です。私の問題は、ノートブックに何桁の数字が表示されているかではなく、問題はファイルに書き込まれる桁数です。 – Timo

+0

ToExpression [ToString [NumberForm [

+0

数値が浮動小数点数の場合は機能しません。私は 'RealDigits'と' FromDigits'で、あなたが示唆しているものに似た何かをするkludgeに取り組んでいます。 – Timo

0

OutputFormは、余分な数字を取り除くためのあなたの友人です。それは

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

また醜いですが、あなたはバッククォートや精度を必要としない場合は、文字列にそれをハック可能性があり、簡単な解決策は以下のとおりです。

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

編集:第二の溶液のdoesnうまくいきません。暫定修正が

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

を、私は反対のことをやってみたいです。多分私は十分にはっきりしていなかったでしょう。とにかく、 'aa = {{2.0437、4.7276、...}、...}'を生成するためにあなたの例を得ることができません。代わりに、私に 'OutputForm'(タイプライターのような、あなたは何か他のことを心に留めて、単に書き留めましたか? – Timo

+0

ティモ:私の間違いだった。'OutputForm'はすべてのレベルにマッピングされるべきではありませんが、' N'はそうでなければなりません。以下を試してください: 'OutputForm [N [#、n]&// @ l]'。 Fookin 'かっこ。 (投稿も同様に編集しました) これらの計算のすべての部分式も同様に評価されるため、数値的には不安定になることがあります。これを理解する方法を見ていきます。 – dvitek

+0

私の例は単純すぎると思う;-)、 'OutputForm'の有用性は指数のない数字に限定されています。たとえば、3.4 *^- 50などのソリューションを試してみてください。 – Timo

0

である私はあなたの問題への直接解決策を持っていないが、私は他の方法で役立つかもしれない提案を持っています。

Mathematicaのセッション状態と定義を保存することに興味がある場合は、Saveではなく、DumpSaveを使用する方がよい場合があります。プレーンテキストファイルの代わりに、ある種のバイナリイメージが得られ、通常はそれほどスペースが少なくて済むだけでなく、読み込み時間も大幅に短縮されます。主な欠点は、生成されたファイルがMathematicaのバージョン間、あるいは異なるOSesなどの間で移植できないことであり、明らかに人間が読めるものではないということです。

InputFormなどでNumberMarksオプションを使用すると、バッククォートと精度を抑制することもできます。実際に精度を下げることに興味があるのであれば、私はNを使って行くと思います。

+3

他の人やシステムにデータを配布しない場合は、DumpSaveは問題ありません。たとえば、OS XマシンはWindowsまたはLinuxで作成されたファイルを読み取ることができず、64ビットWindowsでは32ビットWindowsで作成されたファイルを読み取ることができません(その逆もあります)。一般的にN + 1バージョンでは、バージョンNからファイルを読み込むには(同じOSとビット数を使用していると仮定しますが)、バージョンNはN + 1を読み込めない可能性があります。 –

+0

バイナリイメージは悲しいことに受け入れられません。後で他のプログラムにデータをインポートする必要があるかもしれません。 – Timo

3
ここ

余計な数字を破棄するように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, ...} 

すでに改善されていますが、まだ必要な文字数の2倍を超えています。

EDIT:我々は勝者持っている:私は実際には、精度を追跡したくない

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, ...} 
関連する問題