spm_robust_glm.m 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. function [B, W] = spm_robust_glm(Y, X, dim, ks)
  2. % Apply robust GLM
  3. % FORMAT [B, W] = spm_robust_glm(Y, X, dim, ks)
  4. % Y - data matrix
  5. % X - design matrix
  6. % dim - the dimension along which the function will work
  7. % ks - offset of the weighting function (default: 3)
  8. %
  9. % OUTPUT:
  10. % B - parameter estimates
  11. % W - estimated weights
  12. %
  13. % Implementation of:
  14. % Wager TD, Keller MC, Lacey SC, Jonides J.
  15. % Increased sensitivity in neuroimaging analyses using robust regression.
  16. % Neuroimage. 2005 May 15;26(1):99-113
  17. %__________________________________________________________________________
  18. % Copyright (C) 2008 Wellcome Trust Centre for Neuroimaging
  19. % James Kilner, Vladimir Litvak
  20. % $Id: spm_robust_glm.m 4407 2011-07-26 12:13:00Z vladimir $
  21. if nargin < 3 || isempty(ks)
  22. ks = 3;
  23. end
  24. if nargin < 2 || isempty(dim)
  25. dim = 1;
  26. end
  27. %-Remember the original data size and size of the mean
  28. %--------------------------------------------------------------------------
  29. origsize = size(Y);
  30. borigsize = origsize;
  31. borigsize(dim) = size(X, 2);
  32. %-Convert the data to repetitions x points matrix
  33. %--------------------------------------------------------------------------
  34. if dim > 1
  35. Y = shiftdim(Y, dim-1);
  36. end
  37. if length(origsize) > 2
  38. Y = reshape(Y, size(Y, 1), []);
  39. end
  40. %-Check the design matrix and compute leverages
  41. %--------------------------------------------------------------------------
  42. if size(X, 1) ~= size(Y, 1)
  43. error('The number of rows in the design matrix should match dimension of interest.');
  44. end
  45. H = diag(X*inv(X'*X)*X');
  46. H = repmat(H(:), 1, size(Y, 2));
  47. %-Rescale the data
  48. %--------------------------------------------------------------------------
  49. [Y, scalefactor] = spm_cond_units(Y);
  50. %-Actual robust GLM
  51. %--------------------------------------------------------------------------
  52. ores=1;
  53. nres=10;
  54. n=0;
  55. YY = Y;
  56. YY(isnan(YY)) = 0;
  57. while max(abs(ores-nres))>sqrt(1E-8)
  58. ores=nres;
  59. n=n+1;
  60. if n == 1
  61. W = ones(size(Y));
  62. W(isnan(Y)) = 0;
  63. end
  64. B = zeros(size(X, 2), size(Y, 2));
  65. for i = 1:size(Y, 2);
  66. B(:, i) = inv(X'*diag(W(:, i))*X)*X'*diag(W(:, i))*YY(:, i);
  67. end
  68. if n > 200
  69. warning('Robust GLM could not converge. Maximal number of iterations exceeded.');
  70. break;
  71. end
  72. res = Y-X*B;
  73. mad = nanmedian(abs(res-repmat(nanmedian(res), size(res, 1), 1)));
  74. res = res./repmat(mad, size(res, 1), 1);
  75. res = res.*H;
  76. res = abs(res)-ks;
  77. res(res<0)=0;
  78. nres= (sum(res(~isnan(res)).^2));
  79. W = (abs(res)<1) .* ((1 - res.^2).^2);
  80. W(isnan(Y)) = 0;
  81. W(Y == 0) = 0; %Assuming X is a real measurement
  82. end
  83. disp(['Robust GLM finished after ' num2str(n) ' iterations.']);
  84. %-Restore the betas and weights to the original data dimensions
  85. %--------------------------------------------------------------------------
  86. B = B./scalefactor;
  87. if length(origsize) > 2
  88. B = reshape(B, circshift(borigsize, [1 -(dim-1)]));
  89. W = reshape(W, circshift(origsize, [1 -(dim-1)]));
  90. end
  91. if dim > 1
  92. B = shiftdim(B, length(origsize)-dim+1);
  93. W = shiftdim(W, length(origsize)-dim+1);
  94. end
  95. %-Helper function
  96. %--------------------------------------------------------------------------
  97. function Y = nanmedian(X)
  98. if ~any(any(isnan(X)))
  99. Y = median(X);
  100. else
  101. Y = zeros(1, size(X,2));
  102. for i = 1:size(X, 2)
  103. Y(i) = median(X(~isnan(X(:, i)), i));
  104. end
  105. end