function sheet04
% Generate data
centers = [0, 0; 7, 3; -2, 4; 0, 10; -5, -5];

[X, Y] = generate_data(centers, 50);

% plot the result
figure(1)
gscatter(X(:,1), X(:,2), Y);

% cluster the data set with different choices of K
figure(2)
[Y2, M2] = k_means_clustering(2, X);
plot_clustering(X, Y2, M2)

figure(3)
[Y5, M5] = k_means_clustering(5, X);
plot_clustering(X, Y5, M5)

figure(4)
[Y8, M8] = k_means_clustering(8, X);
plot_clustering(X, Y8, M8)


% 1. Generate data with normally distributed clusters
% with centers given by the rows of C. Generate N
% points from each cluster, and also return a vector K
% which contains the cluster indices for each point.
function [X, K] = generate_data(C, N)
% ...

% 2. Compute K-means clustering. Randomly select K points
% as initial means. Iterate while the difference
% between the old means and the new means matrix in the 
% Frobenius norm (norm(..., 'fro')) is larger than 1e-10.
%
% Return the cluster indices and the matrix of means (means
% are rows).
function [Y, MEANS] = k_means_clustering(K, X)
% ...

% Plot the clustering and the centers.
function plot_clustering(X, Y, MEANS)
gscatter(X(:, 1), X(:, 2), Y);
hold on;
plot(MEANS(:, 1), MEANS(:, 2), '+', 'MarkerSize', 10, 'LineWidth', 3);
hold off;

% Compute all pairwise distances quickly.
function D = pwdist(X, Y)
D = size(X, 2);
N = size(X, 1);
M = size(Y, 1);
  
XX = sum(X.*X, 2);
YY = sum(Y.*Y, 2);
D = repmat(XX, 1, M) + repmat(YY', N, 1) - 2*X*Y';
