2008-05-19 15:22:57 +02:00
|
|
|
function [abscissa,f] = kernel_density_estimate(data,number_of_grid_points,number_of_draws,bandwidth,kernel_function)
|
2008-01-21 13:09:31 +01:00
|
|
|
% Estimates a continuous density.
|
|
|
|
%
|
|
|
|
% INPUTS
|
2008-05-19 15:22:57 +02:00
|
|
|
% data [double] Vector (number_of_draws*1) of draws.
|
|
|
|
% number_of_grid_points [integer] Scalar, number of points where the density is estimated.
|
|
|
|
% This (positive) integer must be a power of two.
|
|
|
|
% number_of_draws [integer] Scalar, number of draws.
|
|
|
|
% bandwidth [double] Real positive scalar.
|
|
|
|
% kernel_function [string] Name of the kernel function: 'gaussian', 'triweight',
|
|
|
|
% 'uniform', 'triangle', 'epanechnikov', 'quartic',
|
|
|
|
% 'triweight' and 'cosinus'
|
2008-01-21 13:09:31 +01:00
|
|
|
%
|
|
|
|
% OUTPUTS
|
2008-05-19 15:22:57 +02:00
|
|
|
% abscissa [double] Vector (number_of_grid_points*1) of values on the abscissa axis.
|
|
|
|
% f: [double] Vector (number_of_grid_points*1) of values on the ordinate axis,
|
|
|
|
% (density estimates).
|
2008-01-21 13:09:31 +01:00
|
|
|
%
|
|
|
|
% SPECIAL REQUIREMENTS
|
2008-05-19 15:22:57 +02:00
|
|
|
% none.
|
|
|
|
%
|
|
|
|
% REFERENCES
|
2008-01-21 13:09:31 +01:00
|
|
|
% A kernel density estimator is used (see Silverman [1986], "Density estimation for statistics and data analysis")
|
|
|
|
% The code is adapted from Anders Holtsberg's matlab toolbox (stixbox).
|
|
|
|
%
|
|
|
|
% part of DYNARE, copyright Dynare Team (2004-2008)
|
|
|
|
% Gnu Public License.
|
|
|
|
|
2008-05-19 15:22:57 +02:00
|
|
|
if min(size(data))>1
|
|
|
|
error('kernel_density_estimate:: data must be a one dimensional array.');
|
|
|
|
else
|
|
|
|
data = data(:);
|
2005-02-18 20:54:39 +01:00
|
|
|
end
|
2008-05-19 15:22:57 +02:00
|
|
|
|
2005-02-18 20:54:39 +01:00
|
|
|
test = log(number_of_grid_points)/log(2);
|
2008-05-19 15:22:57 +02:00
|
|
|
if (abs(test-round(test)) > 1e-12)
|
|
|
|
error('kernel_density_estimate:: The number of grid points must be a power of 2.');
|
2005-02-18 20:54:39 +01:00
|
|
|
end
|
|
|
|
|
2008-05-19 15:22:57 +02:00
|
|
|
%% Kernel specification.
|
2005-02-18 20:54:39 +01:00
|
|
|
if strcmpi(kernel_function,'gaussian')
|
2008-06-12 16:42:16 +02:00
|
|
|
kernel = @(x) inv(sqrt(2*pi))*exp(-0.5*x.^2);
|
2005-02-18 20:54:39 +01:00
|
|
|
elseif strcmpi(kernel_function,'uniform')
|
2008-06-12 16:42:16 +02:00
|
|
|
kernel = @(x) 0.5*(abs(x) <= 1);
|
2005-02-18 20:54:39 +01:00
|
|
|
elseif strcmpi(kernel_function,'triangle')
|
2008-06-12 16:42:16 +02:00
|
|
|
kernel = @(x) (1-abs(x)).*(abs(x) <= 1);
|
2005-02-18 20:54:39 +01:00
|
|
|
elseif strcmpi(kernel_function,'epanechnikov')
|
2008-06-12 16:42:16 +02:00
|
|
|
kernel = @(x) 0.75*(1-x.^2).*(abs(x) <= 1);
|
2005-02-18 20:54:39 +01:00
|
|
|
elseif strcmpi(kernel_function,'quartic')
|
2008-06-12 16:42:16 +02:00
|
|
|
kernel = @(x) 0.9375*((1-x.^2).^2).*(abs(x) <= 1);
|
2005-02-18 20:54:39 +01:00
|
|
|
elseif strcmpi(kernel_function,'triweight')
|
2008-06-12 16:42:16 +02:00
|
|
|
kernel = @(x) 1.09375*((1-x.^2).^3).*(abs(x) <= 1);
|
2005-02-18 20:54:39 +01:00
|
|
|
elseif strcmpi(kernel_function,'cosinus')
|
2008-06-12 16:42:16 +02:00
|
|
|
kernel = @(x) (pi/4)*cos((pi/2)*x).*(abs(x) <= 1);
|
2005-02-18 20:54:39 +01:00
|
|
|
end
|
|
|
|
|
2008-05-19 15:22:57 +02:00
|
|
|
%% Non parametric estimation (Gaussian kernel should be used (FFT)).
|
|
|
|
lower_bound = min(data) - (max(data)-min(data))/3;
|
|
|
|
upper_bound = max(data) + (max(data)-min(data))/3;
|
|
|
|
abscissa = linspace(lower_bound,upper_bound,number_of_grid_points)';
|
|
|
|
inc = abscissa(2)-abscissa(1);
|
|
|
|
xi = zeros(number_of_grid_points,1);
|
|
|
|
xa = (data-lower_bound)/(upper_bound-lower_bound)*number_of_grid_points;
|
|
|
|
for i = 1:number_of_draws
|
2005-02-18 20:54:39 +01:00
|
|
|
indx = floor(xa(i));
|
|
|
|
temp = xa(i)-indx;
|
|
|
|
xi(indx+[1 2]) = xi(indx+[1 2]) + [1-temp,temp]';
|
2008-05-19 15:22:57 +02:00
|
|
|
end
|
|
|
|
xk = [-number_of_grid_points:number_of_grid_points-1]'*inc;
|
|
|
|
kk = kernel(xk/bandwidth);
|
|
|
|
kk = kk / (sum(kk)*inc*number_of_draws);
|
|
|
|
f = ifft(fft(fftshift(kk)).*fft([ xi ; zeros(number_of_grid_points,1) ]));
|
2005-02-18 20:54:39 +01:00
|
|
|
f = real(f(1:number_of_grid_points));
|