% file: homework_02.m
%
% PCA on two data sets

% open output file for writing results
%
output_file=fopen('output.text','w');


fprintf(output_file,'************************* Part 1 *******************************\n');

% the data sets were made using the file graphical_input.m

% assign data set values
%
set1=set_1;
set2=set_2;

% calculate means of each data set
%
m1=mean(set1);
m2=mean(set2);
orig_mean1=m1;
orig_mean2=m2;
fprintf(output_file,'\nmean for set 1: [%2.4f, %2.4f]\nmean for set 2: [%2.4f, %2.4f]\n\n',m1,m2);

% plot the data sets
%
main_data_plot=figure;
hold on;
box on;
grid on;
plot(set1(:,1),set1(:,2),'*');
plot(set2(:,1),set2(:,2),'r*');
set(gca,'Xtick',[-5:1:5],'Ytick',[-6:1:6]);
title('Part I');

fprintf(output_file,'************************* Part 2 *******************************\n');

fprintf(output_file,'\nThe test set:\n\n');

% define the test set
%
x1=[-1 -1];
x2=[0 0];
x3=[.5 .5];
x4=[.5,-.5];
fprintf(output_file,'x1: [%i, %i]\nx2: [%i, %i]\nx3: [%1.1f, %1.1f]\nx4: [%1.1f, %2.1f]\n\n', x1,x2,x3,x4);

% plot the test set
%
plot(x1(1),x1(2),'k*');
plot(x2(1),x2(2),'k*');
plot(x3(1),x3(2),'k*');
plot(x4(1),x4(2),'k*');
legend('Set 1','Set 2', 'Test Set');


fprintf(output_file,'************************* Part 3 *******************************\n');

fprintf(output_file,'\nTest set membership before transformations:\n\n');

% compute Euclidean distances and determine set membership for x1
%
fprintf(output_file,'x1 ');
distance=euclidean(x1,m1,m2,output_file);
fprintf(output_file,'Euclidean distances:\n');
fprintf(output_file,'x1 & set1 mean: %2.4f\n', distance(1));
fprintf(output_file,'x1 & set2 mean: %2.4f\n\n', distance(2));

% compute Euclidean distances and determine set membership for x2
%
fprintf(output_file,'x2 ');
distance=euclidean(x2,m1,m2,output_file);
fprintf(output_file,'Euclidean distances:\n');
fprintf(output_file,'x2 & set1 mean: %2.4f\n', distance(1));
fprintf(output_file,'x2 & set2 mean: %2.4f\n\n', distance(2));

% compute Euclidean distances and determine set membership for x3
%
fprintf(output_file,'x3 ');
distance=euclidean(x3,m1,m2,output_file);
fprintf(output_file,'Euclidean distances:\n');
fprintf(output_file,'x3 & set1 mean: %2.4f\n', distance(1));
fprintf(output_file,'x3 & set2 mean: %2.4f\n\n', distance(2));

% compute Euclidean distances and determine set membership for x4
%
fprintf(output_file,'x4 ');
distance=euclidean(x4,m1,m2,output_file);
fprintf(output_file,'Euclidean distances:\n');
fprintf(output_file,'x4 & set1 mean: %2.4f\n', distance(1));
fprintf(output_file,'x4 & set2 mean: %2.4f\n\n', distance(2));


fprintf(output_file,'************************* Part 4 *******************************\n\n');

% covariance matrices of set1 and set2
%
C1=cov(set1);
C2=cov(set2);

% eigen values and vectors
%
[phi1,lambda1]=eig(C1);
[phi2,lambda2]=eig(C2);

% compute the whitening transform
%
transform1=inv(sqrtm(lambda1))*transpose(phi1);
transform2=inv(sqrtm(lambda2))*transpose(phi2);

% output the whitening transform
%
fprintf(output_file,'Whitening transforms:\n\n');
fprintf(output_file,'tranform 1:[%2.4f %2.4f]\n           [%2.4f  %2.4f]\n',transform1(1,1),transform1(1,2),transform1(2,1),transform1(2,2));
fprintf(output_file,'tranform 2:[%2.4f  %2.4f]\n           [%2.4f %2.4f]\n\n',transform2(1,1),transform2(1,2),transform2(2,1),transform2(2,2));


% apply the transform to the data sets
%
new_set1=transpose(transform1*transpose(set1));
new_set2=transpose(transform2*transpose(set2));


fprintf(output_file,'************************* Part 5 *******************************\n');

fprintf(output_file,'\nTest set membership after transformations:\n\n');

% compute the mean of each set in the transform space
%
m1=mean(new_set1);
m2=mean(new_set2);
trans_mean1=m1; 
trans_mean2=m2;

% transform the test set into the first transform space
%
x1_1=transpose(transform1*transpose(x1));
x2_1=transpose(transform1*transpose(x2));
x3_1=transpose(transform1*transpose(x3));
x4_1=transpose(transform1*transpose(x4));

% transform the test set into the second transform space
%
x1_2=transpose(transform2*transpose(x1));
x2_2=transpose(transform2*transpose(x2));
x3_2=transpose(transform2*transpose(x3));
x4_2=transpose(transform2*transpose(x4));

% compute Euclidean distances and determine set membership for x1
%
fprintf(output_file,'x1 ');
distance=euclidean(x1_1,m1,m2,x1_2,output_file);
fprintf(output_file,'Euclidean distances:\n');
fprintf(output_file,'x1 & set1 mean: %2.4f\n', distance(1));
fprintf(output_file,'x1 & set2 mean: %2.4f\n\n', distance(2));

% compute Euclidean distances and determine set membership for x2
%
fprintf(output_file,'x2 ');
distance=euclidean(x2_1,m1,m2,x2_2,output_file);
fprintf(output_file,'Euclidean distances:\n');
fprintf(output_file,'x2 & set1 mean: %2.4f\n', distance(1));
fprintf(output_file,'x2 & set2 mean: %2.4f\n\n', distance(2));

% compute Euclidean distances and determine set membership for x3
%
fprintf(output_file,'x3 ');
distance=euclidean(x3_1,m1,m2,x3_2,output_file);
fprintf(output_file,'Euclidean distances:\n');
fprintf(output_file,'x3 & set1 mean: %2.4f\n', distance(1));
fprintf(output_file,'x3 & set2 mean: %2.4f\n\n', distance(2));

% compute Euclidean distances and determine set membership for x4
%
fprintf(output_file,'x4 ');
distance=euclidean(x4_1,m1,m2,x4_2,output_file);
fprintf(output_file,'Euclidean distances:\n');
fprintf(output_file,'x4 & set1 mean: %2.4f\n', distance(1));
fprintf(output_file,'x4 & set2 mean: %2.4f\n\n', distance(2));


fprintf(output_file,'************************* Part 6 *******************************\n\n');

% find the covariance of the transformed data sets
%
cov_set_1=cov(new_set1);
cov_set_2=cov(new_set2);
fprintf(output_file,'Covariance of transformed data sets:\n\n');
fprintf(output_file,'set 1: [%2.4f  %2.4f]\n       [%2.4f  %2.4f]\n',cov_set_1(1,1),cov_set_1(1,2),cov_set_1(2,1),cov_set_1(2,2));
fprintf(output_file,'set 2: [%2.4f  %2.4f]\n       [%2.4f  %2.4f]\n',cov_set_2(1,1),cov_set_2(1,2),cov_set_2(2,1),cov_set_2(2,2));




% shift the original data by the mean
%
for i=1:length(new_set1)
	set1_shift(i,:)=set1(i,:)-orig_mean1(1,:);
end

% transform the shifted data
%
set1_trans=transpose(transform1*transpose(set1_shift));

% plot the transformed and shifted data set
%
data_trans_plot1=figure;
grid on;
hold on;
box on;
plot(set1_trans(:,1),set1_trans(:,2),'*');
set(gca,'Xtick',[-5:5],'Ytick',[-6:6]);
title('Set I Transformed Data');

% shift the data by the mean
%
for i=1:length(new_set2)
	set2_shift(i,:)=set2(i,:)-orig_mean2(1,:);
end

% transform the shifted data
%
set2_trans=transpose(transform2*transpose(set2_shift));

% plot the transformed and shifted data set
%
data_trans_plot2=figure;
grid on;
hold on;
box on;
plot(set2_trans(:,1),set2_trans(:,2),'r*');
set(gca,'XTick',[-5:1:5],'YTick',[-5:1:5]);
title('Set II Transformed Data');

% close the output_file
%
fclose(output_file);
