function [k_nearest,class,misclass] = knn(k,training_data,test_data)

dim_y2 = size(test_data,2);
dim_x2 = size(training_data,2);

x = training_data(:,1:dim_x2-1); % training features
group = training_data(:,dim_x2); % training class labels
y = test_data(:,1:dim_y2-1); % test features
test = test_data(:,dim_y2); % test class labels

[neigh_classy,neigh_disty] = nearest_neighsy_k(y,x,group);

[n1,I] = sort(neigh_disty,2); 

dimy = size(y,1);
class = zeros(dimy,1);

for i=1:dimy
    
    k_nearest = neigh_classy(i,I(i,1:k));
    class(i) = mode(k_nearest);
    
end

misclass = sum(class~=test)/dimy;


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

function [neigh_class,neigh_dist] = nearest_neighsy_k(y,x,group)

% x = training data; k = # of classes; rho = distance parameter
% neighs = matrix where column i corresponds to the neighbours of test point
% i among the training set.

dim_x = size(x,1); 
dim_y = size(y,1); 

neigh_dist = zeros(dim_y,dim_x); 
neigh_class = zeros(dim_y,dim_x); 

for i=1:dim_y
    for j=1:dim_x

        p = euclid_dist(y(i,:),x(j,:));
        neigh_dist(i,j) = p;
        neigh_class(i,j) = group(j);

    end
end

function [p] = euclid_dist(x,y)

p = sum((x-y).^2).^(0.5);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%