|
3.1.4 数値の精度
1.1.2で触れたが, Mathematicaはどんな桁精度の実数でも扱える.ここで,実数の精度とは一般に有効桁数の大きさを計る.一方,精度に似た尺度に確度という考えがある.実数近似値において確度とは小数点以下の桁数の大きさを計る.つまり,精度は数値の相対誤差の大きさを計り,確度は絶対誤差の大きさを計る.数の扱いが完全に首尾一貫するためには,精度と確度の値が整数桁に対応しないことがしばしばある.

実数の精度と確度
30桁精度の数を生成する.
In[1]:= x = N[Pi^10, 30]
Out[1]= 
数の桁精度を調べる.
In[2]:= Precision[x]
Out[2]= 
何桁かだけが小数点の右側になっているので確度は低い.
In[3]:= Accuracy[x]
Out[3]= 
この数は桁すべてが小数点の右側になっている.
In[4]:= x / 10^6
Out[4]= 
確度が精度よりも大きくなっている.
In[5]:= {Precision[%], Accuracy[%]}
Out[5]= 
近似実数の値には見えない桁に関連する不確かさが常に付きまとう.精度をこの不確かさの相対的な大きさの尺度と考えることもできる.確度はこの不確かさの絶対的な大きさの尺度である.
Mathematicaは数 の不確かさが であればその真値は から までの大きさ の区間のどこかにあるように設定されている.確度が の近似値の不確かさは で,精度 の非ゼロの近似値の不確かさは であると定義される.

不確かさについての精度と確度の定義
不確かさよりも小さな量を足したり引いたりしても目に見える影響は出ない.
In[6]:= {x - 10^-26, x, x + 10^-26}
Out[6]= 

任意精度数と機械精度数による数値計算
Mathematicaは「任意精度」数と「機械精度」数,すなわち「機械数」の2種類の近似実数を区別する.任意精度数は何桁でもよく,精度の情報も保っていられる.一方機械数は常に同じ桁数で精度情報も持たない.
これは を機械数に近似したものである.
In[7]:= N[Pi]
Out[7]= 
これは両方とも任意精度数である.
In[8]:= {N[Pi, 4], N[Pi, 20]}
Out[8]= 
以下でより詳しく説明するが,機械数は使用しているコンピュータシステムの数値機能を直接使用するものである.結果として,これを使うと計算が速くできることが多い.しかし任意精度数に比べて柔軟性は低く,結果が正しいかどうかの判断に難解な数値解析等が必要なことがある.

機械数
これは機械数を示す記号MachinePrecisionを返す.
In[9]:= Precision[ N[Pi] ]
Out[9]= 
このコンピュータの機械数は16桁より若干劣る.
In[10]:= $MachinePrecision
Out[10]= 
近似実数の入力があると,機械精度数としてか,それとも,任意精度数として扱うかをMathematica内部で選択しなければならない.特に指定しない限り, $MachinePrecisionにある機械精度の桁長より短い桁長で実数を入力したならば,機械精度が使われ,その反対に,より長い桁長で入力したならば,任意精度が使われる.

数の入力形式
計算が終了し答が出力されるとき,読みやすさのため桁長が調整される.こうして出力された答は精度が落ちている可能性があるので,再度入力として使う場合は注意が必要である.求めた答を入力として使いたいときは,入力形を答に作用させ,桁精度調整前の情報が失われていないことを確認する必要がある.
標準出力形を使っている場合,この例にあるように答は6桁になってしまう.
In[11]:= N[Pi]
Out[11]= 
入力形にすると,Mathematicaが現時点で認識している全桁が得られる.
In[12]:= InputForm[%]
Out[12]//InputForm= 3.141592653589793
任意精度の数を標準出力形で出力する.
In[13]:= N[Pi, 20]
Out[13]= 
入力形を使うと,現行の桁精度を特別に表示できる.さらに,必ず現行精度で数を再構築できるよう指定した以上の桁精度で答を出力する.
In[14]:= InputForm[%]
Out[14]//InputForm= 3.1415926535897932384626433832795028842`20.
こうすると桁長の表示はされない.
In[15]:= InputForm[%, NumberMarks->False]
Out[15]//InputForm= 3.1415926535897932385

数の出力形の制御
上記InputFormや後述のToStringとOpenWrite等の数の表記にかかわる関数において,オプション NumberMarksのデフォルト設定は $NumberMarksの値で定められる. したがって,$NumberMarksを設定し直すことによってInputFormを使った数の表記方法をすべて変更できる.
ナンバーマークが常に表示されるよう$NumberMarksを設定する.
In[16]:= $NumberMarks = True
Out[16]= 
常時表示にしたので,機械精度の答にもナンバーマークが付け加えられる.
In[17]:= InputForm[N[Pi]]
Out[17]//InputForm= 3.141592653589793`
ナンバーマークを禁止しても, InputFormを使うと記号 *^を使った科学表記で答が表示される.
In[18]:= InputForm[N[Exp[600], 20], NumberMarks->False]
Out[18]//InputForm= 3.7730203009299398234*^260
数値計算では時には望んでいる精度以下の結果しか得られないことは避けられないことである.特に,ゼロに非常に近い値が得られたときには,その値をゼロと仮定してよいような場合がある.このときにはChopを使うとゼロに非常に近い近似値を整数0で置き換えることができる.

ゼロに近い端数の除去
この例の計算をすると虚数部に非常に小さい値が生じる.
In[19]:= Exp[ N[2 Pi I] ]
Out[19]= 
Chopを作用させ答から虚数部を除去する.
In[20]:= Chop[%]
Out[20]= 
|