spm_pf.m 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. function [qx,qP,qD,xhist] = spm_pf(M,y,U)
  2. % Particle Filtering for dynamic models
  3. % FORMAT [qx,qP,qD,xhist] = spm_pf(M,y)
  4. % M - model specification structure
  5. % y - output or data (N x T)
  6. % U - exogenous input
  7. %
  8. % M(1).x % initial states
  9. % M(1).f = inline(f,'x','v','P') % state equation
  10. % M(1).g = inline(g,'x','v','P') % observer equation
  11. % M(1).pE % parameters
  12. % M(1).V % observation noise precision
  13. %
  14. % M(2).v % initial process noise
  15. % M(2).V % process noise precision
  16. %
  17. % qx - conditional expectation of states
  18. % qP - {1 x T} conditional covariance of states
  19. % qD - full sample
  20. %__________________________________________________________________________
  21. % See notes at the end of this script for details and a demo. This routine
  22. % is based on:
  23. %
  24. % var der Merwe R, Doucet A, de Freitas N and Wan E (2000). The
  25. % unscented particle filter. Technical Report CUED/F-INFENG/TR 380
  26. %__________________________________________________________________________
  27. % Copyright (C) 2008 Wellcome Trust Centre for Neuroimaging
  28. % Karl Friston
  29. % $Id: spm_pf.m 1143 2008-02-07 19:33:33Z spm $
  30. % check model specification
  31. %--------------------------------------------------------------------------
  32. M = spm_DEM_M_set(M);
  33. dt = M(1).E.dt;
  34. if length(M) ~=2
  35. errordlg('spm_pf requires a two-level model')
  36. return
  37. end
  38. % INITIALISATION:
  39. %==========================================================================
  40. T = length(y); % number of time points
  41. n = M(2).l; % number of innovations
  42. N = 200; % number of particles.
  43. % precision of measurement noise
  44. %--------------------------------------------------------------------------
  45. R = M(1).V;
  46. for i = 1:length(M(1).Q)
  47. R = R + M(1).Q{i}*exp(M(1).h(i));
  48. end
  49. P = M(1).pE; % parameters
  50. Q = M(2).V.^-.5; % root covariance of innovations
  51. v = kron(ones(1,N),M(2).v); % innovations
  52. x = kron(ones(1,N),M(1).x); % hidden states
  53. v = v + 128*Q*randn(size(v));
  54. % inputs
  55. %--------------------------------------------------------------------------
  56. if nargin < 3
  57. U = sparse(n,T);
  58. end
  59. for t = 1:T
  60. % PREDICTION STEP: with the (8x) transition prior as proposal
  61. %----------------------------------------------------------------------
  62. for i = 1:N
  63. v(:,i) = 8*Q*randn(n,1) + U(:,t);
  64. f = M(1).f(x(:,i),v(:,i),P);
  65. dfdx = spm_diff(M(1).f,x(:,i),v(:,i),P,1);
  66. xPred(:,i) = x(:,i) + spm_dx(dfdx,f,dt);
  67. end
  68. % EVALUATE IMPORTANCE WEIGHTS: and normalise
  69. %----------------------------------------------------------------------
  70. for i = 1:N
  71. yPred = M(1).g(xPred(:,i),v(:,i),P);
  72. ePred = yPred - y(:,t);
  73. w(i) = ePred'*R*ePred;
  74. end
  75. w = w - min(w);
  76. w = exp(-w/2);
  77. w = w/sum(w);
  78. % SELECTION STEP: multinomial resampling.
  79. %----------------------------------------------------------------------
  80. x = xPred(:,multinomial(1:N,w));
  81. % report and record moments
  82. %----------------------------------------------------------------------
  83. qx(:,t) = mean(x,2);
  84. qP{t} = cov(x');
  85. qX(:,t) = x(:);
  86. fprintf('PF: time-step = %i : %i\n',t,T);
  87. end
  88. % sample density
  89. %==========================================================================
  90. if nargout > 3
  91. xhist = linspace(min(qX(:)),max(qX(:)),32);
  92. for i = 1:T
  93. q = hist(qX(:,i),xhist);
  94. qD(:,i) = q(:);
  95. end
  96. end
  97. return
  98. function I = multinomial(inIndex,q);
  99. %==========================================================================
  100. % PURPOSE : Performs the resampling stage of the SIR
  101. % in order(number of samples) steps.
  102. % INPUTS : - inIndex = Input particle indices.
  103. % - q = Normalised importance ratios.
  104. % OUTPUTS : - I = Resampled indices.
  105. % AUTHORS : Arnaud Doucet and Nando de Freitas
  106. % MULTINOMIAL SAMPLING:
  107. % generate S ordered random variables uniformly distributed in [0,1]
  108. % high speed Niclas Bergman Procedure
  109. %--------------------------------------------------------------------------
  110. q = q(:);
  111. S = length(q); % S = Number of particles.
  112. N_babies = zeros(1,S);
  113. cumDist = cumsum(q');
  114. u = fliplr(cumprod(rand(1,S).^(1./(S:-1:1))));
  115. j = 1;
  116. for i = 1:S
  117. while (u(1,i) > cumDist(1,j))
  118. j = j + 1;
  119. end
  120. N_babies(1,j) = N_babies(1,j) + 1;
  121. end;
  122. % COPY RESAMPLED TRAJECTORIES:
  123. %--------------------------------------------------------------------------
  124. index = 1;
  125. for i = 1:S
  126. if (N_babies(1,i)>0)
  127. for j=index:index+N_babies(1,i)-1
  128. I(j) = inIndex(i);
  129. end;
  130. end;
  131. index = index + N_babies(1,i);
  132. end
  133. return
  134. %==========================================================================
  135. % notes and demo:
  136. %==========================================================================
  137. % The code below generates a nonlinear, non-Gaussian problem (S) comprising
  138. % a model S.M and data S.Y (c.f. van der Merwe et al 2000))
  139. %
  140. % The model is f(x) = dxdt
  141. % = 1 + sin(0.04*pi*t) - log(2)*x + n
  142. % y = g(x)
  143. % = (x.^2)/5 : if t < 30
  144. % -2 + x/2 : otherwise
  145. % i.e. the output nonlinearity becomes linear after 30 time steps. In this
  146. % implementation time is modelled as an auxiliary state variable. n is
  147. % the process noise, which is modelled as a log-normal variate. e is
  148. % Gaussian observation noise.
  149. % model specification
  150. %--------------------------------------------------------------------------
  151. f = '[1; (1 + sin(P(2)*pi*x(1)) - P(1)*x(2) + exp(v))]';
  152. g = '(x(1) > 30)*(-2 + x(2)/2) + ~(x(1) > 30)*(x(2).^2)/5';
  153. M(1).x = [1; 1]; % initial states
  154. M(1).f = inline(f,'x','v','P'); % state equation
  155. M(1).g = inline(g,'x','v','P'); % observer equation
  156. M(1).pE = [log(2) 0.04]; % parameters
  157. M(1).V = exp(4); % observation noise precision
  158. M(2).v = 0; % initial process log(noise)
  159. M(2).V = 2.4; % process log(noise) precision
  160. % generate data (output)
  161. %--------------------------------------------------------------------------
  162. T = 60; % number of time points
  163. S = spm_DEM_generate(M,T);
  164. % Particle filtering
  165. %--------------------------------------------------------------------------
  166. pf_x = spm_pf(M,S.Y);
  167. % plot results
  168. %--------------------------------------------------------------------------
  169. x = S.pU.x{1};
  170. plot([1:T],x(2,:),[1:T],pf_x(2,:))
  171. legend({'true','PF'})