moving_average

PURPOSE ^

MOVING_AVERAGE Smooths a vector through the moving average method.

SYNOPSIS ^

function [Y,Nsum] = moving_average(X,F,DIM)

DESCRIPTION ^

MOVING_AVERAGE   Smooths a vector through the moving average method.

   Syntax:
     [Y,Nsum] = moving_average(X,F,DIM);

   Input:
     X   - Vector or matrix of finite elements.
     F   - Window semi-length. A positive scalar (default 0).
     DIM - If DIM=1: smooths the columns (default); elseif DIM=2 the rows.

   Output:
     Y    - Smoothed X elements.
     Nsum - Number of not NaN's elements that fixed on the moving window.
            Provided to get a sum instead of a mean: Y.*Nsum.

   Description:
     Quickly smooths the vector X by averaging each element along with the
     2*F elements at its sides. The elements at the ends are also averaged
     but the extrems are left intact. With the windows size defined in
     this way, the filter has zero phase.

   Example:
      x = 2*pi*linspace(-1,1)'; 
      yn = cos(x) + 0.25 - 0.5*rand(size(x)); 
      ys = moving_average(yn,4);
      plot(x,[yn ys]), legend('noisy','smooth',4), axis tight

   See also FILTER, RECTWIN and MOVING_AVERAGE2, NANMOVING_AVERAGE,
   NANMOVING_AVERAGE2 by Carlos Vargas and RUNMEAN by Jos van der Geest.

CROSS-REFERENCE INFORMATION ^

This function calls: This function is called by:

SOURCE CODE ^

0001 function [Y,Nsum] = moving_average(X,F,DIM)
0002 %MOVING_AVERAGE   Smooths a vector through the moving average method.
0003 %
0004 %   Syntax:
0005 %     [Y,Nsum] = moving_average(X,F,DIM);
0006 %
0007 %   Input:
0008 %     X   - Vector or matrix of finite elements.
0009 %     F   - Window semi-length. A positive scalar (default 0).
0010 %     DIM - If DIM=1: smooths the columns (default); elseif DIM=2 the rows.
0011 %
0012 %   Output:
0013 %     Y    - Smoothed X elements.
0014 %     Nsum - Number of not NaN's elements that fixed on the moving window.
0015 %            Provided to get a sum instead of a mean: Y.*Nsum.
0016 %
0017 %   Description:
0018 %     Quickly smooths the vector X by averaging each element along with the
0019 %     2*F elements at its sides. The elements at the ends are also averaged
0020 %     but the extrems are left intact. With the windows size defined in
0021 %     this way, the filter has zero phase.
0022 %
0023 %   Example:
0024 %      x = 2*pi*linspace(-1,1)';
0025 %      yn = cos(x) + 0.25 - 0.5*rand(size(x));
0026 %      ys = moving_average(yn,4);
0027 %      plot(x,[yn ys]), legend('noisy','smooth',4), axis tight
0028 %
0029 %   See also FILTER, RECTWIN and MOVING_AVERAGE2, NANMOVING_AVERAGE,
0030 %   NANMOVING_AVERAGE2 by Carlos Vargas and RUNMEAN by Jos van der Geest.
0031 
0032 % Copyright 2006-2008  Carlos Vargas, nubeobscura@hotmail.com
0033 %    $Revision: 3.1 $  $Date: 2008/03/12 18:20:00 $
0034 
0035 %   Written by
0036 %   M. in S. Carlos Adrián Vargas Aguilera
0037 %   Physical Oceanography PhD candidate
0038 %   CICESE
0039 %   Mexico,  march 2008
0040 %
0041 %   nubeobscura@hotmail.com
0042 %
0043 %   Download from:
0044 %   http://www.mathworks.com/matlabcentral/fileexchange/loadAuthor.do?objec
0045 %   tType=author&objectId=1093874
0046 
0047 %   2008 Mar. Use CUMSUM as RUNMEAN by Jos van der Geest, no more
0048 %   subfunctions.
0049 
0050 %% Error checking:
0051 if ~nargin
0052  error('Moving_average:Inputs','There are no inputs.')
0053 elseif nargin<2 || isempty(F)
0054  F = 0;
0055 end
0056 if F==0
0057  Y = X;
0058  return
0059 end
0060 F = round(F);
0061 ndim = ndims(X);
0062 if (ndim ~= 2)
0063  error('Moving_average:Inputs','Input is not a vector or matrix.')
0064 end
0065 [N,M] = size(X);
0066 if nargin<3 || isempty(DIM)
0067  DIM = 1;
0068  if N == 1
0069   DIM = 2;
0070  end
0071 end
0072 if DIM == 2
0073  X = X.';
0074  [N,M] = size(X);
0075 end
0076 if 2*F+1>N
0077  warning('Moving_average:Inputs',... % bug fixed 06 Mar 2008
0078   'Window size must be less or equal as the number of elements.')
0079  Y = X;
0080  if DIM == 2
0081   Y = Y.';
0082  end
0083  return
0084 end
0085 
0086 %% Window width
0087 Wwidth = 2*F + 1;  
0088 
0089 %% Smooth the edges but with the first and last element intact
0090 F2 = Wwidth - 2;
0091 Nsumedge = repmat((1:2:F2)',1,M);
0092 Y1 =        X(     1:F2,:);
0093 Y2 = flipud(X(N-F2+1:N ,:));
0094 Y1 = cumsum(Y1,1);     
0095 Y2 = cumsum(Y2,1);
0096 Y1 = Y1(1:2:F2,:)./Nsumedge;            
0097 Y2 = Y2(1:2:F2,:)./Nsumedge;
0098 
0099 %% Recursive moving average method
0100 % With CUMSUM trick copied from RUNMEAN by Jos van der Geest (12 mar 2008)
0101 Y = [zeros(F+1,M); X; zeros(F,M)];
0102 Y = cumsum(Y,1);
0103 Y = Y(Wwidth+1:end,:)-Y(1:end-Wwidth,:);
0104 Y = Y/Wwidth;
0105 
0106 %% Sets the smoothed edges:
0107 Y(    1:F,:) =        Y1;
0108 Y(N-F+1:N,:) = flipud(Y2);
0109 
0110 %% Get the number of elements that were averaged for each element:
0111 if nargout == 2
0112  Nsum = repmat(Wwidth,size(Y));
0113  Nsum(    1:F,:) = Nsumedge;
0114  Nsum(N-F+1:N,:) = flipud(Nsumedge);
0115  if DIM ==2
0116   Nsum = Nsum.';
0117  end
0118 end
0119 
0120 %% Return the correct size:
0121 if DIM == 2
0122  Y = Y.';
0123 end 
0124 
0125 %% % Recursive moving average code before Jos trick:
0126 % Y = X;
0127 % Y(F+1,:) = sum(X(1:Wwidth,:),1);
0128 % for n = F+2:N-F
0129 %  Y(n,:) = sum([Y(n-1,:); X(n+F,:); -X(n-F-1,:)],1);
0130 % end
0131 % Y = Y/Wwidth;

Generated on Thu 21-Aug-2014 10:40:31 by m2html © 2005