Skip to content

Commit b0fe56c

Browse files
Merge pull request #330 from LAMPSPUC/gb/treat-numerical-errors
Better treatment for numerical errors
2 parents 6a86265 + 07f2871 commit b0fe56c

File tree

5 files changed

+257
-196
lines changed

5 files changed

+257
-196
lines changed

Project.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
name = "StateSpaceModels"
22
uuid = "99342f36-827c-5390-97c9-d7f9ee765c78"
33
authors = ["raphaelsaavedra <[email protected]>, guilhermebodin <[email protected]>, mariohsouto"]
4-
version = "0.6.8"
4+
version = "0.6.9"
55

66
[deps]
77
Distributions = "31c24e10-a181-5473-b8eb-7969acd0382f"

src/filters/multivariate_kalman_filter.jl

Lines changed: 84 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -187,9 +187,10 @@ function update_P!(
187187
end
188188

189189
function update_llk!(kalman_state::MultivariateKalmanState{Fl}) where Fl
190-
kalman_state.llk -=
190+
kalman_state.llk -= (
191191
HALF_LOG_2_PI + 0.5 * (logdet(kalman_state.F) +
192192
kalman_state.v' * inv(kalman_state.F) * kalman_state.v)
193+
)
193194
return kalman_state
194195
end
195196

@@ -301,21 +302,26 @@ function filter_recursions!(
301302
steadystate_tol::Fl,
302303
skip_llk_instants::Int,
303304
) where Fl
304-
RQR = sys.R * sys.Q * sys.R'
305-
@inbounds for t in 1:size(sys.y, 1)
306-
update_kalman_state!(
307-
kalman_state,
308-
sys.y[t, :],
309-
sys.Z,
310-
sys.T,
311-
sys.H,
312-
RQR,
313-
sys.d,
314-
sys.c,
315-
skip_llk_instants,
316-
steadystate_tol,
317-
t,
318-
)
305+
try
306+
RQR = sys.R * sys.Q * sys.R'
307+
@inbounds for t in 1:size(sys.y, 1)
308+
update_kalman_state!(
309+
kalman_state,
310+
sys.y[t, :],
311+
sys.Z,
312+
sys.T,
313+
sys.H,
314+
RQR,
315+
sys.d,
316+
sys.c,
317+
skip_llk_instants,
318+
steadystate_tol,
319+
t,
320+
)
321+
end
322+
catch
323+
@error("Numerical error when applying Kalman filter euqations, the current state is: $kalman_state")
324+
rethrow()
319325
end
320326
return kalman_state.llk
321327
end
@@ -327,20 +333,25 @@ function filter_recursions!(
327333
steadystate_tol::Fl,
328334
skip_llk_instants::Int,
329335
) where Fl
330-
@inbounds for t in 1:size(sys.y, 1)
331-
update_kalman_state!(
332-
kalman_state,
333-
sys.y[t, :],
334-
sys.Z[t],
335-
sys.T[t],
336-
sys.H[t],
337-
sys.R[t],
338-
sys.Q[t],
339-
sys.d[t],
340-
sys.c[t],
341-
skip_llk_instants,
342-
t,
343-
)
336+
try
337+
@inbounds for t in 1:size(sys.y, 1)
338+
update_kalman_state!(
339+
kalman_state,
340+
sys.y[t, :],
341+
sys.Z[t],
342+
sys.T[t],
343+
sys.H[t],
344+
sys.R[t],
345+
sys.Q[t],
346+
sys.d[t],
347+
sys.c[t],
348+
skip_llk_instants,
349+
t,
350+
)
351+
end
352+
catch
353+
@error("Numerical error when applying Kalman filter euqations, the current state is: $kalman_state")
354+
rethrow()
344355
end
345356
return kalman_state.llk
346357
end
@@ -352,23 +363,28 @@ function filter_recursions!(
352363
steadystate_tol::Fl,
353364
skip_llk_instants::Int,
354365
) where Fl
355-
RQR = sys.R * sys.Q * sys.R'
356-
save_a1_P1_in_filter_output!(filter_output, kalman_state)
357-
@inbounds for t in 1:size(sys.y, 1)
358-
update_kalman_state!(
359-
kalman_state,
360-
sys.y[t, :],
361-
sys.Z,
362-
sys.T,
363-
sys.H,
364-
RQR,
365-
sys.d,
366-
sys.c,
367-
skip_llk_instants,
368-
steadystate_tol,
369-
t,
370-
)
371-
save_kalman_state_in_filter_output!(filter_output, kalman_state, t)
366+
try
367+
RQR = sys.R * sys.Q * sys.R'
368+
save_a1_P1_in_filter_output!(filter_output, kalman_state)
369+
@inbounds for t in 1:size(sys.y, 1)
370+
update_kalman_state!(
371+
kalman_state,
372+
sys.y[t, :],
373+
sys.Z,
374+
sys.T,
375+
sys.H,
376+
RQR,
377+
sys.d,
378+
sys.c,
379+
skip_llk_instants,
380+
steadystate_tol,
381+
t,
382+
)
383+
save_kalman_state_in_filter_output!(filter_output, kalman_state, t)
384+
end
385+
catch
386+
@error("Numerical error when applying Kalman filter euqations, the current state is: $kalman_state")
387+
rethrow()
372388
end
373389
return filter_output
374390
end
@@ -380,22 +396,27 @@ function filter_recursions!(
380396
steadystate_tol::Fl,
381397
skip_llk_instants::Int,
382398
) where Fl
383-
save_a1_P1_in_filter_output!(filter_output, kalman_state)
384-
@inbounds for t in 1:size(sys.y, 1)
385-
update_kalman_state!(
386-
kalman_state,
387-
sys.y[t, :],
388-
sys.Z[t],
389-
sys.T[t],
390-
sys.H[t],
391-
sys.R[t],
392-
sys.Q[t],
393-
sys.d[t],
394-
sys.c[t],
395-
skip_llk_instants,
396-
t,
397-
)
398-
save_kalman_state_in_filter_output!(filter_output, kalman_state, t)
399+
try
400+
save_a1_P1_in_filter_output!(filter_output, kalman_state)
401+
@inbounds for t in 1:size(sys.y, 1)
402+
update_kalman_state!(
403+
kalman_state,
404+
sys.y[t, :],
405+
sys.Z[t],
406+
sys.T[t],
407+
sys.H[t],
408+
sys.R[t],
409+
sys.Q[t],
410+
sys.d[t],
411+
sys.c[t],
412+
skip_llk_instants,
413+
t,
414+
)
415+
save_kalman_state_in_filter_output!(filter_output, kalman_state, t)
416+
end
417+
catch
418+
@error("Numerical error when applying Kalman filter euqations, the current state is: $kalman_state")
419+
rethrow()
399420
end
400421
return filter_output
401422
end

src/filters/scalar_kalman_filter.jl

Lines changed: 42 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -191,21 +191,26 @@ function filter_recursions!(
191191
steadystate_tol::Fl,
192192
skip_llk_instants::Int,
193193
) where Fl
194-
RQR = sys.R[1] * sys.Q[1] * sys.R[1]
195-
@inbounds for t in eachindex(sys.y)
196-
scalar_update_kalman_state!(
197-
kalman_state,
198-
sys.y[t],
199-
sys.Z[1],
200-
sys.T[1],
201-
sys.H,
202-
RQR,
203-
sys.d,
204-
sys.c[1],
205-
skip_llk_instants,
206-
steadystate_tol,
207-
t,
208-
)
194+
try
195+
RQR = sys.R[1] * sys.Q[1] * sys.R[1]
196+
@inbounds for t in eachindex(sys.y)
197+
scalar_update_kalman_state!(
198+
kalman_state,
199+
sys.y[t],
200+
sys.Z[1],
201+
sys.T[1],
202+
sys.H,
203+
RQR,
204+
sys.d,
205+
sys.c[1],
206+
skip_llk_instants,
207+
steadystate_tol,
208+
t,
209+
)
210+
end
211+
catch
212+
@error("Numerical error when applying Kalman filter euqations, the current state is: $kalman_state")
213+
rethrow()
209214
end
210215
return kalman_state.llk
211216
end
@@ -217,23 +222,28 @@ function filter_recursions!(
217222
steadystate_tol::Fl,
218223
skip_llk_instants::Int,
219224
) where Fl
220-
RQR = sys.R[1] * sys.Q[1] * sys.R[1]
221-
save_a1_P1_in_filter_output!(filter_output, kalman_state)
222-
@inbounds for t in eachindex(sys.y)
223-
scalar_update_kalman_state!(
224-
kalman_state,
225-
sys.y[t],
226-
sys.Z[1],
227-
sys.T[1],
228-
sys.H,
229-
RQR,
230-
sys.d,
231-
sys.c[1],
232-
skip_llk_instants,
233-
steadystate_tol,
234-
t,
235-
)
236-
save_kalman_state_in_filter_output!(filter_output, kalman_state, t)
225+
try
226+
RQR = sys.R[1] * sys.Q[1] * sys.R[1]
227+
save_a1_P1_in_filter_output!(filter_output, kalman_state)
228+
@inbounds for t in eachindex(sys.y)
229+
scalar_update_kalman_state!(
230+
kalman_state,
231+
sys.y[t],
232+
sys.Z[1],
233+
sys.T[1],
234+
sys.H,
235+
RQR,
236+
sys.d,
237+
sys.c[1],
238+
skip_llk_instants,
239+
steadystate_tol,
240+
t,
241+
)
242+
save_kalman_state_in_filter_output!(filter_output, kalman_state, t)
243+
end
244+
catch
245+
@error("Numerical error when applying Kalman filter euqations, the current state is: $kalman_state")
246+
rethrow()
237247
end
238248
return filter_output
239249
end

src/filters/sparse_univariate_kalman_filter.jl

Lines changed: 47 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,7 @@ end
180180

181181
function update_llk!(kalman_state::SparseUnivariateKalmanState{Fl}) where Fl
182182
kalman_state.llk -= (
183-
HALF_LOG_2_PI + (log(kalman_state.F) + kalman_state.v^2 / kalman_state.F) / 2
183+
HALF_LOG_2_PI + 0.5 * (log(kalman_state.F) + kalman_state.v^2 / kalman_state.F)
184184
)
185185
return kalman_state
186186
end
@@ -255,23 +255,28 @@ function filter_recursions!(
255255
steadystate_tol::Fl,
256256
skip_llk_instants::Int,
257257
) where Fl
258-
RQR = sys.R * sys.Q * sys.R'
259-
T_sparse = sparse(sys.T)
260-
Z_sparse = sparse(sys.Z)
261-
@inbounds for t in eachindex(sys.y)
262-
update_kalman_state!(
263-
kalman_state,
264-
sys.y[t],
265-
Z_sparse,
266-
T_sparse,
267-
sys.H,
268-
RQR,
269-
sys.d,
270-
sys.c,
271-
skip_llk_instants,
272-
steadystate_tol,
273-
t,
274-
)
258+
try
259+
RQR = sys.R * sys.Q * sys.R'
260+
T_sparse = sparse(sys.T)
261+
Z_sparse = sparse(sys.Z)
262+
@inbounds for t in eachindex(sys.y)
263+
update_kalman_state!(
264+
kalman_state,
265+
sys.y[t],
266+
Z_sparse,
267+
T_sparse,
268+
sys.H,
269+
RQR,
270+
sys.d,
271+
sys.c,
272+
skip_llk_instants,
273+
steadystate_tol,
274+
t,
275+
)
276+
end
277+
catch
278+
@error("Numerical error when applying Kalman filter euqations, the current state is: $kalman_state")
279+
rethrow()
275280
end
276281
return kalman_state.llk
277282
end
@@ -283,25 +288,30 @@ function filter_recursions!(
283288
steadystate_tol::Fl,
284289
skip_llk_instants::Int,
285290
) where Fl
286-
RQR = sys.R * sys.Q * sys.R'
287-
T_sparse = sparse(sys.T)
288-
Z_sparse = sparse(sys.Z)
289-
save_a1_P1_in_filter_output!(filter_output, kalman_state)
290-
@inbounds for t in eachindex(sys.y)
291-
update_kalman_state!(
292-
kalman_state,
293-
sys.y[t],
294-
Z_sparse,
295-
T_sparse,
296-
sys.H,
297-
RQR,
298-
sys.d,
299-
sys.c,
300-
skip_llk_instants,
301-
steadystate_tol,
302-
t,
303-
)
304-
save_kalman_state_in_filter_output!(filter_output, kalman_state, t)
291+
try
292+
RQR = sys.R * sys.Q * sys.R'
293+
T_sparse = sparse(sys.T)
294+
Z_sparse = sparse(sys.Z)
295+
save_a1_P1_in_filter_output!(filter_output, kalman_state)
296+
@inbounds for t in eachindex(sys.y)
297+
update_kalman_state!(
298+
kalman_state,
299+
sys.y[t],
300+
Z_sparse,
301+
T_sparse,
302+
sys.H,
303+
RQR,
304+
sys.d,
305+
sys.c,
306+
skip_llk_instants,
307+
steadystate_tol,
308+
t,
309+
)
310+
save_kalman_state_in_filter_output!(filter_output, kalman_state, t)
311+
end
312+
catch
313+
@error("Numerical error when applying Kalman filter euqations, the current state is: $kalman_state")
314+
rethrow()
305315
end
306316
return filter_output
307317
end

0 commit comments

Comments
 (0)