clc; clear

fprintf(1,'Loading Data ....\n');
load PS5train
load PS5test

evidence_Q1_class_1=[]; evidence_Q1_class_2=[];
evidence_Q2=[];
evidence_Q3=[]; 

hlimit=7; hincrement=0.1;
degreelimit=20;
klimit=19;

%**************************************************************************************************
fprintf(1,'Solving Q1! Computing Evidence ');
for i=1:size(train1,2)
    fprintf(1,'.');
    A_1=train1; A_1(:,i)=[];
    B_1=train1(:,i);
    
    A_2=train2; A_2(:,i)=[];
    B_2=train2(:,i);
    
    evidence_Q1_class_1=[evidence_Q1_class_1; parzen_gaussian(A_1,B_1,1:hincrement:hlimit)];
    evidence_Q1_class_2=[evidence_Q1_class_2; parzen_gaussian(A_2,B_2,1:hincrement:hlimit)];
end

%Get the degree with maximum evidence
hrange=1:hincrement:hlimit;
[maxevidence maxindex]=max(mean(evidence_Q1_class_1)); h1=hrange(maxindex);
[maxevidence maxindex]=max(mean(evidence_Q1_class_2)); h2=hrange(maxindex);
fprintf(1, '\nFor class 1: h_1 = %f and h_n = h_1/sqrt(n) = %f\n', h1, h1/(sqrt(size(train1,2)-1)));
fprintf(1, 'For class 2: h_1 = %f and h_n = h_1/sqrt(n) = %f\n', h2, h2/(sqrt(size(train2,2)-1)));

subplot(3,2,1); plot(1:hincrement:hlimit, mean(evidence_Q1_class_1));
xlabel('h'); ylabel('evidence(h)'); title('Class 1: Parzen');
subplot(3,2,2); plot(1:hincrement:hlimit, mean(evidence_Q1_class_2));
xlabel('h'); ylabel('evidence(h)'); title('Class 2: Parzen');
drawnow;

fprintf(1,'\nTesting...');
correct1=0; correct2=0;
for i=1:size(test1,2)
    if parzen_gaussian(train1,test1(i),h1) >= parzen_gaussian(train2,test1(i),h2)
        correct1=correct1+1;
    end
    if parzen_gaussian(train2,test2(i),h2) >= parzen_gaussian(train1,test2(i),h1)
        correct2=correct2+1;
    end
end
fprintf(1,'\n                    Confusion Matrix for the Test Data\n');
fprintf(1,'              Recognized as Class 1          Recognized as Class 2\n');
fprintf(1,'Class 1                %d                              %d\n', correct1, size(test1,2)-correct1);
fprintf(1,'Class 2                %d                              %d\n', size(test2,2)-correct2, correct2);
fprintf(1,'Correct Classification = %f\n', 100*(correct1+correct2)/(size(test1,2)+size(test2,2)));

%**************************************************************************************************
fprintf(1,'\nSolving Q2! Computing Evidence ');
for i=1:size(train1,2)
    fprintf(1,'.');
    A_1=train1; A_1(:,i)=[]; A_2=train2;
    B_1=train1(:,i);
    
    evidence_Q2=[evidence_Q2; linear_discriminant(A_1, A_2, B_1, 1, 1:degreelimit)];
    end
for i=1:size(train2,2)
    fprintf(1,'.');
    A_1=train1; A_2=train2; A_2(:,i)=[];
    B_2=train2(:,i);
    
    evidence_Q2=[evidence_Q2; linear_discriminant(A_1, A_2, B_2,-1, 1:degreelimit)];
end

%Get the degree with maximum evidence
degrange=1:degreelimit;
[maxevidence maxindex]=max(sum(evidence_Q2)); degree_poly=degrange(maxindex);

subplot(3,1,2); plot(1:degreelimit, sum(evidence_Q2));
xlabel('Degree of Polynomial'); ylabel('evidence(degree)'); title('Class 1 and 2: Linear Discriminant');
drawnow;

fprintf(1,'\nTesting...');
correct1=0; correct2=0;
for i=1:size(test1,2)
    if linear_discriminant(train1,train2, test1(i), 1, degree_poly) == 1
        correct1=correct1+1;
    end
    if linear_discriminant(train1,train2, test2(i), -1, degree_poly) == 1
        correct2=correct2+1;
    end
end
fprintf(1,'\n                    Confusion Matrix for the Test Data\n');
fprintf(1,'              Recognized as Class 1          Recognized as Class 2\n');
fprintf(1,'Class 1                %d                              %d\n', correct1, size(test1,2)-correct1);
fprintf(1,'Class 2                %d                              %d\n', size(test2,2)-correct2, correct2);
fprintf(1,'Correct Classification = %f\n', 100*(correct1+correct2)/(size(test1,2)+size(test2,2)));

%**************************************************************************************************
fprintf(1,'\nSolving Q3! Computing Evidence ');
for i=1:size(train1,2)
    fprintf(1,'.');
    A_1=train1; A_1(:,i)=[]; A_2=train2;
    B_1=train1(:,i);
    
    evidence_Q3=[evidence_Q3; knn(A_1, A_2, B_1, 1, 1:2:klimit)];
end
for i=1:size(train2,2)
    fprintf(1,'.');
    A_1=train1; A_2=train2; A_2(:,i)=[];
    B_2=train2(:,i);
    
    evidence_Q3=[evidence_Q3; knn(A_1, A_2, B_2,-1, 1:2:klimit)];
end

%Get the degree with maximum evidence
krange=1:2:klimit;
[maxevidence maxindex]=max(sum(evidence_Q3)); k=krange(maxindex);

subplot(3,1,3); plot(1:2:klimit, sum(evidence_Q3));
xlabel('k'); ylabel('evidence(k)'); title('Class 1 and 2: K-Nearest Neighbour');
drawnow;

fprintf(1,'\nTesting...');
correct1=0; correct2=0;
for i=1:size(test1,2)
    if knn(train1,train2, test1(i), 1, k) == 1
        correct1=correct1+1;
    end
    if knn(train1,train2, test2(i), -1, k) == 1
        correct2=correct2+1;
    end
end
fprintf(1,'\n                    Confusion Matrix for the Test Data\n');
fprintf(1,'              Recognized as Class 1          Recognized as Class 2\n');
fprintf(1,'Class 1                %d                              %d\n', correct1, size(test1,2)-correct1);
fprintf(1,'Class 2                %d                              %d\n', size(test2,2)-correct2, correct2);
fprintf(1,'Correct Classification = %f\n', 100*(correct1+correct2)/(size(test1,2)+size(test2,2)));
