11#=
22utilities.jl
33
4- Provides a collection of utility tools for working with dynamic factor
5- models, such as simulation, filtering, and smoothing.
4+ Provides a collection of utility tools for working with dynamic factor
5+ models, such as simulation, filtering, and smoothing.
66
77@author: Quint Wiersma <q.wiersma@vu.nl>
88
@@ -16,10 +16,10 @@ Select a sample `sample` of the data from the dynamic factor model `model`.
1616"""
1717function select_sample (model:: DynamicFactorModel , sample:: AbstractUnitRange )
1818 μ = select_sample (mean (model), sample)
19- ε = select_sample (errors (model), sample )
19+ ε = copy (errors (model))
2020 F = select_sample (process (model), sample)
2121
22- return DynamicFactorModel (data (model)[:,sample], μ, ε, F)
22+ return DynamicFactorModel (data (model)[:, sample], μ, ε, F)
2323end
2424
2525"""
2828Select a sample `sample` of the data from the mean model `μ`.
2929"""
3030select_sample (μ:: ZeroMean , sample:: AbstractUnitRange ) = ZeroMean (μ. type, μ. n)
31- select_sample (μ:: Exogenous , sample:: AbstractUnitRange ) = Exogenous (regressors (μ)[:,sample], size (slopes (μ), 1 ))
32-
33- """
34- select_sample(ε, sample) -> ε
35-
36- Select a sample `sample` of the data from the error model `ε`.
37- """
38- select_sample (ε:: Simple , sample:: AbstractUnitRange ) = Simple (size (resid (ε), 1 ), length (sample), type= eltype (resid (ε)))
39- select_sample (ε:: SpatialAutoregression , sample:: AbstractUnitRange ) = SpatialAutoregression (size (resid (ε), 1 ), length (sample), copy (weights (ε)), spatial= length (spatial (ε)) == 1 ? :homo : :hetero , type= eltype (resid (ε)))
40- select_sample (ε:: SpatialMovingAverage , sample:: AbstractUnitRange ) = SpatialMovingAverage (size (resid (ε), 1 ), length (sample), copy (weights (ε)), spatial= length (spatial (ε)) == 1 ? :homo : :hetero , type= eltype (resid (ε)))
31+ function select_sample (μ:: Exogenous , sample:: AbstractUnitRange )
32+ Exogenous (regressors (μ)[:, sample], size (slopes (μ), 1 ))
33+ end
4134
4235"""
4336 select_sample(F, sample) -> F
4437
4538Select a sample `sample` of the data from the dynamic factor process `F`.
4639"""
47- select_sample (F:: UnrestrictedStationaryIdentified , sample:: AbstractUnitRange ) = UnrestrictedStationary ((size (loadings (F), 1 ), length (sample), size (F)), dependence= :identified , type= eltype (factors (F)))
48- select_sample (F:: UnrestrictedStationaryFull , sample:: AbstractUnitRange ) = UnrestrictedStationary ((size (loadings (F), 1 ), length (sample), size (F)), dependence= :full , type= eltype (factors (F)))
49- select_sample (F:: UnrestrictedUnitRoot , sample:: AbstractUnitRange ) = UnrestrictedUnitRoot ((size (loadings (F), 1 ), length (sample), size (F)), type= eltype (factors (F)))
50- select_sample (F:: NelsonSiegelStationary , sample:: AbstractUnitRange ) = NelsonSiegelStationary (length (sample), maturities (F), type= eltype (factors (F)))
51- select_sample (F:: NelsonSiegelUnitRoot , sample:: AbstractUnitRange ) = NelsonSiegelUnitRoot (length (sample), maturities (F), type= eltype (factors (F)))
40+ function select_sample (F:: UnrestrictedStationaryIdentified , sample:: AbstractUnitRange )
41+ UnrestrictedStationary ((size (loadings (F), 1 ), length (sample), size (F)),
42+ dependence = :identified , type = eltype (factors (F)))
43+ end
44+ function select_sample (F:: UnrestrictedStationaryFull , sample:: AbstractUnitRange )
45+ UnrestrictedStationary ((size (loadings (F), 1 ), length (sample), size (F)),
46+ dependence = :full , type = eltype (factors (F)))
47+ end
48+ function select_sample (F:: UnrestrictedUnitRoot , sample:: AbstractUnitRange )
49+ UnrestrictedUnitRoot ((size (loadings (F), 1 ), length (sample), size (F)),
50+ type = eltype (factors (F)))
51+ end
52+ function select_sample (F:: NelsonSiegelStationary , sample:: AbstractUnitRange )
53+ NelsonSiegelStationary (length (sample), maturities (F), type = eltype (factors (F)))
54+ end
55+ function select_sample (F:: NelsonSiegelUnitRoot , sample:: AbstractUnitRange )
56+ NelsonSiegelUnitRoot (length (sample), maturities (F), type = eltype (factors (F)))
57+ end
5258
5359"""
54- simulate(F; burn=100, rng= Xoshiro()) -> sim
60+ simulate(F, S; rng = Xoshiro()) -> f
5561
56- Simulate the dynamic factors from the dynamic factor process `F`
57- with a burn-in period of `burn` using the random number generator `rng`.
62+ Simulate the dynamic factors from the dynamic factor process `F` `S` times using the random
63+ number generator `rng`.
5864"""
59- function simulate (F:: AbstractFactorProcess ; burn:: Integer = 100 , rng:: AbstractRNG = Xoshiro ())
60- # burn-in
61- f_prev = rand (rng, dist (F))
62- f_next = similar (f_prev)
63- for _ = 1 : burn
64- f_next .= dynamics (F) * f_prev + rand (rng, dist (F))
65- f_prev .= f_next
66- end
67-
68- # simulate data
69- F_sim = copy (F)
70- for (t, ft) ∈ pairs (eachcol (factors (F_sim)))
71- if t == 1
72- ft .= f_prev
65+ function simulate (F:: AbstractFactorProcess , S:: Integer ; rng:: AbstractRNG = Xoshiro ())
66+ R = size (loadings (F), 2 )
67+ f = similar (factors (F), R, S)
68+ dist = MvNormal (cov (F))
69+ for (s, fs) in pairs (eachcol (f))
70+ if s == 1
71+ # initial condition
72+ fs .= rand (rng, dist)
7373 else
74- ft .= dynamics (F) * factors (F_sim) [:,t - 1 ] + rand (rng, dist (F) )
74+ fs .= dynamics (F) * f [:, s - 1 ] + rand (rng, dist)
7575 end
76+
7677 end
7778
78- return F_sim
79+ return f
7980end
8081
8182"""
82- simulate(ε; rng= Xoshiro()) -> sim
83+ simulate(ε, S ; rng = Xoshiro()) -> e
8384
84- Simulate from the error distribution `ε` using the random number generator
85- `rng`.
85+ Simulate from the error distribution `ε` `S` times using the random number generator `rng`.
8686"""
87- simulate (ε:: Simple ; rng:: AbstractRNG = Xoshiro ()) = Simple (rand (rng, dist (ε), size (resid (ε), 2 )), MvNormal (Diagonal (var (ε))))
88- function simulate (ε:: SpatialAutoregression ; rng:: AbstractRNG = Xoshiro ())
89- e_sim = similar (resid (ε))
90- for et ∈ eachcol (e_sim)
91- et .= poly (ε) \ rand (rng, dist (ε))
87+ function simulate (ε:: Simple , S:: Integer ; rng:: AbstractRNG = Xoshiro ())
88+ rand (rng, MvNormal (cov (ε)), S)
89+ end
90+ function simulate (ε:: SpatialAutoregression , S:: Integer ; rng:: AbstractRNG = Xoshiro ())
91+ e = rand (rng, MvNormal (cov (ε)), S)
92+ G = poly (ε)
93+ for es in eachcol (e)
94+ es .= G \ es
9295 end
9396
94- return SpatialAutoregression (e_sim, MvNormal ( Diagonal ( var (ε))), copy ( spatial (ε)), ε . ρ_max, copy ( weights (ε)))
97+ return e
9598end
96- function simulate (ε:: SpatialMovingAverage ; rng:: AbstractRNG = Xoshiro ())
97- e_sim = similar (resid (ε))
98- for et ∈ eachcol (e_sim)
99- mul! (et, poly (ε), rand (rng, dist (ε)))
99+ function simulate (ε:: SpatialMovingAverage , S:: Integer ; rng:: AbstractRNG = Xoshiro ())
100+ e = rand (rng, MvNormal (cov (ε)), S)
101+ G = poly (ε)
102+ for es in eachcol (e)
103+ es .= G * es
100104 end
101105
102- return SpatialMovingAverage (e_sim, MvNormal ( Diagonal ( var (ε))), copy ( spatial (ε)), ε . ρ_max, copy ( weights (ε)))
106+ return e
103107end
104108
105109"""
@@ -110,15 +114,15 @@ following the approach of Jungbacker and Koopman (2015).
110114"""
111115function collapse (model:: DynamicFactorModel )
112116 # active factors
113- active = [! all (iszero, λ) for λ ∈ eachcol (loadings (model))]
117+ active = [! all (iszero, λ) for λ in eachcol (loadings (model))]
114118
115119 # collapsing matrix
116120 H = cov (model)
117121 if all (active)
118122 C = (H \ loadings (model))' * loadings (model)
119123 Z_basis = (C \ loadings (model)' )'
120124 else
121- Z_basis = loadings (model)[:,active]
125+ Z_basis = loadings (model)[:, active]
122126 end
123127 A_low = (H \ Z_basis)'
124128
@@ -136,7 +140,7 @@ function state_space(model::DynamicFactorModel)
136140 Ty = eltype (data (model))
137141
138142 # active factors
139- active = [! all (iszero, λ) for λ ∈ eachcol (loadings (model))]
143+ active = [! all (iszero, λ) for λ in eachcol (loadings (model))]
140144
141145 # collapsing matrix
142146 if any (active)
@@ -182,7 +186,7 @@ function _filter(y, Z, d, H, T, Q, a1, P1)
182186 P[1 ] = P1
183187
184188 # filter
185- for (t, yt) ∈ pairs (eachcol (y))
189+ for (t, yt) in pairs (eachcol (y))
186190 # forecast error
187191 v[t] = yt - Z * a[t] - view (d, :, t)
188192 F[t] = Z * P[t] * Z' + H
@@ -192,8 +196,8 @@ function _filter(y, Z, d, H, T, Q, a1, P1)
192196
193197 # prediction
194198 if t < n
195- a[t+ 1 ] = T * a[t] + K[t] * v[t]
196- P[t+ 1 ] = T * P[t] * (T - K[t] * Z)' + Q
199+ a[t + 1 ] = T * a[t] + K[t] * v[t]
200+ P[t + 1 ] = T * P[t] * (T - K[t] * Z)' + Q
197201 end
198202 end
199203
@@ -242,7 +246,7 @@ function smoother(model::DynamicFactorModel)
242246 L = similar (P1)
243247
244248 # smoother
245- for t ∈ reverse (eachindex (a))
249+ for t in reverse (eachindex (a))
246250 L .= T - K[t] * Z
247251
248252 # backward recursion
@@ -252,7 +256,7 @@ function smoother(model::DynamicFactorModel)
252256 # smoothing
253257 α̂[t] = a[t] + P[t] * r
254258 V[t] = P[t] - P[t] * N * P[t]
255- t > 1 && (Γ[t- 1 ] = I - P[t] * N)
259+ t > 1 && (Γ[t - 1 ] = I - P[t] * N)
256260 t < length (a) && (Γ[t] *= L * P[t])
257261 end
258262
265269Forecast the mean model `μ` `periods` ahead.
266270"""
267271forecast (μ:: AbstractMeanSpecification , periods:: Integer ) = error (" forecast for $(Base. typename (typeof (μ)). wrapper) not implemented." )
268- forecast (μ:: ZeroMean , periods:: Integer ) = Zeros (μ. type, μ. n, periods)
272+ forecast (μ:: ZeroMean , periods:: Integer ) = Zeros (μ. type, μ. n, periods)
0 commit comments