/tags/R2008-02-16/extra/tsa/inst/detrend.m

# · MATLAB · 157 lines · 90 code · 13 blank · 54 comment · 22 complexity · 2f08eed17b3b6fdf381496087153f845 MD5 · raw file

  1. function [X,T]=detrend(t,X,p)
  2. % DETREND removes the trend from data, NaN's are considered as missing values
  3. %
  4. % DETREND is fully compatible to previous Matlab and Octave DETREND with the following features added:
  5. % - handles NaN's by assuming that these are missing values
  6. % - handles unequally spaced data
  7. % - second output parameter gives the trend of the data
  8. % - compatible to Matlab and Octave
  9. %
  10. % [...]=detrend([t,] X [,p])
  11. % removes trend for unequally spaced data
  12. % t represents the time points
  13. % X(i) is the value at time t(i)
  14. % p must be a scalar
  15. %
  16. % [...]=detrend(X,0)
  17. % [...]=detrend(X,'constant')
  18. % removes the mean
  19. %
  20. % [...]=detrend(X,p)
  21. % removes polynomial of order p (default p=1)
  22. %
  23. % [...]=detrend(X,1) - default
  24. % [...]=detrend(X,'linear')
  25. % removes linear trend
  26. %
  27. % [X,T]=detrend(...)
  28. %
  29. % X is the detrended data
  30. % T is the removed trend
  31. %
  32. % see also: SUMSKIPNAN, ZSCORE
  33. % This program is free software; you can redistribute it and/or modify
  34. % it under the terms of the GNU General Public License as published by
  35. % the Free Software Foundation; either version 2 of the License, or
  36. % (at your option) any later version.
  37. %
  38. % This program is distributed in the hope that it will be useful,
  39. % but WITHOUT ANY WARRANTY; without even the implied warranty of
  40. % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  41. % GNU General Public License for more details.
  42. %
  43. % You should have received a copy of the GNU General Public License
  44. % along with this program; If not, see <http://www.gnu.org/licenses/>.
  45. % Copyright (C) 1995, 1996 Kurt Hornik <Kurt.Hornik@ci.tuwien.ac.at>
  46. % $Id: detrend.m 4585 2008-02-04 13:47:45Z adb014 $
  47. % Copyright (C) 2001,2007 by Alois Schloegl <a.schloegl@ieee.org>
  48. % This function is part of the TSA-toolbox
  49. % http://www.dpmi.tu-graz.ac.at/~schloegl/matlab/tsa/
  50. if (nargin == 1)
  51. p = 1;
  52. X = t;
  53. t = [];
  54. elseif (nargin == 2)
  55. if strcmpi(X,'constant'),
  56. p = 0;
  57. X = t;
  58. t = [];
  59. elseif strcmpi(X,'linear'),
  60. p = 1;
  61. X = t;
  62. t = [];
  63. elseif ischar(X)
  64. error('unknown 2nd input argument');
  65. elseif all(size(X)==1),
  66. p = X;
  67. X = t;
  68. t = [];
  69. else
  70. p = 1;
  71. end;
  72. elseif (nargin == 3)
  73. if ischar(X),
  74. warning('input arguments are not supported');
  75. end;
  76. elseif (nargin > 3)
  77. fprintf (1,'usage: detrend (x [, p])\n');
  78. end;
  79. % check data, must be in culomn order
  80. [m, n] = size (X);
  81. if (m == 1)
  82. X = X';
  83. r=n;
  84. else
  85. r=m;
  86. end
  87. % check time scale
  88. if isempty(t),
  89. t = (1:r).'; % make time scale
  90. elseif ~all(size(t)==size(X))
  91. t = t(:);
  92. end;
  93. % check dimension of t and X
  94. if ~all(size(X,1)==size(t,1))
  95. fprintf (2,'detrend: size(t,1) must same as size(x,1) \n');
  96. end;
  97. % check the order of the polynomial
  98. if (~(all(size(p)==1) & (p == round (p)) & (p >= 0)))
  99. fprintf (2,'detrend: p must be a nonnegative integer\n');
  100. end
  101. if (nargout>1) , % needs more memory
  102. T = zeros(size(X))+nan;
  103. %T=repmat(nan,size(X)); % not supported by Octave 2.0.16
  104. if (size(t,2)>1), % for multiple time scales
  105. for k=1:size(X,2),
  106. idx=find(~isnan(X(:,k)));
  107. b = (t(idx,k) * ones (1, p + 1)) .^ (ones (length(idx),1) * (0 : p));
  108. T(idx,k) = b * (b \ X(idx,k));
  109. end;
  110. else % if only one time scale is used
  111. b = (t * ones (1, p + 1)) .^ (ones (length(t),1) * (0 : p));
  112. for k=1:size(X,2),
  113. idx=find(~isnan(X(:,k)));
  114. T(idx,k) = b(idx,:) * (b(idx,:) \ X(idx,k));
  115. %X(idx,k) = X(idx,k) - T(idx,k); % 1st alternative implementation
  116. %X(:,k) = X(:,k) - T(:,k); % 2nd alternative
  117. end;
  118. end;
  119. X = X-T; % 3nd alternative
  120. if (m == 1)
  121. X = X';
  122. T = T';
  123. end
  124. else % needs less memory
  125. if (size(t,2)>1), % for multiple time scales
  126. for k = 1:size(X,2),
  127. idx = find(~isnan(X(:,k)));
  128. b = (t(idx,k) * ones (1, p + 1)) .^ (ones (length(idx),1) * (0 : p));
  129. X(idx,k) = X(idx,k) - b * (b \ X(idx,k));
  130. end;
  131. else % if only one time scale is used
  132. b = (t * ones (1, p + 1)) .^ (ones (length(t),1) * (0 : p));
  133. for k = 1:size(X,2),
  134. idx = find(~isnan(X(:,k)));
  135. X(idx,k) = X(idx,k) - b(idx,:) * (b(idx,:) \ X(idx,k));
  136. end;
  137. end;
  138. if (m == 1)
  139. X = X';
  140. end
  141. end;