spm_nlsi.m 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. function varargout = spm_nlsi(M,U,Y)
  2. % nonlinear system identification of a MIMO system
  3. % FORMAT [Ep,Cp,Eh,K0,K1,K2,M0,M1,L1,L2] = spm_nlsi(M,U,Y)
  4. % FORMAT [K0,K1,K2,M0,M1,L1,L2] = spm_nlsi(M)
  5. %
  6. % Model specification
  7. %--------------------------------------------------------------------------
  8. % M.f - dx/dt = f(x,u,P,M) {function string or m-file}
  9. % M.g - y = g(x,u,P,M) {function string or m-file}
  10. %
  11. % M.pE - (p x 1) Prior expectation of p model parameters
  12. % M.pC - (p x p) Prior covariance for p model parameters
  13. %
  14. % M.x - (n x 1) intial state x(0)
  15. % M.m - m number of inputs
  16. % M.n - n number of states
  17. % M.l - l number of outputs
  18. % M.N - kernel depth
  19. % M.dt - kernel resolution {secs}
  20. %
  21. % System inputs
  22. %--------------------------------------------------------------------------
  23. % U.u - (v x m) m inputs
  24. % U.dt - sampling interval for inputs
  25. %
  26. % System outputs
  27. %--------------------------------------------------------------------------
  28. % Y.y - (v x l) l outputs
  29. % Y.X0 - (v x c) Confounds or null space
  30. % Y.dt - sampling interval for outputs
  31. % Y.Q - observation error precision components
  32. %
  33. % Model Parameter estimates - conditional moments
  34. %--------------------------------------------------------------------------
  35. % Ep - (p x 1) conditional expectation E{P|y}
  36. % Cp - (p x p) conditional covariance Cov{P|y}
  37. % Eh - (v x v) conditional log-precision
  38. %
  39. % System identification - Volterra kernels
  40. %--------------------------------------------------------------------------
  41. % K0 - (l x 1) = k0(t) = y(t)
  42. % K1 - (N x l x m) = k1i(t,s1) = dy(t)/dui(t - s1)
  43. % K2 - (N x N x l x m x m) = k2ij(t,s1,s2) = d2y(t)/dui(t - s1)duj(t - s2)
  44. %
  45. % System identification - Bilinear approximation
  46. %--------------------------------------------------------------------------
  47. % M0 - (n x n) df/dq
  48. % M1 - {m}(n x n) d2f/dqdu
  49. % L1 - (l x n) dg/dq
  50. % L2 - {l}(n x n) d2g/dqdq
  51. %
  52. %__________________________________________________________________________
  53. %
  54. % Returns the moments of the posterior p.d.f. of the parameters of a
  55. % nonlinear MIMO model under Gaussian assumptions
  56. %
  57. % dx/dt = f(x,u,P)
  58. % y = g(x,u,P) + e (1)
  59. %
  60. % evaluated at x(0) = x0, using a Bayesian estimation scheme with priors
  61. % on the model parameters P, specified in terms of expectations and
  62. % covariance. The estimation uses a Gauss-Newton method with MAP point
  63. % estimators at each iteration. Both Volterra kernel and state-space
  64. % representations of the Bilinear approximation are provided.
  65. % The Bilinear approximation to (1), evaluated at x(0) = x and u = 0 is:
  66. %
  67. % dq/dt = M0*q + u(1)*M1{1}*q + u(2)*M1{2}*q + ....
  68. % y(i) = L1(i,:)*q + q'*L2{i}*q;
  69. %
  70. % where the states are augmented with a constant
  71. %
  72. % q(t) = [1; x(t) - x(0)]
  73. %
  74. % The associated kernels are derived using closed form expressions based
  75. % on the bilinear approximation.
  76. %
  77. %--------------------------------------------------------------------------
  78. % If the inputs U and outputs Y are not specified the model is simply
  79. % characterised in terms of its Volterra kernels and Bilinear
  80. % approximation expanding around M.pE
  81. %
  82. % see also
  83. % spm_nlsi_GN: Bayesian parameter estimation using an EM/Gauss-Newton method
  84. % spm_bireduce: Reduction of a fully nonlinear MIMO system to Bilinear form
  85. % spm_kernels: Returns global Volterra kernels for a MIMO Bilinear system
  86. %
  87. % SEE NOTES AT THE END OF THIS SCRIPT FOR EXAMPLES
  88. %__________________________________________________________________________
  89. % Copyright (C) 2008 Wellcome Trust Centre for Neuroimaging
  90. % Karl Friston
  91. % $Id: spm_nlsi.m 3764 2010-03-08 20:18:10Z guillaume $
  92. % check integrator
  93. %--------------------------------------------------------------------------
  94. try
  95. M.IS;
  96. catch
  97. M.IS = 'spm_int';
  98. end
  99. % Expansion point (in parameter space) for Bilinear-kernel representations
  100. %--------------------------------------------------------------------------
  101. if nargin == 3
  102. % Gauss-Newton/Bayesian/EM estimation
  103. %======================================================================
  104. [Ep,Cp,Eh,F] = spm_nlsi_GN(M,U,Y);
  105. if nargout < 4, varargout = {Ep,Cp,Eh}; return, end
  106. else
  107. % Use prior expectation to expand around
  108. %----------------------------------------------------------------------
  109. Ep = M.pE;
  110. end
  111. % Bilinear representation
  112. %==========================================================================
  113. [M0,M1,L1,L2] = spm_bireduce(M,Ep);
  114. % Volterra kernels
  115. %==========================================================================
  116. % time bins (if not specified)
  117. %--------------------------------------------------------------------------
  118. try
  119. dt = M.dt;
  120. N = M.N;
  121. catch
  122. s = real(eig(full(M0)));
  123. s = max(s(s < 0));
  124. N = 32;
  125. dt = -4/(s*N);
  126. M.dt = dt;
  127. M.N = N;
  128. end
  129. % get kernels
  130. %--------------------------------------------------------------------------
  131. [K0,K1,K2] = spm_kernels(M0,M1,L1,L2,N,dt);
  132. % graphics
  133. %==========================================================================
  134. if ~isdeployed && length(dbstack) < 2
  135. subplot(2,1,1)
  136. plot([1:N]*dt,K1(:,:,1))
  137. xlabel('time')
  138. ylabel('response')
  139. title('1st-order kernel')
  140. grid on
  141. subplot(2,1,2)
  142. imagesc([1:N]*dt,[1:N]*dt,K2(:,:,1,1,1))
  143. xlabel('time')
  144. ylabel('time')
  145. title('2nd-order kernel')
  146. grid on
  147. axis image
  148. drawnow
  149. end
  150. % output arguments
  151. %--------------------------------------------------------------------------
  152. if nargin == 3
  153. varargout = {Ep,Cp,Eh,K0,K1,K2,M0,M1,L1,L2,F};
  154. else
  155. varargout = {K0,K1,K2,M0,M1,L1,L2};
  156. end
  157. return
  158. % NOTES ON USE
  159. %==========================================================================
  160. % Consider the system
  161. %
  162. % dx/dt = 1./(1 + exp(-x*P)) + u
  163. % y = x + e
  164. %
  165. % Specify a model structure:
  166. %--------------------------------------------------------------------------
  167. M.f = inline('1./(1 + exp(-P*x)) + [u; 0]','x','u','P','M');
  168. M.g = inline('x','x','u','P','M');
  169. M.pE = [-1 .3;.5 -1]; % Prior expectation of parameters
  170. M.pC = speye(4,4); % Prior covariance for parameters
  171. M.x = zeros(2,1) % intial state x(0)
  172. M.m = 1; % number of inputs
  173. M.n = 2; % number of states
  174. M.l = 2; % number of outputs
  175. % characterise M in terms of Volterra kernels and Bilinear matrices:
  176. %--------------------------------------------------------------------------
  177. [K0,K1,K2,M0,M1,L1,L2] = spm_nlsi(M);
  178. % or estimate the model parameters with inputs and outputs
  179. %==========================================================================
  180. % inputs
  181. %--------------------------------------------------------------------------
  182. U.name = 'input';
  183. U.u = randn(64,1);
  184. U.dt = 1;
  185. % outputs
  186. %--------------------------------------------------------------------------
  187. Y.name = 'response';
  188. y = spm_int_D(M.pE,M,U);
  189. Y.y = y + randn(size(y))/32;
  190. Y.dt = U.dt*length(U.u)/length(Y.y);
  191. % estimate
  192. %--------------------------------------------------------------------------
  193. [Ep,Cp,Eh,K0,K1,K2,M0,M1,L1,L2,F] = spm_nlsi(M,U,Y);