%% Adult Height Example

clear x label

n=200;

% Simulate the Data
for ind=1:n
    
    if rand<.5
        % Heights of Women
        x(ind)=normrnd(64,2);
        label(ind)=1;
    else
        % Heights of Men
        x(ind)=normrnd(70,2);
        label(ind)=2;
    end
end

figure(1)
hist(x)

figure(2)
hist(x(label==1))
h = findobj(gca,'Type','patch');
set(h,'FaceColor',[1 0 0],'EdgeColor','k');
hold on
hist(x(label==2))
hold off

%% Height Example Distance Matrix

%Calculate the distance matrix
distmat=zeros(n);

for ind=1:n
    for jnd=(ind+1):n
        distmat(ind,jnd)=abs(x(ind)-x(jnd));
        distmat(jnd,ind)=distmat(ind,jnd);
    end
end

figure(3) % Poor way of showing the disance matrix
imagesc(distmat);
colormap gray
colorbar

[labsort sortind]=sort(x);

figure(4) % Ideal way of showing the distance matrix
imagesc(distmat(sortind,sortind));
colormap gray
colorbar

[labsort sortind]=sort(label);

figure(5) % Good way of showing the distance matrix
imagesc(distmat(sortind,sortind));
colormap gray
colorbar

%% Classification for Heights

[labsort yind]=sort(label);

y=x(yind);

cutoff=min(find(labsort==2));

%Calculate the distance matrix
distmat=zeros(n);
for ind=1:n
    for jnd=(ind+1):n
        distmat(ind,jnd)=abs(y(ind)-y(jnd));
        distmat(jnd,ind)=distmat(ind,jnd);
    end
end

% Nearest Neighbor Classifier
NNclass=zeros(n,1);
for ind=1:n
    [dsort dind]=sort(distmat(ind,:));
    if (labsort(dind(2))==labsort(ind))
        NNclass(ind)=1;
    end
    
end

NNclassE=(n-sum(NNclass))/n*100

% Average Distance Classifier
Avgclass=zeros(n,1);
for ind=1:n
    % Calculates average distance to first group
    if (ind < cutoff)
        avgdist(1)=mean(distmat(ind,[1:(ind-1) (ind+1):(cutoff-1)]));
    else
        avgdist(1)=mean(distmat(ind,1:(cutoff-1)));
    end
    
    % Calculates average distance to first group
    if (ind >= cutoff)
        avgdist(2)=mean(distmat(ind,[cutoff:(ind-1) (ind+1):n]));
    else
        avgdist(2)=mean(distmat(ind,cutoff:n));
    end
    
    % Determines the smallest group
    [minavg pred]=min(avgdist);
    if (pred==labsort(ind))
        Avgclass(ind)=1;
    end
end

AvgclassE=(n-sum(Avgclass))/n*100


%% 2 by 3 image Example

A{1}=[1 1 1; 1 1 1];

A{2}=[1 1 1; 1 1 0];

A{3}=[1 1 0; 1 1 0];

A{4}=[1 1 0; 1 0 0];

A{5}=[1 0 1; 0 1 0];

A{6}=[0 1 0; 1 0 1];

A{7}=[1 1 1; 1 0 1];

A{8}=[0 0 0; 1 0 1];

A{9}=[0 0 0; 0 0 0];

A{10}=[0 0 1; 0 0 0];

A{11}=[0 0 0; 0 0 1];

A{12}=[0 0 0; 1 0 0];

lab=[1 1 1 1 2 2 2 2 3 3 3 3];

n=12;

% Compute distance
distE=zeros(n);
distM=zeros(n);

for ind=1:n
    for jnd=1:n
        distE(ind,jnd)=sqrt(sum(sum((im2double(A{ind})-im2double(A{jnd})).^2)));
        distM(ind,jnd)=(sum(sum(abs(im2double(A{ind})-im2double(A{jnd})))));        
    end
end

figure(31)
imagesc(distE)
colormap gray

figure(32)
imagesc(distM)
colormap gray


% Performs classification


% Nearest Neighbor Classifier
NNclassE=zeros(n,1);
NNclassM=zeros(n,1);
for ind=1:n
    [dsortE dindE]=sort(distE(ind,:));
    [dsortM dindM]=sort(distM(ind,:));
    if (lab(dindE(2))==lab(ind))
        NNclassE(ind)=1;
    end
    if (lab(dindM(2))==lab(ind))
        NNclassM(ind)=1;
    end
    
end

NNclassE=(n-sum(NNclassE))/n*100
NNclassM=(n-sum(NNclassM))/n*100



% Average Distance Classifier
Avgclass=zeros(n,1);
cutoff1=5; % the first in group 2
cutoff2=9; % the first in group 3

for ind=1:n
    %%% Euclidean Distances
    % Calculates average distance to first group
    if (ind < cutoff1)
        avgdistE(1)=mean(distE(ind,[1:(ind-1) (ind+1):(cutoff1-1)]));
    else
        avgdistE(1)=mean(distE(ind,1:(cutoff1-1)));
    end
    
    % Calculates average distance to second group
    if (ind >= cutoff1 && ind<cutoff2)
        avgdistE(2)=mean(distE(ind,[cutoff1:(ind-1) (ind+1):(cutoff2-1)]));
    else
        avgdistE(2)=mean(distE(ind,cutoff1:(cutoff2-1)));
    end
    
    % Calculates average distance to third group
    if (ind >= cutoff2)
        avgdistE(3)=mean(distE(ind,[cutoff2:(ind-1) (ind+1):n]));
    else
        avgdistE(3)=mean(distE(ind,cutoff2:n));
    end
    
    % Determines the smallest group
    [minavg pred]=min(avgdistE);
    if (pred==lab(ind))
        AvgclassE(ind)=1;
    end

    %%% Manhattan Distances    
        % Calculates average distance to first group
    if (ind < cutoff1)
        avgdistM(1)=mean(distM(ind,[1:(ind-1) (ind+1):(cutoff1-1)]));
    else
        avgdistM(1)=mean(distM(ind,1:(cutoff1-1)));
    end
    
    % Calculates average distance to second group
    if (ind >= cutoff1 && ind<cutoff2)
        avgdistM(2)=mean(distM(ind,[cutoff1:(ind-1) (ind+1):(cutoff2-1)]));
    else
        avgdistM(2)=mean(distM(ind,cutoff1:(cutoff2-1)));
    end
    
    % Calculates average distance to third group
    if (ind >= cutoff2)
        avgdistM(3)=mean(distM(ind,[cutoff2:(ind-1) (ind+1):n]));
    else
        avgdistM(3)=mean(distM(ind,cutoff2:n));
    end
    
    
    % Determines the smallest group
    [minavg pred]=min(avgdistM);
    if (pred==lab(ind))
        AvgclassM(ind)=1;
    end
    
    
    
end

AvgclassE=(n-sum(AvgclassE))/n*100
AvgclassM=(n-sum(AvgclassM))/n*100


