Skip to content

Commit 16413c8

Browse files
committed
using scipy.optimize to replace brent_max test
1 parent aef973e commit 16413c8

File tree

1 file changed

+36
-34
lines changed

1 file changed

+36
-34
lines changed

lectures/ak2.md

+36-34
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ kernelspec:
1515

1616
In addition to what’s in Anaconda, this lecture will need the following libraries:
1717

18-
```{code-cell}
18+
```{code-cell} ipython3
1919
:tags: [hide-output]
2020
2121
!pip install --upgrade quantecon
@@ -407,15 +407,16 @@ $$
407407
408408
### Implementation
409409
410-
```{code-cell}
410+
```{code-cell} ipython3
411411
import numpy as np
412412
import matplotlib.pyplot as plt
413413
from quantecon.optimize import brent_max
414+
from scipy.optimize import minimize_scalar
414415
```
415416
416417
For parameters $\alpha = 0.3$ and $\beta = 0.5$, let's compute $\hat{K}$:
417418
418-
```{code-cell}
419+
```{code-cell} ipython3
419420
# parameters
420421
α = 0.3
421422
β = 0.5
@@ -433,8 +434,7 @@ Knowing $\hat K$, we can calculate other equilibrium objects.
433434
434435
Let's first define some Python helper functions.
435436
436-
```{code-cell}
437-
437+
```{code-cell} ipython3
438438
def K_to_Y(K, α):
439439
440440
return K ** α
@@ -465,28 +465,28 @@ def K_to_C(K, D, τ, r, α, β):
465465
466466
We can use these helper functions to obtain steady state values $\hat{Y}$, $\hat{r}$, and $\hat{W}$ associated with steady state values $\hat{K}$ and $\hat{r}$.
467467
468-
```{code-cell}
468+
```{code-cell} ipython3
469469
Y_hat, r_hat, W_hat = K_to_Y(K_hat, α), K_to_r(K_hat, α), K_to_W(K_hat, α)
470470
Y_hat, r_hat, W_hat
471471
```
472472
473473
Since steady state government debt $\hat{D}$ is $0$, all taxes are used to pay for government expenditures
474474
475-
```{code-cell}
475+
```{code-cell} ipython3
476476
G_hat = τ_hat * Y_hat
477477
G_hat
478478
```
479479
480480
We use the optimal consumption plans to find steady state consumptions for young and old
481481
482-
```{code-cell}
482+
```{code-cell} ipython3
483483
Cy_hat, Co_hat = K_to_C(K_hat, D_hat, τ_hat, r_hat, α, β)
484484
Cy_hat, Co_hat
485485
```
486486
487487
Let's store the steady state quantities and prices using an array called `init_ss`
488488
489-
```{code-cell}
489+
```{code-cell} ipython3
490490
init_ss = np.array([K_hat, Y_hat, Cy_hat, Co_hat, # quantities
491491
W_hat, r_hat, # prices
492492
τ_hat, D_hat, G_hat # policies
@@ -536,7 +536,7 @@ We'll then compute the single remaining undetermined policy variable from the go
536536
537537
When we simulate transition paths, it is useful to distinguish **state variables** at time $t$ such as $K_t, Y_t, D_t, W_t, r_t$ from **control variables** that include $C_{yt}, C_{ot}, \tau_{t}, G_t$.
538538
539-
```{code-cell}
539+
```{code-cell} ipython3
540540
class ClosedFormTrans:
541541
"""
542542
This class simulates length T transitional path of a economy
@@ -681,7 +681,7 @@ class ClosedFormTrans:
681681
682682
We can create an instance `closed` for model parameters $\{\alpha, \beta\}$ and use it for various fiscal policy experiments.
683683
684-
```{code-cell}
684+
```{code-cell} ipython3
685685
closed = ClosedFormTrans(α, β)
686686
```
687687
@@ -711,7 +711,7 @@ The first step is to prepare sequences of policy variables that describe fiscal
711711
712712
We must define sequences of government expenditure $\{G_t\}_{t=0}^{T}$ and debt level $\{D_t\}_{t=0}^{T+1}$ in advance, then pass them to the solver.
713713
714-
```{code-cell}
714+
```{code-cell} ipython3
715715
T = 20
716716
717717
# tax cut
@@ -730,7 +730,7 @@ Let's use the `simulate` method of `closed` to compute dynamic transitions.
730730
731731
Note that we leave `τ_pol` as `None`, since the tax rates need to be determined to satisfy the government budget constraint.
732732
733-
```{code-cell}
733+
```{code-cell} ipython3
734734
quant_seq1, price_seq1, policy_seq1 = closed.simulate(T, init_ss,
735735
D_pol=D_seq,
736736
G_pol=G_seq)
@@ -739,7 +739,7 @@ closed.plot()
739739
740740
We can also experiment with a lower tax cut rate, such as $0.2$.
741741
742-
```{code-cell}
742+
```{code-cell} ipython3
743743
# lower tax cut rate
744744
τ0 = 0.15 * (1 - 0.2)
745745
@@ -753,7 +753,7 @@ quant_seq2, price_seq2, policy_seq2 = closed.simulate(T, init_ss,
753753
G_pol=G_seq)
754754
```
755755
756-
```{code-cell}
756+
```{code-cell} ipython3
757757
fig, axs = plt.subplots(3, 3, figsize=(14, 10))
758758
759759
# quantities
@@ -797,7 +797,7 @@ The government targets the same tax rate $\tau_t=\hat{\tau}$ and to accumulate
797797
798798
To conduct this experiment, we pass `τ_seq` and `G_seq` as inputs and let `D_pol` be determined along the path by satisfying the government budget constraint.
799799
800-
```{code-cell}
800+
```{code-cell} ipython3
801801
# government expenditure cut by a half
802802
G_seq = τ_hat * 0.5 * Y_hat * np.ones(T+1)
803803
@@ -812,7 +812,7 @@ As the government accumulates the asset and uses it in production, the rental r
812812
813813
As a result, the ratio $-\frac{D_t}{K_t}$ of the government asset to physical capital used in production will increase over time
814814
815-
```{code-cell}
815+
```{code-cell} ipython3
816816
plt.plot(range(T+1), -closed.policy_seq[:-1, 1] / closed.quant_seq[:, 0])
817817
plt.xlabel('t')
818818
plt.title('-D/K');
@@ -839,7 +839,7 @@ But now let the government cut its expenditures only at $t=0$.
839839
840840
From $t \geq 1$, the government expeditures return to $\hat{G}$ and $\tau_t$ adjusts to maintain the asset level $-D_t = -D_1$.
841841
842-
```{code-cell}
842+
```{code-cell} ipython3
843843
# sequence of government purchase
844844
G_seq = τ_hat * Y_hat * np.ones(T+1)
845845
G_seq[0] = 0
@@ -911,7 +911,7 @@ Let's implement this "guess and verify" approach
911911
912912
We start by defining the Cobb-Douglas utility function
913913
914-
```{code-cell}
914+
```{code-cell} ipython3
915915
def U(Cy, Co, β):
916916
917917
return (Cy ** β) * (Co ** (1-β))
@@ -921,7 +921,7 @@ We use `Cy_val` to compute the lifetime value of an arbitrary consumption plan,
921921
922922
Note that it requires knowing future prices $r_{t+1}$ and tax rate $\tau_{t+1}$.
923923
924-
```{code-cell}
924+
```{code-cell} ipython3
925925
def Cy_val(Cy, W, r_next, τ, τ_next, δy, δo_next, β):
926926
927927
# Co given by the budget constraint
@@ -934,14 +934,16 @@ An optimal consumption plan $C_y^*$ can be found by maximizing `Cy_val`.
934934
935935
Here is an example that computes optimal consumption $C_y^*=\hat{C}_y$ in the steady state with $\delta_{yt}=\delta_{ot}=0,$ like one that we studied earlier
936936
937-
```{code-cell}
937+
```{code-cell} ipython3
938938
W, r_next, τ, τ_next = W_hat, r_hat, τ_hat, τ_hat
939939
δy, δo_next = 0, 0
940940
941-
Cy_opt, U_opt, _ = brent_max(Cy_val, # maximand
942-
1e-6, # lower bound
943-
W*(1-τ)-δy-1e-6, # upper bound
944-
args=(W, r_next, τ, τ_next, δy, δo_next, β))
941+
result = minimize_scalar(lambda Cy: -Cy_val(Cy, W, r_next, τ, τ_next, δy, δo_next, β),
942+
bounds=(1e-6, W*(1-τ)-δy-1e-6),
943+
method='bounded')
944+
945+
Cy_opt = result.x
946+
U_opt = -result.fun
945947
946948
Cy_opt, U_opt
947949
```
@@ -950,7 +952,7 @@ Let's define a Python class `AK2` that computes the transition paths with the
950952
951953
It can handle nonzero lump sum taxes
952954
953-
```{code-cell}
955+
```{code-cell} ipython3
954956
class AK2():
955957
"""
956958
This class simulates length T transitional path of a economy
@@ -1121,13 +1123,13 @@ class AK2():
11211123
11221124
We can initialize an instance of class `AK2` with model parameters $\{\alpha, \beta\}$ and then use it to conduct fiscal policy experiments.
11231125
1124-
```{code-cell}
1126+
```{code-cell} ipython3
11251127
ak2 = AK2(α, β)
11261128
```
11271129
11281130
We first examine that the "guess and verify" method leads to the same numerical results as we obtain with the closed form solution when lump sum taxes are muted
11291131
1130-
```{code-cell}
1132+
```{code-cell} ipython3
11311133
δy_seq = np.ones(T+2) * 0.
11321134
δo_seq = np.ones(T+2) * 0.
11331135
@@ -1141,22 +1143,22 @@ D_pol[0] = D_hat
11411143
D_pol[1:] = D1
11421144
```
11431145
1144-
```{code-cell}
1146+
```{code-cell} ipython3
11451147
quant_seq3, price_seq3, policy_seq3 = ak2.simulate(T, init_ss,
11461148
δy_seq, δo_seq,
11471149
D_pol=D_pol, G_pol=G_pol,
11481150
verbose=True)
11491151
```
11501152
1151-
```{code-cell}
1153+
```{code-cell} ipython3
11521154
ak2.plot()
11531155
```
11541156
11551157
Next, we activate lump sum taxes.
11561158
11571159
Let's alter our {ref}`exp-tax-cut` fiscal policy experiment by assuming that the government also increases lump sum taxes for both young and old people $\delta_{yt}=\delta_{ot}=0.005, t\geq0$.
11581160
1159-
```{code-cell}
1161+
```{code-cell} ipython3
11601162
δy_seq = np.ones(T+2) * 0.005
11611163
δo_seq = np.ones(T+2) * 0.005
11621164
@@ -1170,7 +1172,7 @@ quant_seq4, price_seq4, policy_seq4 = ak2.simulate(T, init_ss,
11701172
11711173
Note how "crowding out" has been mitigated.
11721174
1173-
```{code-cell}
1175+
```{code-cell} ipython3
11741176
fig, axs = plt.subplots(3, 3, figsize=(14, 10))
11751177
11761178
# quantities
@@ -1224,7 +1226,7 @@ We can use our code to compute the transition ignited by launching this system
12241226
12251227
Let's compare the results to the {ref}`exp-tax-cut`.
12261228
1227-
```{code-cell}
1229+
```{code-cell} ipython3
12281230
δy_seq = np.ones(T+2) * Cy_hat * 0.1
12291231
δo_seq = np.ones(T+2) * -Cy_hat * 0.1
12301232
@@ -1235,7 +1237,7 @@ quant_seq5, price_seq5, policy_seq5 = ak2.simulate(T, init_ss,
12351237
D_pol=D_pol, G_pol=G_pol)
12361238
```
12371239
1238-
```{code-cell}
1240+
```{code-cell} ipython3
12391241
fig, axs = plt.subplots(3, 3, figsize=(14, 10))
12401242
12411243
# quantities

0 commit comments

Comments
 (0)