Pythonで数値計算プログラムを書き直そうシリーズ

## リスト（順次追加）

### 基本
非線形方程式：
　　<a href="https://qiita.com/Sunset_Yuhi/items/e2cdb34ddf362b7128e1">二分法</a>　<a href="https://qiita.com/Sunset_Yuhi/items/b598ca0cb62b6c706a41">Newton法</a>

常微分方程式：
　　<a href="https://qiita.com/Sunset_Yuhi/items/fb574091fe380e677735">Euler法</a>　2次のRunge-Kutta法（中点法、Heun法）　4次のRunge-Kutta法
　　<a href="https://qiita.com/Sunset_Yuhi/items/d938718ad277eeab746c">scipy.integrate.odeint</a>

数値積分：
　　<a href="https://qiita.com/Sunset_Yuhi/items/6e424c998d5c38d000be">台形則</a>　Simpson則　モンテカルロ法

線型連立方程式（直接法）：
　　<a href="https://qiita.com/Sunset_Yuhi/items/23e5cf7cea1be7eccb1a">Gauss-Jordanの消去法</a>　Gaussの消去法　LU分解法

線型連立方程式（反復法）：
　　Jacobi法　Gauss-Seidel法

補間と近似：
　　Lagrangeの補間法　Newtonの補間法　スプライン補間　最小二乗法

### 有限差分法
1次元有限差分法（常微分方程式）：
　　移流方程式　拡散方程式　波動方程式

2次元有限差分法（偏微分方程式）：
　　移流方程式　拡散方程式　波動方程式

2次元有限差分法（連立偏微分方程式）：
　　反応拡散方程式　渦度・流れ関数法

2次元有限差分法の応用：
　　FDTD法（音）　FDTD法（電磁気）　格子Boltzmann法　MAC法

### 有限要素法
1次元有限要素法（常微分方程式）：
　　<a href="https://qiita.com/Sunset_Yuhi/items/4c4ddc25609a7619cce0">Poisson方程式（暫定）</a>　Helmholtz方程式　構造解析

2次元有限要素法（偏微分方程式）：
　　Poisson方程式　Helmholtz方程式　構造解析

### その他
粒子・エージェント系：
　　分子動力学　感染症流行モデル


## 事の発端
　「数値計算」ってなんか響きがカッコいいですよね。似た言葉で「シミュレーション」とか「数値解析」とかいう言葉もありますが、やってる人ってなんか頭良さそうだし、実際何かの役に立ちそうじゃないですか。テレビやネットでも数値計算の映像とかよく見るし、自分もやってみたい！　でも、技術には興味があっても地道に勉強するのは面倒くさい。なんとか簡単にサクッと学ぶ方法は無いんでしょうか。



## いい情報源が見つからない
　重い腰を上げて書籍を探してみます。ところがビックリ。そもそも、理論の説明はあってもプログラムが載ってない本もあります。やっとこさプログラム付きの本を見つけたと思ったら、FortranやC言語で書かれた化石プログラムのオンパレード。プログラムで分からない構文を見つけても、古いコードや専門的な内容となると、ネットで探してもよく分かりません。ゲームのアプリとか作ってる人は、すげえ最新のプログラミング言語とか使ってて超楽しそうなのに、なんで自分はこんなかすれた文字の本を読んでるのでしょうか？　自問自答を始めます。



## どう見てもプログラムに欠陥がある
　なんとかプログラムの実行環境を作り、とりあえずサンプルプログラムを実行してみます。文字がバーっと出て、終わり。あっけない気もするけど、でも初めてプログラムを動かせたので、それなりに楽しい。じゃあプログラムの中身も勉強してみよう。……あれ、なんだこれ。おかしくね？　なんでこんな書き方してるの？　全体的に読みずらいし、こういう条件だと動かないし、そもそもこの手法って効率的なの？　でもプログラムの書き直し方が分からない！　もう嫌だ死にたい。



## 何冊かの本が目に留まる
　――長い時が経ち（言っても数年）、数値計算はそれなりに勉強したはずなのだが、いまいち何も身に付いてない感覚に捕らわれていた。しかしこの間に、手元にはいくつかの数値計算本が揃っていた。ちょっと手に取ってみる。なるほど、わざわざ買っただけあって、為になることは書いてある。でも、ここはこうした方がいいんじゃないかな。自分だったらこう書くのに。……私はその時、自分なりに数値計算プログラムを書き直してみようという気持ちになったのだった。



## 参考にする予定の本（随時追加予定）
　何を具体的にどうするとか決めてない部分も多いのだが、とりあえず扱う予定の本は以下。

### 小高知宏, 『Pythonによる数値計算とシミュレーション』, オーム社 (2018)
　個人的に良いと思う点は、まずPythonを使って数値計算プログラムを書いていること。変にiPythonとかJupyterとか使ってないのもいい。最近出た本ということもあり、NumPyやMatplotlibを使ったサンプルプログラムも載っているのがいい。あと、数値計算の過程で生じる誤差についての説明もあるし、微分方程式の数値解法などの基本的な内容だけでなく、クラスを使ったエージェントシミュレーションなんかも載っていて、見た感じ良さそうに見える。しかし、いざプログラムを見てみると、「ここはもっとこう書きたい」という箇所がいくつか出てきた。数値計算例が網羅されているという訳ではないが、適宜参考にする予定。

### 大和田勇人, 金盛克俊, 『Pythonで始めるプログラミング入門』, コロナ社 (2015)
　こちらもPythonによる数値計算本。良いと思う点は、序盤の7章までを使って変数や関数やモジュールやクラスなどを懇切丁寧に説明している点。プログラムの書き方がとても簡潔なのも良いと思う。ただ、サンプルプログラムがダウンロードできなかったり、NumPyすら使わないプログラムの書き方をしているのが残念（ライブラリに頼らないのは長所でもあるかもしれないが）。あと、数値計算を学ぶにはちょっと例題が少ない。このシリーズでは補助的に使う予定だが、書き方についてはかなり参考にするかもしれない。

### 三井田惇郎, 須田宇宙, 『数値計算法 [第2版・新装版]』, 森北出版 (2014)
　これはC言語による数値計算本。類書は他にもたくさんあるが、関数を使って簡潔に書かれたプログラムが個人的に好み。極端に古い書き方をしてる訳ではないので読みやすいと思う。こちらもサンプルプログラムのダウンロードが不可なのだが、プログラムの不満点はあまりないので参考にしたい。フーリエ変換のプログラムとかが載ってるのもいい。ただ、がっつり数値計算する人はもちろんFortranとかでやるべきだと思うけど、自分で数値計算プログラムを作るのはさしあたり原理を理解するためで、現実的には後で偉い人が作ったライブラリを利用することが多いと思うから、勉強する分にはPythonでも問題ないと思っている。

### 堀之内總一, 酒井幸吉, 榎園茂, 『Cによる数値計算法入門(第2版)新装版』, 森北出版 (2015)
　これもC言語で書かれており、色んなプログラム例が載っているが、とにかくプログラムの書き方が古い。古すぎる。そして冗長すぎる。2分法を例に挙げても、『Pythonで始めるプログラミング入門』ではたった13行で書かれているのに、この本では50行以上も使っている。おかしいだろこれは。大学のゼミで使ったのだが、内容がほとんど記憶に残らなかった。本は手元に無いのだが、プログラムは残ってるので考え方だけ参考にするかもしれない。

### 柳田英二, 三村昌泰, 中木達幸, 『理工系の数理 数値計算』, 裳華房 (2014)
　こちらもC言語の本。たまたま手に取ったのだが、これはプログラムの書き方がひどい。反復計算をするのにwhile文でなくfor文で20回くらい回して終了させていたり、行列に値を代入するのにA[0][0]=0; A[0][1]=1; A[0][2]=-2;と1行ごとに1成分ずつ値を入れたりしている。非効率と冗長さがこの本のプログラムには詰まっている。自分のプログラムスキルなんてヘボヘボだと思っていたところ、思いがけなく勇気をもらった。主に反面教師として使う予定。

### 伊理正夫, 藤野和建, 『数値計算の常識』, 共立出版 (1985)
　数値計算特有の注意点や誤差の原因についてまとめられた本。古めの本だが現在でもかなり通用するように思う。常識として知っておくべき内容が多いと思うので、このシリーズでも適宜触れる予定。プログラム例があまり無いのが残念。

### 大石進一（編著）, 『精度保証付き数値計算の基礎』, コロナ社 (2018)
　精度保証がメインの理論解説書。浮動少数や丸め誤差に始まり、指数関数や三角関数などの基本関数の精度保証や、非線型方程式・微分方程式の数値解法などでの解の検証方法などが載っている。とても勉強になるが、この辺を厳密に考え出すといつまでも勉強が進まない気がしたので、今回は精度保証まではあまり考えないことにした。もちろん精度を度外視する訳ではないので、参考にはさせていただく。所々でMATLABでの実装例が載っている。



## 参考にする予定のサイト（随時追加予定）
　本だけ参考にする理由もないので、適宜ネット上の情報も活用することにした。

### ForNext - さまざまな言語で数値計算
　http://fornext1119.web.fc2.com/NumericOperation
　様々な言語による様々な数値計算プログラムを公開しているサイト。Pythonプログラムにしても非常に参考になるが、NumPyも使っていなかったり、汎用性にやや難がある書き方に見えるので、自分はそれを補うようなプログラムを書きたいと思っている。

### 科学技術計算についての記事 - org-技術
　https://org-technology.com/categories/ke-xue-ji-shu-ji-suan.html
　様々な数値計算手法の解説と、Pythonでの実装例がある。SciPy関係の解説も充実している。

### Pythonで数値計算
　http://japanichaos.appspot.com
　NumPyや微分方程式の解法について解説がある。


## 方針を決める
　使用言語にはPython（というかAnaconda環境）を使います。超基礎的な内容から始めますが、まず第一に自分用のメモとして、第二にモチベーションを保つために、Qiitaに記事を投稿していきます。更新頻度は遅いと思われます。あと個人的に練習として、主な処理は関数内に書き、「if __name__ == '__main__':」を使ってテストができ、Numbaとかで最適化しやすそうなプログラムを書く予定です。書き方はなるべくPEP8に準拠します。また、計算結果はコンソールに表示して終わりではなく、何らかの方法で可視化したいと思っています。新しく記事を書いたら、この記事のトップにリンクを追加していきます。間違いの指摘やリクエストなども歓迎します。
　なお、数値計算を行う上では精度保証も重要になりますが、このシリーズではあまり触れない予定です。というのも、計算精度を考える場合、多項式や三角関数など基本的な関数の精度も考慮する必要がありますが、そうしたことを包括的に記述することが自分には難しいと思えたからです。片手落ち感はありますが、記事を読む方は参考程度に見ていただければと思います。