Pythonによる数値計算について
数値計算を勉強し始めたので普段使いできる程度の数学と物理を記録として残しておこうと思います。数値計算系の記事ではPython3、numpy、scipy、matplotlibは既にインストール済みである事を前提として書いてます。まだインストールしていない場合は適切なサイトを見つけてくれればと思います。
なお今後は微分方程式とか出てきますが、これらも既に習得済みである事を前提として書いているので、適切な教科書を読んでいただければと思います。おそらくそんなに高度な数学は使わないでしょう。僕自身は物理系ですので、そちらとも絡めていけたらと考えています。
導入
何かの問題を解こうとする際、あまりにも数式が複雑で直感的な理解ができなかったり、あるいは解かなければならない数式が膨大である場合に、それらを自分一人で解く事は骨が折れます。そこで、そのような課題を解決するために開発されたのが計算機であり、これがコンピュータの原型となります。コンピュータアーキテクチャの説明やコンピュータの歴史と起源については冗長ですし専門家でもないので避けますが、要はコンピュータの本職は計算であり、人間よりも圧倒的に早く計算を行う能力があります。なので、この道具を使わない手はない、という事になります。
じゃあ何でもかんでも数式を入れれば答えを出してくれるのかと言うとそんなことはありません。実は、人間が数式を解くのとコンピュータが数値計算を行うのには決定的な違いがあります。例として、次の積分を解くことにしましょう。
S = \int_{0}^{1}x dx
人間がこの積分の答えを求めようとすると、高校生のとき習ったようにxの二乗の形を思い浮かべて、定義域を代入した値の差から積分を求めるでしょう。人間は定理や公式など便利でスマートな道具を持っています。それらを使えば簡単に問題を解くことができるのです。しかし、コンピュータはそれらを知りません。そこで、コンピュータはこの積分を解くために定義域を細かく分割し、分割した定義域にその定義域における値域の平均値をかけることで小さい台形の面積を求めて、それを分割した分だけ足しあわせます。これはいわゆる区分求積法と呼ばれる計算方法です。コンピュータは人間のように便利な道具を知らない代わりに、ちょっとだけ泥臭く強引な方法を使うことで答えを求めるのです。おそらく人間がこの方法を使って答えを導くにはかなり手間がかかるでしょう。定義域の分割数が100程度であればなんとかなるかもしれませんが、この答えをより正確に求めるために定義域の分割数を10000程度にすると途端に面倒になるので、人間には難しいです。
このように人間とコンピュータでは問題の解を求める方法が少しだけ異なります。人間は簡単な数式(手計算で求められるような方程式を解析的と言うと思いますが)の答えを直接的に求めることが得意です。一方、コンピュータは複雑で直感的に解くことのできない問題や膨大なデータが絡む計算であっても少々強引に、かつ高速に解いてしまいます。
以下に数値計算の(おそらく)初歩的で(おそらく)基本的な思考プロセスをまとめました。
- 数値計算の手法(区分求積法、ニュートン法など)で解く事のできる数式を用意する。
- 定義域を設定する。
- 数値計算の手法を用いて、定義域のデータを渡してその定義域に対応する値域のデータを出力する。
- 数値計算の結果として得られた値域のデータを保存する。
- 定義域と得られた値域のデータから、結果を可視化する。
1.から3.までは既に説明しましたが、これは歴史的に見てもC言語やFortranで散々行われてきたものです。Pythonが本領を発揮するのは5.についてです。Pythonにはmatplotlibという強力なライブラリーによってpylabというモジュールが用意されています。pylabは柔軟性の高いグラフを作ることができるので、数値計算の結果をきれいに出力することができます。今後の数値計算の記事では先ほどの数値計算の手法と、得られた結果のpylabによる可視化が主なテーマになると思います。