%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  function [ WAVG ] = window_average( [N [,X [,K [,M1 [,M2]]]]])
%
%           Computed the average of selected values of a sequence
%           The function can be called with a various number of paramenters
%           When used without any arguments it produces demo data:
%                N=-20:20, X=sinusoidal(n*pi/8), K=8, M1=M2=2
%
%           N is the domain of the input sequence
%           X is the input sequence
%           K is the sample position at which to compute the average
%           M1 and M2 are the averaging left and right-sided limits
%           WAVG is the computed average within the window specified
%
%           The computation is based on the formula:
%               a = 1/(M1+M2+1) * Ó x[n-k], k=-M1...M2
%
%  Dependences: sinusoidal, limits
%

%
% Copyright © 16-Oct-2012 George P. Pavlidis® (sepdek@sepdek.net, gpavlid@gmail.com)
%
function varargout = window_average( varargin)

switch nargin
	case 0			% no arguments -> demo data
		fprintf('**No arguments :: Producing demo data of a aimple sinusodial.\n');
		n = -20:20;
		x = sinusoidal( n*pi/8);
		k = 8;
		M1 = 2;
		M2 = 2;
	case 1			% just domain -> demo data
		fprintf('**No sequence defintion :: Producing demo data of a aimple sinusodial.\n');
		n = varargin{1};
		x = sinusoidal( n*pi/8);
		k = round( mean( limits( n)));
		M1 = max( 2, round(length(n)/10));
		M2 = max( 2, round(length(n)/10));
	case 2			% domain and values -> demo averaging position & range
		fprintf('**No average position and range :: Computing at the center of the sequence.\n');
		n = varargin{1};
		x = varargin{2};
		k = round( mean( limits( n)));
		M1 = max( 2, round(length(n)/10));
		M2 = max( 2, round(length(n)/10));
	case 3			% domain, values and position -> demo averaging range
		fprintf('**No averaging range :: Computing based on the sequence.\n');
		n = varargin{1};
		x = varargin{2};
		k = varargin{3};
		M1 = max( 2, round(length(n)/10));
		M2 = max( 2, round(length(n)/10));
	case 4			% only left-sided range definition -> right=left
		n = varargin{1};
		x = varargin{2};
		k = varargin{3};
		M1 = varargin{4};
		M2 = varargin{4};
	otherwise
		n = varargin{1};
		x = varargin{2};
		k = varargin{3};
		M1 = varargin{4};
		M2 = varargin{5};
end

% parameters check-up
if k<n(1) || k>n(end)
	error( 'Averaging position overflow!');
end
if k-M1<n(1)
	error( 'Left-side range limit overflow!');
end
if k+M2>n(end)
	error( 'Right-side range limit overflow!');
end
	
% computations
scale_factor = 1 / (M1 + M2 + 1);
sample_range = find(n==k-M1):find(n==k+M2);
s = sum(x(sample_range));
mavg = scale_factor * s;

% reporing
switch nargout
	case 0
		disp( mavg);
	case 1
		varargout{1} = mavg;
	otherwise
end
