KalmanFilter
continuous_logistic.m
Go to the documentation of this file.
1 clear all;
2 addpath('..');
3 
4 %setting the seed for reproducability
5 isOctave = exist('OCTAVE_VERSION', 'builtin') ~= 0;
6 if isOctave==true
7  randn("seed",1);
8 else
9  rng(1);
10 end
11 
12 %define continuous logistic growth model and its jacobian
13 rate = 0.5;
14 max_pop = 100;
15 deriv_func = @(x) rate*x*(1 - x/max_pop);%logistic population model (quadratic in x)
16 if isOctave==true
17  jacobian_func = @(x) rate - (2*x*rate)/max_pop;%manual derivative - octave might have its own function
18 else
19  %in case you don't want to compute the jacobian manually and you have access
20  %to Matlab then you can compute it symbolically and then extract a function from it
21  xx = sym('x',[1,1]);
22  jacobian_func = matlabFunction(jacobian(deriv_func(xx),xx),'Vars',xx);
23 end
24 deriv_func = @(x,t) deriv_func(x) + 0.*t;
25 jacobian_func = @(x,t) jacobian_func(x) + 0.*t;
26 
27 
28 %in this model the time is only necessary
29 %for plotting an interpreting the results.
30 t_start = 0;
31 t_final = 10;
32 outputs = 1000;
33 dt = (t_final - t_start)/outputs;
34 
35 
36 R_c = 0.01;
37 %discrete noise covariance.
38 R_d = 1;
39 %continuous process noise covariance
40 Q_c = 10;
41 %measurement matrix
42 C = 1;
43 
44 %generate data and measurements
45 state_count = 1;
46 sensor_count = 1;
47 
48 %model results if there was no process noise
49 ideal_data = zeros(state_count,outputs);
50 %actual data (with process noise)
51 process_noise_data = zeros(state_count,outputs);
52 %noisy measurements of actual data
53 measurements = zeros(sensor_count,outputs);
54 
55 %initial condition for ideal
56 %and real process data
57 x_0 = max_pop/2;
58 P_0 = 1;
59 
60 %initial condition for ideal
61 %and real process data
62 x = x_0;
63 x_noise = x_0;
64 
65 %generate the data
66 curTime = t_start;
67 for ii=1:outputs
68  %Explicit Eulers
69  x = x + dt.*deriv_func(x,curTime);
70  ideal_data(:,ii) = x;
71 
72  %Euler-Maruyama
73  x_noise = x_noise+dt.*deriv_func(x_noise,curTime)+sqrt(dt.*Q_c)*randn(state_count,1);
74  process_noise_data(:,ii) = x_noise;
75  measurements(ii) = C*x_noise + sqrt(R_d)*randn(sensor_count,1);
76 
77  curTime = curTime + dt;
78 end
79 
80 %filter the noisy measurements
81 rk4_steps = 1;%internal for code - type 'help cdekf' for more info
82 [estimates,covariances] = cdekf(deriv_func,jacobian_func,dt,rk4_steps,t_start,...
83  state_count,sensor_count,outputs,C,chol(Q_c)',chol(R_d)',chol(P_0)',x_0,measurements);
84 
85 %The ideal data is not plotted and is only for reference
86 time = 0:dt:(outputs-1)*dt;
87 h = figure;
88 hold on;
89 limit = 100;
90 plot(time(1:limit),measurements(1:limit),'LineWidth',2);
91 plot(time(1:limit),process_noise_data(1:limit),'LineWidth',2);
92 plot(time(1:limit),estimates(1:limit),'LineWidth',2);
93 legend('Measurement','Real data','Estimate');
94 xlabel('Time')
95 ylabel('Population')
96 
97 h = figure;
98 hold on;
99 plot(0:dt:(outputs-1)*dt,measurements);
100 plot(0:dt:(outputs-1)*dt,process_noise_data);
101 plot(0:dt:(outputs-1)*dt,estimates(1:end-1));
102 legend('Measurement','Real data','Estimate');
103 xlabel('Time')
104 ylabel('Population')
function cdekf(in f_func, in jacobian_func, in dt_between_measurements, in rk4_steps, 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)