nets_netmats_ar.m 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. %
  2. % nets_netmats - create network matrices ("netmats") for each separate run/subject in ts
  3. % Steve Smith, Ludo Griffanti, Roser Sala and Eugene Duff 2013-2014
  4. %
  5. % netmats = nets_netmats(ts,z,method);
  6. % netmats = nets_netmats(ts,z,method,method_parameter);
  7. %
  8. % ts: structure containing node information including all timeseries
  9. % *OR* it can be a single timeXspace matrix (in which case the output netmat is square, not unwrapped)
  10. % z: set to 1 to convert from r to z; set to 0 to leave netmats as r
  11. % This is only applied for methods generating correlations.
  12. % For all partial correlation options, this conversion assumes no regularisation,
  13. % so most likely will not generate true z-stats for regularised options.
  14. % method: a string determining which netmat estimation method to use (list below)
  15. %
  16. % e.g.: netmats=nets_netmats(ts,1,'icov');
  17. %
  18. % The output (netmats) is a matrix of (runs/subjects) X (netmat elements), meaning that each row
  19. % is the netmat for a given run/subject, unwrapped from the square form into a single row vector.
  20. % So for 20 subjects and 10 nodes, netmat will be 20x10^2 = 20x100
  21. %
  22. % Methods:
  23. % 'cov' - covariance (non-normalised "correlation")
  24. % 'amp' - only use nodes' amplitudes - the individual original "netmats" are then (Nnodes X 1) and not a aquare matrix
  25. % 'corr' - full correlation (diagonal is set to zero)
  26. % 'rcorr' - full correlation after regressing out global mean timecourse
  27. % 'icov' - partial correlation, optionally "ICOV" L1-regularised (if a lambda parameter is given as the next option)
  28. % e.g.: netmats=nets_netmats(ts,1,'icov'); % (unregularised) partial correlation
  29. % e.g.: netmats=nets_netmats(ts,1,'icov',10); % "ICOV" L1-norm regularised partial correlation with lambda=10
  30. % L1-regularisation requires the L1precision toolbox from http://www.di.ens.fr/~mschmidt/Software/L1precision.html
  31. % 'ridgep' - partial correlation using L2-norm Ridge Regression (aka Tikhonov)
  32. % e.g.: netmats=nets_netmats(ts,1,'ridgep'); % default regularisation rho=0.1
  33. % e.g.: netmats=nets_netmats(ts,1,'ridgep',1); % rho=1
  34. %
  35. function [netmats] = nets_netmats(ts,do_rtoz,do_rtoz_corr,method,varargin);
  36. INMODE=0;
  37. if (size(ts,1) ~=1)
  38. grot=ts; clear ts;
  39. ts.Nsubjects=1;
  40. ts.ts=grot;
  41. ts.Nnodes=size(ts.ts,2);
  42. ts.NtimepointsPerSubject=size(ts.ts,1);
  43. INMODE=1;
  44. end
  45. N=ts.Nnodes;
  46. just_diag=0; % are we keeping just the amplitudes?
  47. MethodType=0; % not generating correlations, so never run r2z conversion
  48. for s=1:ts.Nsubjects
  49. grot=ts.ts((s-1)*ts.NtimepointsPerSubject+1:s*ts.NtimepointsPerSubject,:);
  50. switch lower(method)
  51. case {'cov','covariance','multiggm'} % plain cov() needed to feed into multiggm
  52. grot=cov(grot);
  53. case {'amp','amplitude'}
  54. grot=std(grot);
  55. just_diag=1; % we are keeping just the amplitudes
  56. case {'corr','correlation'}
  57. grot=corr(grot); grot(eye(N)>0)=0;
  58. MethodType=1;
  59. case {'rcorr'} % corr() after regressing out mean timecourse
  60. mgrot=mean(grot,2); grot=grot- (mgrot * (pinv(mgrot)*grot));
  61. grot=corr(grot); grot(eye(N)>0)=0;
  62. MethodType=1;
  63. case {'icov','partial'}
  64. grot=cov(grot);
  65. if nargin==4 % simple partial correlation
  66. grot=-inv(grot);
  67. else % ICOV L1-norm regularised partial correlation
  68. grot=-L1precisionBCD(grot/mean(diag(grot)),varargin{1}/1000);
  69. end
  70. grot=(grot ./ repmat(sqrt(abs(diag(grot))),1,N)) ./ repmat(sqrt(abs(diag(grot)))',N,1); grot(eye(N)>0)=0;
  71. MethodType=2;
  72. case {'ridgep'}
  73. grot=cov(grot); grot=grot/sqrt(mean(diag(grot).^2));
  74. if nargin==4
  75. rho=0.1;
  76. else
  77. rho=varargin{1};
  78. end
  79. grot=-inv(grot+rho*eye(N));
  80. grot=(grot ./ repmat(sqrt(abs(diag(grot))),1,N)) ./ repmat(sqrt(abs(diag(grot)))',N,1); grot(eye(N)>0)=0;
  81. MethodType=2;
  82. case {'pwling'}
  83. if nargin==4
  84. pwl=4;
  85. else
  86. pwl=varargin{1};
  87. end
  88. grot=pwling(grot',pwl);
  89. otherwise
  90. disp(sprintf('unknown method "%s"',method))
  91. end
  92. if just_diag==0
  93. netmats(s,:)=reshape(grot,1,N*N);
  94. else
  95. netmats(s,:)=grot;
  96. end
  97. end
  98. if (strcmp(method, 'multiggm'))
  99. if nargin==4
  100. rho=0.1;
  101. else
  102. rho=varargin{1};
  103. end
  104. NS = repmat(ts.NtimepointsPerSubject,1,ts.Nsubjects);
  105. [grotPRECISIONS grotOBJ]= learn_multitask_ggm(reshape(netmats',N,N,ts.Nsubjects), NS, rho, 20);
  106. for s=1:ts.Nsubjects
  107. grot = - reshape(grotPRECISIONS(:,:,s),N,N);
  108. grot=(grot ./ repmat(sqrt(abs(diag(grot))),1,N)) ./ repmat(sqrt(abs(diag(grot)))',N,1); grot(eye(N)>0)=0;
  109. netmats(s,:) = reshape(grot,1,N*N);
  110. end
  111. MethodType=2;
  112. end
  113. if do_rtoz==1 && MethodType>0
  114. % quick crappy estimate of median AR(1) coefficient
  115. arone=[];
  116. for s=1:ts.Nsubjects
  117. grot=ts.ts((s-1)*ts.NtimepointsPerSubject+1:s*ts.NtimepointsPerSubject,:);
  118. for i=1:N
  119. g=grot(:,i); arone=[arone sum(g(1:end-1).*g(2:end))/sum(g.*g)];
  120. end
  121. end
  122. arone=median(arone);
  123. % create null data using the estimated AR(1) coefficient
  124. clear grot*; grotR=[];
  125. for s=1:ts.Nsubjects
  126. for i=1:N
  127. grot(1)=randn(1);
  128. for t=2:ts.NtimepointsPerSubject
  129. grot(t)=grot(t-1)*arone+randn(1);
  130. end
  131. grotts((s-1)*ts.NtimepointsPerSubject+1:s*ts.NtimepointsPerSubject,i)=grot;
  132. end
  133. if MethodType==1
  134. grotr=corr(grotts((s-1)*ts.NtimepointsPerSubject+1:s*ts.NtimepointsPerSubject,:));
  135. else
  136. grotr=-inv(cov(grotts((s-1)*ts.NtimepointsPerSubject+1:s*ts.NtimepointsPerSubject,:)));
  137. grotr=(grotr ./ repmat(sqrt(abs(diag(grotr))),1,N)) ./ repmat(sqrt(abs(diag(grotr)))',N,1);
  138. end
  139. grotR=[grotR; grotr(eye(N)<1)];
  140. end
  141. grotZ=0.5*log((1+grotR)./(1-grotR));
  142. RtoZcorrection=1/std(grotZ);
  143. if do_rtoz_corr==1
  144. netmats=0.5*log((1+netmats)./(1-netmats))*RtoZcorrection;
  145. else
  146. netmats=0.5*log((1+netmats)./(1-netmats));
  147. end
  148. end
  149. if ( INMODE == 1 )
  150. netmats = reshape(netmats,N,N);
  151. end