function [h,f,xx] = plotdens(x,h,positive,kernel)
%PLOTDENS Draw a nonparametric density estimate. 
%
%         plotdens(X)
%
%	  A density estimate is plotted using a kernel density
%	  estimate. A longer form plotdens(X,h,P,K) may be used
%	  where h is the kernel bandwidth, P is 1 if the density
%	  is known to be 0 for negative X, and K is
%
%	  1 Gaussian (the default)
%	  2 Epanechnikov 
%	  3 Biweight
%	  4 Triangular
%
%	  Below the density estimate a jittered plot of the obser-
%	  vations is shown.
%
%	  See also HISTO.

%       GPL Copyright (c) Anders Holtsberg, 1999-04-26

x = x(:);
n = length(x);
if nargin < 4, kernel = 1; end
if nargin < 3, positive = 0; end
if nargin < 2, h = []; end
if isempty(h)
   h = 1.06 * std(x) * n^(-1/5);  % Silverman page 45
end
if positive & any(x < 0)
   error('There is a negative element in X')
end

mn1 = min(x);
mx1 = max(x);
mn = mn1 - (mx1-mn1)/3;
mx = mx1 + (mx1-mn1)/3;
gridsize = 256;
xx = linspace(mn,mx,gridsize)';
d = xx(2) - xx(1);
xh = zeros(size(xx));
xa = (x-mn)/(mx-mn)*gridsize;
for i=1:n
   il = floor(xa(i));
   a  = xa(i) - il;
   xh(il+[1 2]) = xh(il+[1 2])+[1-a, a]';
end

% --- Compute -------------------------------------------------

xk = [-gridsize:gridsize-1]'*d;
if kernel == 1
   K = exp(-0.5*(xk/h).^2);
elseif kernel == 2 
   K = max(0,1-(xk/h).^2/5);
elseif kernel == 3
   c = sqrt(1/7);
   K = (1-(xk/h*c).^2).^2 .* ((1-abs(xk/h*c)) > 0);
elseif kernel == 4 
   c = sqrt(1/6);
   K = max(0,1-abs(xk/h*c));
end
K = K / (sum(K)*d*n);
f = ifft(fft(fftshift(K)).*fft([xh ;zeros(size(xh))]));
f = real(f(1:gridsize));

if positive & min(xx) < 0
   m = sum(xx<0);
   f(m+(1:m)) = f(m+(1:m)) + f(m:-1:1);
   f(1:m) = zeros(size(f(1:m)));
   xx(m+[0 1]) = [0 0];
end

% --- Plot it -------------------------------------------------

plot(xx,f)
if ~ishold
   hold on
   d = diff(get(get(gcf,'CurrentAxes'),'Ylim'))/100;
   plot(x,(-rand(size(x))*6-1)*d,'.')
   plot([mn mx],[0 0])
%   plot([mn mx],-[1 1]*d*8)
   axis([mn mx -0.2*max(f) max(f)*1.2])
   hold off
end

