{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "(chap:7-differenceEq)=\n", "# 差分方程式と経済分析" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "<div name=\"html-admonition\" style=\"font-size: 0.8em\">\n", "<input type=\"button\" onclick=\"location.href='https://translate.google.com/translate?hl=&sl=ja&tl=en&u='+window.location;\" value=\"Google translation\" style=\"color:#ffffff;background-color:#008080; height:25px\" onmouseover=\"this.style.background='#99ccff'\" onmouseout=\"this.style.background='#008080'\"/> in English or the language of your choice.\n", "</div><br>" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import japanize_matplotlib\n", "import numpy as np\n", "import pandas as pd\n", "import statsmodels.formula.api as sm\n", "\n", "# numpy v1の表示を使用\n", "np.set_printoptions(legacy='1.21')\n", "# 警告メッセージを非表示\n", "import warnings\n", "warnings.filterwarnings(\"ignore\")" ] }, { "cell_type": "markdown", "metadata": { "heading_collapsed": true, "jp-MarkdownHeadingCollapsed": true }, "source": [ "## はじめに" ] }, { "cell_type": "markdown", "metadata": { "hidden": true }, "source": [ "この章ではまず第一に,動学モデルの基礎(の基礎)を理解することである。マクロ経済は時間を考慮せざるを得ない。経済成長,インフレ,デフレ,景気循環などは全て時間軸に沿って考える必要がある。マクロ経済では変数の変化が重要な役割を果たすためである。そして時間と密接に関係するのがpersistenceと呼ばれるマクロ変数の特徴である。persistenceとは,マクロ変数が一度ある状態に陥ると,その状態が継続する傾向にある性質を指す。典型的な例がデフレである。日本はデフレからなかなか脱却できないが,それがデフレのpersistenceである。これは前期の影響が今期に,今期の影響が来期に現れることによって発生する。時間という概念から離れてpersistenceを考えるのは難しい。一方で,時間を扱う「動学」と聞くと難しく感じるかもしれないが,構える必要はない。高校数学で習った漸化式(以下では「差分方程式」を同義として扱う)を使うが,解法テクニックが重要ではなく,漸化式の考え方を捉えるコードを書き,後は`Python`が計算することになる。" ] }, { "cell_type": "markdown", "metadata": { "heading_collapsed": true }, "source": [ "## 1階差分方程式" ] }, { "cell_type": "markdown", "metadata": { "heading_collapsed": true, "hidden": true, "jp-MarkdownHeadingCollapsed": true }, "source": [ "### 説明" ] }, { "cell_type": "markdown", "metadata": { "hidden": true }, "source": [ "差分方程式(漸化式)とは,初期の値を所与として値の数列を定義する方程式である。言い換えると,$t$期の変数の値は$t-1$期やそれ以前の値に依存する関係を表す式である。例を考えよう。" ] }, { "cell_type": "markdown", "metadata": { "hidden": true }, "source": [ "$$\n", "x_{t+1}=ax_t+b,\\quad b\\geq0\n", "$$\n", "\n", "$x_0$は与えられていると仮定しよう。連続して代入する(逐次代入法)。\n", "\n", "$$\n", "\\begin{align*}\n", "x_{t+1}\n", "&=ax_t+b\\\\\n", "&=a(ax_{t-1}+b)+b=a^2x_{t-1}+b(1+a) \\\\\n", "&=a^2(ax_{t-2}+b)+b(1+a)=a^3x_{t-2}+b(1+a+a^2) \\\\\n", "&=a^3(ax_{t-3}+b)+b(1+a+a^2)=a^4x_{t-3}+b(1+a+a^2+a^3) \\\\\n", "&\\qquad\\vdots \\\\\n", "&=a^{t+1}x_0+b\\sum_{i=0}^ta^i\n", "\\end{align*}\n", "$$" ] }, { "cell_type": "markdown", "metadata": { "hidden": true }, "source": [ "このことから次のことがわかる。\n", "\n", "$t\\rightarrow\\infty$とすると($x_0\\ne 0$)\n", "* $a=1$の場合\n", " * $b=0$の場合,$x_t$は同じ値$x_0$にとどまる。\n", " * $b>0$の場合,$b\\sum_{i=0}^ta^i=b(1+t)\\rightarrow\\infty$となり$x_t$は発散する。\n", " * $b<0$の場合,$b\\sum_{i=0}^ta^i=b(1+t)\\rightarrow-\\infty$となり$x_t$は発散する。\n", "* $a=-1$の場合\n", " * $b$の値に関わらず,$x_t$は振動する。\n", "* $a>1$の場合,$a^{t+1}\\rightarrow\\infty$となり$x_t$は正の無限大に発散する。\n", "* $a<-1$の場合,$x_t$は振動し$a^{t+1}\\rightarrow\\infty$もしくは$-\\infty$となり発散する。\n", "* $|a|<1$の場合$x_t$は収束\n", " * $0<a<1$の場合は単調的に収束\n", " * $-1<a<0$の場合は振動し収束\n", " * $a^{t+1}x_0\\rightarrow 0$\n", " * $\\sum_{i=0}^ta^t$は$S$に収束する。\n", " \n", " $$\n", " \\begin{align*}\n", " S&=\\sum_{i=0}^{\\infty}a^t=1+a+a^2+a^3+\\cdots \\\\\n", " aS&=a+a^2+a^3+\\cdots \\\\\n", " S-aS&=1 \\\\\n", " &\\Downarrow \\\\\n", " S&=\\dfrac{1}{1-a}\n", " \\end{align*}\n", " $$\n", " \n", " * $t\\rightarrow\\infty$の場合の$x_t$の値を$x_{*}$としよう。$t\\rightarrow\\infty$の下では$x_t=x_{t-1}\\equiv x_{*}$となるため以下が成立する。\n", " \n", " $$\n", " x_{*}=ax_{*}+b\n", " \\quad\n", " \\Rightarrow\n", " \\quad\n", " x_{*}=\\dfrac{b}{1-a}=bS\n", " $$\n", "\n", "均衡を考える上で$x_t$が発散するケースは除外し,収束するケースに着目する。" ] }, { "cell_type": "markdown", "metadata": { "heading_collapsed": true, "hidden": true }, "source": [ "### 例1" ] }, { "cell_type": "markdown", "metadata": { "hidden": true }, "source": [ "* 初期値:$x_0=1$\n", "\n", " $$\n", " x_{t+1}=0.4x_{t}+3\n", " $$ (eq:8-1)\n", "\n", "* $0.4<1$なため収束することが分かる。\n", "* 定常状態は次の値となる。\n", "\n", " $$\n", " x_{*}=0.4x_{*}+3\n", " \\quad\\Rightarrow\\quad\n", " x_{*}=\\dfrac{3}{1-0.4}=5\n", " $$" ] }, { "cell_type": "markdown", "metadata": { "hidden": true }, "source": [ "ここでまとめたことは{numref}`fig:8-ex1`から確認できる。\n", "* ① 初期を$x_0<5$(例えば,1)とする。\n", "* ② $x_0$を所与として式[](eq:8-1)の右辺によって$x_1$が決まる。\n", "* ③ $x_1$を縦軸で確かめる。\n", "* ④ ③から平行移動した45度線上の点\n", "* ⑤ ④から垂直に降りて横軸に$x_1$を確認できる。\n", "* ⑥ $x_1$を所与として式[](eq:8-1)の右辺によって$x_2$が決まる。\n", "* ⑦ $x_2$を縦軸で確かめる。\n", "* ⑧ ⑦から平行移動した45度線上の点\n", "* ⑨ ⑧から垂直に降りて横軸に$x_2$を確認できる。\n", "* このプロセスのリピートし最終的に定常状態($x_t=x_{t+1}$)に収束する\n", "\n", "この場合の定常状態を「安定的(stable)」と呼ぶ。ここで覚えて欲しいことは,まず第一に式[](eq:8-1)と45度線の交点が定常状態である。そして45度線の傾きは1に対して式[](eq:8-1)の傾きは0.4なので,式[](eq:8-1)は「上から」45度線と交わっている。\n", "\n", "```{figure} /images/ex1.jpeg\n", "---\n", "scale: 35%\n", "name: fig:8-ex1\n", "---\n", "例1\n", "```\n", "\n", "次にコードを書いて$x_t$を計算しプロットするが,3つの方法を紹介する。" ] }, { "cell_type": "markdown", "metadata": { "heading_collapsed": true, "hidden": true }, "source": [ "#### 方法1" ] }, { "cell_type": "markdown", "metadata": { "hidden": true }, "source": [ "計算した$x$の値を一時的に割り当てるアップデート用の変数を使う方法を考える。この方法は,下で説明する方法1と2よりも`Python`的(Pythonic)な方法であり,一番オススメの方法である。" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "hidden": true }, "outputs": [], "source": [ "x = 1 # 1\n", "\n", "x_lst = [x] # 2\n", "\n", "for i in range(20):\n", " \n", " x = 0.4 * x + 3 # 3\n", " \n", " x_lst.append(x) # 4" ] }, { "cell_type": "markdown", "metadata": { "hidden": true }, "source": [ "```{admonition} コードの説明\n", ":class: dropdown\n", "\n", "1. `x`はアップデート用の変数として使う。初期値は1。\n", "2. 初期値が入ったリストであり、このリストに計算結果を追加する。\n", "3. 来期の`x`の計算\n", " * 1回目のループ:右辺では(1)で設定した`x`の初期値を使い計算し,結果を左辺の`x`に割り当てる。この時点で,(1)の`x`は(3)の左辺の`x`と同じ変数なので,同じ計算結果が割り当てられアップデートされる。\n", " * 2回目以降のループ:右辺では`x`の最新の値を使い計算し,結果を左辺の`x`に割り当てる。この時点,(1)の`x`は(3)の左辺の`x`と同じ変数なので,同じ計算結果が割り当てられアップデートされる。\n", "4. (3)の左辺の`x`を(2)のリストに追加する。\n", "```" ] }, { "cell_type": "markdown", "metadata": { "hidden": true }, "source": [ "次に`x_list`をプロットするが,ここでは`DataFrame`のメソッド`.plot()`を使う図示の方法を説明する。非常に簡単であり,`DataFrame`を`df`とすると次の構文となる。\n", "```\n", "df.plot()\n", "```\n", "これだけでプロットが表示される。\n", "\n", "まず`DataFrame`を作成しよう。様々な作成方法があるが,以下では辞書を使う方法を紹介する。辞書のキーが列ラベルになり,値が列の値となる。" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "hidden": true }, "outputs": [], "source": [ "df = pd.DataFrame({'X':x_lst})\n", "\n", "df.head()" ] }, { "cell_type": "markdown", "metadata": { "hidden": true }, "source": [ "では図示してみよう。" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "hidden": true }, "outputs": [], "source": [ "df.plot()\n", "pass" ] }, { "cell_type": "markdown", "metadata": { "hidden": true }, "source": [ "この図の縦軸は$x_t$であり,横軸は行インデックスが`float`として表示されており,ループの回数と同じ(自動表示なので整数となる場合もある)。強制的に横軸に整数を表示したい場合は`df.plot()`の代わりに次のコードを使えば良いだろう。\n", "```\n", "ax_ = df.plot()\n", "ax_.set_xticks(range(21))\n", "```\n", "\n", "```{admonition} コードの説明\n", ":class: dropdown\n", "\n", "* 1行目:`.plot()`で生成される「軸」を`ax_`に割り当てる。\n", "* 2行目:`ax_`のメソッド`.set_xticks`は横軸の目盛を設定し,引数には使う目盛を指定する。`range(21)`を使うことで`0`から`10`の全ての整数を指定しているが,`range(0,11,2)`にすれば`0`,`2`,`4`,`6`...といった表示も可能である。\n", "```" ] }, { "cell_type": "markdown", "metadata": { "heading_collapsed": true, "hidden": true }, "source": [ "#### 方法2" ] }, { "cell_type": "markdown", "metadata": { "hidden": true }, "source": [ "この方法では,値を格納するために使うリストを使うが、その中にある値を直接`for`ループの中で使う。" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "hidden": true }, "outputs": [], "source": [ "x_lst = [1] # 1\n", "\n", "for i in range(20):\n", " \n", " x = 0.4 * x_lst[i] + 3 # 2\n", " \n", " x_lst.append(x) # 3\n", "\n", "pd.DataFrame({'X':x_lst}).plot()\n", "pass" ] }, { "cell_type": "markdown", "metadata": { "hidden": true }, "source": [ "```{admonition} 主なコードの説明\n", ":class: dropdown\n", "\n", "1. 初期値が入ったリストを用意する。\n", "2. リストの中にある`i`番目の値を使い右辺を計算し`x`に割り当てる。\n", "3. (2)で計算した`x`の値をリストに追加する。\n", "```" ] }, { "cell_type": "markdown", "metadata": { "heading_collapsed": true, "hidden": true }, "source": [ "#### 方法3" ] }, { "cell_type": "markdown", "metadata": { "hidden": true }, "source": [ "`1`(初期値)と計算する回数分の`Numpy`の`array`を用意し、計算結果をその中に格納する。" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "hidden": true }, "outputs": [], "source": [ "n = 20 # 1\n", "\n", "arr = np.zeros(1+n) # 2\n", "arr[0] = 1 # 3\n", "\n", "for i in range(n):\n", " \n", " arr[i+1] = 0.4 * arr[i] + 3 # 4\n", "\n", "pd.DataFrame({'X':arr}).plot()\n", "pass" ] }, { "cell_type": "markdown", "metadata": { "hidden": true }, "source": [ "```{admonition} コードの説明\n", ":class: dropdown\n", "\n", "1. ループの回数\n", "2. `np.zeros()`は引数の数だけ`0`が並ぶ`array`を作成する関数。`1+n`の`1`は(3)で初期値を代入するために必要となる。\n", "3. `arr`の`0`番目に初期値を代入する。\n", "4. 右辺では`arr`の`i`番目の値を使い来期の値を計算し,`=`を使い`arr`の`i+1`番目に代入する。\n", "```" ] }, { "cell_type": "markdown", "metadata": { "heading_collapsed": true, "hidden": true }, "source": [ "### 例2" ] }, { "cell_type": "markdown", "metadata": { "hidden": true }, "source": [ "$$\n", "x_{t+1}=1.2x_{t}-0.2\n", "$$ (eq:8-ex2)\n", "\n", "* $1.2>1$なため発散する。\n", "* 定常状態の値を計算する。\n", "\n", " $$\n", " x_{*}=1.2x_{*}-0.2\n", " \\quad\\Rightarrow\\quad\n", " x_{*}=\\dfrac{0.2}{1.2-1.0}=1\n", " $$\n", "\n", "この結果は{numref}`fig:8-ex2`を使って確認できる。図の読み方は例1と同じである。式[](eq:8-ex2)は「下から」45度線を交差している。初期値を$x_0=1.1>x_*$として発散することを示しているが,$x_0<1$の場合でも発散することになる(試してみよう)。この場合の定常状態$x_*$は「不安定(unstable)」と呼ぶ。\n", "\n", "```{figure} /images/ex2.jpeg\n", "---\n", "scale: 35%\n", "name: fig:8-ex2\n", "---\n", "例2\n", "```\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "hidden": true }, "outputs": [], "source": [ "x = 1.1 # 初期値 x0\n", "\n", "x_lst = [x]\n", "\n", "for i in range(50):\n", " \n", " x = 1.2 * x - 0.2\n", " \n", " x_lst.append(x)\n", "\n", "pd.DataFrame({'X':x_lst}).plot()\n", "pass" ] }, { "cell_type": "markdown", "metadata": { "heading_collapsed": true, "hidden": true }, "source": [ "### 例3" ] }, { "cell_type": "markdown", "metadata": { "hidden": true }, "source": [ "$$\n", "x_{t+1}=ax_{t}^{0.5},\\quad x_t>0,\\;a>0\n", "$$ (eq:8-ex3)\n", "\n", "この式は上の例と違って非線形の差分方程式となっている。しかし,数値計算のための`Python`コードに関しては大きな違いはない。単に,コードの中で非線形の式を書くだけで良い。しかし収束か発散かの安定性(stability)を解析的に確認するには,定常状態の**近傍**を考える必要がある。基本的なアイデアは次のようなものである。定常状態に非常に近い周辺を考えよう。十分に定常状態に近ければ、非線形差分方程式は線形に非常に近くなる。例えば、地球は丸いが、その上で暮らす小さな人間にとって大きな地球は平らに感じる。これは無意識に線形近似を行なっているのと同じである。この考えを使い、非線形差分方程式を定常状態の周りで線形近似することで,あたかも線形の様に考えて安定性を確認できる。手法としてはテイラー展開を使い線形近似する。\n", "\n", "<テイラー展開による1次線形近似>\n", "* 関数$y=f(k)$を$k_{*}$でテイラー展開すると次式となる。\n", "\n", " $$\n", " y=f(k_{*})+\\left.\\frac{df}{dk}\\right|_{k=k_{*}}(k-k_{*})\n", " $$\n", "\n", "[式](eq:8-ex3)に当てはめると次のような対応関係にある。\n", "* $y\\;\\Rightarrow\\;x_{t+1}$\n", "* $f(k)\\;\\Rightarrow\\;ak_{t}^{0.5}$\n", "* $k_{*}\\;\\Rightarrow\\;x_{*}$\n", "\n", "テーラー展開する前に,$x_{*}$を計算してみよう。[式](eq:8-ex3)で$x_{t+1}=x_{t}=x_{*}$とすると\n", "\n", "$$\n", "x_{*}=ax_{*}^{0.5}\n", "\\quad\\Rightarrow\\quad\n", "x_{*}=a^2\n", "$$\n", "\n", "\n", "これらを使い,[式](eq:8-ex3)をテーラー展開すると\n", "\n", "$$\n", "\\begin{align*}\n", "x_{t+1}\n", "&=ax_{*}^{0.5}\n", "+\\left.0.5ax_{t}^{-0.5}\\right|_{x_t=x_{*}}(x_t-x_{*}) \\\\\n", "&=ax_{*}^{0.5}+0.5ax_{*}^{-0.5}(x_t-x_{*}) \\\\\n", "&=a\\left(a^2\\right)^{0.5}+0.5a\\left(a^2\\right)^{-0.5}(x_t-a^2) \\\\\n", "&=a^{2}+0.5(x_t-a^2)\\\\\n", "&=0.5x_t+0.5a^2\n", "\\end{align*}\n", "$$\n", "\n", "となる。$0.5<1$なので収束することが確認できた。また,定常状態も次のように計算できる。\n", "\n", "$$\n", "x_{*}=0.5x_{*}+0.5a^2\n", "\\quad\n", "\\Rightarrow\n", "\\quad\n", "x_{*}=a^2\n", "$$\n", "\n", "図示すると{numref}`fig:8-ex3`の様になる。" ] }, { "cell_type": "markdown", "metadata": { "hidden": true }, "source": [ "```{figure} /images/ex3.jpeg\n", "---\n", "scale: 35%\n", "name: fig:8-ex3\n", "---\n", "例3\n", "```" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "差分方程式が**45度線近傍で増加関数**の場合はもっと簡単な判定方法がある。\n", "> 縦軸に$x_{t+1}$,横軸に$x_t$の図で差分方程式が45度線と\n", "> * 「上から交差」する場合,$x_t$は定常値へ収束する(定常状態は安定的)\n", "> * 「下から交差」する場合,$x_t$は発散する(定常状態は不安定)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "$a=2$としてコードを書いて実行してみよう。" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "hidden": true }, "outputs": [], "source": [ "x = 3.5 # 初期値 x0\n", "\n", "x_lst = [x]\n", "\n", "for i in range(20):\n", " \n", " x = 2 * x ** 0.5\n", " \n", " x_lst.append(x)\n", "\n", "pd.DataFrame({'X':x_lst}).plot()\n", "pass" ] }, { "cell_type": "markdown", "metadata": { "heading_collapsed": true, "hidden": true }, "source": [ "### 例4" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "次の非線形差分方程式を考えてみよう。\n", "\n", "$$\n", "x_{t+1}=a * x_{t}^{b} + 10,\n", "\\qquad x_t>0,\n", "\\quad a\\ne 0,\n", "\\quad b\\ne 0\n", "$$\n", "\n", "数値計算をせずとも,$0<b<1$の場合は上の式は45度線と「上から交差」するため安定的であることは直ぐにわかる。\n", "定常状態$x_{*}$は\n", "\n", "$$\n", "x_{*}=a * x_{*}^{b} + 10\n", "$$\n", "\n", "で定義されるが,解を明示的に求めることはできない。\n", "しかし,数値計算で$x_t$の値は簡単に計算できる。\n", "\n", "初期値`x0`,パラメータ`a`,`for`ループ計算関数`n`を引数として,関数を作成して確かめよう。" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "def my_dynamics(x0, a, b, n):\n", "\n", " x = x0\n", "\n", " x_lst = []\n", "\n", " for _ in range(n):\n", "\n", " x = a * x**b + 10\n", " x_lst.append(x)\n", "\n", " return pd.DataFrame({'X': x_lst})" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "my_dynamics(x0=40, a=1, b=0.9, n=5)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "$0<b<1$のケースをプロットしてみよう。" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "my_dynamics(x0=40, a=1, b=0.9, n=20).plot(marker='o')\n", "pass" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "$b>1$のケースをプロットしてみよう。" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "my_dynamics(x0=40, a=1, b=1.1, n=15).plot(marker='o')\n", "pass" ] }, { "cell_type": "markdown", "metadata": { "heading_collapsed": true, "jp-MarkdownHeadingCollapsed": true }, "source": [ "## 45度線モデル" ] }, { "cell_type": "markdown", "metadata": { "hidden": true }, "source": [ "マクロ経済学の基本モデルとなるケインズの45度線モデルを考えてみる。次の仮定を置く。\n", "* 所得恒等式:$y_t=c_t+inv_t$\n", "* 消費:$c_t=a+by_t$\n", " * $a>0$:所得とは独立した消費\n", " * $0<b<1$:限界消費性向\n", "* 投資:$inv_t=d+fy_{t-1}$\n", " * $t$期の投資は前期である$t-1$期の産出量に依存すると仮定する。工場を建てたりするには時間が掛かる様に投資計画を実行するには時間を要することを捉えている。この仮定により産出量の動学的な動きが発生する事になる。\n", " * $f>0$:前期の産出量に依存する投資\n", " * $d>0$:産出量に依存しない投資\n", "* 均衡式:$y_t=a+by_t+d+fy_{t-1}$\n", "\n", "均衡式を1期進めると次式となる。\n", "\n", "$$\n", "y_{t+1}=\\frac{f}{1-b}y_t+\\frac{a+d}{1-b}\n", "$$ (eq:8-45degree)\n", " \n", "この式から次のことが分かる。定常状態の安定性は$\\dfrac{f}{1-b}$に依存しており,パラメータの値から定常状態は安定的であり,初期値$y_0$から収束することになる。定常状態を計算しよう。実質変数である$y_t$が一定になる状態なので次式が成立する。\n", "\n", "$$\n", "\\begin{align*}\n", " y_{t+1}&=y_t=y_* \\\\\n", " &\\Downarrow \\\\\n", " y_*&=\\frac{a+d}{1-b-f}\n", "\\end{align*}\n", "$$\n", " \n", "定常状態で$y_*>0$が成立してこそ意味があるので,$1>b+f$を仮定しよう。モデルの動学を図示したのが{numref}`fig:8-45degree`である。" ] }, { "cell_type": "markdown", "metadata": { "hidden": true }, "source": [ "```{figure} /images/45degree.jpeg\n", "---\n", "scale: 40%\n", "name: fig:8-45degree\n", "---\n", "45度線モデル\n", "``` \n", "\n", "次に,実際にコードを書いて$y_t$の動学的な動きを確認してみよう。次の関数を定義する。" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "hidden": true }, "outputs": [], "source": [ "def model45(y0, a, b, d, f, n=10):\n", " \"\"\"引数 #1\n", " y0: GDPの初期値\n", " a: 所得に依存しない消費\n", " b: 限界消費性向\n", " d: 産出量に依存しない投資\n", " f: 前期の産出量に依存する投資\n", " n: ループの回数(デフォルト10)\n", " 戻り値\n", " yの値からなるDataFrame\"\"\"\n", " \n", " y = y0 #2\n", " \n", " y_lst = [y0] #3\n", "\n", " for i in range(n):\n", " \n", " y = y * f / (1-b) + (a+d) / (1-b) # 4\n", " y_lst.append(y) # 5\n", "\n", " yss = (a+d) / (1-b-f) # 6\n", " \n", " print(f'定常状態での産出量:{yss:.1f}') # 7\n", " \n", " return pd.DataFrame({'output':y_lst}) # 8" ] }, { "cell_type": "markdown", "metadata": { "hidden": true }, "source": [ "```{admonition} コードの説明\n", ":class: dropdown\n", "\n", "1. `\"\"\"`と`\"\"\"`で挟んだ領域は`docstring`と呼ばれ、関数の説明をする。書かなくても良いが、自分が忘れた頃に関数のコードを読むことになるかも知れないので、書く方がオススメ。\n", "\n", "2. `y`はアップデート用の変数であり,初期値`y0`を`y`に割り当てる。\n", "3. 初期値が入ったリストであり,`for`ループで計算する`y`を格納する。\n", "4. 右辺の`y`は(1)の`y`であり,右辺の計算結果を左辺の`y`に割り当て(1)の`y`の値をアップデートする。\n", "5. (3)で計算した`y`の値を`y_list`に追加する。\n", "6. 定常状態`yss`を計算する。\n", "7. 定常状態の値を表示する。`:.1f`は小数点第一位まで表示することを指定する。\n", "8. `DataFrame`を作成し,関数が実行されるとそれを返す。\n", "```" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "hidden": true }, "outputs": [], "source": [ "model45(100, a=50, b=0.5, d=50, f=0.2).plot()\n", "pass" ] }, { "cell_type": "markdown", "metadata": { "hidden": true }, "source": [ "```{admonition} コードの説明\n", ":class: dropdown\n", "\n", "`model45()`の返り値は`DataFrame`である。そのメソッド`.plot()`を直接使って図示している。\n", "```" ] }, { "cell_type": "markdown", "metadata": { "hidden": true }, "source": [ "初期値は定常状態の値よりも低く設定されているため,産出量は徐々に増加することになる。初期値を定常状態の値よりも大きい場合どうなるか確認してみよう。" ] }, { "cell_type": "markdown", "metadata": { "heading_collapsed": true, "jp-MarkdownHeadingCollapsed": true }, "source": [ "## 蜘蛛の巣モデル" ] }, { "cell_type": "markdown", "metadata": { "hidden": true }, "source": [ "もう一つの簡単な経済モデルを取り上げる。需要と供給モデルであり,均衡では価格と財の量が決定される。\n", "\n", "* 需要曲線\n", " * 消費者は今期の価格に基づいて今期の需要を決める。\n", " \n", " $$\n", " d_t = a - bp_t,\\quad a,b>0\n", " $$\n", " \n", "* 供給曲線\n", " * 生産者は価格を観察し生産量を決めるが,その決定は1期前の価格に依存すると仮定する。例えば,農家が想定できる。種を植え収穫し市場に供給するまで時間が掛かることを$p_{t-1}$が捉えている。\n", " \n", " $$\n", " s_t = -c + dp_{t-1},\\quad c,d>0\n", " $$\n", " \n", " * $t$期の供給量が$t-1$期の価格に依存することにより,動学的な動きが発生する事になる。\n", " \n", "* 均衡条件\n", "\n", " $$\n", " d_t=s_t\\equiv q_t\n", " $$" ] }, { "cell_type": "markdown", "metadata": { "hidden": true }, "source": [ "均衡式を1つにまとめる。\n", "\n", "$$\n", "p_t = \\frac{a+c}{b} - \\frac{d}{b}p_{t-1}\n", "$$ (eq:8-cobweb)" ] }, { "cell_type": "markdown", "metadata": { "hidden": true }, "source": [ "この式から定常状態の安定性が簡単に確認できる。均衡が収束するのか発散するのかは需要と供給の価格の係数,言い換えると,需要と供給がどれだけ価格に反応するかに依存していることが分かる。この結果を需要曲線と供給曲線の傾きで表すために次のこと確認しよう。\n", "\n", "$$\n", "\\text{需要曲線の傾き}=\\frac{1}{b},\n", "\\quad\n", "\\text{供給曲線の傾き}=\\frac{1}{d}\n", "$$\n", "\n", "* 収束:$\\dfrac{d}{b}<1$もしくは$\\dfrac{1}{b}<\\dfrac{1}{d}$\n", " * 需要曲線と比べて供給曲線の傾きが大きい場合に長期均衡に収束する。\n", "* 発散:$\\dfrac{d}{b}>1$もしくは$\\dfrac{1}{b}>\\dfrac{1}{d}$\n", " * 需要曲線と比べて供給曲線の傾きが小さい場合に発散する。\n", "* 2期間サイクル:$\\dfrac{d}{b}=1$\n", "\n", "式[](eq:8-cobweb)を使うと定常状態(長期的均衡)の価格は次のように計算できる。\n", "\n", "$$\n", "\\begin{align*}\n", "p_*\n", "&= \\frac{a+c}{b} - \\frac{d}{b}p_{*} \\\\\n", "&\\Downarrow \\\\\n", "p_{*}&=\\dfrac{a+c}{b+d}\n", "\\end{align*}\n", "$$\n", "\n", "また定常状態の量は需要曲線もしくは供給曲線を使って計算する。\n", "\n", "$$\n", "q_t=q_{*}=a-bp_{*}\n", "$$" ] }, { "cell_type": "markdown", "metadata": { "hidden": true }, "source": [ "{numref}`fig:8-cobweb`は価格$p_t$の動学を示している。需要曲線に比べて供給曲線がより急な傾きになっているため定常状態に収束している。その逆の場合は発散することになるので図を描いて確かめてみよう。\n", "\n", "```{figure} /images/cobweb.jpeg\n", "---\n", "scale: 35%\n", "name: fig:8-cobweb\n", "---\n", "蜘蛛の巣モデル(モデル名は均衡の軌跡が蜘蛛の巣に似てるため)\n", "```\n", "\n", "次にコードを書いて価格と量の動学を確かめるが,45度線モデルと同じように関数を作りプロットする。" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "hidden": true }, "outputs": [], "source": [ "def cobweb(p0, a, b, c, d, n=10):\n", " \"\"\"引数\n", " p0: 初期値\n", " a: 需要曲線の切片\n", " b: 需要曲線の傾き\n", " c: 供給曲線の切片\n", " d: 供給曲線の傾き\n", " n: ループ計算の回数\n", " 返り値:\n", " 価格と量のDataFrame\n", " \"\"\"\n", " \n", " p = p0 # 初期の価格\n", " \n", " q_lst = []\n", " p_lst = []\n", "\n", " for i in range(n):\n", " \n", " p = (a+c) / b - (d/b) * p\n", " q = a - b * p\n", "\n", " q_lst.append(q)\n", " p_lst.append(p)\n", "\n", " # 定常状態\n", " pss = (a+c) / (b+d)\n", " qss = a - b * pss\n", " \n", " print(f'定常状態での価格:{pss:.1f}\\n定常状態での量: {qss:.1f}')\n", " \n", " dic = {'output':q_lst, 'price':p_lst}\n", " return pd.DataFrame(dic)" ] }, { "cell_type": "markdown", "metadata": { "hidden": true }, "source": [ "まず$\\dfrac{d}{b}<1$を仮定し収束するケースを考えよう。" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "hidden": true }, "outputs": [], "source": [ "cobweb(45, a=100, b=1.1, c=1, d=1, n=50).plot(secondary_y='price')\n", "pass" ] }, { "cell_type": "markdown", "metadata": { "hidden": true }, "source": [ "```{admonition} コードの説明\n", ":class: dropdown\n", "\n", "`.plot()`の引数`secondary_y`は右の縦軸の変数をしている。ここでは`'price'`を指定している。凡例を見ると`price (right)`となっている。\n", "```\n", "\n", "$\\dfrac{d}{b}>1$を仮定し発散するケースをプロットする。" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "hidden": true }, "outputs": [], "source": [ "cobweb(45, a=100, b=1, c=1, d=1.1, n=50).plot(secondary_y='price')\n", "pass" ] } ], "metadata": { "celltoolbar": "Tags", "kernelspec": { "display_name": "Python 3 (ipykernel)", "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.11.9" } }, "nbformat": 4, "nbformat_minor": 4 }