function s = movingstd(x,k,windowmode) % movingstd: efficient windowed standard deviation of a time series % usage: s = movingstd(x,k,windowmode) % % Movingstd uses filter to compute the standard deviation, using % the trick of std = sqrt((sum(x.^2) - n*xbar.^2)/(n-1)). % Beware that this formula can suffer from numerical problems for % data which is large in magnitude. % % At the ends of the series, when filter would generate spurious % results otherwise, the standard deviations are corrected by % the use of shorter window lengths. % % arguments: (input) % x - vector containing time series data % % k - size of the moving window to use (see windowmode) % All windowmodes adjust the window width near the ends of % the series as necessary. % % k must be an integer, at least 1 for a 'central' window, % and at least 2 for 'forward' or 'backward' % % windowmode - (OPTIONAL) flag, denotes the type of moving window used % DEFAULT: 'central' % % windowmode = 'central' --> use a sliding window centered on % each point in the series. The window will have total width % of 2*k+1 points, thus k points on each side. % % windowmode = 'backward' --> use a sliding window that uses the % current point and looks back over a total of k points. % % windowmode = 'forward' --> use a sliding window that uses the % current point and looks forward over a total of k points. % % Any simple contraction of the above options is valid, even % as short as a single character 'c', 'b', or 'f'. Case is % ignored. % % arguments: (output) % s - vector containing the windowed standard deviation. % length(s) == length(x) % check for a windowmode if (nargin<3) || isempty(windowmode) % supply the default: windowmode = 'central'; elseif ~ischar(windowmode) error 'If supplied, windowmode must be a character flag.' end % check for a valid shortening. valid = {'central' 'forward' 'backward'}; windowmode = lower(windowmode); ind = strmatch(windowmode,valid); if isempty(ind) error 'Windowmode must be a character flag: ''c'', ''b'', or ''f''.' else windowmode = valid{ind}; end % length of the time series n = length(x); % check for valid k if (nargin<2) || isempty(k) || (rem(k,1)~=0) error 'k was not provided or not an integer.' end switch windowmode case 'central' if k<1 error 'k must be at least 1 for windowmode = ''central''.' end if n<(2*k+1) error 'k is too large for this short of a series and this windowmode.' end otherwise if k<2 error 'k must be at least 2 for windowmode = ''forward'' or ''backward''.' end if (n