|
1.12.1 計算の内部機構への依存性
本書では,主にMathematicaで何ができるかに関して説明を行っている.どうMathematicaがそれを達成するかについてではない.しかし,本章では少し趣を変え,どのようにMathematicaが計算処理を行うかについて多少説明を加える.より詳しい説明はA.9を参考にしてほしい.
Mathematicaの内部処理機構を知ることは,知的な興味をそそるものではあるだろうが,それが分かって実際どのくらい役に立つかというと,最初に考えていたほどのことではないだろう.
Mathematicaの強みのひとつは,どのように数学的な操作や他の操作がコンピュータ内部で具体的に処理されているか等の疑問をもつ必要なしに,ユーザが行いたい操作に取り組める環境を提供していることにある.
例えば,多項式 を因数分解するには,ユーザは,Factor[x^15 - 1]と入力するだけでよい.Mathematicaの内部コードにおいて,どんな複雑な方法で実際に因数分解が行われているか等は,ユーザは全く知る必要がない.
Mathematicaの内部機構が実際の使用にはほとんど関係ないと,ほとんどのMathematicaの用途に対して言うことができる.極端ではあるが,Mathematicaを単に,特定の数学的操作等を行うための,抽象化されたシステムととらえても何の支障もきたさない.
内部でどう処理しているか分からなければ,求まる答が信頼できるものかどうか判断できないではないか,と読者によっては危惧されるかもしれない.実際に一部の操作ではそのような状況もなくはないが,ほとんどの場合は,Mathematicaの行う計算は,数式やその他の操作を定義した規則で完全に決定されるため,そのような心配をする必要はない.
例えば,3^40は,Mathematicaがどう内部で計算しようが,常に12157665459056928801である.
それでも,場合によっては,形式的な数学の定義に矛盾しない解が複数個存在する.例えば,記号的な積分の計算において,同じ導関数を与える複数の異なる式を得ることがある.その場合,どちらの式が実際にIntegrateにより生成されるかは,Integrateがどのように内部処理を行うかに依存する.
これが,Integrateの生成する答である.
In[1]:= Integrate[1/x + 1/x^2, x]
Out[1]= 
これも正解の1つである.Integrateの内部処理の仕方が別のものであったなら,この答が返されてきたかもしれない.
In[2]:= Together[%]
Out[2]= 
数値計算でも同じような現象が起こることがある.例えば,FindRootを使い方程式の根を求めることができるが,方程式によっては複数の根が存在する.その中のどれが実際に求まるかは,FindRootの内部処理の詳細による.
の根を探させる.
In[3]:= FindRoot[Cos[x] + Sin[x], {x, 10.5}]
Out[3]= 
初期値を変えると,違った根が求まる.違う初期値に対してどちらの根が得られるかは,探索で使われる内部アルゴリズムの詳細により違ってくる.
In[4]:= FindRoot[Cos[x] + Sin[x], {x, 10.8}]
Out[4]= 
内部アルゴリズムへの依存度は,数値解析法をその有効範囲ぎりぎりのところで使うならばさらに増大する.
例えば,病理的な積分式を関数NIntegrateに与えると,関数で使われる内部アルゴリズムの詳細に依存して,返される答は意味のあるものであったり,そうでなかったりする.
NIntegrateにより結果が信頼できないものと判断される.結果は内部アルゴリズムの詳細に依存する,との警告が発せられる.
In[5]:= NIntegrate[Sin[1/x], {x, 0, 1}]


Out[5]= 
従来の数値解析システムでは,どんな計算でも,得られる結果は少なくとも名目上は同じ精度で求まらなければならないとする傾向がある.このような考え方によると,結果が正確なものかどうかは得られた結果を見るだけでは判明しない.本当に正確かどうかは,計算に使ったアルゴリズムの動作詳細を分析しないと見極めることができない,という結論が導かれてしまう.そして,この事実は人々に,数値計算に使われた内部アルゴリズムをはっきりさせることが常に重要である,というような印象を植え付けてしまっている.
しかし,Mathematicaで取られるアプローチは違うので,上述の議論はほとんどの場合当てはまらない.つまり,多くの数値解析の問題では,Mathematicaは任意精度による数値計算機能を使うことができるので,得られる結果はその作られるすべての桁において達成される演算の厳密な数学定義を満足する.つまり,内部処理には依存しない.
これも近似値の計算ではあるが,求まる答のすべての桁数字は, の数学定義で決定される.
In[6]:= N[Pi, 30]
Out[6]= 
これも,すべての桁が の数学定義で決定されたものである.
In[7]:= N[Sin[10^50], 20]
Out[7]= 
機械精度の数が使われると,Mathematicaは信頼できる結果を与えられなくなってしまう.つまり,答は内部アルゴリズムの詳細に依存してしまう.
In[8]:= Sin[10.^50]
Out[8]= 
これは一般論だが,得られる答が内部アルゴリズムの詳細に依存するものであれば,その答は疑いの目で見られるべきである.他の要因が同じであっても,Mathematicaのバージョンが違えば,違った結果を生成することがある.そのような現象が起こる理由は,同じアルゴリズムでも,違ったコンピュータシステムで使うと若干異なった動作をしたり,違ったときにリリースされたバージョンでは,使われるアルゴリズムが根本的に違う場合もあるためである.
これは,あるタイプのコンピュータにおける の結果である.
In[1]:= Sin[10.^50]
Out[1]= 
同じ計算を他のタイプのコンピュータで行うと結果はこうなる.
In[1]:= Sin[10.^50]
Out[1]= -0.0528229
これは,Mathematicaバージョン1による結果である.
In[2]:= Sin[10.^50]
Out[2]= 0.0937538
特に,複雑な問題を解く場合は,内部アルゴリズムを分析することは十分に価値あることと思えるだろう.そうすれば,どう計算を進めたら最も効率よく計算できるかが予測できる,とも考えられる.事実,まれにではあるが,そのようなアルゴリズムの分析の結果,大きな向上が得られることがある.
しかし,このような分析は,ほとんどの解法において徒労に終ってしまう.その理由として,Mathematicaの内部機構が複雑なことがある.また,仮に特定の目的のために使われるアルゴリズムの基本動作の説明を受けたとしても,このアルゴリズムが特定の状況で実際にどう挙動するかを予測するのは通常,非常に困難である.
さらに,Mathematicaの演算機構において各種の最適化が図られており,実際にどの最適化手段が適用されるかは計算問題の詳細により違ってくるため,計算効率も大きく変わってしまう.
|