bugfix> python > 投稿

Pythonで複素数に対していくつかの簡単な算術演算を行う次のPythonコードを検討してください。

import numpy as np
s = 2
l = 5
v = np.array([np.exp(1j*2*np.pi/l)])
A = pow(s*v, l) + s*v
#Print the precision of np.complex128
print np.finfo(np.complex128).precision
#Export using 20 decimal places for real and imaginary parts
np.savetxt('A.csv', A, fmt=['%.20e%+.20ej'], delimiter=',')

これを見た回答  np.complex128 の精度を印刷するためPythonの変数と私が得るものは15です。SpyderでAの値を確認すると、 (32.61803398874989+1.9021130325903035j) が表示されますその虚数部の小数点以下の桁数は15を超えています。また、エクスポートされたCSVファイルの値は 3.26180339887498931262e+01+1.90211303259030350965e+00j です実部と虚部の両方が20有用 小数位。

私はここで混乱しています:精度が15の場合、それらの余分な小数位は何ですか?によるここに、 np.complex128 2つの64ビット浮動小数点で構成され、1つは実数部、もう1つは虚数部です。

しかし、私の主な問題は、プログラムでこれらの操作の多くを複素数(加算、乗算、行列反転など)で実行しており、実行するたびに異なる結果、時には正しい、時には間違った結果になることです。私のプログラムはこれらの操作の正確さに非常に敏感であるようです。複素数の精度はPythonでどのように定量化されますか、また最大値は何ですか?

Python 2.7.14とNumpy 1.14.3を使用しています。

回答 1 件
  • 完全な回答には多くのスペースが必要です。手始めに、バイナリ浮動小数点型がどのように機能し、どのように保存されるかを説明する数値解析に関する本を読む必要があります。しかし、ここにいくつかの部分的な説明があります。

    64ビットの浮動小数点値は、10進数ではなくバイナリで保存されます。したがって、10進数について言われていることのほとんどは、完全な話ではなく、近似値でなければなりません。

    np.finfo(np.complex128).precision の場合  (または他の何か)は、有効な10進数が15桁あると言います。つまり、これらの15桁を超える数字は当てにできないということです。 IPythonコンソールからの例を以下に示します。

    In [4]: 9.000000000000001
    Out[4]: 9.000000000000002
    In [5]: 9.000000000000001 == 9.000000000000002
    Out[5]: True
    
    

    Pythonは、デフォルトで小数点付きの数値に64ビット浮動小数点型を使用しますが、これら2つの16桁の数字を同一として扱います。数字 9.000000000000001 を使用する場合  最初の15桁の10進数のみが正しく保存されることが保証されています。それ以降は保証されません。この場合は 1 が表示されます  基本的には 2 に変更されます 。

    15桁以上の10進数を取得できる場合があります。たとえば、数値はバイナリで保存されるため、 1.0 よりわずかに大きい数値   9.0 のような数値よりも基数ポイントの後に多くの2進数があります  意志。これは、 9   1 の間に4桁の2進数を使用します  は1つだけを使用するため、基数ポイントの後にさらに3桁の2進数を使用できます。それでは、数字の虚数部 1.9021130325903035 を見てみましょう。 :

    In [17]: 1.902113032590303 == 1.9021130325903035
    Out[17]: False
    In [18]: 1.9021130325903036 == 1.9021130325903035
    Out[18]: True
    In [19]: 1.902113032590304 == 1.9021130325903035
    Out[19]: False
    
    

    数値には17桁の10進数が表示されていますが、最終桁を5から6に変更してもPythonには何の変化もないことがわかります。しかし、その数値を16桁の10進数に切り上げるか切り上げると、変更があります。したがって、数値は16桁以上の10進数で格納されていると言えます。そのため、精度を説明するときに、浮動小数点数には15桁の有効な10進数が保証されているが、16桁ある可能性があり、実際の精度はそれよりわずかに高いと言います。もっと簡単に言うと、有効桁数は15または16桁です。

    Pythonには、浮動小数点数を出力する2つの基本的な方法があります: str  関数と repr  関数。ザ・ str  関数は物事を簡単に出力するので、ユーザーはあまり詳細に説明しなくても結果を理解できます。ザ・ repr  関数はより多くの詳細を提供し、保存されたデータが印刷内容によって完全に決定されるほど多くの詳細を印刷しようとします。 repr  は、コンソールに数値を入力したり、見たようにSpyderの変数エクスプローラーを使用するなど、場合によっては目に見えないように使用されます。

    SpyderまたはPythonが repr を実行する場合  あなたの番号 1.9021130325903035  数字を完全に定義するのに十分な桁数を与えます。上記で見たように、小数点以下16桁しか表示されない場合は、最終的な 5 を削除します 、結果は保存されているものとわずかに異なります。したがって、Pythonは追加の数字を出力するため、値が何であるかを知ることができます。 Pythonが最終的な 6 を出力した場合   5 ではなく  値は同じでしたが、Pythonがその数字を完全に省略した場合、値は変更されます。したがって、 repr 経由のPython  あまりにも多くの数字を与える側のエラー。 17桁の数字が印刷されていますが、そのうちの16桁のみが確実です。

    最後に、csvファイルには20桁の10進数が表示されます。これは、 %.20e のためにPythonに20桁の10進数を表示するように指示したためです。   np.savetxt の指定子  コマンド。これらの20桁の数字はすべて「有用 Pythonは基本的に、格納された値にバイナリビット、すべてゼロを追加し、それを20に出力しました。ただし、これらのゼロのバイナリビットは値に格納されませんでした。

あなたの答え