%% Exercise 2
clear all; close all; clc;
%% Part a
variance=0.1;
standard_deviation = sqrt(variance);
mean_value = 0;
N=10; % # of data points
e = normrnd(mean_value,standard_deviation,[N,1]);
x=rand(N,1);
f=0.45*cos(2.1*pi*x)+0.6*sin(7*pi*x)+0.55;
y=f+e;

% for visualization purposes
N_vis=100000; % # of data points
X=rand(N_vis,1);
F=0.45*cos(2.1*pi*X)+0.6*sin(7*pi*X)+0.55;

M=[1 3 5 7 8 9]; % order of the polynomial

weights1=polyfit(x,y,M(1));
approx_function1=polyval(weights1,X);
weights3=polyfit(x,y,M(2));
approx_function3=polyval(weights3,X);
weights5=polyfit(x,y,M(3));
approx_function5=polyval(weights5,X);
weights7=polyfit(x,y,M(4));
approx_function7=polyval(weights7,X);
weights8=polyfit(x,y,M(5));
approx_function8=polyval(weights8,X);
weights9=polyfit(x,y,M(6));
approx_function9=polyval(weights9,X);

figure(1)
plot(x,y,'r*',X,F,'g.',X,approx_function1,'b.');
legend('X-Y','X-f(x)','X-Approximation function (M=1)');
title('Y Vs. f(x) Vs. Approximation function (Polynomial order=1)')
xlabel('X')
axis([0 1 -2.5 2.5])
grid on
saveas(gcf,'ex2_a1.png')

figure(2)
plot(x,y,'r*',X,F,'g.',X,approx_function3,'b.');
legend('X-Y','X-f(x)','X-Approximation function (M=3)');
title('Y Vs. f(x) Vs. Approximation function (Polynomial order=3)')
xlabel('X')
axis([0 1 -2.5 2.5])
grid on
saveas(gcf,'ex2_a2.png')

figure(3)
plot(x,y,'r*',X,F,'g.',X,approx_function5,'b.');
legend('X-Y','X-f(x)','X-Approximation function (M=5)');
title('Y Vs. f(x) Vs. Approximation function (Polynomial order=5)')
xlabel('X')
axis([0 1 -2.5 2.5])
grid on
saveas(gcf,'ex2_a3.png')

figure(4)
plot(x,y,'r*',X,F,'g.',X,approx_function7,'b.');
legend('X-Y','X-f(x)','X-Approximation function (M=7)');
title('Y Vs. f(x) Vs. Approximation function (Polynomial order=7)')
xlabel('X')
axis([0 1 -2.5 2.5])
grid on
saveas(gcf,'ex2_a4.png')

figure(5)
plot(x,y,'r*',X,F,'g.',X,approx_function8,'b.');
legend('X-Y','X-f(x)','X-Approximation function (M=8)');
axis([0 1 -2.5 2.5])
title('Y Vs. f(x) Vs. Approximation function (Polynomial order=8)')
xlabel('X')
grid on
saveas(gcf,'ex2_a5.png')

figure(6)
plot(x,y,'r*',X,F,'g.',X,approx_function9,'b.');
grid on
legend('X-Y','X-f(x)','X-Approximation function (M=9)');
axis([0 1 -2.5 2.5])
title('Y Vs. f(x) Vs. Approximation function (Polynomial order=9)')
xlabel('X')
saveas(gcf,'ex2_a6.png')

save('weights_2a.mat','weights1', 'weights3', 'weights5', 'weights7', 'weights8', 'weights9');
%% Part b
clear all;close all;clc;
variance=0.1;
standard_deviation = sqrt(variance);
mean_value = 0;
N=[10 20 100 500]; % # of data points

% For visualization purposes
N_vis=10000; % # of data points
X=rand(N_vis,1);
F=0.45*cos(2.1*pi*X)+0.6*sin(7*pi*X)+0.55;

e1 = normrnd(mean_value, standard_deviation, [N(1),1]);
x1=rand(N(1),1);
f1=0.45*cos(2.1*pi*x1)+0.6*sin(7*pi*x1)+0.55;
y1=f1+e1;
e2 = normrnd(mean_value, standard_deviation, [N(2),1]);
x2=rand(N(2),1);
f2=0.45*cos(2.1*pi*x2)+0.6*sin(7*pi*x2)+0.55;
y2=f2+e2;
e3 = normrnd(mean_value, standard_deviation, [N(3),1]);
x3=rand(N(3),1);
f3=0.45*cos(2.1*pi*x3)+0.6*sin(7*pi*x3)+0.55;
y3=f3+e3;
e4 = normrnd(mean_value, standard_deviation, [N(4),1]);
x4=rand(N(4),1);
f4=0.45*cos(2.1*pi*x4)+0.6*sin(7*pi*x4)+0.55;
y4=f4+e4;

M=9;% order of the polynomial

weights1=polyfit(x1,y1,M);
approx_function1=polyval(weights1,X);
weights2=polyfit(x2,y2,M);
approx_function2=polyval(weights2,X);
weights3=polyfit(x3,y3,M);
approx_function3=polyval(weights3,X);
weights4=polyfit(x4,y4,M);
approx_function4=polyval(weights4,X);

figure(1)
plot(x1,y1,'r*',X,F,'g.',X,approx_function1,'b.');
axis([0 1 -3 3])
legend('X-Y','X-f(x)','X-Approximation function');
title('Y Vs. f(x) Vs. Approximation function (Samples = 10)')
xlabel('X')
grid on
saveas(gcf,'ex2_b1.png')


figure(2)
plot(x2,y2,'r*',X,F,'g.',X,approx_function2,'b.');
axis([0 1 -3 3])
legend('X-Y','X-f(x)','X-Approximation function');
title('Y Vs. f(x) Vs. Approximation function (Samples = 20)')
xlabel('X')
grid on
saveas(gcf,'ex2_b2.png')


figure(3)
plot(x3,y3,'r*',X,F,'g.',X,approx_function3,'b.');
legend('X-Y','X-f(x)','X-Approximation function');
axis([0 1 -3 3])
title('Y Vs. f(x) Vs. Approximation function (Samples = 100)')
xlabel('X')
grid on
saveas(gcf,'ex2_b3.png')


figure(4)
plot(x4,y4,'r*',X,F,'g.',X,approx_function4,'b.');
axis([0 1 -3 3])
legend('X-Y','X-f(x)','X-Approximation function');
title('Y Vs. f(x) Vs. Approximation function (Samples = 500)')
xlabel('X')
grid on
saveas(gcf,'ex2_b4.png')

save('weights_2b.mat', 'weights1', 'weights2', 'weights3', 'weights4');
%% Part c
clear all;clc;close all;
variance=[0 0.1 0.2 0.5];
standard_deviation = sqrt(variance);
mean_value = 0;
N=100; % # of data points
x=rand(N,1);
M=9; % order of the polynomial
f=0.45*cos(2.1*pi*x)+0.6*sin(7*pi*x)+0.55;


% for visualization purposes
N_vis=10000; % # of data points
X=rand(N_vis,1);
F=0.45*cos(2.1*pi*X)+0.6*sin(7*pi*X)+0.55;

 
e1 = normrnd(mean_value, standard_deviation(1), [N,1]);
y1=f+e1;

e2 = normrnd(mean_value, standard_deviation(2), [N,1]);
y2=f+e2;

e3 = normrnd(mean_value, standard_deviation(3), [N,1]);
y3=f+e3;

e4 = normrnd(mean_value, standard_deviation(4), [N,1]);
y4=f+e4;

weights1=polyfit(x,y1,M);
approx_function1=polyval(weights1,X);
weights2=polyfit(x,y2,M);
approx_function2=polyval(weights2,X);
weights3=polyfit(x,y3,M);
approx_function3=polyval(weights3,X);
weights4=polyfit(x,y4,M);
approx_function4=polyval(weights4,X);

figure(1)
plot(x,y1,'ro',X,F,'g.',X,approx_function1,'b.');
axis([0 1 -3 3])
legend('X-Y','X-f(x)','X-Approximation function');
title('Y Vs. f(x) Vs. Approximation function (Variance = 0)')
xlabel('X')
grid on
saveas(gcf,'ex2_c1.png')


figure(2)
plot(x,y2,'ro',X,F,'g.',X,approx_function2,'b.');
axis([0 1 -3 3])
legend('X-Y','X-f(x)','X-Approximation function');
title('Y Vs. f(x) Vs. Approximation function (Variance = 0.1)')
xlabel('X')
grid on
saveas(gcf,'ex2_c2.png')


figure(3)
plot(x,y3,'ro',X,F,'g.',X,approx_function3,'b.');
axis([0 1 -3 3])
legend('X-Y','X-f(x)','X-Approximation function');
title('Y Vs. f(x) Vs. Approximation function (Variance = 0.2)')
xlabel('X')
grid on
saveas(gcf,'ex2_c3.png')


figure(4)
plot(x,y4,'ro',X,F,'g.',X,approx_function4,'b.');
axis([0 1 -3 3])
legend('X-Y','X-f(x)','X-Approximation function');
title('Y Vs. f(x) Vs. Approximation function (Variance = 0.5)')
xlabel('X')
grid on
saveas(gcf,'ex2_c4.png')

save('weights_2c.mat', 'weights1', 'weights2', 'weights3', 'weights4');
%% Part d
clear all;clc;close all;
variance=0.2;
standard_deviation = sqrt(variance);
N=10; % # of data points
x=rand(N,1);
e = normrnd(0, standard_deviation, [N,1]);
f=0.45*cos(2.1*pi*x)+0.6*sin(7*pi*x)+0.55;
y=f+e;
% y=y';
% Case of M=10
M1=10; % # of RBFs
g1 = [0.05 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1];
centers_1 = linspace(0,1,M1); % centers uniformly (equal distance from each other) between 0 and 1.
% Gaussian RBF
clear i;
for i=1:length(g1)
    Fi1 = gaussian_rbf(x,centers_1,g1(i),M1);
    Wml1 = inv(Fi1)*y;
    figure()
    plot(x,y,'r*')
    hold on
    grid on
    axis ([0 1 -10 10])
    fplot(@(k) 0.45*cos(2.1*pi*k)+0.6*sin(7*pi*k)+0.55, [0 1]);
    hold on
    fplot(@(k) gaussian_rbf(k,centers_1,g1(i),M1)*Wml1, [0 1]);
    legend('X-Y','X-f(x)','X-Approximation function');
    tit=strcat('Y Vs. f(x) Vs. Approximation function (RBFs = 10) - γ value =  ', num2str(g1(i)));
    title(tit)
    xlabel('X')
    title_save=strcat('ex2_d1_', num2str(i), '.png');
    saveas(gcf,title_save)
end
 close all;

% Case of M=50
M2=50; % # of RBFs
centers_2 = linspace(0,1,M2); % centers uniformly (equal distance from each other) between 0 and 1.
g2 = [0.05 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1];
clear i;
for i=1:length(g2)
    Fi2 = gaussian_rbf(x,centers_2,g2(i),M2);
    Wml2 = Fi2'*inv(Fi2*Fi2')*y;
    figure()
    plot(x,y,'r*')
    hold on
    grid on
    axis ([0 1 -10 10])
    fplot(@(k) 0.45*cos(2.1*pi*k)+0.6*sin(7*pi*k)+0.55, [0 1]);
    hold on
    fplot(@(k) gaussian_rbf(k,centers_2,g2(i),M2)*Wml2, [0 1]);
    legend('X-Y','X-f(x)','X-Approximation function');
    tit=strcat('Y Vs. f(x) Vs. Approximation function (RBFs = 50) - γ value =  ', num2str(g2(i)));
    title(tit)
    xlabel('X')
    title_save=strcat('ex2_d2_', num2str(i), '.png');
    saveas(gcf,title_save)
end
close all;
