@@ -50,18 +50,26 @@ function fit!(
50
50
51
51
residuals_variances = get_variances (model, estimation_ε, coefs, components_indexes)
52
52
53
- T = typeof (model. y) <: Vector ? length (model. y) : size (model. y, 1 )
53
+ T = typeof (model. y) <: Vector ? length (model. y) : size (model. y, 1 )
54
54
55
- ε, fitted = get_fit_and_residuals (
56
- estimation_ε, coefs, model. X, valid_indexes, T
57
- )
55
+ ε, fitted = get_fit_and_residuals (estimation_ε, coefs, model. X, valid_indexes, T)
58
56
59
- if typeof (model. y) <: Vector
57
+ if typeof (model. y) <: Vector
60
58
output = Output (coefs, ε, fitted, residuals_variances, valid_indexes, components)
61
59
else
62
60
output = Output[]
63
61
for i in eachindex (coefs)
64
- push! (output, Output (coefs[i], ε[i], fitted[i], residuals_variances[i], valid_indexes, components[i]))
62
+ push! (
63
+ output,
64
+ Output (
65
+ coefs[i],
66
+ ε[i],
67
+ fitted[i],
68
+ residuals_variances[i],
69
+ valid_indexes,
70
+ components[i],
71
+ ),
72
+ )
65
73
end
66
74
end
67
75
return model. output = output
@@ -85,11 +93,13 @@ function forecast(
85
93
model:: StateSpaceLearningModel ,
86
94
steps_ahead:: Int ;
87
95
Exogenous_Forecast:: Matrix{Fl} = zeros (steps_ahead, 0 ),
88
- ):: Union{Matrix{<:AbstractFloat}, Vector{<:AbstractFloat}} where Fl <: AbstractFloat
89
-
90
- exog_idx = typeof (model. output) == Output ? model. output. components[" Exogenous_X" ][" Indexes" ] : model. output[1 ]. components[" Exogenous_X" ][" Indexes" ]
91
- @assert length (exog_idx) ==
92
- size (Exogenous_Forecast, 2 ) " If an exogenous matrix was utilized in the estimation procedure, it must be provided its prediction for the forecast procedure. If no exogenous matrix was utilized, Exogenous_Forecast must be missing"
96
+ ):: Union{Matrix{<:AbstractFloat},Vector{<:AbstractFloat}} where {Fl<: AbstractFloat }
97
+ exog_idx = if typeof (model. output) == Output
98
+ model. output. components[" Exogenous_X" ][" Indexes" ]
99
+ else
100
+ model. output[1 ]. components[" Exogenous_X" ][" Indexes" ]
101
+ end
102
+ @assert length (exog_idx) == size (Exogenous_Forecast, 2 ) " If an exogenous matrix was utilized in the estimation procedure, it must be provided its prediction for the forecast procedure. If no exogenous matrix was utilized, Exogenous_Forecast must be missing"
93
103
@assert size (Exogenous_Forecast, 1 ) == steps_ahead " Exogenous_Forecast must have the same number of rows as steps_ahead"
94
104
95
105
Exogenous_X = model. X[:, exog_idx]
@@ -109,11 +119,14 @@ function forecast(
109
119
)
110
120
111
121
if typeof (model. output) == Output
112
- return AbstractFloat .(complete_matrix[(end - steps_ahead + 1 ): end , :] * model. output. coefs)
122
+ return AbstractFloat .(
123
+ complete_matrix[(end - steps_ahead + 1 ): end , :] * model. output. coefs
124
+ )
113
125
else
114
126
prediction = Matrix {AbstractFloat} (undef, steps_ahead, length (model. output))
115
127
for i in eachindex (model. output)
116
- prediction[:, i] = complete_matrix[(end - steps_ahead + 1 ): end , :] * model. output[i]. coefs
128
+ prediction[:, i] =
129
+ complete_matrix[(end - steps_ahead + 1 ): end , :] * model. output[i]. coefs
117
130
end
118
131
return AbstractFloat .(prediction)
119
132
end
@@ -140,16 +153,19 @@ function simulate(
140
153
N_scenarios:: Int ;
141
154
Exogenous_Forecast:: Matrix{Fl} = zeros (steps_ahead, 0 ),
142
155
seasonal_innovation_simulation:: Int = 0 ,
143
- ):: Union{Vector{Matrix{<:AbstractFloat}}, Matrix{<:AbstractFloat}} where Fl <: AbstractFloat
156
+ ):: Union{Vector{Matrix{<:AbstractFloat}},Matrix{<:AbstractFloat}} where {Fl <: AbstractFloat }
144
157
@assert seasonal_innovation_simulation >= 0 " seasonal_innovation_simulation must be a non-negative integer"
145
158
@assert seasonal_innovation_simulation >= 0 " seasonal_innovation_simulation must be a non-negative integer"
146
159
147
- prediction = StateSpaceLearning. forecast (model, steps_ahead; Exogenous_Forecast= Exogenous_Forecast)
160
+ prediction = StateSpaceLearning. forecast (
161
+ model, steps_ahead; Exogenous_Forecast= Exogenous_Forecast
162
+ )
148
163
149
164
is_univariate = typeof (model. output) == StateSpaceLearning. Output
150
165
151
166
simulation_X = zeros (steps_ahead, 0 )
152
- valid_indexes = is_univariate ? model. output. valid_indexes : model. output[1 ]. valid_indexes
167
+ valid_indexes =
168
+ is_univariate ? model. output. valid_indexes : model. output[1 ]. valid_indexes
153
169
components_matrix = zeros (length (valid_indexes), 0 )
154
170
N_components = 1
155
171
@@ -168,54 +184,112 @@ function simulate(
168
184
169
185
if is_univariate
170
186
components_matrix = hcat (components_matrix, model. output. ε[valid_indexes])
171
- @assert N_components < length (model. y) // seasonal_innovation_simulation " The parameter `seasonal_innovation_simulation` is too large for the given dataset, please reduce it"
187
+ @assert N_components < length (model. y)// seasonal_innovation_simulation " The parameter `seasonal_innovation_simulation` is too large for the given dataset, please reduce it"
172
188
else
173
189
for i in eachindex (model. output)
174
190
components_matrix = hcat (components_matrix, model. output[i]. ε[valid_indexes])
175
191
end
176
- N_mv_components = N_components* length (model. output)
177
- @assert N_mv_components < size (model. y, 1 ) // seasonal_innovation_simulation " The parameter `seasonal_innovation_simulation` is too large for the given dataset, please reduce it"
192
+ N_mv_components = N_components * length (model. output)
193
+ @assert N_mv_components < size (model. y, 1 )// seasonal_innovation_simulation " The parameter `seasonal_innovation_simulation` is too large for the given dataset, please reduce it"
178
194
end
179
195
simulation_X = hcat (simulation_X, Matrix (1.0 * I, steps_ahead, steps_ahead))
180
196
components_matrix += rand (Normal (0 , 1 ), size (components_matrix)) ./ 1e9 # Make sure matrix is positive definite
181
197
182
198
MV_dist_vec = Vector {MvNormal} (undef, steps_ahead)
183
- o_noises = is_univariate ? zeros (steps_ahead, N_scenarios) : [zeros (steps_ahead, N_scenarios) for _ in 1 : length (model. output)]
199
+ o_noises = if is_univariate
200
+ zeros (steps_ahead, N_scenarios)
201
+ else
202
+ [zeros (steps_ahead, N_scenarios) for _ in 1 : length (model. output)]
203
+ end
184
204
185
205
if seasonal_innovation_simulation == 0
186
206
∑ = cov (components_matrix)
187
207
for i in 1 : steps_ahead
188
- MV_dist_vec[i] = is_univariate ? MvNormal (zeros (N_components), ∑) : MvNormal (zeros (N_mv_components), ∑)
208
+ MV_dist_vec[i] = if is_univariate
209
+ MvNormal (zeros (N_components), ∑)
210
+ else
211
+ MvNormal (zeros (N_mv_components), ∑)
212
+ end
189
213
end
190
214
191
215
if model. outlier
192
216
if is_univariate
193
- o_noises = rand (Normal (0 , std (model. output. components[" o" ][" Coefs" ])), steps_ahead, N_scenarios)
217
+ o_noises = rand (
218
+ Normal (0 , std (model. output. components[" o" ][" Coefs" ])),
219
+ steps_ahead,
220
+ N_scenarios,
221
+ )
194
222
else
195
- o_noises = [rand (Normal (0 , std (model. output[i]. components[" o" ][" Coefs" ])), steps_ahead, N_scenarios) for i in eachindex (model. output)]
223
+ o_noises = [
224
+ rand (
225
+ Normal (0 , std (model. output[i]. components[" o" ][" Coefs" ])),
226
+ steps_ahead,
227
+ N_scenarios,
228
+ ) for i in eachindex (model. output)
229
+ ]
196
230
end
197
231
end
198
232
else
199
233
start_seasonal_term = (size (components_matrix, 1 ) % seasonal_innovation_simulation)
200
234
for i in 1 : steps_ahead
201
- ∑ = cov (components_matrix[i + start_seasonal_term: seasonal_innovation_simulation: end , :])
202
- MV_dist_vec[i] = is_univariate ? MvNormal (zeros (N_components), ∑) : MvNormal (zeros (N_mv_components), ∑)
235
+ ∑ = cov (
236
+ components_matrix[
237
+ (i + start_seasonal_term): seasonal_innovation_simulation: end , :,
238
+ ],
239
+ )
240
+ MV_dist_vec[i] = if is_univariate
241
+ MvNormal (zeros (N_components), ∑)
242
+ else
243
+ MvNormal (zeros (N_mv_components), ∑)
244
+ end
203
245
if is_univariate
204
- model. outlier ? o_noises[i, :] = rand (Normal (0 , std (model. output. components[" o" ][" Coefs" ][i + start_seasonal_term: seasonal_innovation_simulation: end ])), N_scenarios) : nothing
246
+ if model. outlier
247
+ o_noises[i, :] = rand (
248
+ Normal (
249
+ 0 ,
250
+ std (
251
+ model. output. components[" o" ][" Coefs" ][(i + start_seasonal_term): seasonal_innovation_simulation: end ],
252
+ ),
253
+ ),
254
+ N_scenarios,
255
+ )
256
+ else
257
+ nothing
258
+ end
205
259
else
206
260
for j in eachindex (model. output)
207
- model. outlier ? o_noises[j][i, :] = rand (Normal (0 , std (model. output[j]. components[" o" ][" Coefs" ][i + start_seasonal_term: seasonal_innovation_simulation: end ])), N_scenarios) : nothing
261
+ if model. outlier
262
+ o_noises[j][i, :] = rand (
263
+ Normal (
264
+ 0 ,
265
+ std (
266
+ model. output[j]. components[" o" ][" Coefs" ][(i + start_seasonal_term): seasonal_innovation_simulation: end ],
267
+ ),
268
+ ),
269
+ N_scenarios,
270
+ )
271
+ else
272
+ nothing
273
+ end
208
274
end
209
275
end
210
- end
276
+ end
277
+ end
211
278
279
+ simulation = if is_univariate
280
+ AbstractFloat .(hcat ([prediction for _ in 1 : N_scenarios]. .. ))
281
+ else
282
+ [
283
+ AbstractFloat .(hcat ([prediction[:, i] for _ in 1 : N_scenarios]. .. )) for
284
+ i in eachindex (model. output)
285
+ ]
212
286
end
213
-
214
- simulation = is_univariate ? AbstractFloat .(hcat ([prediction for _ in 1 : N_scenarios]. .. )) : [AbstractFloat .(hcat ([prediction[:, i] for _ in 1 : N_scenarios]. .. )) for i in eachindex (model. output)]
215
287
if is_univariate
216
288
fill_simulation! (simulation, MV_dist_vec, o_noises, simulation_X)
217
289
else
218
- fill_simulation! (simulation, MV_dist_vec, o_noises, simulation_X, length (model_innovations))
290
+ fill_simulation! (
291
+ simulation, MV_dist_vec, o_noises, simulation_X, length (model_innovations)
292
+ )
219
293
simulation = Vector {Matrix{<:AbstractFloat}} (simulation)
220
294
end
221
295
0 commit comments