function lloyd
n = 2^5;
r = 2^7;
m = r^2;
k = 0;
l = 0;
meth = 'flo';
dopt = 'col';
stop = false;
fig1 = false;
fig2 = false;
x = 1:r; y = 1:r;
[X Y] = meshgrid(x,y);
scr = get(0,'ScreenSize');
[sx, sy, n] = generate_sites(n, r, meth);
lab = label(sx, sy, X, Y);
[e,dc,h] = calc(n, m, sx, sy, lab, 'Random Init°');
fig1 = disp_label(scr, fig1, k, x, y, lab, sx, sy, dopt);
[fig2, K,E,Dc,H] = disp_graph(scr,fig2, [],[],[],[], k,e,dc,h);
while ~stop
[sx, sy] = centroidal_move(n, sx, sy, lab, X, Y);
newlab = label(sx, sy, X, Y); k=k+1;
[e,dc,h] = calc(n, m, sx, sy, newlab, '');
disp_label(scr, fig1, k, x, y, newlab, sx, sy, dopt);
[~,K,E,Dc,H] = disp_graph(scr,fig2, K,E,Dc,H, k,e,dc,h);
if E(end-1)-E(end) > eps, lab = newlab;
else l=l+1; if l>5, stop = true; end;
end
end
calc(n, m, sx, sy, lab, 'Final Lloyd');
pause; clear all; close all;
function [sx, sy, n] = generate_sites(n, r, meth)
if strcmp(meth,'uni')
no = floor(sqrt(n)); n = no^2;
l = linspace(1,r,no+2);
l = 7+l(2:no+1);
sx = reshape(ones(no,1)*l, 1, n);
sy = reshape(l'*ones(1,no), 1, n);
elseif strcmp(meth,'rnd')
sx = r*rand(1,n);
sy = r*rand(1,n);
elseif strcmp(meth,'flo')
sx = 3*r/8 + r/4*rand(1,n);
sy = 3*r/8 + r/4*rand(1,n);
else
error('Wrong point generation method');
end
function D2 = sq_dist(X,Y)
nx = size(X,1); ny = size(Y,1);
D2 = sum(X.^2,2)*ones(1,ny) + ones(nx,1)*sum(Y.^2,2)' - 2*(X*Y');
function lab = label(sx, sy, X, Y)
D2 = sq_dist([sx',sy'],[X(:),Y(:)]);
[~, lab] = min(D2, [], 1);
lab = reshape(lab, size(X));
function [sx, sy] = centroidal_move(n, sx, sy, A, X, Y)
for i=1:n
sx(i) = mean(X(A == i));
sy(i) = mean(Y(A == i));
end
function Etot = energy(n, m, sx, sy, A)
r = sqrt(m);
[X Y] = meshgrid(1:r,1:r);
D2 = sq_dist([sx',sy'],[X(:),Y(:)]);
Id = ones(n,1)*(A(:)');
[~, Yd] = meshgrid(1:m,1:n);
Idx = (Yd == Id);
E = D2(Idx);
Etot = sum(E);
function H = entropy(P)
if abs(sum(P)-1) > 1000*eps
error('Sum of probabilities not equal to 1: %0.4f', sum(P));
end
Ok = (P > eps) & (P < 1-eps);
H = sum(P(Ok).*log2(1./P(Ok)));
function [E, dc, H] = calc(n, m, sx, sy, A, str)
E = energy(n, m, sx, sy, A);
C = histc(A(:),1:n);
H = entropy(C/m);
cs = m/n;
dc = 1/n*sum((C/cs - 1).^2);
fprintf('-> E = %0.0f - dc = %0.4f - H = %0.4f bits %s\n', E, dc, H, str);
function fig1 = disp_label(scr, fig1, k, x, y, lab, sx, sy, dopt)
f1 = figure(1);
if ~fig1, fig1 = true; set(gcf,'Color',[0.2,0.2,0.2]);
set(f1,'Position',[2*scr(3)/3, scr(4)/2, scr(3)/3, scr(4)/2-50*2]); end;
tit = sprintf('-> k = %d <-', k);
if strcmp(dopt,'col')
imagesc(x,y,lab); axis image;
hold on; voronoi(sx, sy, 'w'); hold off;
elseif strcmp(dopt, 'bw')
plot(sx, sy, 'k.'); axis image;
axis([min(x) max(x) min(y) max(y)]);
else
error('Wrong display option');
end
title(tit, 'Color', 'w');
function [fig2, K,E,Dc,H] = disp_graph(scr,fig2, K,E,Dc,H, k,e,dc,h)
f2 = figure(2);
if ~fig2, fig2 = true; set(gcf,'Color',[0.2,0.2,0.2]);
set(f2,'Position',[2*scr(3)/3, 0, scr(3)/3, scr(4)/2-45*2]); end;
K = cat(1,K,k); E = cat(1,E,e); Dc = cat(1,Dc,dc); H = cat(1,H,h);
subplot(3,1,1); plot(K, E, 'r-'); title('global energy','color','w');
subplot(3,1,2); plot(K, Dc, 'b-'); title('capacity error','color','w');
subplot(3,1,3); plot(K, H, 'm-'); title('entropy','color','w');
-> E = 21774920 - dc = 2.6842 - H = 3.5352 bits Random Init°
-> E = 4078270 - dc = 1.2385 - H = 4.1530 bits
-> E = 2952635 - dc = 0.8488 - H = 4.3814 bits
-> ...
-> E = 1401286 - dc = 0.0054 - H = 4.9962 bits
-> E = 1401286 - dc = 0.0054 - H = 4.9962 bits
-> E = 1401286 - dc = 0.0054 - H = 4.9962 bits Final Lloyd