spm_ekf.m 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. function [x,P] = spm_ekf(M,y)
  2. % Extended Kalman Filtering for dynamic models
  3. % FORMAT [x,P] = spm_ekf(M,y)
  4. % M - model specification structure
  5. % y - output or data (N x T)
  6. %
  7. % M(1).x % initial states
  8. % M(1).f = inline(f,'x','v','P') % state equation
  9. % M(1).g = inline(g,'x','v','P') % observer equation
  10. % M(1).pE % parameters
  11. % M(1).V % observation noise precision
  12. %
  13. % M(2).v % initial process f(noise)
  14. % M(2).V % process f(noise) precision
  15. %
  16. % x - conditional expectation of states
  17. % P - {1 x T} conditional covariance of states
  18. %__________________________________________________________________________
  19. % See notes at the end of this script for details and a demo. This routine
  20. % is based on:
  21. %
  22. % var der Merwe R, Doucet A, de Freitas N and Wan E (2000). The
  23. % unscented particle filter. Technical Report CUED/F-INFENG/TR 380
  24. %__________________________________________________________________________
  25. % Copyright (C) 2008 Wellcome Trust Centre for Neuroimaging
  26. % Karl Friston
  27. % $Id: spm_ekf.m 1143 2008-02-07 19:33:33Z spm $
  28. % check model specification
  29. %--------------------------------------------------------------------------
  30. M = spm_DEM_M_set(M);
  31. dt = M(1).E.dt;
  32. if length(M) ~=2
  33. errordlg('spm_ekf requires a two-level model')
  34. return
  35. end
  36. % INITIALISATION:
  37. % =========================================================================
  38. dfdx = spm_diff(M(1).f,M(1).x,M(2).v,M(1).pE,1);
  39. dfdv = spm_diff(M(1).f,M(1).x,M(2).v,M(1).pE,2);
  40. dgdx = spm_diff(M(1).g,M(1).x,M(2).v,M(1).pE,1);
  41. Jx = spm_expm(dfdx);
  42. T = length(y); % number of time points
  43. % covariances
  44. %--------------------------------------------------------------------------
  45. iR = M(1).V;
  46. for i = 1:length(M(1).Q)
  47. iR = iR + M(1).Q{i}*exp(M(1).hE(i));
  48. end
  49. iQ = M(1).W;
  50. for i = 1:length(M(1).R)
  51. iQ = iQ + M(1).R{i}*exp(M(1).gE(i));
  52. end
  53. R = inv(iR); % EKF measurement noise variance.
  54. Q = inv(iQ); % EKF process noise variance.
  55. x = M(1).x; % EKF estimate of the mean of states
  56. Q = Q + Jx*dfdv*inv(M(2).V)*dfdv'*Jx'; % EKF process noise variance.
  57. P = {pinv(full(dgdx'*R*dgdx))}; % EKF conditional covariance of states
  58. for t = 2:T
  59. % PREDICTION STEP:
  60. %----------------------------------------------------------------------
  61. f = M(1).f(M(1).x,M(2).v,M(1).pE);
  62. dfdx = spm_diff(M(1).f,M(1).x,M(2).v,M(1).pE,1);
  63. xPred = M(1).x + spm_dx(dfdx,f,dt);
  64. Jx = spm_expm(dfdx);
  65. PPred = Q + Jx*P{t-1}*Jx';
  66. % CORRECTION STEP:
  67. %----------------------------------------------------------------------
  68. yPred = M(1).g(xPred,M(2).v,M(1).pE);
  69. Jy = spm_diff(M(1).g,xPred,M(2).v,M(1).pE,1);
  70. K = PPred*Jy'*inv(R + Jy*PPred*Jy');
  71. M(1).x = xPred + K*(y(:,t) - yPred);
  72. x(:,t) = M(1).x;
  73. P{t} = PPred - K*Jy*PPred;
  74. % report
  75. %----------------------------------------------------------------------
  76. fprintf('EKF: time-step = %i : %i\n',t,T);
  77. end
  78. return
  79. % notes and demo:
  80. %==========================================================================
  81. % The code below generates a nonlinear, non-Gaussian problem (S) comprising
  82. % a model S.M and data S.Y (c.f. van der Merwe et al 2000))
  83. %
  84. % The model is f(x) = dxdt
  85. % = 1 + sin(o.o4*pi*t) - log(2)*x + n
  86. % y = g(x)
  87. % = (x.^2)/5 : if t < 30
  88. % -2 + x/2 : otherwise
  89. % i.e. the output nonlinearity becomes linear after 30 time steps. In this
  90. % implementation time is modelled as an auxiliary state variable. n is
  91. % the process noise, which is modelled as a log-normal variate. e is
  92. % Gaussian observation noise.
  93. % model specification
  94. %--------------------------------------------------------------------------
  95. f = '[1; (1 + sin(P(2)*pi*x(1)) - P(1)*x(2) + exp(v))]';
  96. g = '(x(1) > 30)*(-2 + x(2)/2) + ~(x(1) > 30)*(x(2).^2)/5';
  97. M(1).x = [1; 1]; % initial states
  98. M(1).f = inline(f,'x','v','P'); % state equation
  99. M(1).g = inline(g,'x','v','P'); % observer equation
  100. M(1).pE = [log(2) 0.04]; % parameters
  101. M(1).V = 1e5; % observation noise precision
  102. M(2).v = 0; % initial process log(noise)
  103. M(2).V = 2.4; % process log(noise) precision
  104. % generate data (output)
  105. %--------------------------------------------------------------------------
  106. T = 60; % number of time points
  107. S = spm_DEM_generate(M,T);
  108. % EKF
  109. %--------------------------------------------------------------------------
  110. ekf_x = spm_ekf(M,S.Y);
  111. % plot results
  112. %--------------------------------------------------------------------------
  113. x = S.pU.x{1};
  114. plot([1:T],x(2,:),[1:T],ekf_x(2,:))
  115. legend({'true','EKF'})