Skip to contents

The recursion alternates a prediction and an update, and the prediction error decomposition gives the exact log-likelihood as a by-product. With Q = 0, F = I, H = I and P0 = R the filtered state is exactly the running mean of the prior mean and the observations so far, which is the closed form the tests check.

Usage

Kalmf(y, F, H, Q, R, x0 = NULL, P0 = NULL)

Arguments

y

Observation matrix, one row per time point.

F

State transition matrix.

H

Observation matrix.

Q

State noise covariance.

R

Observation noise covariance.

x0

Initial state mean; zero by default.

P0

Initial state covariance; the identity by default.

Value

List with estimate, state, cov, predicted, predicted_cov, loglik, n, method.

Details

Formula: x_pred = F x; P_pred = F P F' + Q; S = H P_pred H' + R; K = P_pred H' S^{-1}; x = x_pred + K (y - H x_pred); P = (I - K H) P_pred.

References

Kalman (1960), A new approach to linear filtering and prediction problems, Transactions of the ASME, Journal of Basic Engineering 82(1):35-45. doi:10.1115/1.3662552

Examples

set.seed(1)
y <- matrix(cumsum(rnorm(20)) + rnorm(20), 20, 1)
Kalmf(y, F = matrix(1), H = matrix(1), Q = matrix(0.1), R = matrix(1))
#> $estimate
#> [1] 2.885739
#> 
#> $state
#> $state[[1]]
#> [1] 0.1532266
#> 
#> $state[[2]]
#> [1] 0.2247193
#> 
#> $state[[3]]
#> [1] -0.2413166
#> 
#> $state[[4]]
#> [1] -0.669023
#> 
#> $state[[5]]
#> [1] -0.1172496
#> 
#> $state[[6]]
#> [1] -0.148668
#> 
#> $state[[7]]
#> [1] -0.06467182
#> 
#> $state[[8]]
#> [1] -0.1612138
#> 
#> $state[[9]]
#> [1] 0.1943665
#> 
#> $state[[10]]
#> [1] 0.6128912
#> 
#> $state[[11]]
#> [1] 1.581138
#> 
#> $state[[12]]
#> [1] 1.997379
#> 
#> $state[[13]]
#> [1] 2.265658
#> 
#> $state[[14]]
#> [1] 1.743686
#> 
#> $state[[15]]
#> [1] 1.309204
#> 
#> $state[[16]]
#> [1] 1.239908
#> 
#> $state[[17]]
#> [1] 1.190555
#> 
#> $state[[18]]
#> [1] 1.50002
#> 
#> $state[[19]]
#> [1] 2.260943
#> 
#> $state[[20]]
#> [1] 2.885739
#> 
#> 
#> $cov
#> $cov[[1]]
#>           [,1]
#> [1,] 0.5238095
#> 
#> $cov[[2]]
#>           [,1]
#> [1,] 0.3841642
#> 
#> $cov[[3]]
#>           [,1]
#> [1,] 0.3262201
#> 
#> $cov[[4]]
#>          [,1]
#> [1,] 0.298846
#> 
#> $cov[[5]]
#>          [,1]
#> [1,] 0.285125
#> 
#> $cov[[6]]
#>           [,1]
#> [1,] 0.2780435
#> 
#> $cov[[7]]
#>           [,1]
#> [1,] 0.2743335
#> 
#> $cov[[8]]
#>           [,1]
#> [1,] 0.2723746
#> 
#> $cov[[9]]
#>          [,1]
#> [1,] 0.271336
#> 
#> $cov[[10]]
#>           [,1]
#> [1,] 0.2707841
#> 
#> $cov[[11]]
#>           [,1]
#> [1,] 0.2704905
#> 
#> $cov[[12]]
#>           [,1]
#> [1,] 0.2703342
#> 
#> $cov[[13]]
#>          [,1]
#> [1,] 0.270251
#> 
#> $cov[[14]]
#>           [,1]
#> [1,] 0.2702067
#> 
#> $cov[[15]]
#>           [,1]
#> [1,] 0.2701831
#> 
#> $cov[[16]]
#>           [,1]
#> [1,] 0.2701705
#> 
#> $cov[[17]]
#>           [,1]
#> [1,] 0.2701638
#> 
#> $cov[[18]]
#>           [,1]
#> [1,] 0.2701603
#> 
#> $cov[[19]]
#>           [,1]
#> [1,] 0.2701584
#> 
#> $cov[[20]]
#>           [,1]
#> [1,] 0.2701574
#> 
#> 
#> $predicted
#> $predicted[[1]]
#> [1] 0
#> 
#> $predicted[[2]]
#> [1] 0.1532266
#> 
#> $predicted[[3]]
#> [1] 0.2247193
#> 
#> $predicted[[4]]
#> [1] -0.2413166
#> 
#> $predicted[[5]]
#> [1] -0.669023
#> 
#> $predicted[[6]]
#> [1] -0.1172496
#> 
#> $predicted[[7]]
#> [1] -0.148668
#> 
#> $predicted[[8]]
#> [1] -0.06467182
#> 
#> $predicted[[9]]
#> [1] -0.1612138
#> 
#> $predicted[[10]]
#> [1] 0.1943665
#> 
#> $predicted[[11]]
#> [1] 0.6128912
#> 
#> $predicted[[12]]
#> [1] 1.581138
#> 
#> $predicted[[13]]
#> [1] 1.997379
#> 
#> $predicted[[14]]
#> [1] 2.265658
#> 
#> $predicted[[15]]
#> [1] 1.743686
#> 
#> $predicted[[16]]
#> [1] 1.309204
#> 
#> $predicted[[17]]
#> [1] 1.239908
#> 
#> $predicted[[18]]
#> [1] 1.190555
#> 
#> $predicted[[19]]
#> [1] 1.50002
#> 
#> $predicted[[20]]
#> [1] 2.260943
#> 
#> 
#> $predicted_cov
#> $predicted_cov[[1]]
#>      [,1]
#> [1,]  1.1
#> 
#> $predicted_cov[[2]]
#>           [,1]
#> [1,] 0.6238095
#> 
#> $predicted_cov[[3]]
#>           [,1]
#> [1,] 0.4841642
#> 
#> $predicted_cov[[4]]
#>           [,1]
#> [1,] 0.4262201
#> 
#> $predicted_cov[[5]]
#>          [,1]
#> [1,] 0.398846
#> 
#> $predicted_cov[[6]]
#>          [,1]
#> [1,] 0.385125
#> 
#> $predicted_cov[[7]]
#>           [,1]
#> [1,] 0.3780435
#> 
#> $predicted_cov[[8]]
#>           [,1]
#> [1,] 0.3743335
#> 
#> $predicted_cov[[9]]
#>           [,1]
#> [1,] 0.3723746
#> 
#> $predicted_cov[[10]]
#>          [,1]
#> [1,] 0.371336
#> 
#> $predicted_cov[[11]]
#>           [,1]
#> [1,] 0.3707841
#> 
#> $predicted_cov[[12]]
#>           [,1]
#> [1,] 0.3704905
#> 
#> $predicted_cov[[13]]
#>           [,1]
#> [1,] 0.3703342
#> 
#> $predicted_cov[[14]]
#>          [,1]
#> [1,] 0.370251
#> 
#> $predicted_cov[[15]]
#>           [,1]
#> [1,] 0.3702067
#> 
#> $predicted_cov[[16]]
#>           [,1]
#> [1,] 0.3701831
#> 
#> $predicted_cov[[17]]
#>           [,1]
#> [1,] 0.3701705
#> 
#> $predicted_cov[[18]]
#>           [,1]
#> [1,] 0.3701638
#> 
#> $predicted_cov[[19]]
#>           [,1]
#> [1,] 0.3701603
#> 
#> $predicted_cov[[20]]
#>           [,1]
#> [1,] 0.3701584
#> 
#> 
#> $loglik
#> [1] -39.83011
#> 
#> $n
#> [1] 20
#> 
#> $method
#> [1] "predict/update recursion of Kalman (1960) with the prediction error decomposition"
#> 
#> attr(,"class")
#> [1] "morie_rich_result" "list"