Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Time series model update #278

Merged
merged 28 commits into from
Jan 5, 2024
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
0dbf48d
updated lectures
annabellasd Sep 26, 2023
ab24bd6
Update seir_model.md
annabellasd Sep 26, 2023
f0317ce
update
annabellasd Sep 28, 2023
0603548
Update covid_sde.md
annabellasd Sep 29, 2023
4b3477e
Update covid_sde.md
annabellasd Oct 5, 2023
088e6a2
spacing updates
annabellasd Oct 6, 2023
b4cf4ee
updates
annabellasd Oct 11, 2023
d034c04
getting back so only changing one lecture
annabellasd Oct 11, 2023
01cdd57
updated; Trang's comments
annabellasd Nov 6, 2023
2df15c9
tiny update
annabellasd Nov 9, 2023
dc8565f
MAINT: run cache monthly to avoid stale cache
mmcky Dec 20, 2023
51842d1
MAINT: Upgrade quantecon-book-theme and python=3.11 (#281)
mmcky Dec 30, 2023
4b7cf91
edit unicode conversion (#280)
htrangtr Dec 30, 2023
bf0ae39
Julia 1.10 support (#283)
jlperla Jan 3, 2024
6d3b093
Multi agent models update (#276)
annabellasd Jan 4, 2024
8a91e66
Dynamic programming squared update (#277)
annabellasd Jan 4, 2024
202e764
updated lectures
annabellasd Sep 26, 2023
8c3555a
Update seir_model.md
annabellasd Sep 26, 2023
60f7449
update
annabellasd Sep 28, 2023
b48604a
Update covid_sde.md
annabellasd Sep 29, 2023
563e60a
Update covid_sde.md
annabellasd Oct 5, 2023
ac31de6
spacing updates
annabellasd Oct 6, 2023
1e18eda
updates
annabellasd Oct 11, 2023
6fd6bf8
getting back so only changing one lecture
annabellasd Oct 11, 2023
d34c2af
updated; Trang's comments
annabellasd Nov 6, 2023
3dfb2ee
tiny update
annabellasd Nov 9, 2023
6af52ca
Merge branch 'time_series_model_update' of https://github.com/QuantEc…
jlperla Jan 4, 2024
234bb70
Final format cleanup
jlperla Jan 5, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions lectures/continuous_time/covid_sde.md
Original file line number Diff line number Diff line change
Expand Up @@ -604,5 +604,4 @@ In this case, there are significant differences between the early and late death

This bleak simulation has assumed that no individuals has long-term immunity and that there will be no medical advancements on that time horizon - both of which are unlikely to be true.

Nevertheless, it suggests that the timing of lifting lockdown has a more profound impact after 18 months if we allow stochastic shocks imperfect immunity.

Nevertheless, it suggests that the timing of lifting lockdown has a more profound impact after 18 months if we allow stochastic shocks imperfect immunity.
1 change: 0 additions & 1 deletion lectures/continuous_time/seir_model.md
Original file line number Diff line number Diff line change
Expand Up @@ -517,4 +517,3 @@ Despite its richness, the model above is fully deterministic. The policy $\bar{
One way that randomness can lead to aggregate fluctuations is the granularity that comes through the discreteness of individuals. This topic, the connection between SDEs and the Langevin equations typically used in the approximation of chemical reactions in well-mixed media is explored in further lectures on continuous time Markov chains.

Instead, in the {doc}`next lecture <covid_sde>`, we will concentrate on randomness that comes from aggregate changes in behavior or policy.

24 changes: 12 additions & 12 deletions lectures/time_series_models/additive_functionals.md
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,7 @@ function AMF_LSS_VAR(A, B, D, F = nothing; ν = nothing)
# construct BIG state space representation
lss = construct_ss(A, B, D, F, ν, nx, nk, nm)
annabellasd marked this conversation as resolved.
Show resolved Hide resolved

return (A = A, B = B, D = D, F = F, ν = ν, nx = nx, nk = nk, nm = nm, lss = lss)
return (;A, B, D, F, ν, nx, nk, nm, lss)
annabellasd marked this conversation as resolved.
Show resolved Hide resolved
end

AMF_LSS_VAR(A, B, D) =
annabellasd marked this conversation as resolved.
Show resolved Hide resolved
Expand Down Expand Up @@ -335,14 +335,14 @@ function multiplicative_decomp(A, B, D, F, ν, nx)
end
annabellasd marked this conversation as resolved.
Show resolved Hide resolved
annabellasd marked this conversation as resolved.
Show resolved Hide resolved

function loglikelihood_path(amf, x, y)
@unpack A, B, D, F = amf
(;A, B, D, F) = amf
k, T = size(y)
FF = F * F'
FFinv = inv(FF)
temp = y[:, 2:end]-y[:, 1:end-1] - D*x[:, 1:end-1]
obs = temp .* FFinv .* temp
obssum = cumsum(obs)
scalar = (logdet(FF) + k * log()) * (1:T)
scalar = (logdet(FF) + k * log(2pi)) * (1:T)

return -(obssum + scalar) / 2
end
Expand All @@ -356,7 +356,7 @@ end
function plot_additive(amf, T; npaths = 25, show_trend = true)

# pull out right sizes so we know how to increment
@unpack nx, nk, nm = amf
(;nx, nk, nm) = amf
annabellasd marked this conversation as resolved.
Show resolved Hide resolved

# allocate space (nm is the number of additive functionals - we want npaths for each)
mpath = zeros(nm*npaths, T)
Expand Down Expand Up @@ -428,7 +428,7 @@ end

function plot_multiplicative(amf, T, npaths = 25, show_trend = true)
# pull out right sizes so we know how to increment
@unpack nx, nk, nm = amf
(;nx, nk, nm) = amf
annabellasd marked this conversation as resolved.
Show resolved Hide resolved
# matrices for the multiplicative decomposition
H, g, ν_tilde = multiplicative_decomp(A, B, D, F, ν, nx)
annabellasd marked this conversation as resolved.
Show resolved Hide resolved

Expand Down Expand Up @@ -508,7 +508,7 @@ end
function plot_martingales(amf, T, npaths = 25)

# pull out right sizes so we know how to increment
@unpack A, B, D, F, ν, nx, nk, nm = amf
(;A, B, D, F, ν, nx, nk, nm) = amf
annabellasd marked this conversation as resolved.
Show resolved Hide resolved
# matrices for the multiplicative decomposition
H, g, ν_tilde = multiplicative_decomp(A, B, D, F, ν, nx)
annabellasd marked this conversation as resolved.
Show resolved Hide resolved

Expand Down Expand Up @@ -571,7 +571,7 @@ function plot_given_paths(T, ypath, mpath, spath, tpath, mbounds, sbounds;
trange = 1:T

# allocate transpose
mpathᵀ = Matrix(mpath')
mpath_T = Matrix(mpath')

# create figure
plots=plot(layout = (2, 2), size = (800, 800))
Expand All @@ -589,7 +589,7 @@ function plot_given_paths(T, ypath, mpath, spath, tpath, mbounds, sbounds;

# plot martingale component
plot!(plots[2], trange, mpath[1, :], color = :magenta, label = "")
plot!(plots[2], trange, mpathᵀ, alpha = 0.45, color = :magenta, label = "")
plot!(plots[2], trange, mpath_T, alpha = 0.45, color = :magenta, label = "")
ub = mbounds[2, :]
lb = mbounds[1, :]
plot!(plots[2], ub, fillrange = lb, alpha = 0.25, color = :magenta, label = "")
annabellasd marked this conversation as resolved.
Show resolved Hide resolved
Expand Down Expand Up @@ -645,18 +645,18 @@ Random.seed!(42);
```

```{code-cell} julia
ϕ_1, ϕ_2, ϕ_3, ϕ_4 = 0.5, -0.2, 0, 0.5
σ = 0.01
phi_1, phi_2, phi_3, phi_4 = 0.5, -0.2, 0, 0.5
sigma = 0.01
ν = 0.01 # growth rate
annabellasd marked this conversation as resolved.
Show resolved Hide resolved

## A matrix should be n x n
A = [ϕ_1 ϕ_2 ϕ_3 ϕ_4;
A = [phi_1 phi_2 phi_3 phi_4;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

columns of matrix may need to be aligned

1 0 0 0;
0 1 0 0;
0 0 1 0]

# B matrix should be n x k
B = [σ, 0, 0, 0]
B = [sigma, 0, 0, 0]

D = [1 0 0 0] * A
F = [1, 0, 0, 0] ⋅ vec(B)
annabellasd marked this conversation as resolved.
Show resolved Hide resolved
annabellasd marked this conversation as resolved.
Show resolved Hide resolved
Expand Down
70 changes: 35 additions & 35 deletions lectures/time_series_models/arma.md
Original file line number Diff line number Diff line change
Expand Up @@ -237,10 +237,10 @@ plt_1=plot()
plt_2=plot()
plots = [plt_1, plt_2]

for (i, ϕ) in enumerate((0.8, -0.8))
for (i, phi) in enumerate((0.8, -0.8))
times = 0:16
acov = [ϕ.^k ./ (1 - ϕ.^2) for k in times]
label = L"autocovariance, $\phi = %$ϕ$"
acov = [phi.^k ./ (1 - phi.^2) for k in times]
label = L"autocovariance, $\phi = %$phi$"
plot!(plots[i], times, acov, color=:blue, lw=2, marker=:circle, markersize=3,
alpha=0.6, label=label)
plot!(plots[i], legend=:topright, xlabel="time", xlim=(0,15))
Expand All @@ -254,9 +254,9 @@ plot(plots[1], plots[2], layout=(2,1), size=(700,500))
tags: [remove-cell]
---
@testset begin
ϕ = 0.8
phi = 0.8
times = 0:16
acov = [ϕ.^k ./ (1 - ϕ.^2) for k in times]
acov = [phi.^k ./ (1 - phi.^2) for k in times]
@test acov[4] ≈ 1.422222222222223 # Can't access acov directly because of scoping.
@test acov[1] ≈ 2.7777777777777786
end
Expand Down Expand Up @@ -480,19 +480,19 @@ It is a nice exercise to verify that {eq}`ma1_sd_ed` and {eq}`ar1_sd_ed` are ind
Plotting {eq}`ar1_sd_ed` reveals the shape of the spectral density for the AR(1) model when $\phi$ takes the values 0.8 and -0.8 respectively

```{code-cell} julia
ar1_sd(ϕ, ω) = 1 ./ (1 .- 2 * ϕ * cos.(ω) .+ ϕ.^2)
ar1_sd(phi, omega) = 1 ./ (1 .- 2 * phi * cos.(omega) .+ phi.^2)

ω_s = range(0, π, length = 180)
omega_s = range(0, pi, length = 180)

plt_1=plot()
plt_2=plot()
plots=[plt_1, plt_2]

for (i, ϕ) in enumerate((0.8, -0.8))
sd = ar1_sd(ϕ, ω_s)
label = L"spectral density, $\phi = %$ϕ$"
plot!(plots[i], ω_s, sd, color=:blue, alpha=0.6, lw=2, label=label)
plot!(plots[i], legend=:top, xlabel="frequency", xlim=(0,π))
for (i, phi) in enumerate((0.8, -0.8))
sd = ar1_sd(phi, omega_s)
label = L"spectral density, $\phi = %$phi$"
plot!(plots[i], omega_s, sd, color=:blue, alpha=0.6, lw=2, label=label)
plot!(plots[i], legend=:top, xlabel="frequency", xlim=(0,pi))
end
plot(plots[1], plots[2], layout=(2,1), size=(700,500))
```
Expand All @@ -502,9 +502,9 @@ plot(plots[1], plots[2], layout=(2,1), size=(700,500))
tags: [remove-cell]
---
@testset begin
@test ar1_sd(0.8, ω_s)[18] ≈ 9.034248169239635
@test ar1_sd(-0.8, ω_s)[18] ≈ 0.3155260821833043
@test ω_s[1] == 0.0 && ω_s[end] ≈ π && length(ω_s) == 180 # Grid invariant.
@test ar1_sd(0.8, omega_s)[18] ≈ 9.034248169239635
@test ar1_sd(-0.8, omega_s)[18] ≈ 0.3155260821833043
@test omega_s[1] == 0.0 && omega_s[end] ≈ pi && length(omega_s) == 180 # Grid invariant.
end
```

Expand Down Expand Up @@ -536,20 +536,20 @@ products on the right-hand side of {eq}`sumpr` is large.
These ideas are illustrated in the next figure, which has $k$ on the horizontal axis

```{code-cell} julia
ϕ = -0.8
phi = -0.8
times = 0:16
y1 = [ϕ.^k ./ (1 - ϕ.^2) for k in times]
y2 = [cos.(π * k) for k in times]
y1 = [phi.^k ./ (1 - phi.^2) for k in times]
y2 = [cos.(pi * k) for k in times]
y3 = [a * b for (a, b) in zip(y1, y2)]

# Autocovariance when ϕ = -0.8
# Autocovariance when phi = -0.8
plt_1 = plot(times, y1, color=:blue, lw=2, marker=:circle, markersize=3,
alpha=0.6, label=L"\gamma(k)")
plot!(plt_1, seriestype=:hline, [0], linestyle=:dash, alpha=0.5,
lw=2, label="")
plot!(plt_1, legend=:topright, xlim=(0,15), yticks=[-2, 0, 2])

# Cycles at frequence π
# Cycles at frequence pi
plt_2 = plot(times, y2, color=:blue, lw=2, marker=:circle, markersize=3,
alpha=0.6, label=L"cos(\pi k)")
plot!(plt_2, seriestype=:hline, [0], linestyle=:dash, alpha=0.5,
Expand Down Expand Up @@ -583,20 +583,20 @@ not matched, the sequence $\gamma(k) \cos(\omega k)$ contains
both positive and negative terms, and hence the sum of these terms is much smaller

```{code-cell} julia
ϕ = -0.8
phi = -0.8
times = 0:16
y1 = [ϕ.^k ./ (1 - ϕ.^2) for k in times]
y2 = [cos.(π * k/3) for k in times]
y1 = [phi.^k ./ (1 - phi.^2) for k in times]
y2 = [cos.(pi * k/3) for k in times]
y3 = [a * b for (a, b) in zip(y1, y2)]

# Autocovariance when ϕ = -0.8
# Autocovariance when phi = -0.8
plt_1 = plot(times, y1, color=:blue, lw=2, marker=:circle, markersize=3,
alpha=0.6, label=L"\gamma(k)")
plot!(plt_1, seriestype=:hline, [0], linestyle=:dash, alpha=0.5,
lw=2, label="")
plot!(plt_1, legend=:topright, xlim=(0,15), yticks=[-2, 0, 2])

# Cycles at frequence π
# Cycles at frequence pi
plt_2 = plot(times, y2, color=:blue, lw=2, marker=:circle, markersize=3,
alpha=0.6, label=L"cos(\pi k/3)")
plot!(plt_2, seriestype=:hline, [0], linestyle=:dash, alpha=0.5,
Expand Down Expand Up @@ -755,7 +755,7 @@ using QuantEcon, Random
function plot_spectral_density(arma, plt)
(w, spect) = spectral_density(arma, two_pi=false)
plot!(plt, w, spect, lw=2, alpha=0.7,label="")
plot!(plt, title="Spectral density", xlim=(0,π),
plot!(plt, title="Spectral density", xlim=(0,pi),
xlabel="frequency", ylabel="spectrum", yscale=:log)
return plt
end
Expand Down Expand Up @@ -839,9 +839,9 @@ We'll use the model $X_t = 0.5 X_{t-1} + \epsilon_t - 0.8 \epsilon_{t-2}$

```{code-cell} julia
Random.seed!(42) # For reproducible results.
ϕ = 0.5;
θ = [0, -0.8];
arma = ARMA(ϕ, θ, 1.0)
phi = 0.5;
theta = [0, -0.8];
arma = ARMA(phi, theta, 1.0)
quad_plot(arma)
```

Expand All @@ -864,7 +864,7 @@ end
The call

```{code-block} julia
arma = ARMA(ϕ, θ, σ)
arma = ARMA(phi, theta, sigma)
```

creates an instance `arma` that represents the ARMA($p, q$) model
Expand All @@ -874,15 +874,15 @@ X_t = \phi_1 X_{t-1} + ... + \phi_p X_{t-p} +
\epsilon_t + \theta_1 \epsilon_{t-1} + ... + \theta_q \epsilon_{t-q}
$$

If `ϕ` and `θ` are arrays or sequences, then the interpretation will
If `phi` and `theta` are arrays or sequences, then the interpretation will
be

* `ϕ` holds the vector of parameters $(\phi_1, \phi_2,..., \phi_p)$
* `θ` holds the vector of parameters $(\theta_1, \theta_2,..., \theta_q)$
* `phi` holds the vector of parameters $(\phi_1, \phi_2,..., \phi_p)$
* `theta` holds the vector of parameters $(\theta_1, \theta_2,..., \theta_q)$

The parameter `σ` is always a scalar, the standard deviation of the white noise.
The parameter `sigma` is always a scalar, the standard deviation of the white noise.

We also permit `ϕ` and `θ` to be scalars, in which case the model will be interpreted as
We also permit `phi` and `theta` to be scalars, in which case the model will be interpreted as

$$
X_t = \phi X_{t-1} + \epsilon_t + \theta \epsilon_{t-1}
Expand Down
Loading
Loading