Home > vbmeg > functions > tool_box > linear_connectome_dynamics_toolbox > wmn_solution.m

wmn_solution

PURPOSE ^

Weighted Minimum Norm solution for the static inverse problem.

SYNOPSIS ^

function [optlambda, optsigma2, optcriteria, Jest, F, Info] = wmn_solution(B, G, X, w, option)

DESCRIPTION ^

 Weighted Minimum Norm solution for the static inverse problem.
  
 Solve the following minimization problem  
   min {E(J) = (B-GJ)'X(B-GJ) + lam*J'WJ}  
 with optimization of 'lam' by ABIC or GCV. 
 When 'option.lapacian' exists, the following minimization problem
   min {E(J) = (B-GJ)'X(B-GJ) + lam*J'LWLJ}  
 is solved ('LORETA' solution).
  
 [Syntax] 
   > [lambda, sigma2, ABIC, Jest, F, Info] = wmn_solution(B, G, Ceps, W, option)

 [Example]
 >> option.criteria = 'ABIC'
 >> option.flag_current = 1;
 >> [lambda, sigma2, ABIC, Jest, F] = wmn_solution(B, G, Ceps, W, option)

 returns optimal parameters, estimates of J, and the inverse filter using ABIC 
 as the statisitcal criteria for optimization.

 [Output]
   optlambda : optimum regularization parameter
   optsigma2 : optimum observation variance
   optcriteria : the value of criteria (ABIC or GCV) at optlambda
   Jest : estimated J
   F    : inverse filter (mapping from B to J) 
   Info : information of the optimization 
        1st column : lambda
        2nd column : criteria (ABIC or GCV)
        3rd column : observation noise variance (SIG2)

 [Input]
   B : EEG/MEG observation of a single trial (Nch*Nt matrix)
   G : lead field matrix  (Nch * Nj matrix)
   X : observation weight matrix (inverse of observation noise)
   w : the diagonal elements of prior weight matrix W (should be diagonal, because of memory problem) 

 [Optional Input]
   option.criteria : criteria for the estimation of reguralization parameter 
   option.laplacian : if exist, W is replaced by LWL (L is lapalcian)
   option.flag_plot : if 1, the values of 'criteria' (ABIC or GCV) are displayed with respect to 'lambda' 
   option.flag_current : if 1, the current is reconstrcted in the third output (default:1)  
   option.Npoints : the number of grid points in lambda axis to be explored (default:100) 
   option.lambda  : fix the regularization parameter  (default : []) 
   option.search_margin : parameter to define range of lambda to be searched (default:5).

 2016-03-22 O.Yamashita
 * allow empty X and w to speed up (avoid time-consuming sqrtm function)
 2014-03-03 O.Yamashita 
 * add a new field 'search_margin' to 'option' struct
 2014-02-10 O.Yamashita
 * add a new field 'lambda' to 'option' struct
 * modify comments 
 2012-11-07 O.Yamashita
 * save information for the optimization in 'Info' 
 2012-04-26 O.Yamashita
 * bug fix for the lines to compute square root of a matrix (sqrt --> sqrtm)
   previous version causes complex values 
 * add inverse filter 'F' as an output argument (important)
 2005-04-26 O.Yamashita beta-version,

CROSS-REFERENCE INFORMATION ^

This function calls: This function is called by:

SOURCE CODE ^

0001 function [optlambda, optsigma2, optcriteria, Jest, F, Info] = wmn_solution(B, G, X, w, option)
0002 % Weighted Minimum Norm solution for the static inverse problem.
0003 %
0004 % Solve the following minimization problem
0005 %   min {E(J) = (B-GJ)'X(B-GJ) + lam*J'WJ}
0006 % with optimization of 'lam' by ABIC or GCV.
0007 % When 'option.lapacian' exists, the following minimization problem
0008 %   min {E(J) = (B-GJ)'X(B-GJ) + lam*J'LWLJ}
0009 % is solved ('LORETA' solution).
0010 %
0011 % [Syntax]
0012 %   > [lambda, sigma2, ABIC, Jest, F, Info] = wmn_solution(B, G, Ceps, W, option)
0013 %
0014 % [Example]
0015 % >> option.criteria = 'ABIC'
0016 % >> option.flag_current = 1;
0017 % >> [lambda, sigma2, ABIC, Jest, F] = wmn_solution(B, G, Ceps, W, option)
0018 %
0019 % returns optimal parameters, estimates of J, and the inverse filter using ABIC
0020 % as the statisitcal criteria for optimization.
0021 %
0022 % [Output]
0023 %   optlambda : optimum regularization parameter
0024 %   optsigma2 : optimum observation variance
0025 %   optcriteria : the value of criteria (ABIC or GCV) at optlambda
0026 %   Jest : estimated J
0027 %   F    : inverse filter (mapping from B to J)
0028 %   Info : information of the optimization
0029 %        1st column : lambda
0030 %        2nd column : criteria (ABIC or GCV)
0031 %        3rd column : observation noise variance (SIG2)
0032 %
0033 % [Input]
0034 %   B : EEG/MEG observation of a single trial (Nch*Nt matrix)
0035 %   G : lead field matrix  (Nch * Nj matrix)
0036 %   X : observation weight matrix (inverse of observation noise)
0037 %   w : the diagonal elements of prior weight matrix W (should be diagonal, because of memory problem)
0038 %
0039 % [Optional Input]
0040 %   option.criteria : criteria for the estimation of reguralization parameter
0041 %   option.laplacian : if exist, W is replaced by LWL (L is lapalcian)
0042 %   option.flag_plot : if 1, the values of 'criteria' (ABIC or GCV) are displayed with respect to 'lambda'
0043 %   option.flag_current : if 1, the current is reconstrcted in the third output (default:1)
0044 %   option.Npoints : the number of grid points in lambda axis to be explored (default:100)
0045 %   option.lambda  : fix the regularization parameter  (default : [])
0046 %   option.search_margin : parameter to define range of lambda to be searched (default:5).
0047 %
0048 % 2016-03-22 O.Yamashita
0049 % * allow empty X and w to speed up (avoid time-consuming sqrtm function)
0050 % 2014-03-03 O.Yamashita
0051 % * add a new field 'search_margin' to 'option' struct
0052 % 2014-02-10 O.Yamashita
0053 % * add a new field 'lambda' to 'option' struct
0054 % * modify comments
0055 % 2012-11-07 O.Yamashita
0056 % * save information for the optimization in 'Info'
0057 % 2012-04-26 O.Yamashita
0058 % * bug fix for the lines to compute square root of a matrix (sqrt --> sqrtm)
0059 %   previous version causes complex values
0060 % * add inverse filter 'F' as an output argument (important)
0061 % 2005-04-26 O.Yamashita beta-version,
0062 
0063 %profile on
0064 
0065 [Nch, Nt] = size(B);
0066 [Nj] = size(G,2);
0067 
0068 
0069 % default
0070 criteria = 'ABIC';
0071 flag_plot = 1;
0072 flag_current = 1;
0073 L = speye(Nj);
0074 Npoints = 100;   % Number of points on the curve.
0075 lambda = [];
0076 search_margin = 5;  % in log scale
0077 
0078 %% Error check
0079 if exist('option') == 1  & isfield(option, 'criteria')
0080     criteria = option.criteria;
0081 end
0082 if exist('option') == 1  & isfield(option, 'flag_plot')
0083     flag_plot = option.flag_plot ;
0084 end
0085 if exist('option') == 1  & isfield(option, 'flag_current')
0086     flag_current = option.flag_current;
0087 end  
0088 if exist('option') == 1  & isfield(option, 'laplacian')
0089     L = option.laplacian;
0090     L = L / max(L(:));
0091 end
0092 if exist('option') == 1  & isfield(option, 'Npoints')
0093     Npoints = option.Npoints;
0094 end
0095 if exist('option') == 1  & isfield(option, 'lambda')
0096     lambda = option.lambda;
0097 end
0098 if exist('option') == 1  & isfield(option, 'search_margin')
0099     search_margin = option.search_margin;
0100 end
0101 
0102 % pre-whitening
0103 if isempty(X)
0104     Xsqrt = eye(Nch);
0105 else
0106     Xsqrt = sqrtm(X);
0107 end
0108 if isempty(w)
0109     wsqrt = ones(Nj,1);
0110 else
0111     wsqrt = sqrt(w);
0112 end
0113 
0114 Btil = Xsqrt * B; 
0115 Gtil = Xsqrt * G / L * spdiags(1./wsqrt, 0, Nj, Nj) ;
0116 
0117 [U s V] = csvd1(Gtil);
0118 
0119 % Sets grid points
0120 if isempty(lambda)
0121     minloglx = log(s(end)) - search_margin;
0122     maxloglx = log(s(1)) + search_margin;
0123     bin = (maxloglx-minloglx)/(Npoints-1);
0124     loglx_points = [minloglx : bin : maxloglx];
0125 else
0126     loglx_points = log(lambda);   % fixed lambda
0127 end
0128 
0129 Npoints = length(loglx_points); 
0130 SIG2 = zeros(Npoints,1);
0131 CRITERIA = zeros(Npoints,1);
0132 
0133 UtB = U'*Btil;
0134 BB = UtB * UtB';
0135 s2=s.*s; 
0136 
0137 % find optimum regularization parameter
0138 switch criteria
0139     case 'ABIC'
0140         %% calculate ABIC
0141         for i = 1 : Npoints
0142           lam = exp(loglx_points(i));         
0143           l2=lam;
0144           r = l2./(s2+l2); 
0145           sig2 = sum(sum(diag(r).*BB))/Nch/Nt; %tr(diag(r)*BB)
0146           ABIC1=Nch*Nt*log(sig2);
0147           ABIC2= -Nt*sum(log(r));
0148           CRITERIA(i)=ABIC1+ABIC2;
0149           SIG2(i) = sig2;
0150         end
0151         
0152     case 'GCV'
0153         %% calculate GCV
0154         for i = 1 : Npoints
0155           lam = exp(loglx_points(i));         
0156           l2=lam;
0157           r = l2./(s2+l2);
0158           nume = sum(sum(diag(r.^2).*BB));
0159           denom = (sum(r))^2;
0160           GCV = nume/denom;
0161           sig2 = sum(sum(diag(r).*BB))/Nch/Nt; %tr(diag(r)*BB)
0162           CRITERIA(i) = GCV;
0163           SIG2(i) = sig2;
0164         end
0165         
0166     otherwise
0167         disp('No such a method');
0168 end
0169 
0170 [tmp, ind] = min(CRITERIA);
0171 optlambda = exp(loglx_points(ind));
0172 optsigma2 = SIG2(ind);
0173 optcriteria = CRITERIA(ind);
0174 Info = [exp(loglx_points(:)) CRITERIA(:) SIG2(:)];
0175 
0176 %% current reconstruction
0177 
0178 if flag_current 
0179     l2= optlambda;
0180     r = s./(s2+l2); 
0181     Jtil = V *diag(r)*UtB;
0182     Jest = L\ Jtil ./ wsqrt(:,ones(1,Nt));  %Jest = L\ spdiags(1./wsqrt, 0, Nj, Nj) * Jtil;
0183     F = L\spdiags(1./wsqrt, 0, Nj, Nj)*V*diag(r)*U'*Xsqrt;
0184 else
0185     Jest = [];
0186     F = [];
0187 end
0188 
0189 if flag_plot
0190     figure
0191     [AX,H1,H2] = plotyy(loglx_points, CRITERIA, loglx_points, SIG2);
0192     xlabel('Log of lambda');
0193     set(get(AX(1),'Ylabel'),'String','ABIC or GCV')
0194     set(get(AX(2),'Ylabel'),'String','Observation Noise Variance');
0195     hold on;
0196     plot([loglx_points(ind) loglx_points(ind)], [min(get(AX(1),'ytick')) max(get(AX(1),'ytick'))], 'k--');
0197 end
0198     
0199 
0200 %profile viewer
0201 
0202

Generated on Mon 22-May-2023 06:53:56 by m2html © 2005