spm_dcm_sparse.m 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. function [Ep,Cp] = spm_dcm_sparse(DCM,field)
  2. % Bayesian model reduction of all permutations of model parameters
  3. % FORMAT [RCM,BMR] = spm_dcm_sparse(DCM,field
  4. %
  5. % DCM - A single estimated DCM (or PEB) structure:
  6. %
  7. % DCM.M.pE - prior expectation
  8. % DCM.M.pC - prior covariance
  9. % DCM.Ep - posterior expectation
  10. % DCM.Cp - posterior covariances
  11. % DCM.gamma - prior variance of reduced parameters (default: 0)
  12. %
  13. % field - parameter fields in DCM{i}.Ep to optimise [default: {'A','B'}]
  14. % 'All' will invoke all fields (i.e. random effects)
  15. % If Ep is not a structure, all parameters will be considered
  16. %
  17. % Returns:
  18. % Ep - (BMA) posterior expectation
  19. % Cp - (BMA) posterior covariance
  20. %
  21. %--------------------------------------------------------------------------
  22. % This routine searches over reduced (nested) models of a full model (DCM)
  23. % using Bayesian model reduction and performs Bayesian Model Averaging.
  24. % 'Reduced' means some free parameters (parameters with a non-
  25. % zero prior covariance) are switched off by fixing their prior variance
  26. % to zero.This version incorporates a sparsity prior over models (with a
  27. % Gaussian hyperprior). In other words, the free energy is taken to be the
  28. % likelihood of some data under a given model. The prior on that model
  29. % corresponds to a softmax function of the prior entropy. Finally, the
  30. % softmax (Gibbs) parameter is equipped with a Gaussian prior. Using
  31. % Bayesian model reduction, this routine evaluates the joint probability
  32. % over model and softmax sparsity parameter. The marginals over model space
  33. % are then used to form Bayesian model averaging.
  34. %
  35. % The greedy search in this version simply evaluates the log evidence of
  36. % models with and without each parameter and then successively removes the
  37. % parameters with the least evidence.
  38. %
  39. % See also: spm_dcm_bmr and spm_dcm_bmr_all
  40. %__________________________________________________________________________
  41. % Copyright (C) 2010-2014 Wellcome Trust Centre for Neuroimaging
  42. % Karl Friston, Peter Zeidman
  43. % $Id: spm_dcm_sparse.m 7082 2017-05-27 19:36:36Z karl $
  44. %-Number of parameters to consider before invoking greedy search
  45. %--------------------------------------------------------------------------
  46. nmax = 8;
  47. %-specification of null prior covariance
  48. %--------------------------------------------------------------------------
  49. if isfield(DCM,'beta'), beta = DCM.beta; else, beta = 0; end
  50. if isfield(DCM,'gamma'), gamma = DCM.gamma; else, gamma = 0; end
  51. %-Check fields of parameter stucture
  52. %--------------------------------------------------------------------------
  53. if nargin < 2 || isempty(field)
  54. field = {'A','B'};
  55. end
  56. if ischar(field)
  57. field = {field};
  58. end
  59. %-dela with filenames stucture
  60. %--------------------------------------------------------------------------
  61. if ischar(DCM)
  62. DCM = load(DCM,'DCM');
  63. DCM = DCM.DCM;
  64. end
  65. % Get prior covariances
  66. %--------------------------------------------------------------------------
  67. if isstruct(DCM.M.pC), DCM.M.pC = diag(spm_vec(DCM.M.pC)); end
  68. if spm_length(DCM.M.pE) ~= size(DCM.M.pC,1)
  69. DCM.M.pC = diag(spm_vec(DCM.M.pC));
  70. end
  71. % Get priors and posteriors
  72. %--------------------------------------------------------------------------
  73. qE = DCM.Ep;
  74. qC = DCM.Cp;
  75. pE = DCM.M.pE;
  76. pC = DCM.M.pC;
  77. % Remove (a priori) null space
  78. %--------------------------------------------------------------------------
  79. U = spm_svd(pC);
  80. qE = U'*spm_vec(qE);
  81. pE = U'*spm_vec(pE);
  82. qC = U'*qC*U;
  83. pC = U'*pC*U;
  84. %-Greedy search (GS) - eliminating parameters in a top down fashion
  85. %==========================================================================
  86. % Accumulated reduction vector (C)
  87. %--------------------------------------------------------------------------
  88. q = diag(DCM.M.pC);
  89. if sum(q < 1024)
  90. C = double(q > mean(q(q < 1024))/1024);
  91. else
  92. C = double(q > 0);
  93. end
  94. %-Find free coupling parameters
  95. %----------------------------------------------------------------------
  96. if isstruct(DCM.Ep)
  97. k = spm_fieldindices(DCM.Ep,field{:});
  98. else
  99. k = 1:spm_length(DCM.Ep);
  100. end
  101. k = k(find(C(k))); %#ok<FNDSB>
  102. % Model search over new prior without the i-th parameter
  103. %------------------------------------------------------------------
  104. nparam = length(k);
  105. for i = 1:nparam
  106. % Identify parameters to retain r and to remove s
  107. %--------------------------------------------------------------
  108. r = C; r(k(i)) = 0; s = 1 - r;
  109. % Create reduced priors
  110. %--------------------------------------------------------------
  111. R = U'*diag(r + s*gamma)*U;
  112. rC = R*pC*R;
  113. F(i) = spm_log_evidence(qE,qC,pE,pC,pE,rC);
  114. end
  115. % Find parameters with the least evidence
  116. %--------------------------------------------------------------------------
  117. [F,i] = sort(-F);
  118. k = k(i);
  119. M = cell(0);
  120. for i = 1:nparam
  121. % parameters to retain (r) and to remove (s)
  122. %----------------------------------------------------------------------
  123. r = C; r(k(1:i)) = 0; s = 1 - r;
  124. % Create reduced prior covariance matrix
  125. %----------------------------------------------------------------------
  126. R = U'*diag(r + s*gamma)*U;
  127. rC = R*pC*R;
  128. % record
  129. %----------------------------------------------------------------------
  130. M(i).F = spm_log_evidence(qE,qC,pE,pC,pE,rC)
  131. M(i).H = spm_logdet(rC);
  132. M(i).rC = rC;
  133. end
  134. % Sparsity hyperpriors
  135. %--------------------------------------------------------------------------
  136. s = (1:64)/64;
  137. Ps = exp(-((1:64) - 32).^2/(2*16));
  138. Ps = Ps/sum(Ps);
  139. % model likelihood, model prior and sparsity hyperprior
  140. %--------------------------------------------------------------------------
  141. Lm = spm_softmax(spm_vec(M.F));
  142. for i = 1:numel(s)
  143. Pm = spm_softmax(-s(i)*spm_vec(M.H));
  144. Qm(:,i) = Lm.*Pm*Ps(i);
  145. end
  146. % evidence and log evidence
  147. %--------------------------------------------------------------------------
  148. Qm = Qm/sum(sum(Qm));
  149. G = log(sum(Qm,2));
  150. %-Bayesian model average
  151. %==========================================================================
  152. qE = DCM.Ep;
  153. qC = DCM.Cp;
  154. pE = DCM.M.pE;
  155. pC = DCM.M.pC;
  156. pE = spm_vec(pE);
  157. Gmax = max(G);
  158. BMA = {};
  159. for i = 1:length(G)
  160. if G(i) > (Gmax - 4)
  161. [F,Ep,Cp] = spm_log_evidence_reduce(qE,qC,pE,pC,pE,M(i).rC);
  162. BMA{end + 1} = struct('Ep',Ep,'Cp',Cp,'F',F);
  163. end
  164. end
  165. BMA = spm_dcm_bma(BMA);
  166. Ep = BMA.Ep;
  167. Cp = BMA.Cp;
  168. if isstruct(Cp) || (spm_length(Cp) == spm_length(Ep))
  169. Cp = diag(spm_vec(Cp));
  170. end
  171. % Show results
  172. % -------------------------------------------------------------------------
  173. GRAPHICS = 1;
  174. if ~GRAPHICS, return, end
  175. spm_figure('Getwin','BMR - all'); clf
  176. subplot(3,2,1)
  177. imagesc(log(Qm)')
  178. title('Joint density','FontSize',16)
  179. xlabel('model','FontSize',12)
  180. ylabel('sparsity','FontSize',12)
  181. axis square
  182. subplot(3,2,2)
  183. plot(DCM.Ep,Ep,'.',DCM.Ep,DCM.Ep,':')
  184. title('Full and reduced expectations','FontSize',16)
  185. xlabel('Full expectations','FontSize',12)
  186. ylabel('Reduced expectations','FontSize',12)
  187. axis square
  188. subplot(3,2,3)
  189. plot(s,sum(Qm,1))
  190. title('Marginal over sparsity','FontSize',16)
  191. xlabel('sparsity parameter','FontSize',12)
  192. ylabel('probability','FontSize',12)
  193. axis square
  194. subplot(3,2,4)
  195. plot(sum(Qm,2))
  196. title('Marginal over model','FontSize',16)
  197. xlabel(' model','FontSize',12)
  198. ylabel('probability','FontSize',12)
  199. axis square
  200. drawnow