% ENSC 180 - Introduction to Engineering Analysis Tools
% Solution to Assignment #4 - Interpolation

% ----- Task 1 ----- 
time_even = 0:2:22;
time_odd = 1:2:23;
temp_even = [9.2, 9.0, 6.8, 5.9, 7.2, 9.2, 10.9, 10.6, 10.3, 8.2, 8.8, 7.5];
temp_odd =  [9.6, 7.7, 6.0, 4.3, 8.9, 10.2, 10.6, 10.7, 8.6, 8.0, 7.1, 7.5];

P = polyfit(time_even,temp_even,1); % Step 1)
temp_int_odd = polyval(P,time_odd);     % Step 2)
MSE = sum((temp_int_odd - temp_odd).^2)/length(temp_odd); % Step 3)

temp = zeros(1,24);
temp((0:2:22)+1) = temp_even;
temp((1:2:23)+1) = temp_odd;
temp_int = zeros(1,24);
temp_int((0:2:22)+1) = temp_even;
temp_int((1:2:23)+1) = temp_int_odd;
figure(1)
plot(0:23,temp,'-b',0:23,temp_int,'-r',0:23,polyval(P,0:23),'-g');
title('Hourly temperature variation')
xlabel('Time'); ylabel('Temperature (degrees Celsius)');
legend('True','Interpolated','Polynomial fit');


% ----- Task 2 ----- 
MSE = zeros(1,9);
for N = 1:9
    P = polyfit(time_even,temp_even,N); % Step 1)
    temp_int_odd = polyval(P,time_odd);     % Step 2)
    MSE(N) = sum((temp_int_odd - temp_odd).^2)/length(temp_odd); % Step 3)
end
figure(2)
plot(1:9,MSE);
title('Interpolating temperature at odd-valued hours');
xlabel('Polynomial degree'); ylabel('Interpolation MSE');
MSE


% ----- Task 3 ----- 
temp_int = zeros(1,24);
temp_int((0:2:22)+1) = temp_even;
% Nearest neighbor interpolation
for i = 1:2:23
    temp_int(i+1) = temp_int(i);
end
% A more efficient way, avoiding for loop, would be
%temp_int((1:2:23)+1) = temp_even;
MSE = sum((temp_int - temp).^2)/length(temp_odd)
figure(3)
plot(0:23,temp,'-b',0:23,temp_int,'-r');
title('Hourly temperature variation')
xlabel('Time'); ylabel('Temperature (degrees Celsius)');
legend('True','Nearest neighbor interpolation');


% ----- Task 4 ----- 
temp_int = zeros(1,24);
temp_int((0:2:22)+1) = temp_even;
% Local linear interpolation
for i = 1:2:21
    temp_int(i+1) = (temp_int(i)+ temp_int(i+2))/2;
end
temp_int(23+1) = temp_int(22+1);
MSE = sum((temp_int - temp).^2)/length(temp_odd)
figure(4)
plot(0:23,temp,'-b',0:23,temp_int,'-r');
title('Hourly temperature variation')
xlabel('Time'); ylabel('Temperature (degrees Celsius)');
legend('True','Local linear interpolation');


% ----- Task 5 -----
temp_int_odd = spline(time_even, temp_even, time_odd);
% replace the last odd sample with the last even sample (nearest neighbor
% interpolation) since it did not have a future neighbor
temp_int_odd(length(time_odd)) = temp_even(length(time_even));
MSE = sum((temp_int_odd - temp_odd).^2)/length(temp_odd)

temp_int = zeros(1,24);
temp_int((0:2:22)+1) = temp_even;
temp_int((1:2:23)+1) = temp_int_odd;
figure(5)
plot(0:23,temp,'-b',0:23,temp_int,'-r');
title('Hourly temperature variation')
xlabel('Time'); ylabel('Temperature (degrees Celsius)');
legend('True','Cubic spline interpolation');

% On this data, local linear interpolation gives the lowest MSE, followed
% by cubic spline interpolation

