PageRenderTime 26ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/spm12/toolbox/spectral/spm_mar_spectra.m

https://bitbucket.org/matthewbrett/spm-versions
Objective C | 212 lines | 190 code | 22 blank | 0 comment | 34 complexity | f7af912e4ae4aae29d5606e2a35f29fc MD5 | raw file
  1. function [mar] = spm_mar_spectra (mar,freqs,ns,show)
  2. % Get spectral estimates from MAR model
  3. % FORMAT [mar] = spm_mar_spectra (mar,freqs,ns,show)
  4. %
  5. % mar - MAR data structure (see spm_mar.m)
  6. % freqs - [Nf x 1] vector of frequencies to evaluate spectra at
  7. % ns - samples per second (default: ns = 2*freqs(end))
  8. % show - 1 if you wish to plot estimates (default is 0)
  9. %
  10. % The returned mar will have the following fields specified:
  11. %
  12. % .P [Nf x d x d] Power Spectral Density matrix
  13. % .H [Nf x d x d] Transfer Function matrix
  14. % .C [Nf x d x d] Coherence matrix
  15. % .dtf [Nf x d x d] Kaminski's Directed Transfer Function matrix
  16. % .pve [Nf x d x d] Geweke's proportion of variance explained
  17. % .gew [Nf x d x d] Geweke's frequency domain Granger causality
  18. % .pdc [Nf x d x d] Baccala's Partial Directed Coherence
  19. % .L [Nf x d x d] Phase matrix
  20. % .f [Nf x 1] Frequency vector
  21. % .ns Sample rate
  22. %
  23. % dtf(f,i,j) is the DTF at frequency f from signal j to signal i
  24. % pdc(f,i,j) is the PDC at frequency f from signal j to signal i
  25. % pve(f,i,j) is the proportion of power in signal i at frequency f that can
  26. % be predicted by signal j.
  27. % gew(f,i,j) is the Granger casuality from signal j to signal i at frequency f.
  28. % gew=-log(1-pev)
  29. %
  30. % For DTF and PDC see L. Baccala and K. Sameshima (2001) Biol Cyb 84, 463-474.
  31. % For PVE and GEW see A. Brovelli et al. (2004) PNAS 101(26) 9849-9854.
  32. %
  33. % In addition to the definition of PDC in the above paper, in this
  34. % implementation PDC is also scaled by the observation noise variance
  35. % (Baccala, personal communication).
  36. %
  37. % Also note that PVE and GEW are only valid for d=2 time series
  38. %__________________________________________________________________________
  39. % Copyright (C) 2008 Wellcome Trust Centre for Neuroimaging
  40. % Will Penny
  41. % $Id: spm_mar_spectra.m 6198 2014-09-25 10:38:48Z karl $
  42. % options
  43. %--------------------------------------------------------------------------
  44. if nargin < 4 || isempty(show), show = 0; end
  45. % Nyquist
  46. %--------------------------------------------------------------------------
  47. if nargin < 3, ns = 2*freqs(end); end
  48. % dimensions (from mar.lag)
  49. %--------------------------------------------------------------------------
  50. p = length(mar.lag);
  51. d = length(mar.lag(1).a);
  52. Nf = length(freqs);
  53. mar.f = freqs;
  54. w = 2*pi*freqs/ns;
  55. % precision of innovation
  56. %--------------------------------------------------------------------------
  57. if isfield(mar,'noise_cov');
  58. noise_cov = mar.noise_cov;
  59. prec = diag(diag(inv(noise_cov)));
  60. else
  61. noise_cov = eye(d,d);
  62. prec = eye(d,d);
  63. end
  64. % Get Power Spectral Density matrix and DTF
  65. %==========================================================================
  66. for ff = 1:Nf,
  67. % transfer function (H) and CSD (P)
  68. %------------------------------------------------------------------------
  69. af_tmp = eye(d,d);
  70. for k = 1:p
  71. af_tmp = af_tmp + mar.lag(k).a*exp(-1i*w(ff)*k);
  72. end
  73. iaf_tmp = inv(af_tmp);
  74. mar.H(ff,:,:) = iaf_tmp;
  75. mar.P(ff,:,:) = iaf_tmp * noise_cov * iaf_tmp';
  76. % Get DTF and PDC
  77. %------------------------------------------------------------------------
  78. for ii = 1:d
  79. for j = 1:d
  80. % DTF uses iaf_tmp and normalises wrt rows (to = sink)
  81. %----------------------------------------------------------------
  82. mar.dtf(ff,ii,j) = abs(iaf_tmp(ii,j))/sqrt(iaf_tmp(ii,:)*iaf_tmp(ii,:)');
  83. % PDC uses af_tmp and normalises wrt columns (from = source)
  84. %----------------------------------------------------------------
  85. mar.pdc(ff,ii,j) = abs(af_tmp(ii,j))/sqrt(abs(af_tmp(:,j)'*prec*af_tmp(:,j)));
  86. end
  87. end
  88. end
  89. % Get Coherence and Phase
  90. %--------------------------------------------------------------------------
  91. for k = 1:d
  92. for j = 1:d
  93. rkj = mar.P(:,k,j)./(sqrt(mar.P(:,k,k)).*sqrt(mar.P(:,j,j)));
  94. mar.C(:,k,j) = abs(rkj);
  95. mar.L(:,k,j) = atan(imag(rkj)./real(rkj));
  96. end
  97. end
  98. % Get Geweke's formulation of Granger Causality in the Frequency domain
  99. %--------------------------------------------------------------------------
  100. C = noise_cov;
  101. for j = 1:d
  102. for k = 1:d
  103. rkj = C(j,j)-(C(j,k)^2)/C(k,k);
  104. sk = abs(mar.P(:,k,k));
  105. hkj = abs(mar.H(:,k,j)).^2;
  106. mar.pve(:,k,j) = rkj*hkj./sk;
  107. mar.gew(:,k,j) = -log(1 - mar.pve(:,k,j));
  108. end
  109. end
  110. % Normalise cross spectral density
  111. %--------------------------------------------------------------------------
  112. mar.P = 2*mar.P/ns;
  113. % plot results if requested
  114. %==========================================================================
  115. if show
  116. % Plot spectral estimates
  117. h=figure;
  118. set(h,'name','Log Power Spectral Density');
  119. for k = 1:d
  120. for j = 1:d
  121. index=(k-1)*d+j;
  122. subplot(d,d,index);
  123. psd=real(mar.P(:,k,j)).^2;
  124. plot(mar.f,log(psd));
  125. end
  126. end
  127. h=figure;
  128. set(h,'name','Coherence');
  129. for k = 1:d
  130. for j = 1:d
  131. if ~(k==j)
  132. index=(k-1)*d+j;
  133. subplot(d,d,index);
  134. coh=real(mar.C(:,k,j)).^2;
  135. plot(mar.f,coh);
  136. axis([min(mar.f) max(mar.f) 0 1]);
  137. end
  138. end
  139. end
  140. % h=figure;
  141. % set(h,'name','DTF');
  142. % for k=1:d,
  143. % for j=1:d,
  144. % if ~(k==j)
  145. % index=(k-1)*d+j;
  146. % subplot(d,d,index);
  147. % dtf=mar.dtf(:,k,j);
  148. % plot(mar.f,dtf);
  149. % end
  150. % end
  151. % end
  152. h=figure;
  153. set(h,'name','PDC');
  154. for k = 1:d
  155. for j = 1:d
  156. if ~(k==j)
  157. index=(k-1)*d+j;
  158. subplot(d,d,index);
  159. pdc=mar.pdc(:,k,j);
  160. plot(mar.f,pdc);
  161. axis([min(mar.f) max(mar.f) 0 1]);
  162. end
  163. end
  164. end
  165. % h=figure;
  166. % set(h,'name','Phase');
  167. % for k=1:d,
  168. % for j=1:d,
  169. % if ~(k==j)
  170. % index=(k-1)*d+j;
  171. % subplot(d,d,index);
  172. % ph=mar.L(:,k,j);
  173. % plot(mar.f,ph);
  174. % end
  175. % end
  176. % end
  177. %
  178. % h=figure;
  179. % set(h,'name','Delay/ms');
  180. % for k=1:d,
  181. % for j=1:d,
  182. % if ~(k==j)
  183. % index=(k-1)*d+j;
  184. % subplot(d,d,index);
  185. % ph=mar.L(:,k,j);
  186. % plot(mar.f,1000*ph'./(2*pi*mar.f));
  187. % end
  188. % end
  189. % end
  190. end