{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Python 入門2\n", "\n", "この回では、プログラミングの基本的知識についてさらに学ぶ。\n", "\n", "前回学習した`while`ループのような制御構造である`for`ループや`if`文の使い方、\n", "さらに、科学計算用ライブラリ`numpy`の基本的な使用方法について学ぶ。" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 繰り返し構造\n", "\n", "### for ループ\n", "\n", "`for`ループは、`while`ループによく似た繰り返し処理を行うための枠組みである。\n", "ただし、Pythonの`for`ループは、FortranやC言語のものとは少し異なる。" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "# 文字列を複数格納したリスト\n", "words = ['cat', 'window', 'defenestrate']" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "cat 3\n", "window 6\n", "defenestrate 12\n" ] } ], "source": [ "for w in words:\n", " print(w, len(w))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "ここで`for w in words:`は、\n", "\n", "+ `words`の中から1つ要素を取り出してきて`w`に代入する。\n", "+ `for`文以下ブロックの命令を実行する\n", "+ それが終わると、`words`の次の要素を`w`に代入する。\n", "+ すべての要素について計算が終われば`for`文の実行を終わる。" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### range() 関数 を用いた繰り返し\n", "\n", "`for`文によく用いられるものが`range`関数である。" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "0\n", "1\n", "2\n", "3\n", "4\n" ] } ], "source": [ "for i in range(5):\n", " print(i)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "このように、`for i in range(5):`とすることで、`i`に0〜4までの数字を順に入れて繰り返し計算をすることが可能である。" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### for ループの応用 〜ベクトル・行列計算〜\n", "\n", "これまで学習したリストと `for` ループを使って、ベクトル・行列演算を実装してみよう。\n", "\n", "なお、ベクトル・行列演算は後述のnumpyという計算ライブラリに実装されている。\n", "速度・確実性の観点から、本来は確立されたライブラリの機能を用いる方がよい。\n", "\n", "今回はプログラミング学習のため、あえてこれを実装する。" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [], "source": [ "# 以下の2つのベクトルの内積を計算する。\n", "x = [1.0, 2.0]\n", "y = [1.0, 3.0]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "len(x) がリストxの要素数を返すことを思い出そう。\n", "\n", "上記の`range()`関数と組み合わせることで\n", "\n", "`for i in range(len(x)):` \n", "\n", "`i` を0からxの要素数まで変化させることができる。" ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "ExecuteTime": { "end_time": "2016-07-28T19:46:09.098450", "start_time": "2016-07-28T19:46:09.093247" } }, "outputs": [], "source": [ "dot = 0.0\n", "for i in range(len(x)):\n", " dot += x[i] * y[i]" ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "ExecuteTime": { "end_time": "2016-07-28T19:46:12.352178", "start_time": "2016-07-28T19:46:12.347940" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "7.0\n" ] } ], "source": [ "print(dot)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 課題1\n", "\n", "同様に、以下のベクトルの内積を計算せよ\n", "$$\n", "\\mathbf{x} = \\left(\\begin{array}{ccc}\n", "1.0 & 2.0 & 3.0\\end{array}\\right)^\\text{T}\n", "$$\n", "\n", "$$\n", "\\mathbf{y} = \\left(\\begin{array}{ccc}\n", "2.0 & -1.0 & 2.0\\end{array}\\right)^\\text{T}\n", "$$" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [], "source": [ "# 解答をここに記入する" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 行列とベクトルの内積" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "行列は、リストの中にリストを作ることで表すことができる。\n", "\n", "$$\n", "A = \\left(\\begin{array}{cc}\n", "1.0 & 0.0 \\\\ 2.0 & 3.0\n", "\\end{array}\\right)\n", "$$\n", "\n", "は、以下のように表現できる。" ] }, { "cell_type": "code", "execution_count": 8, "metadata": { "ExecuteTime": { "end_time": "2017-02-17T23:37:52.065531", "start_time": "2017-02-17T23:37:52.055510" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[[1.0, 0.0], [2.0, 3.0]]\n" ] } ], "source": [ "A = [[1.0, 0.0], [2.0, 3.0]]\n", "print(A)" ] }, { "cell_type": "code", "execution_count": 9, "metadata": { "ExecuteTime": { "end_time": "2017-02-17T23:37:52.999589", "start_time": "2017-02-17T23:37:52.995902" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[1.0, 0.0]\n" ] } ], "source": [ "print(A[0])" ] }, { "cell_type": "code", "execution_count": 10, "metadata": { "ExecuteTime": { "end_time": "2017-02-17T23:37:53.387487", "start_time": "2017-02-17T23:37:53.384865" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "0.0\n" ] } ], "source": [ "print(A[0][1])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 課題2\n", "\n", "上の例と同様に、行列とベクトルの積を計算せよ。\n", "\n", "なお、`len(A)`で行の数を、`len(A[0])`で列の数を得ることができる。\n", "\n", "また、リストの`.append()`関数を使うことでリストへの要素の追加が可能である。" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "$$\n", "\\mathrm{A} = \\left(\\begin{array}{cc}\n", "1.0 & 2.0 \\\\\n", "2.0 & 3.0\n", "\\end{array}\\right)\n", "$$\n", "\n", "$$\n", "\\mathbf{x} = \\left(\\begin{array}{cc}\n", "2.0 & -1.0\n", "\\end{array}\\right)^\\text{T}\n", "$$\n", "\n", "としたときの $A$ と $x$ の内積を計算せよ。" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [], "source": [ "# 解答をここに記入する" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Pythonの関数\n", "\n", "上記の内積・行列積・外積のように、何度も行う操作を、操作の数だけコードを書くことは非効率である。\n", "このような同一の操作を汎用的に行うことができる仕組みを**関数**と呼ぶ。\n", "\n", "関数は、**引数**で与えられた入力に対して、何か計算した結果を**戻り値**として返すものである。\n", "例えば、これまで出てきた`len()`も関数である。\n", "\n", "リスト`x`が引数に与えられたとき、その要素数を戻り値として返す。" ] }, { "cell_type": "code", "execution_count": 12, "metadata": { "ExecuteTime": { "end_time": "2016-07-28T20:06:48.817423", "start_time": "2016-07-28T20:06:48.796588" } }, "outputs": [ { "data": { "text/plain": [ "2" ] }, "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ "len(x) # リスト(など)を引数にとり、要素数を返す関数" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "関数は、以下のように定義する。ここでは、2つのリストを引数に持ち、その内積を計算する関数を作る。" ] }, { "cell_type": "code", "execution_count": 13, "metadata": { "ExecuteTime": { "end_time": "2016-07-28T20:09:59.368213", "start_time": "2016-07-28T20:09:59.352801" } }, "outputs": [], "source": [ "# 関数の例 `def` + 関数の名前(この場合はlist_dot)+ カッコ として定義する。\n", "# カッコの中に引数を入れる。\n", "def list_dot(x1, x2):\n", " \"\"\"\n", " 2つのリストを受け取り、その内積を計算する関数。\n", " なお関数に関する説明は、\n", " このように3つの連続するダブルコーテーション内に記述することが推奨されている。\n", " \"\"\"\n", " dot = 0.0\n", " for i in range(len(x1)):\n", " dot += x1[i]*x2[i] # x += y は、x に x+y を代入することを表す。\n", " return dot # return 文で計算した値を返す。" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "この場合 ``list_dot(x, y)`` のように関数名(変数, 変数)とすることで、\n", "この関数を実行することができる。\n", "\n", "この関数が実行されると、まず``dot``という変数が定義され、値 0.0 が代入される。\n", "次の `for` ループにより内積の値が`dot`に代入される。\n", "計算された`dot`の値が返される。" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "このように定義した関数は、繰り返し用いることができる。" ] }, { "cell_type": "code", "execution_count": 14, "metadata": { "ExecuteTime": { "end_time": "2016-07-28T20:10:32.616094", "start_time": "2016-07-28T20:10:32.611717" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "4.0\n" ] } ], "source": [ "x = [1.0, 2.0]\n", "y = [2.0, 1.0]\n", "print(list_dot(x, y))" ] }, { "cell_type": "code", "execution_count": 15, "metadata": { "ExecuteTime": { "end_time": "2016-07-28T20:10:43.383877", "start_time": "2016-07-28T20:10:43.371478" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "0.0\n" ] } ], "source": [ "x = [1.0, -2.0]\n", "y = [2.0, 1.0]\n", "print(list_dot(x, y))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 課題3\n", "\n", "2つの行列 $A, B$ の積を計算する関数を作成せよ。\n", "1つの関数により、以下の組み合わせの行列に対して計算せよ。\n", "\n", "1. \n", "$$\n", "\\;\\; \n", "A = \\left(\\begin{array}{cc}\n", "1.0 & 2.0 \\\\\n", "2.0 & 3.0\n", "\\end{array}\\right)\n", ",\\;\\;\n", "B = \\left(\\begin{array}{cc}\n", "-1.0 & -3.0 \\\\\n", "0.0 & 1.0\n", "\\end{array}\\right)\n", "$$\n", "\n", "2. \n", "$$\n", "\\;\\; \n", "A = \\left(\\begin{array}{ccc}\n", "1.0 & 0.1 & 1.5 \\\\\n", "0.9 & 0.2 & -1.0\n", "\\end{array}\\right)\n", ",\\;\\; \n", "B = \\left(\\begin{array}{cc}\n", "-2.0 & -0.5 \\\\\n", "0.0 & 1.2 \\\\\n", "0.8 & 1.0 \\\\\n", "\\end{array}\\right)\n", "$$\n", "\n" ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [], "source": [ "# 解答をここに記入する" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 数値計算ライブラリNumpy\n", "\n", "Pythonは科学計算に用いることのできるライブラリが十分に用意されていることが特徴である。\n", "ここでは、最も基本的な数値計算ライブラリであるNumpyを使用する。" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 基本的な使い方\n", "\n", "まず、PythonでNumpyを用いるための命令をする必要がある。\n", "これは前回学んだ`matplotlib`を用いるときと同様の`import`文を用いる。" ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [], "source": [ "# まず最初に、グラフ描画ライブラリと、数値計算ライブラリをimportしておく。\n", "import numpy as np\n", "# 同様にmatplotlibもimportしておく。\n", "%matplotlib inline\n", "import matplotlib.pyplot as plt" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "なお、`as np` の部分は、`numpy`を省略して`np`として用いる、という意味である。\n", "\n", "原理的には各自の好きな略語にできるが、`numpy`の場合、`np`と略すのが一般的である。\n", "逆にそれ以外の略称を用いることは、コードをわかりづらくさせるので避けるべきである。" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 数学関数の計算\n", "\n", "ここでは、`Numpy`の機能の1つである特殊関数の計算をしてみる。\n", "\n", " " ] }, { "cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "0.8414709848078965" ] }, "execution_count": 18, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# sin 関数\n", "np.sin(1)" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "このように、numpyの機能を用いる場合は、`np.`の後に関数名を書いて実行する。\n", "\n", "他に使える数学関数の一覧は\n", "\n", "http://docs.scipy.org/doc/numpy/reference/routines.math.html\n", "\n", "にリストされている。\n", "\n", "なお、Colabでは関数にカーソルをホールドすることで、その関数の説明を見ることができる。\n", "Jupyter-notebook では、関数の括弧内にカーソルがあるときに `Shift + Tab` を押すことで、同様の説明を見ることができる。\n", "説明は英語であるが、わざわざマニュアルを検索しなくても簡単な情報は得られるようになっている。\n", "\n", "" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "次に、この関数の形を視覚的に把握するためにグラフにプロットする。" ] }, { "cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [], "source": [ "# まず、計算する範囲、個数を指定する。今回は、-5~5, 100 点で計算する。\n", "x = []\n", "y = []\n", "for i in range(100):\n", " x.append(-5.0 + 10.0 / 100 * i)\n", " y.append(np.sin(x[i]))" ] }, { "cell_type": "code", "execution_count": 20, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[]" ] }, "execution_count": 20, "metadata": {}, "output_type": "execute_result" }, { "data": { "image/png": "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", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "plt.plot(x, y, '-o')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 課題4\n", "以下の関数を(-3 ~ 3)の範囲でプロットせよ\n", "\n", "$$\n", "f(x) = \\frac{\\sin(2\\pi x)}{2\\pi x}\n", "$$\n", "\n", "なお、$f(0)=1$であることに注意する。" ] }, { "cell_type": "code", "execution_count": 21, "metadata": {}, "outputs": [], "source": [ "# 解答をここに記入する" ] }, { "cell_type": "markdown", "metadata": { "collapsed": true }, "source": [ "### 課題5\n", "\n", "大きな整数 $k$ の階乗は\n", "\n", "$$\n", "k! \\sim \\sqrt{2\\pi k}\\left(\\frac{k}{e}\\right)^k\n", "$$\n", "\n", "で近似できることが知られている(スターリングの近似)。\n", "\n", "$k = 1, 2, ... , 200$ について、$\\log(k!)$ および $\\frac{1}{2}\\log(2\\pi k) + k\\log(k) - k$ を一つのグラフ上に描画せよ。\n", "なお、$\\pi$の値は`np.pi`から得ることができる。" ] }, { "cell_type": "code", "execution_count": 22, "metadata": {}, "outputs": [], "source": [ "# 解答をここに記入する" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 条件分岐\n", "\n", "以降では具体例として, 精度よくかつ効率的に$\\log(k!)$の値を計算できるプログラムを作成することを目指す. \n", "それを通して, コンピュータで数値計算をさせるための基礎を学ぶ. \n", "具体的には, ユーザーにより与えられた$k$の値に応じて, $\\log(k!)$の値を計算し, 画面に表示することを目指す. \n", "\n", "$k$の値が小さいとき, $\\log(k!)$の値は, $\\sum_{n=1}^{k}\\log(n)$からすぐに計算できる. \n", "一方で$k$の値が例えば100,000を超えるようなときは, 100,000回の対数の計算をする必要があり, \n", "大きな計算コストが必要である. \n", "そこで前章の演習問題で学んだように, \n", "大きい$k$の場合には直接$\\sum_{n=1}^{k}\\log(n)$を計算するよりも, \n", "その近似である$k\\log{k}-k$を計算する方が圧倒的に高速である. \n", "\n", "高精度・高効率に$\\log(k!)$を計算するプログラムは以下のような手順を実行することになる. \n", "\n", "1. ユーザーから$k$の値を受け取る. \n", "2. 与えられた$k$の値が, あるしきい値$k_0$よりも小さければ$\\sum_{n=1}^{k}\\log(n)$を計算する. \n", "3. 与えられた$k$の値が, あるしきい値$k_0$よりも大きければ$k\\log{k}-k$を計算する. \n", "4. 結果を画面に表示する. " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 課題6\n", "\n", "$\\sum_{n=1}^{k}\\log(n)$の値と$\\frac{1}{2}\\log(2\\pi k) + k\\log{k}-k$の値の差の絶対値を\n", "$k=1,2, \\cdots, 1000$について計算し, その差が$10^{-4}$より小さくなる最小の$k$の値を求めよ. \n", "\n", "なお, 本課題は以下の**条件分岐**を学んでから取り組むと, 効率的に解決できる. " ] }, { "cell_type": "code", "execution_count": 23, "metadata": {}, "outputs": [], "source": [ "# 解答をここに記入する" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### if 文の文法\n", "\n", "上記に示した手順のうち, 2および3は, 特定の条件が満たされたときに計算の挙動を変化させている. \n", "それを実現する枠組みを**条件分岐**と呼ぶ. \n", "Pythonでは, `if`文を用いて条件分岐を行う. \n", "\n", "以下に, `if`文の一つの用例を示す. \n", "ここでは, 二次方程式の判別式を計算して, それが正, 零, 負であるときにそれぞれ異なる処理を行っている. " ] }, { "cell_type": "code", "execution_count": 24, "metadata": {}, "outputs": [], "source": [ "def discriminant(a, b, c):\n", " \"\"\"\n", " a x**2 + b x + c = 0 に実数解が存在するか調べるプログラム。\n", " 2つの実数解が存在する場合は `two real roots` を、重根が存在する場合は `one real root`を、\n", " 実数解が存在しない場合は `two complex roots` を表示する。\n", " \"\"\"\n", " d = b**2 - 4.0*a*c\n", " if d > 0.0:\n", " print('two real roots')\n", " elif d == 0.0:\n", " print('one real root')\n", " else:\n", " print('two complex roots')" ] }, { "cell_type": "code", "execution_count": 25, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "two complex roots\n" ] } ], "source": [ "discriminant(3.0, 2.0, 1.0)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "このように`if`文を使えば、`if`文直後の条件が真か偽かに応じて処理を分岐することができる。\n", "\n", "具体的には以下の表のように、適当な等式あるいは不等式を書くことが多い。\n", "\n", "| Pythonでの書き方 | 意味 |\n", "|:-----------:|:--------------:|\n", "| `x == y` | $x=y$ (イコール)| \n", "| `x != y` | $x\\neq y$ (ノットイコール)| \n", "| `x < y` | $x y` | $x> y$ (大なり)| \n", "| `x >= y` | $x \\leq y$ (大なりイコール)| \n", "\n", "\n", "`if`文の仕様パターンは大きくは以下の3通りである。\n", "\n", "```\n", "if 条件:\n", " 処理 \n", "```\n", "\n", "```\n", "if 条件:\n", " 真の場合の処理\n", "else:\n", " 偽の場合の処理\n", "```\n", "\n", "```\n", "if 条件1:\n", " 条件1が真の場合の処理\n", "elif 条件2:\n", " 条件1が偽であり条件2が真の場合の処理\n", "else:\n", " 条件1、2が偽である場合の処理\n", "```\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 課題7\n", "\n", "二次方程式の判別式を計算し、それが正の時は二実数解、零の時は重解、負の時は複素数解を計算するプログラムを作成せよ。\n", "\n", "なお、複素数は $a + b i$ は `a + bj` で以下のように表すことができる。" ] }, { "cell_type": "code", "execution_count": 26, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(2+3j)" ] }, "execution_count": 26, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# 2+3i は以下のように表す。\n", "2 + 3j" ] }, { "cell_type": "code", "execution_count": 27, "metadata": {}, "outputs": [], "source": [ "# 解答をここに記入する" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 課題8\n", "\n", "以前の演習問題で求めた $\\sum_{n=1}^k \\log(k)$ の値と $\\frac{1}{2}\\log(2\\pi k) + k \\log k - k$ の差が$10^{-4}$ より小さくなる$k$の値を用いて、効率よく$\\log(k!)$を計算できる関数を作成せよ。" ] }, { "cell_type": "code", "execution_count": 28, "metadata": {}, "outputs": [], "source": [ "# 解答をここに記入する" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 特殊関数の計算\n", "\n", "Pythonの特徴は、多様な数学ライブラリが簡単に使える点にある。\n", "ここでは特殊関数の一つである[ベッセル関数](https://ja.wikipedia.org/wiki/%E3%83%99%E3%83%83%E3%82%BB%E3%83%AB%E9%96%A2%E6%95%B0)の計算をする。\n", "ベッセル関数は\n", "\n", "$$\n", "x^{2}{\\frac {d^{2}y}{dx^{2}}}+x{\\frac {dy}{dx}}+(x^{2}-\\alpha ^{2})y=0\n", "$$\n", "\n", "の特殊解の一つであり、\n", "第一種ベッセル関数は\n", "\n", "$$\n", "\\displaystyle J_{\\alpha }(x)=\\sum _{{m=0}}^{\\infty }{\\frac {(-1)^{m}}{m!\\Gamma (m+\\alpha +1)}}\\left({\\frac {x}{2}}\\right)^{{2m+\\alpha }}\n", "$$\n", "\n", "の形で表される。\n", "ここで $\\Gamma(x)$ は別の特殊関数である[ガンマ関数](https://ja.wikipedia.org/wiki/%E3%82%AC%E3%83%B3%E3%83%9E%E9%96%A2%E6%95%B0)である。\n", "\n", "発展的な数学に関するライブラリとしては `scipy` が有名である。\n", "特にこのような特殊関数は `scipy.special` にまとめられている。\n", "\n", "`v`次の第一種ベッセル関数は `scipy.special.jv(v, x)` \n", "とすることで呼び出すことができる。詳しくは\n", "[こちら](https://docs.scipy.org/doc/scipy/reference/generated/scipy.special.jv.html#scipy.special.jv)を参考にすること。" ] }, { "cell_type": "code", "execution_count": 29, "metadata": {}, "outputs": [], "source": [ "# scipy.special をインポート\n", "import scipy.special" ] }, { "cell_type": "code", "execution_count": 30, "metadata": {}, "outputs": [], "source": [ "# まず、計算する範囲、個数を指定する。今回は、-5~5, 100 点で計算する。\n", "x = []\n", "j0 = [] # α=0 のベッセル関数を計算し格納するリスト\n", "j1 = [] # α=1\n", "j2 = [] # α=2\n", "for i in range(100):\n", " x.append(20.0 / 100 * i)\n", " j0.append(scipy.special.jv(0, x[i])) \n", " j1.append(scipy.special.jv(1, x[i])) \n", " j2.append(scipy.special.jv(2, x[i]))" ] }, { "cell_type": "code", "execution_count": 31, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 31, "metadata": {}, "output_type": "execute_result" }, { "data": { "image/png": "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", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "# これらの結果をプロットする\n", "plt.plot(x, j0, label='a=0') # `label=` のあとに文字列を指定することにより、後ほど凡例を表示できる。\n", "plt.plot(x, j1, label='a=1')\n", "plt.plot(x, j2, label='a=2')\n", "plt.legend() # 凡例を表示するためのコマンド" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 課題9\n", "\n", "[こちらのページ](https://docs.scipy.org/doc/scipy/reference/special.html)に、 `scipy.special` で使うことのできる特殊関数がまとめられている。 \n", "好きな関数を一つピックアップし、グラフに描画せよ。" ] }, { "cell_type": "code", "execution_count": 32, "metadata": {}, "outputs": [], "source": [ "# 解答をここに記入する" ] } ], "metadata": { "anaconda-cloud": {}, "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.9.5" }, "latex_envs": { "bibliofile": "biblio.bib", "cite_by": "apalike", "current_citInitial": 1, "eqLabelWithNumbers": true, "eqNumInitial": 0 }, "toc": { "toc_cell": false, "toc_number_sections": true, "toc_threshold": 6, "toc_window_display": false } }, "nbformat": 4, "nbformat_minor": 1 }