model = (;α=0.3, β=0.96, γ=4, δ=0.1, s=0.2)
# we add the saving rate to the model(α = 0.3, β = 0.96, γ = 4, δ = 0.1, s = 0.2)
Pablo Winant
Prerequisites
This tutorial refers to the lecture on the convergence of sequences.
Also, make sure you went through the Julia Basics before.
A representative agent uses capital \(k_t\) to produce \(y_t\) using the following production function:
\[y_t = k_t^{\alpha}\]
He chooses to consume an amount \(c_t \in ]0, y_t]\) and invests what remains:
\[i_t = y_t - c_t\]
He accumulates capital \(k_t\) according to:
\[k_{t+1} = \left( 1-\delta \right) k_{t} + i_{t}\]
where \(\delta\) is the depreciation rate and \(i_t\) is the amount invested.
The goal of the representative agent is to maximize:
\[\sum_{t\geq 0} \beta^t U(c_t)\]
where \(U(x)=\frac{x^{1-\gamma}}{1-\gamma}\) and \(\beta<1\) is the discount factor.
For now, we ignore the objective and assume that the saving rate \(s=\frac{c_t}{y_t}\) is constant over time.
Create a NamedTuple to hold parameter values \(\beta=0.96\), \(\delta=0.1\), \(\alpha=0.3\), \(\gamma=4\).
# your code here
(α = 0.3, β = 0.96, γ = 4, δ = 0.1, s = 0.2)
Write down the formula of function \(f\) such that \(k_{t+1}\): \(k_{t+1} = f(k_t)\).
\(k_{t+1} = (1-\delta) k_t + ( s \underbrace{k_t^\alpha}_{\text{production yesterday}} )\)
Define a function f(k::Float64, p::NamedTuple)::Float64 to represent \(f\) for a given calibration
# your code here
f (generic function with 1 method)
0.000006 seconds (1 allocation: 16 bytes)
0.30340677254400195
Write a function simulate(k0::Float64, T::Int, p::NamedTuple)::Vector{Float64} to compute the simulation over T periods starting from initial capital level k0.
# your code here
simulate (generic function with 1 method)
simulate_noalloc (generic function with 1 method)
0.010058 seconds (13.08 k allocations: 645.609 KiB, 99.68% compilation time)
Make a nice plot to illustrate the convergence. Do we get convergence from any initial level of capital?
# your code here
# different starting points
T = 100
tv = 0:T
kv1 = simulate(0.2, T, model);
kv2 = simulate(0.4, T, model);
kv3 = simulate(1.0, T, model);
pl = plot()
# plot!(pl,tv,kv1,label="k_0")
# plot!(pl,tv,kv1,label="\$k_0\$") # escape the dollar sign to avoid string interpolation
# better : use latexstrings library
plot!(pl,tv,kv1,label=L"k_0=0.2") # escape the dollar sign to avoid string interpolation
plot!(pl,tv,kv2,label=L"k_0=0.4")
plot!(pl,tv,kv3,label=L"k_0=1.0")3-element Vector{Vector{Float64}}:
[0.2, 0.30340677254400195, 0.4129080792968781, 0.525003373019628, 0.6373491155565568, 0.7483344417178636, 0.856841626057419, 0.9620988898971137, 1.0635841029776287, 1.1609587708409257 … 2.6873040218731723, 2.6876186883735818, 2.6879113388853018, 2.6881835130861362, 2.6884366430712516, 2.6886720608576273, 2.688891005366757, 2.689094628921639, 2.6892840032916374, 2.6894601253165105]
[0.4, 0.5119315585864748, 0.6243422704616431, 0.7355508583035453, 0.8443911415579223, 0.9500568333602588, 1.0520006449771238, 1.1498654505051582, 1.2434355847290326, 1.3326014179604118 … 2.687878421679744, 2.6881528990807855, 2.6884081711777905, 2.688645581245582, 2.6888663786779268, 2.68907172553918, 2.689262702660023, 2.689440315308841, 2.6896054984681297, 2.6897591217433026]
[1.0, 1.1, 1.195801151884219, 1.2872430129191352, 1.3742574618933996, 1.456845771393547, 1.5350611815735393, 1.6089955116075123, 1.6787687913320717, 1.7445211874595348 … 2.689166098397878, 2.689350471394512, 2.6895219419408285, 2.689681412713881, 2.689829723270148, 2.6899676544549416, 2.6900959325043807, 2.69021523286128, 2.6903261837248396, 2.6904293693526475]
7-element Vector{Tuple{Float64, Vector{Float64}}}:
(0.5, [0.5, 0.6124504792712471, 0.7238493517042889, 0.832984403877418, 0.9390166705127817, 1.041375090175603, 1.139684956743144, 1.233717469453318, 1.3233531316502873, 1.40855461086888 … 2.688124717954504, 2.688381961924404, 2.688621205942895, 2.6888437090435797, 2.6890506422578495, 2.68924309475745, 2.6894220795694443, 2.689588538893184, 2.689743349046873, 2.6898873250694084])
(1.0, [1.0, 1.1, 1.195801151884219, 1.2872430129191352, 1.3742574618933996, 1.456845771393547, 1.5350611815735393, 1.6089955116075123, 1.6787687913320717, 1.7445211874595348 … 2.689166098397878, 2.689350471394512, 2.6895219419408285, 2.689681412713881, 2.689829723270148, 2.6899676544549416, 2.6900959325043807, 2.69021523286128, 2.6903261837248396, 2.6904293693526475])
(1.5, [1.5, 1.5758693870913711, 1.6475201583781263, 1.7150841935587584, 1.7787098808849766, 1.8385565989758454, 1.8947904001991414, 1.9475806400433953, 1.9970973557459901, 2.0435092411105487 … 2.690038701794708, 2.690162007527074, 2.6902766834944245, 2.6903833335592306, 2.6904825193434627, 2.6905747631813886, 2.690660550866222, 2.6907403342049774, 2.6908145333948923, 2.6908835392338535])
(2.0, [2.0, 2.0462288826689834, 2.089528674917447, 2.1300608401704926, 2.167981873889157, 2.2034426980783923, 2.236588248806851, 2.2675572178060395, 2.2964819166036654, 2.323488237574935 … 2.6908188642471536, 2.6908875669597023, 2.6909514609901906, 2.691010882877752, 2.691066145613052, 2.6911175402854264, 2.691165337614891, 2.691209789377058, 2.691251129728435, 2.691289576439058])
(2.5, [2.5, 2.5132764408668473, 2.5256439052536868, 2.5371632360808465, 2.5478914001362627, 2.55788170636122, 2.567184016288864, 2.5758449461261734, 2.5839080601599886, 2.591414055321149 … 2.6915374078420995, 2.691555815991904, 2.69157293560767, 2.691588856881855, 2.691603663694112, 2.6916174340530916, 2.691630240507338, 2.691642150527427, 2.691653226861366, 2.691663527865125])
(3.0, [3.0, 2.978077834063182, 2.957736712267823, 2.9388597852310765, 2.9213391975269687, 2.9050753518220396, 2.8899762381820255, 2.8759568222703935, 2.8629384868079684, 2.85084852124176 … 2.6922106739009313, 2.6921819530398157, 2.6921552427276807, 2.692130402214114, 2.692107300602852, 2.692085816161768, 2.692065835681197, 2.6920472538771976, 2.692029972836609, 2.6920139015009763])
(3.5, [3.5, 3.441239588644217, 3.3868796568970985, 3.3365748704315115, 3.2900088329017825, 3.246891465688538, 3.206956642848077, 3.169960055137818, 3.135677279705747, 3.103902034472177 … 2.6928486431769474, 2.6927752608377347, 2.692707015841194, 2.69264354849513, 2.692584524296366, 2.692529632166085, 2.6924785828088926, 2.6924311071869056, 2.692386955100806, 2.6923458938703417])
Dict{Float64, Vector{Float64}} with 7 entries:
2.0 => [2.0, 2.04623, 2.08953, 2.13006, 2.16798, 2.20344, 2.23659, 2.26756, 2…
0.5 => [0.5, 0.61245, 0.723849, 0.832984, 0.939017, 1.04138, 1.13968, 1.23372…
3.5 => [3.5, 3.44124, 3.38688, 3.33657, 3.29001, 3.24689, 3.20696, 3.16996, 3…
1.5 => [1.5, 1.57587, 1.64752, 1.71508, 1.77871, 1.83856, 1.89479, 1.94758, 1…
2.5 => [2.5, 2.51328, 2.52564, 2.53716, 2.54789, 2.55788, 2.56718, 2.57584, 2…
1.0 => [1.0, 1.1, 1.1958, 1.28724, 1.37426, 1.45685, 1.53506, 1.609, 1.67877,…
3.0 => [3.0, 2.97808, 2.95774, 2.93886, 2.92134, 2.90508, 2.88998, 2.87596, 2…
OrderedDict{Float64, Vector{Float64}} with 7 entries:
0.5 => [0.5, 0.61245, 0.723849, 0.832984, 0.939017, 1.04138, 1.13968, 1.23372…
1.0 => [1.0, 1.1, 1.1958, 1.28724, 1.37426, 1.45685, 1.53506, 1.609, 1.67877,…
1.5 => [1.5, 1.57587, 1.64752, 1.71508, 1.77871, 1.83856, 1.89479, 1.94758, 1…
2.0 => [2.0, 2.04623, 2.08953, 2.13006, 2.16798, 2.20344, 2.23659, 2.26756, 2…
2.5 => [2.5, 2.51328, 2.52564, 2.53716, 2.54789, 2.55788, 2.56718, 2.57584, 2…
3.0 => [3.0, 2.97808, 2.95774, 2.93886, 2.92134, 2.90508, 2.88998, 2.87596, 2…
3.5 => [3.5, 3.44124, 3.38688, 3.33657, 3.29001, 3.24689, 3.20696, 3.16996, 3…
UndefVarError: `each` not defined in `Main` Suggestion: check for spelling errors or missing imports. Stacktrace: [1] top-level scope @ ./In[24]:2 [2] eval(m::Module, e::Any) @ Core ./boot.jl:489
"This is a string. You can refer to external values inside: 100"
Suppose you were interested in using f to compute the steady-state. What would you propose to measure convergence speed? To speed-up convergence? Implement these ideas.
# your code here
UndefVarError: `p` not defined in `Main` Suggestion: check for spelling errors or missing imports. Stacktrace: [1] eval(m::Module, e::Any) @ Core ./boot.jl:489
compute_steadystate (generic function with 1 method)
Converged in 228 iterations
0.028495 seconds (15.55 k allocations: 813.156 KiB, 19.92% gc time, 99.51% compilation time)
2.6918002585299976
compute_steadystate_new (generic function with 1 method)
Converged in 228 iterations
0.011282 seconds (9.09 k allocations: 457.492 KiB, 99.02% compilation time)
2.6918002585299976
Converged in 15 iterations
0.000088 seconds (18 allocations: 640 bytes)
2.6918003470184395
function compute_steadystate_2(k0, T, p ; τ_η=1e-8)
# store the result in a vector
# η = 0.0 # defining \eta puts it in the local scope
# local η
for t ∈ 1:T
k1 = f(k0, p)
η = abs(k1-k0)
k0 = k1
if η<τ_η
break # stops the for loop
end
end
# println(η) # η defined inside the loop
# if t>=T
# error("No convergence")
# end
return k0
end