1 function [estimates,covariances] =
enkf_stochastic(func,state_count,sensor_count,measurement_count,ensemble_size,C,R,Q,P_0,x_0, measurements)
2 %Runs discrete-discrete Extended Kalman filter on data. The initial
3 %estimate and covariances are at the time step before all the
4 %measurements - be wary of the off-by-one error. If f_func is a
5 %linear
function the code is equivalent to discrete-discrete Kalman
7 %[estimates, covariances] =
ddekf(f_func,jacobian_func,state_count,sensor_count,measurement_count,C,Q,R_root,P_0_root,x_0, measurements)
9 % f_func: x_{k+1} = f_func(x_k) where x_k is the state.
11 % state_count: dimension of the state
13 % sensor_count: dimension of observation vector
15 % measurement_count: number of measurements
17 % ensemble_size: Ensemble size of the ensemble filter
19 % C: observation matrix of size
'sensor_count by state_count' 21 % R: Sensor error covariance
23 % Q: Process noise covariance
25 % P: Initial covariance
27 % x_0: Initial state estimate of size
'state_count by 1' 29 % measurements: ith column is ith measurement. Matrix of size
30 %
'sensor_count by measurement_count' 33 % estimates:
'state_count by measurement_count+1' 34 % ith column is ith estimate. first column is x_0
36 % covariances: cell of size
'measurement_count+1' by 1
37 % where each entry is the P covariance matrix at that time
38 % Time is computed based on dt_between_measurements
41 assert(size(C,1) == sensor_count & size(C,2) == state_count);
42 assert(size(R,1) == sensor_count & size(R,2) == sensor_count);
43 assert(size(P_0,1) == state_count & size(P_0,2) == state_count);
44 assert(size(x_0,1) == state_count & size(x_0,2) == 1);
45 assert(size(measurements,1) == sensor_count & size(measurements,2) == measurement_count);
46 assert(size(func(zeros(state_count,1)),1) == state_count & size(func(zeros(state_count,1)),2) == 1);
48 covariances = cell(1,measurement_count);
49 estimates = zeros(state_count,measurement_count);
51 ensemble = mvnrnd(zeros(state_count,1),P_0,ensemble_size)
' + x_0; 53 for ii=1:measurement_count 55 propagated = func(ensemble); 56 sampled_process_noise = mvnrnd(zeros(state_count,1),Q,ensemble_size)';
57 propagated = propagated + sampled_process_noise;
58 x_mean = (1/ensemble_size).*sum(propagated,2);
59 propagated_covariance = (propagated - x_mean);
60 propagated_covariance = (1/(ensemble_size-1)).*propagated_covariance*propagated_covariance
'; 61 Kalman_gain = propagated_covariance*C'/(C*propagated_covariance*C
' + R); 63 %draw a stastistically consistent observation set: 64 u_samples = mvnrnd(zeros(sensor_count,1),R,ensemble_size)';
65 y_propagated = C*propagated;
67 updated_ensemble = propagated + Kalman_gain*(measurements(:,ii) + u_samples - y_propagated);
68 ensemble = updated_ensemble;
70 estimates(:,ii) = (1/ensemble_size).*sum(ensemble,2);
71 covariances{ii} = (1/(ensemble_size-1)).*((ensemble-estimates(:,ii)))*((ensemble-estimates(:,ii)))
'; function ddekf(in f_func, in jacobian_func, in dt_between_measurements, in start_time, in state_count, in sensor_count, in measurement_count, in C, in Q_root, in R_root, in P_0_root, in x_0, in measurements)
function enkf_stochastic(in func, in state_count, in sensor_count, in measurement_count, in ensemble_size, in C, in R, in Q, in P_0, in x_0, in measurements)