§E20.44数値計算の実装と検証

最終更新

数値実験の結論は、コードが方程式を正しく解いていることの確認(検証)と、その方程式が現象を正しく表していることの確認(妥当性確認)を経て、はじめて信頼に値する。 本記事では、格子・刻み幅を系統的に細分化して誤差の減少率を測る収束試験を定義し、観測収束次数の推定とリチャードソン外挿を証明し、厳密解が手元にないときでも離散化を検証する製作解法(MMS)を導入する。最後に、浮動小数点加算の非結合性と、実験を再現可能にするための要件を整理する。

以下、AAを求めたい厳密な量(積分・解の値など)、A(h)A(h)を刻み幅h>0h > 0の離散法が返す近似値、e(h):=A(h)−Ae(h) := A(h) - Aを誤差とする。丸めの単位uu、浮動小数点演算モデルは前項(floating-point-conditioning)の§E20.1 系 3.2を用いる。

1 検証と妥当性確認

数値実験の誤りには、性質の異なる二つの源がある。両者を混同すると、正しいコードを疑い続けたり、不適切なモデルを精緻化し続けたりする。

定義 1.1. 数理モデル(方程式)M\mathcal{M}を離散化・実装して数値解A(h)A(h)を得る過程について、次を区別する。

  1. 検証 (verification)(verification)——「方程式を正しく解いているか」。離散解A(h)A(h)が、h→0h \to 0でM\mathcal{M}の厳密解AAに、理論が予言する次数で収束することの確認。数学とコードの問題であり、実世界のデータを必要としない。
  2. 妥当性確認 (validation)(validation)——「正しい方程式を解いているか」。モデルM\mathcal{M}の解が、実際の観測・実験データと許容範囲で一致することの確認。モデル化の問題であり、外部データを要する。

検証は数値解と厳密解の比較、妥当性確認は数値解(またはモデル解)と現実の比較である。

検証を経ずに妥当性確認へ進むと、離散化誤差とモデル誤差が相殺・累積して見分けがつかなくなる。本記事が主題とするのは、外部データを要さずに実行できる検証の手続きである。

2 収束試験と観測収束次数

検証の中核は、刻み幅を細かくしたときに誤差が理論どおりの速さで減るかを測ることである。

定義 2.1. 基準刻み幅h0h_0と細分化比r>1r > 1(多くはr=2r = 2)を固定し、刻み幅の列hj=h0/r jh_j = h_0 / r^{\,j}(j=0,1,2,…j = 0, 1, 2, \dots)に対して離散解A(hj)A(h_j)を計算する手続きを収束試験 (convergence study) という。厳密解AAが既知なら誤差e(hj)=A(hj)−Ae(h_j) = A(h_j) - Aを、未知なら連続する解の差A(hj)−A(hj+1)A(h_j) - A(h_{j+1})を、jjに対して記録する。e(hj)e(h_j)をhjh_jの両対数目盛にとった図(収束プロット (convergence plot))の傾きが、以下の観測収束次数を可視化する。

離散法の設計時に理論上の収束次数pp(例:局所打切り誤差O(hp+1)O(h^{p+1})の一段法が与える大域誤差O(hp)O(h^p)、中心差分が与えるO(h2)O(h^2))が分かっていても、実装のバグや仮定の破れは、この理論次数が観測されないこととして現れる。したがって観測次数を理論次数と突き合わせることが検証になる。

命題 2.2. 誤差がe(h)=C hp+o(hp)e(h) = C\,h^p + o(h^p)(h→0h \to 0、C≠0C \ne 0、p>0p > 0)の形をもつとする。細分化比をr>1r > 1とすると、次が成り立つ。

  1. 厳密解が既知で誤差e(h)e(h)が測れるとき、p=lim⁡h→0log⁡ ⁣(e(h)/e(h/r))log⁡r.p = \lim_{h \to 0} \frac{\log\!\big(e(h)/e(h/r)\big)}{\log r}.
  2. 厳密解が未知でも、三つの格子解A(h), A(h/r), A(h/r2)A(h),\,A(h/r),\,A(h/r^2)からp=lim⁡h→01log⁡r log⁡ ⁣(A(h)−A(h/r)A(h/r)−A(h/r2)).p = \lim_{h \to 0} \frac{1}{\log r}\,\log\!\left(\frac{A(h) - A(h/r)}{A(h/r) - A(h/r^2)}\right).

証明.(1)を示す。仮定よりe(h)=Chp+o(hp)e(h) = C h^p + o(h^p)、また(h/r)p=r−php(h/r)^p = r^{-p} h^pゆえe(h/r)=Cr−php+o(hp)e(h/r) = C r^{-p} h^p + o(h^p)。C≠0C \ne 0だからe(h)e(h/r)=Chp(1+o(1))Cr−php(1+o(1))=rp(1+o(1)).\frac{e(h)}{e(h/r)} = \frac{C h^p\big(1 + o(1)\big)}{C r^{-p} h^p\big(1 + o(1)\big)} = r^p\big(1 + o(1)\big).両辺の対数をlog⁡r\log rで割るとlog⁡(e(h)/e(h/r))/log⁡r=p+o(1)→p\log(e(h)/e(h/r))/\log r = p + o(1) \to p。

(2)を示す。厳密解をAAとするとA(h)−A=Chp+o(hp)A(h) - A = C h^p + o(h^p)。差をとるとA(h)−A(h/r)=(A(h)−A)−(A(h/r)−A)=C(1−r−p)hp+o(hp),A(h) - A(h/r) = \big(A(h) - A\big) - \big(A(h/r) - A\big) = C\big(1 - r^{-p}\big) h^p + o(h^p),A(h/r)−A(h/r2)=C(1−r−p)(h/r)p+o(hp)=C(1−r−p)r−php+o(hp).A(h/r) - A(h/r^2) = C\big(1 - r^{-p}\big)(h/r)^p + o(h^p) = C\big(1 - r^{-p}\big) r^{-p} h^p + o(h^p).C(1−r−p)≠0C(1 - r^{-p}) \ne 0(r>1r > 1より1−r−p>01 - r^{-p} > 0)だから、両者の比はA(h)−A(h/r)A(h/r)−A(h/r2)=C(1−r−p)hp(1+o(1))C(1−r−p)r−php(1+o(1))=rp(1+o(1)),\frac{A(h) - A(h/r)}{A(h/r) - A(h/r^2)} = \frac{C(1 - r^{-p}) h^p\big(1+o(1)\big)}{C(1 - r^{-p}) r^{-p} h^p\big(1+o(1)\big)} = r^p\big(1 + o(1)\big),再び対数をとってppを得る。▨

(2)は厳密解を要さないため、実問題の検証で実際に使う形である。33格子で推定したppが理論値へ近づかないなら、細分化がまだ漸近域に入っていないか、離散化・実装に欠陥があるかのいずれかである。

3 リチャードソン外挿

誤差が刻み幅のべきで展開できるとき、二つの解を線形結合して主要誤差項を消去できる。これにより高精度解と、その場で使える誤差推定の両方が得られる。

定理 3.1 (リチャードソン外挿). 近似が誤差展開A(h)=A+cp hp+cq hq+o(hq)(0<p<q, cp≠0)A(h) = A + c_p\,h^p + c_q\,h^q + o(h^q) \qquad (0 < p < q,\ c_p \ne 0)をもち、主要次数ppが既知とする。細分化比r>1r > 1に対しリチャードソン外挿値をAR(h):=rp A(h/r)−A(h)rp−1A_R(h) := \frac{r^p\,A(h/r) - A(h)}{r^p - 1}で定めると、次が成り立つ。

  1. AR(h)A_R(h)の誤差は一段高い次数qqをもつ:AR(h)=A+cq r p−q−1rp−1 hq+o(hq)=A+O(hq).A_R(h) = A + c_q\,\frac{r^{\,p-q} - 1}{r^p - 1}\,h^q + o(h^q) = A + O(h^q).
  2. 細かい側の解A(h/r)A(h/r)の誤差は、二つの解の差から主要次数まで推定できる:A(h/r)−A=A(h/r)−A(h)rp−1+o(hp).A(h/r) - A = \frac{A(h/r) - A(h)}{r^p - 1} + o(h^p).

証明.(1)を示す。展開にh↦h/rh \mapsto h/rを代入すると(h/r)p=r−php(h/r)^p = r^{-p} h^p、(h/r)q=r−qhq(h/r)^q = r^{-q} h^qよりA(h/r)=A+cp r−php+cq r−qhq+o(hq).A(h/r) = A + c_p\,r^{-p} h^p + c_q\,r^{-q} h^q + o(h^q).両辺をrpr^p倍してA(h)A(h)を引くと、hph^pの項がちょうど打ち消し合う:

rpA(h/r)−A(h)=(rp−1)A+(cphp−cphp)+cq(r p−q−1)hq+o(hq).r^p A(h/r) - A(h) = \big(r^p - 1\big) A + \big(c_p h^p - c_p h^p\big) + c_q\big(r^{\,p-q} - 1\big) h^q + o(h^q).

右辺のhqh^qの係数はcq(rp−q−1)c_q(r^{p-q}-1)で、rp−1>0r^p - 1 > 0で割るとAR(h)=A+cq r p−q−1rp−1 hq+o(hq).A_R(h) = A + c_q\,\frac{r^{\,p-q} - 1}{r^p - 1}\,h^q + o(h^q).q>pq > pよりrp−q−1=r−(q−p)−1r^{p-q} - 1 = r^{-(q-p)} - 1は00でない有限値だから、主要誤差はO(hq)O(h^q)である。

(2)を示す。展開の主要項だけを見るとA(h)−A=cphp+o(hp)A(h) - A = c_p h^p + o(h^p)、A(h/r)−A=cpr−php+o(hp)A(h/r) - A = c_p r^{-p} h^p + o(h^p)。差をとってA(h)−A(h/r)=cp(1−r−p)hp+o(hp)=cpr−php (rp−1)+o(hp).A(h) - A(h/r) = c_p\big(1 - r^{-p}\big) h^p + o(h^p) = c_p r^{-p} h^p\,\big(r^p - 1\big) + o(h^p).両辺をrp−1r^p - 1で割ると右辺はcpr−php+o(hp)=(A(h/r)−A)+o(hp)c_p r^{-p} h^p + o(h^p) = \big(A(h/r) - A\big) + o(h^p)、すなわちA(h/r)−A=A(h)−A(h/r)rp−1+o(hp)=A(h/r)−A(h)−(rp−1)⋅(−1)+o(hp).A(h/r) - A = \frac{A(h) - A(h/r)}{r^p - 1} + o(h^p) = \frac{A(h/r) - A(h)}{-(r^p-1)}\cdot(-1) + o(h^p).符号を整理すれば主張の等式を得る。▨

外挿値AR(h)A_R(h)を新たなA(⋅)A(\cdot)とみなして展開の次の項cqhqc_q h^qに同じ操作を繰り返すと、O(hq)O(h^{q})、さらに高次へと段階的に精度を上げられる。積分に対してこれを台形則から系統的に行うのがロンバーグ積分である。

検算(台形則へのリチャードソン外挿).∫01ex dx=e−1=1.7182818285…\displaystyle\int_0^1 e^x\,dx = e - 1 = 1.7182818285\ldotsを複合台形則で近似する。台形則の誤差はオイラー・マクローリン展開により偶数べきT(h)=A+c2h2+c4h4+⋯T(h) = A + c_2 h^2 + c_4 h^4 + \cdotsをもつので、p=2p = 2、q=4q = 4、r=2r = 2とし、外挿式はAR=(22 T(h/2)−T(h))/3=(4 T(h/2)−T(h))/3A_R = \big(2^2\,T(h/2) - T(h)\big)/3 = \big(4\,T(h/2) - T(h)\big)/3となる。各TTは等比和の閉形式で厳密に評価し、誤差比を二重確認した。

nn h=1/nh = 1/n 台形則T(h)T(h) 誤差∣e(h)∣\lvert e(h)\rvert 観測次数pp 外挿ARA_R 外挿誤差
11 11 1.85914091421.8591409142 1.409×10−11.409\times10^{-1} — — —
22 1/21/2 1.75393109251.7539310925 3.565×10−23.565\times10^{-2} 1.9821.982 1.71886115191.7188611519 5.79×10−45.79\times10^{-4}
44 1/41/4 1.72722190461.7272219046 8.940×10−38.940\times10^{-3} 1.9961.996 1.71831884191.7183188419 3.70×10−53.70\times10^{-5}
88 1/81/8 1.72051859221.7205185922 2.237×10−32.237\times10^{-3} 1.9991.999 1.71828415471.7182841547 2.33×10−62.33\times10^{-6}

観測次数(真誤差からlog⁡(e(h)/e(h/2))/log⁡2\log(e(h)/e(h/2))/\log 2で算出)は22へ収束し、台形則の理論次数O(h2)O(h^2)と一致する(命題 2.2)。外挿値の誤差は5.79×10−4→3.70×10−5→2.33×10−65.79\times10^{-4} \to 3.70\times10^{-5} \to 2.33\times10^{-6}と、11段細分化ごとに約16=2416 = 2^4倍で減っており、定理 3.1の予言するO(h4)O(h^4)を確認する。n=8n = 8の台形則が2.24×10−32.24\times10^{-3}の誤差にとどまるのに対し、n=4,8n = 4, 8からの外挿は2.33×10−62.33\times10^{-6}——同じ計算量でおよそ10001000倍の精度である。

4 製作解法(MMS)

検証は厳密解AAの存在を前提とするが、実際の問題の厳密解はまず得られない。そこで解を先に決め、それを厳密解にする方程式を逆算する。

定義 4.1. 微分作用素L\mathcal{L}に対する問題Lu=f\mathcal{L}u = fを解くコードを検証したいとする。製作解法 (method of manufactured solutions) (method of manufactured solutions, MMS)とは、次の手順をいう。

  1. 十分滑らかな関数u∗u^\ast(製作解 (manufactured solution))を任意に選ぶ。物理的意味は要らない。
  2. 強制項をf∗:=Lu∗f^\ast := \mathcal{L}u^\astと解析的に計算する。これによりu∗u^\astはLu=f∗\mathcal{L}u = f^\astの厳密解になる。境界・初期条件もu∗u^\astから定める。
  3. 強制項f∗f^\astを入力してコードで数値解uhu_hを求め、既知のu∗u^\astとの誤差∥uh−u∗∥\lVert u_h - u^\ast\rVertを格子ごとに測り、観測収束次数を理論次数と照合する。

MMS はu∗u^\astを自由に選べるため、あらゆる項(拡散・移流・反応・非線形・境界)を励起する解を設計でき、離散化のどの部分が理論次数を出していないかを切り分けられる。例えば区間(0,1)(0,1)上の−u′′=f-u'' = f、u(0)=u(1)=0u(0) = u(1) = 0を検証するにはu∗(x)=sin⁡(πx)u^\ast(x) = \sin(\pi x)ととればf∗(x)=− (u∗)′′(x)=π2sin⁡(πx)f^\ast(x) = -\,(u^\ast)''(x) = \pi^2 \sin(\pi x)で、境界条件u∗(0)=u∗(1)=0u^\ast(0) = u^\ast(1) = 0も自動的に満たされる。これを二階中心差分で解けば、L∞L^\infty誤差がO(h2)O(h^2)で減ることを確認できる。観測次数が22に届かなければ、境界の扱いか行列組み立てにバグがある。MMS はモデルの正しさ(妥当性確認)ではなく、離散化・実装の正しさ(定義 1.1の検証)を試す道具であることに注意する。

5 浮動小数点と再現性

以上の手続きは、同じコードが同じ入力に対して同じ出力を返すことを暗黙に仮定している。有限精度の計算では、この「同じ」が思うほど自明でない。

注意 5.1 (浮動小数点加算の非結合性). 実数の加算は結合的だが、丸めを伴う浮動小数点加算⊕\oplus(§E20.1 系 3.2)は結合的でない:一般に(a⊕b)⊕c≠a⊕(b⊕c)(a \oplus b) \oplus c \ne a \oplus (b \oplus c)。IEEE 倍精度でx=1016x = 10^{16}、y=−1016y = -10^{16}、z=1z = 1をとると、101610^{16}の近傍では表現可能な数の間隔(ULP)が22なので1016⊕110^{16} \oplus 1は最近接丸めで101610^{16}に戻る。したがって(x⊕y)⊕z=0⊕1=1,x⊕(y⊕z)=x⊕(−1016)=0,(x \oplus y) \oplus z = 0 \oplus 1 = 1, \qquad x \oplus (y \oplus z) = x \oplus (-10^{16}) = 0,と結果が食い違う(後者はz=1z = 1が桁落ちで消える。§E20.3 注意 7.3)。帰結として、総和の評価順序が結果を変える。並列リダクションやベクトル化、スレッド数の変更、コンパイラの再結合最適化は加算順序を変えうるため、同じプログラムでもビット単位で異なる答えを返す。これが数値実験のビット単位再現性を破る主要因である。

順序に依存しない総和が必要なら、補償付き加算(カハンの総和)や、ペアワイズ総和、あるいは整数化した固定小数点での確定的リダクションを使う。いずれも、非結合性という事実(注意 5.1)を迂回するための設計である。

注意 5.2 (再現性の要件). 計算実験が再現可能であるとは、第三者(および将来の自分)が結論を同じ手順で再現できることをいう。次を固定し記録する。

  1. 乱数シード——確率的な要素(初期値、モンテカルロ標本、確率的最適化)に用いた擬似乱数生成器と、そのシード。
  2. 依存バージョン——言語・ライブラリ・BLAS などの数値カーネルのバージョン。丸めや縮約順序は実装に依存しうる(注意 5.1)。
  3. 環境——OS・CPU/GPU・スレッド数・コンパイラと最適化フラグ。並列度が結果に影響しうる。
  4. データと前処理——入力データの版と、前処理・スケーリングの全手順。

再現性には二つの水準を区別する。ビット単位再現性は上のすべてを固定して同一のビット列を得る厳しい要求で、並列環境では縮約順序の固定を要する。科学的再現性は、報告した誤差許容(§E20.2 定義 2.1の前進誤差の範囲)内で結論が再現できればよい、より現実的な水準である。論文・実験ログには、どちらの水準を主張するかを明記する。

前提記事