Search code examples
matlabstatisticsvectorizationkernel-densityprobability-density

Optimize computation time for PDF approximation based on Kernel Density Estimation


I have a code to find the pdf's approximation of a vector based on the formula for kernel estimation: enter image description here
I implemented this formula in the code below (see previous question). However, that code takes long time to run (two loops are used). Could you see the below code and help me to make it faster?

This is the code:

function pdf_est=KDE()
close all;
%%Random values of 20 pixels, range=[1 256]
data=randi([1 256],1,20)-1; %// changed: "-1"

%% Estimate histogram%%%%% 
pdf_est=zeros(1,256);
z=256;

for i=0:z-1 %// changed_ subtracted 1 
    for j=1:length(data)
        pdf_est(i+1)=pdf_est(i+1)+Gaussian(i-data(j)); %// changed: "+1" (twice)
    end
end
%% Plot real histogram 1 to 256; binsize=1;
hold on
plot(0:255, imhist(uint8(data))./length(data),'r'); %// changed: explicit x axis
%% Plot histogram estimation
plot(0:255, pdf_est./length(data),'b'); %// changed: explicit x axis
hold off
function K=Gaussian(x)
   sigma=1; %// change? Set as desired
   K=1./(sqrt(2*pi)*sigma)*exp(-x^2./(2*sigma^2));

Solution

  • You can get rid of both of those nasty nested loops and then use the hardcoded sigma to have a mega-reduced vectorized solution -

    pdf_est = sum(1./(sqrt(2*pi))*exp(-bsxfun(@minus,[0:z-1]',data).^2/2),2)
    

    Or if you would like to have the flexibility to have sigma around, use this -

    sum(1./(sqrt(2*pi)*sigma)*exp(-bsxfun(@minus,[0:z-1]',data).^2/(2*sigma^2)),2)
    

    That's all really there is!

    Quick tests put this to speedup the original code by 10x!