function [yCDF,xCDF,n,emsg] = cdfcalc(x,xname)
%CDFCALC Calculate an empirical cumulative distribution function.
%   [YCDF,XCDF] = CDFCALC(X) calculates an empirical cumulative
%   distribution function (CDF) of the observations in the data sample
%   vector X. X may be a row or column vector, and represents a random
%   sample of observations from some underlying distribution.  On
%   return XCDF is the set of X values at which the CDF increases.
%   At XCDF(i), the function increases from YCDF(i) to YCDF(i+1).
%
%   [YCDF,XCDF] = CDFCALC(X,XNAME) uses XNAME as the name of the
%   input vector in any error messages.
%
%   [YCDF,XCDF,N] = CDFCALC(...) also returns N, the sample size.
%
%   [YCDF,XCDF,N,EMSG] = CDFCALC(...) also returns an error message if X
%   is not a vector or if it contains no values other than NaN.
%
%   See also CDFPLOT.

% Author(s): Tom Lane (modified from CDFPLOT by R.A. Baker), 4/27/99
% Copyright 1993-2000 The MathWorks, Inc. 
%   $Revision: 1.3 $  $Date: 2000/05/26 17:28:30 $

% Ensure the data is a VECTOR.
yCDF = [];
xCDF = [];
if (nargin < 2)
   xname = 'X';
end
n = 0;
if (min(size(x)) ~= 1)
    emsg = sprintf('Input sample %s must be a vector.', xname);
    return;
end

% Remove missing observations indicated by NaN's.
x = x(~isnan(x));
n = length(x);
if n == 0
   emsg = sprintf('Input sample %s has no valid data (all NaN''s).', ...
                  xname);
   return;
end

% Sort observation data in ascending order.
x = sort(x(:));

%
% Compute cumulative sum such that the sample CDF is
% F(x) = (number of observations <= x) / (total number of observations).
% Note that the bin edges are padded with +/- infinity for auto-scaling of
% the x-axis.
%

% Get cumulative sums
yCDF = (1:n)' / n;

% Remove duplicates; only need final one with total count
notdup = ([diff(x(:)); 1] > 0);
xCDF = x(notdup);
yCDF = [0; yCDF(notdup)];
emsg = '';

