function eigenfaces()
n=40;
dim = 112*92;
x = zeros(dim,n);
% Read and vectorize the images
for i=1:n
    x(:,i) = reshape(double(imread(strcat('train/s', num2str(i), '.1.tif'))), [dim 1]);
end
% Compute the mean image
m = mean(x,2);
% Subtract the mean
x = bsxfun(@minus, x, m);
% Find the eigenvectors directly from x
[U,S,V] = svd(x);
% Plot the eigenvalues (not scaled correctly) to see how many to take
figure; plot(diag(S), 'bo'); set(gcf, 'color','w'); title('Eigenvalues');
% Plot the best 8 eigenfaces (the eigenvectors with largest eigenvalues)
figure; set(gcf, 'color', 'w'); title('8 best eigenfaces');
for i=1:8
    subplot(2,4,i); imshow(reshape(U(:,i), [112,92]), []);
end
% The basis for the eigenspace
E = U(:,1:8);
% Generate 8-dimensional "weights" for each training vector in x
W = E'*x;
% Project each test image into face space and minimize the weight difference
y = zeros(dim,n);
for i=1:n
    y(:,i) = reshape(double(imread(strcat('test/s', num2str(i), '.2.tif'))), [dim 1]);
end
y = bsxfun(@minus, y, m);
Z = E'*y;
% For each projection in Z, find the best match in W (minimum Euclidean distance)
matches = zeros(1,40);
for i=1:40
    minDistance = Inf;
    index = 0;
    for j=1:40
        distance = norm(Z(:,i) - W(:,j));
        if distance < minDistance
            minDistance = distance;
            index = j;
        end
    end
    matches(i) = index;
end
% Plot the matches (40 perfect matches would make a diagonal line)
figure; plot(matches, 'bo'); set(gcf, 'color','w'); title('Matches');
xlabel('Test image ID'); ylabel('Person ID');

end