はじめに
プログラミング云々ばかり言っていても、それがどのように計算されているかを知らないと仕様が無い。ということで数値解析を学んでいく。
基本的には
を参照しつつ、他書で補足する。
0. 数値アルゴリズム
数値解析は実数上で定義された計算表現のアルゴリズムを研究する学問である。平方根がその例であり、今日ではこれらの評価を計算機上ないし計算プログラムにおいて二乗計算と同じくらいに簡単かのように計算する。これで可能になったのが数値解析であり、この数値解析がどのようになされるかを学んでいく。
数値解析について説明するには2つの異なる段階がある:
原理的にはこれらは独立したものである。しかし現実にはアルゴリズムの発展はアルゴリズム解析もしくは同じものや同類の問題をより簡単に計算するアルゴリズムから導出されることもある。
ある程度対立関係にある、実数を用いるアルゴリズムには3つの特徴がある:
- アルゴリズムの精確さ(一貫性) アルゴリズムは適当な制約下において要求された精度で望まれた値に近似することを意味する。
- アルゴリズムの安定性 アルゴリズムの挙動がそのパラメータの観点で連続であることを意味する。
- 有限精度の計算による影響(すなわち丸め誤差) 有限精度の計算のための良い数学モデルは存在せず、有限精度の計算の挙動に対しては荒い上限を為すことを甘受せざるを得ない。
安定したアルゴリズムの精度ないし効率性を改善しようとすると、不安定、その結果として最低限度の値に関するアルゴリズムを検討することになることもままある。アルゴリズムの効率性はより複雑な概念であるが、一方のアルゴリズムを別のものから選別する基本になり得る。
数値解析の別のテーマは適応性()である。計算アルゴリズムを効率性および/ないし安定性を改善する方法として問題のデータに適用することを意味する。
1. 数値計算における誤差
解の水準に基づいてアルゴリズムの精度は求められる。(物理)現象を数理モデリングする際、数値的に計算することが必要になり得るが、理論的なモデリングはその必要な精度を得るのには適当だとは限らない。必要に応じて変形したり別の手法を用いたりと、数値計算のために独自の手法やアイディアを考える必要がある。
1.1. 数値表現
計算機内部では数値は2進数または16進数で表現されている。またひとつの数値を表現するのに一定の桁数(ビット数)が与えられているが、そのために実数をコンピュータを扱おうと思っても、コンピュータは有限桁の有限個の数値しか扱えず、表現可能な数値に制約がある。
実数型の数値には32ビットを使用する単精度実数と64ビットを使用する倍精度実数の2種類がある。両者とも計算機内部では以下のような浮動小数点で記憶される。
と表示される。ここで
: | 基数 | ||
: | 桁数 | ||
: | 最小指数 | ||
: | 最大指数 | ||
,, | : | 仮数部 | |
: | 指数部 |
と呼ぶ。この表記方法を進桁浮動小数点数という。
このため演算の結果は、たとえ無理数であっても、何らかの形(四捨五入、切り上げ、切り捨てなど)でこの形態に収められる。
1.1.1 近似方法
実数をコンピュータで表示するのに近似する方法はいくつか存在する。
1つが、切り捨てである。実数
においてが成立しているとする。このときの近似値として
を採用するものである。
また
を採用する方式を四捨五入(捨入)という。
1.2. 絶対誤差と相対誤差
を具体的に求めるべく計算しようとしても、何らかの原因から厳密解を求められるとは限らず、近似値を求めることも少なくない。そうなれば厳密解との差異を議論することでその精度を検討することが必要となる。
そのために“誤差”という概念を導入する。をの近似値とするとき、
をそれぞれの誤差、の絶対誤差、そして誤差の限界という。
単位(水準)が相違するときには相対誤差
を用いる。
また限界は
に注意すると、が充分に小さい場合には
と近似できる。
1.3. 丸めの誤差
現在の規格IEEE754-2008におけるbinary64(倍精度実数型)ではとしている。この規格で扱える最大および最小の数は
である。
「1よりも大きい最小の数値と1との差」で計算機イプシロンを定義し、と書くことにすると、
であり、これよりも大きく最小の数値は
であるから、
である。この規格では制約として
があり、しかもその範囲内であってもすべての値を表すことができない。
たとえばとすると
仮数部 | 指数部 | ||
であるから、このときには
とこの体系で表現できるものの、
はいずれもこの体系では表現できない。したがって、計算のために入力した値や計算途中で算出される中間値、そして最終的な答えはすべてこの体系で表現できる値に近似される。このように「計算において入力値、中間値および最終的な解の値がコンピュータで利用できる規格に変換されることで生じる厳密値との乖離」を実数を浮動小数点に丸めるといい、誤差
1.4. 桁落ちと情報落ち
1.4.1 浮動小数点数の演算
浮動小数点数での四則演算は以下のようになされる。
が与えられているとする。このとき
加減算 | ||||
(1) | 指数を一致させるように仮数部を調整する。 | |||
(2) | 仮数部の加減算を実行する。 | |||
(3) | 桁の浮動小数点数になるように丸める。 | |||
乗除算 | ||||
(1) | 仮数の乗除算を行う。 | |||
(2) | 乗算のときはを、除算のときはを新たな指数とする。 | |||
(3) | 桁の浮動小数点数になるように丸める。 |
1.4.2 桁落ち
ある実数の近似値としてが得られており、それらが小数第5位まで正しいとする。このとき
であるため、が得られる。この誤差限界はの相対誤差限界であるに比べてかなり大きい。
なぜこのように大きな誤差が生じたのか。これは途中で丸めが発生し有効数字が減ったためである。このように「途中で丸めが発生し有効数字が減った中で値がほぼ等しい数値差を求めた時に発生する誤差」を桁落ちといい、その発生に注意しなければ相当の誤差が生じ得る。
1.4.3 情報落ち
たとえば2次方程式の解を、解の公式
で求めることを考える。
ならば、の分子の計算において桁落ちが生じる。そのため
と変形すべきである。他方でかつならば
と変形すべきである。
実際にとおいたとき、
(1) | 解の公式 | ||
(2) | 変形式 | ||
(3) | 絶対誤差 | ||
(4) | 相対誤差 |
と相対誤差ベースでみると誤差の大きさを無視し得ないことが推察される。
また指数部に大きな差のある2つの数による和や差でも同様に大きな誤差が生じる。これを情報落ちという。
1.5. 打ち切り誤差
関数の無限級数展開
を有限項で打ち切って
とおくとき誤差
が生じる。このように無限項の和の操作を有限項で打ち切ったことで生じた誤差を打ち切り誤差という。
コンピュータは有限界の四則演算しかできないため、ある関数の値を求める際、有限項からなるそれの近似値を用いて近似する。このとき自体でも代入されるでも丸めの誤差が発生するため 、コンピュータにはが表示される。その誤差は
1.6. オーバーフロー・アンダーフローと非正規化数
計算の途中で数値が表現可能な上限値を値が超えてしまい、その値を表現できなくなることをオーバーフローという。IEEE754-2008では
であるから、これよりも大きくなればオーバーフローを起こす。
逆に絶対値が小さすぎるためにでない実数がに丸められてしまうことをアンダーフローという。
IEEEでは、逆によりも小さい正数を用いることもできる。実際、
が利用でき、これを非正規化数という。非正規化数のうち絶対値が最も小さい値は
であり、絶対値が最大の正数は
である。
1.7 誤差評価
アルゴリズムを評価するには、2つの観点からの評価が必要となる。
1.9. 計算量と誤差
あらゆる計算は有限の資源を用いて有限の時間内に終了しなければならない。そこで計算さの複雑さ(計算量)を考慮する必要がある。計算の開始から終了までに要する数値演算の総量で計算量を見積もりたいものの、計算機の計算作業は複雑であるため、負荷の大部分を占める特定の演算の実行回数を数えることで計算量を大雑把に把握しておく。
なお計算量には別の制約としてメモリの量的な問題がある。
1.9.1 Landauの記号
のとき
と有界ならば、は高々の位数(order)にあるといい、
と書く。
例えば、に対して
であるから、
これはでがにほぼ比例することを意味する。
特にのとき
ならば(すなわちの場合)、
と書く。
1.10 実装(計算機イプシロン)
1.10.1 Python
######################## ### 計算機イプシロン ### ######################## import sys info_eps = sys.float_info.epsilon print(info_eps) # 定義通りの計算方法 EPS = 0.0 tmp = 1.0 while 1.0 + tmp > 1.0: EPS = tmp tmp /= 2 print(EPS) # もう1つの計算方法 a = 4 / 3 b = a - 1 c = b + b + b EPS = 1 - c print(EPS)
1.10.2 Julia
######################## ### 計算機イプシロン ### ######################## # 計算機イプシロン ϵ_m = eps() println(ϵ_m) # 定義による計算 EPS = 0.0 tmp = 1.0 while 1.0 + tmp > 1.0 EPS = tmp tmp /= 2 end println(EPS)
今日の復習
参考文献
- 伊理正夫・藤野和建(1985)「数値計算の常識」(共立出版)
- 菊地文雄・齊藤宣一(2016)「数値解析の原理 現象の解明をめざして」(岩波書店)
- 齊藤宣一(2012)「数値解析入門」(東京大学出版)
- 齊藤宣一(2017)「数値解析」(共立出版)
- 高橋大輔(1996)「理工系の基礎数学8 数値計算」(岩波書店)
- 山本哲朗(2003)「数値解析入門[増訂版]」(サイエンス社)
- 日本応用数理学会 監修・ 櫻井 鉄也 編・ 松尾 宇泰 編・ 片桐 孝洋 編(2018)「数値線形代数の数理とHPC」(共立出版)
- Ridgway Scott, Larkin (2011), "Numerical Analysis", (Princeton University Press)