123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237 |
- function [Ep,Cp] = spm_dcm_sparse(DCM,field)
- % Bayesian model reduction of all permutations of model parameters
- % FORMAT [RCM,BMR] = spm_dcm_sparse(DCM,field
- %
- % DCM - A single estimated DCM (or PEB) structure:
- %
- % DCM.M.pE - prior expectation
- % DCM.M.pC - prior covariance
- % DCM.Ep - posterior expectation
- % DCM.Cp - posterior covariances
- % DCM.gamma - prior variance of reduced parameters (default: 0)
- %
- % field - parameter fields in DCM{i}.Ep to optimise [default: {'A','B'}]
- % 'All' will invoke all fields (i.e. random effects)
- % If Ep is not a structure, all parameters will be considered
- %
- % Returns:
- % Ep - (BMA) posterior expectation
- % Cp - (BMA) posterior covariance
- %
- %--------------------------------------------------------------------------
- % This routine searches over reduced (nested) models of a full model (DCM)
- % using Bayesian model reduction and performs Bayesian Model Averaging.
- % 'Reduced' means some free parameters (parameters with a non-
- % zero prior covariance) are switched off by fixing their prior variance
- % to zero.This version incorporates a sparsity prior over models (with a
- % Gaussian hyperprior). In other words, the free energy is taken to be the
- % likelihood of some data under a given model. The prior on that model
- % corresponds to a softmax function of the prior entropy. Finally, the
- % softmax (Gibbs) parameter is equipped with a Gaussian prior. Using
- % Bayesian model reduction, this routine evaluates the joint probability
- % over model and softmax sparsity parameter. The marginals over model space
- % are then used to form Bayesian model averaging.
- %
- % The greedy search in this version simply evaluates the log evidence of
- % models with and without each parameter and then successively removes the
- % parameters with the least evidence.
- %
- % See also: spm_dcm_bmr and spm_dcm_bmr_all
- %__________________________________________________________________________
- % Copyright (C) 2010-2014 Wellcome Trust Centre for Neuroimaging
- % Karl Friston, Peter Zeidman
- % $Id: spm_dcm_sparse.m 7082 2017-05-27 19:36:36Z karl $
- %-Number of parameters to consider before invoking greedy search
- %--------------------------------------------------------------------------
- nmax = 8;
- %-specification of null prior covariance
- %--------------------------------------------------------------------------
- if isfield(DCM,'beta'), beta = DCM.beta; else, beta = 0; end
- if isfield(DCM,'gamma'), gamma = DCM.gamma; else, gamma = 0; end
- %-Check fields of parameter stucture
- %--------------------------------------------------------------------------
- if nargin < 2 || isempty(field)
- field = {'A','B'};
- end
- if ischar(field)
- field = {field};
- end
- %-dela with filenames stucture
- %--------------------------------------------------------------------------
- if ischar(DCM)
- DCM = load(DCM,'DCM');
- DCM = DCM.DCM;
- end
- % Get prior covariances
- %--------------------------------------------------------------------------
- if isstruct(DCM.M.pC), DCM.M.pC = diag(spm_vec(DCM.M.pC)); end
- if spm_length(DCM.M.pE) ~= size(DCM.M.pC,1)
- DCM.M.pC = diag(spm_vec(DCM.M.pC));
- end
- % Get priors and posteriors
- %--------------------------------------------------------------------------
- qE = DCM.Ep;
- qC = DCM.Cp;
- pE = DCM.M.pE;
- pC = DCM.M.pC;
- % Remove (a priori) null space
- %--------------------------------------------------------------------------
- U = spm_svd(pC);
- qE = U'*spm_vec(qE);
- pE = U'*spm_vec(pE);
- qC = U'*qC*U;
- pC = U'*pC*U;
- %-Greedy search (GS) - eliminating parameters in a top down fashion
- %==========================================================================
- % Accumulated reduction vector (C)
- %--------------------------------------------------------------------------
- q = diag(DCM.M.pC);
- if sum(q < 1024)
- C = double(q > mean(q(q < 1024))/1024);
- else
- C = double(q > 0);
- end
- %-Find free coupling parameters
- %----------------------------------------------------------------------
- if isstruct(DCM.Ep)
- k = spm_fieldindices(DCM.Ep,field{:});
- else
- k = 1:spm_length(DCM.Ep);
- end
- k = k(find(C(k))); %#ok<FNDSB>
- % Model search over new prior without the i-th parameter
- %------------------------------------------------------------------
- nparam = length(k);
- for i = 1:nparam
-
- % Identify parameters to retain r and to remove s
- %--------------------------------------------------------------
- r = C; r(k(i)) = 0; s = 1 - r;
-
- % Create reduced priors
- %--------------------------------------------------------------
- R = U'*diag(r + s*gamma)*U;
- rC = R*pC*R;
- F(i) = spm_log_evidence(qE,qC,pE,pC,pE,rC);
-
- end
- % Find parameters with the least evidence
- %--------------------------------------------------------------------------
- [F,i] = sort(-F);
- k = k(i);
- M = cell(0);
- for i = 1:nparam
-
- % parameters to retain (r) and to remove (s)
- %----------------------------------------------------------------------
- r = C; r(k(1:i)) = 0; s = 1 - r;
-
- % Create reduced prior covariance matrix
- %----------------------------------------------------------------------
- R = U'*diag(r + s*gamma)*U;
- rC = R*pC*R;
-
- % record
- %----------------------------------------------------------------------
- M(i).F = spm_log_evidence(qE,qC,pE,pC,pE,rC)
- M(i).H = spm_logdet(rC);
- M(i).rC = rC;
-
- end
- % Sparsity hyperpriors
- %--------------------------------------------------------------------------
- s = (1:64)/64;
- Ps = exp(-((1:64) - 32).^2/(2*16));
- Ps = Ps/sum(Ps);
- % model likelihood, model prior and sparsity hyperprior
- %--------------------------------------------------------------------------
- Lm = spm_softmax(spm_vec(M.F));
- for i = 1:numel(s)
- Pm = spm_softmax(-s(i)*spm_vec(M.H));
- Qm(:,i) = Lm.*Pm*Ps(i);
- end
- % evidence and log evidence
- %--------------------------------------------------------------------------
- Qm = Qm/sum(sum(Qm));
- G = log(sum(Qm,2));
- %-Bayesian model average
- %==========================================================================
- qE = DCM.Ep;
- qC = DCM.Cp;
- pE = DCM.M.pE;
- pC = DCM.M.pC;
- pE = spm_vec(pE);
- Gmax = max(G);
- BMA = {};
- for i = 1:length(G)
- if G(i) > (Gmax - 4)
- [F,Ep,Cp] = spm_log_evidence_reduce(qE,qC,pE,pC,pE,M(i).rC);
- BMA{end + 1} = struct('Ep',Ep,'Cp',Cp,'F',F);
- end
- end
- BMA = spm_dcm_bma(BMA);
- Ep = BMA.Ep;
- Cp = BMA.Cp;
- if isstruct(Cp) || (spm_length(Cp) == spm_length(Ep))
- Cp = diag(spm_vec(Cp));
- end
- % Show results
- % -------------------------------------------------------------------------
- GRAPHICS = 1;
- if ~GRAPHICS, return, end
- spm_figure('Getwin','BMR - all'); clf
- subplot(3,2,1)
- imagesc(log(Qm)')
- title('Joint density','FontSize',16)
- xlabel('model','FontSize',12)
- ylabel('sparsity','FontSize',12)
- axis square
- subplot(3,2,2)
- plot(DCM.Ep,Ep,'.',DCM.Ep,DCM.Ep,':')
- title('Full and reduced expectations','FontSize',16)
- xlabel('Full expectations','FontSize',12)
- ylabel('Reduced expectations','FontSize',12)
- axis square
- subplot(3,2,3)
- plot(s,sum(Qm,1))
- title('Marginal over sparsity','FontSize',16)
- xlabel('sparsity parameter','FontSize',12)
- ylabel('probability','FontSize',12)
- axis square
- subplot(3,2,4)
- plot(sum(Qm,2))
- title('Marginal over model','FontSize',16)
- xlabel(' model','FontSize',12)
- ylabel('probability','FontSize',12)
- axis square
- drawnow
|