sum_error-plt.py 技術ドキュメント

プログラムの動作

このプログラム sum_error-plt.py は、異なる浮動小数点精度(float16float32float64)における累積誤差を比較することを目的としています。

主な機能は以下の通りです。

  1. 加算シミュレーション: 指定された初期値 $h$ を指定された回数 $N$ だけ繰り返し加算します。この際、numpyfloat16float32float64 の各データ型を使用して演算を行います。

  2. 誤差計算: 各ステップにおいて、最高精度 (float64) で計算された「真の値」と、各精度 (float16, float32, float64) で計算された累積値との差を「誤差」として計算します。

  3. CSV出力: 計算された各ステップでの真の値、各精度の累積値、および各精度の誤差をCSVファイルに保存します。

  4. グラフ表示: 各精度の誤差の累積状況を、Matplotlib を用いてグラフとして視覚化します。グラフは3つのサブプロットから構成され、それぞれ float16float32float64 の誤差の推移を示します。

このプログラムは、浮動小数点演算における丸め誤差が、データ型が持つ精度によってどのように蓄積され、結果に影響を与えるかという課題を具体的に示し、理解を深めることを支援します。

原理

プログラムは、浮動小数点数の加算における丸め誤差の蓄積という現象を扱っています。コンピュータにおける数値表現は有限であるため、多くの場合、実数を正確に表現することはできません。このため、演算のたびに微小な誤差(丸め誤差)が生じます。特に、多数回の演算を繰り返すと、これらの微小な誤差が積み重なり、最終的な結果に大きな影響を与える可能性があります。これを累積誤差と呼びます。

プログラムでは以下の数式に基づいて誤差を計算します。

  1. 真の値: 各ステップ $i$ (\(0\) から $N-1$ まで) における真の値 $X_i$ は、初期値 $h$$i+1$ 回加算したものとして定義されます。これはプログラム内部で numpy.float64 型で計算され、最も正確な値とみなされます。

    \[X_i = (i+1) \cdot h\]
  2. 各精度での累積値: 各浮動小数点精度 $P$ (float16, float32, float64) における累積値 $S_{P,i}$ は、前のステップの累積値 $S_{P,i-1}$ に、その精度 $P$$h$ を加算することで計算されます。

    \[S_{P,i} = S_{P,i-1} + h_P\]

    ここで $h_P$ は、初期値 $h$ をそれぞれの精度 $P$ のデータ型に変換したものです。

  3. 誤差: 各精度 $P$ におけるステップ $i$ での誤差 $E_{P,i}$ は、真の値 $X_i$ とその精度での累積値 $S_{P,i}$ との差として定義されます。

    \[E_{P,i} = X_i - S_{P,i}\]

これらの計算を $N$ 回繰り返すことで、各精度における誤差の累積挙動を追跡し、その違いを分析します。float16 は精度が低く、float64 は最も高い精度を持つため、一般的に float16 で最も大きな累積誤差が観測され、float64 で最も小さな累積誤差が観測されることが期待されます。

必要な非標準ライブラリとインストール方法

このプログラムは以下の非標準ライブラリを使用しています。

  • NumPy: 数値計算、特に異なる浮動小数点データ型 (np.float16, np.float32, np.float64) を扱うために必要です。

  • Matplotlib: 計算された誤差データをグラフとしてプロットするために必要です。

これらのライブラリは pip コマンドを使用してインストールできます。

pip install numpy matplotlib

必要な入力ファイル

このプログラムは、実行時に特定の入力ファイルを必要としません。すべての設定パラメータ(加算回数 $N$, 加算する値 $h$, 出力CSVファイル名, コンソール表示ステップ間隔)はプログラムのソースコード内にデフォルト値として定義されています。

生成される出力ファイル

プログラムは以下の出力を生成します。

  1. CSVファイル:

    • ファイル名: sum_error.csv (デフォルト)

    • 内容: 各加算ステップにおける計算結果と誤差がカンマ区切り形式で保存されます。

      • exact: 最高精度 (float64) で計算された真の値。

      • float16: float16 型で累積された値。

      • float32: float32 型で累積された値。

      • float64: float64 型で累積された値。

      • error(float16): float16 型での累積誤差 (exact - float16)。

      • error(float32): float32 型での累積誤差 (exact - float32)。

      • error(float64): float64 型での累積誤差 (exact - float64)。

    • :

      exact,float16,float32,float64,error(float16),error(float32),error(float64)
      0.01,0.01,0.01,0.01,0.0,0.0,0.0
      0.02,0.02,0.02,0.02,0.0,0.0,0.0
      ...
      0.1,0.0999755859375,0.10000000149011612,0.1,-2.44140625e-05,-1.4901161193847656e-09,0.0
      ...
      
  2. グラフウィンドウ:

    • 表示内容: Matplotlibによって生成されるグラフウィンドウが表示されます。このウィンドウには3つのサブプロットが含まれています。

      • 各サブプロットは、横軸に加算回数 $N$、縦軸に累積誤差 $error$ を取り、それぞれの浮動小数点精度 (float16, float32, float64) における誤差の推移を示します。

      • 各グラフには凡例、軸ラベル、グリッド線が表示され、視覚的に誤差の蓄積の違いを比較できます。

    • 特徴:

      • グラフは plt.show(block=False) によって非ブロックモードで表示され、コンソールからの入力を待機します。

      • ユーザーがEnterキーを押すことでプログラムが終了し、グラフウィンドウも閉じます。

コマンドラインでの使用例 (Usage)

このプログラムは、コマンドライン引数を必要としません。Pythonインタープリタを使用して直接実行します。

python sum_error-plt.py

コマンドラインでの具体的な使用例

上記の使用例を実行した場合の挙動について説明します。

  1. 実行コマンド:

    python sum_error-plt.py
    
  2. コンソール出力例: プログラムを実行すると、以下のようなメッセージがコンソールに表示されます。これは、計算の進行状況と、指定されたステップ (iprintstep_def = 10) ごとに現在の真の値、各精度での累積値、およびそれぞれの誤差を示しています。

    Summing up 0.01 for 101 times with different precision floating point types
    Write to [sum_error.csv]
    
      exact  :           sum16 (error)           sum32 (error)           sum64 (error)
    
    0.0000: 0.000000000000000000 (+0.00e+00)  0.000000000000000000 (+0.00e+00)  0.000000000000000000 (+0.00e+00)  
    
    0.1000: 0.099975585937500000 (-2.44e-05)  0.100000001490116120 (-1.49e-09)  0.100000000000000000 (+0.00e+00)  
    
    0.2000: 0.199951171875000000 (-4.88e-05)  0.200000002980232240 (-2.98e-09)  0.200000000000000000 (+0.00e+00)  
    
    ... (以下同様に10ステップごとに表示) ...
    
    1.0000: 0.999755859375000000 (-2.44e-04)  1.000000000000000000 (+0.00e+00)  1.000000000000000000 (+0.00e+00)  
    
    Press ENTER to exit>>
    
  3. CSVファイルの生成: プログラムと同じディレクトリに sum_error.csv というファイルが生成されます。このファイルには、上記のコンソール出力よりも詳細な(すべてのステップの)計算結果と誤差が記録されます。

    exact,float16,float32,float64,error(float16),error(float32),error(float64)
    0.01,0.01,0.01,0.01,0.0,0.0,0.0
    0.02,0.02,0.02,0.02,0.0,0.0,0.0
    ...
    0.09,0.0899658203125,0.09000000357627869,0.09,-3.41796875e-05,-3.5762786865234375e-09,0.0
    0.1,0.0999755859375,0.10000000149011612,0.1,-2.44140625e-05,-1.4901161193847656e-09,0.0
    ...
    1.0,0.999755859375,1.0000000000000000,1.0,-2.44140625e-04,0.0,0.0
    1.01,1.009765625,1.0100000000000000,1.01,-2.34375e-04,0.0,0.0
    
  4. グラフの表示: コンソール出力と同時に、以下のような Matplotlib のグラフウィンドウが表示されます(具体的な数値は実行環境によって微差がある可能性があります)。

    • 左側のグラフ (float16) では、誤差が比較的大きく、階段状に増加していく様子が確認できます。これは float16 が非常に低い精度しか持たないため、早い段階で丸め誤差が蓄積・顕在化するためです。

    • 中央のグラフ (float32) では、float16 よりも誤差は小さいものの、徐々に誤差が蓄積し、変動が見られます。

    • 右側のグラフ (float64) では、誤差が非常に小さく、ほぼゼロに近い値で推移していることが確認できます。これは float64 が高い精度を持つため、今回の加算回数では累積誤差がほとんど顕在化しないことを示しています。

    ユーザーはグラフウィンドウを閉じる前に、コンソールでEnterキーを押す必要があります。