Curve fitting error comparison dividing the data into regions
Q1. Write code to fit a linear and cubic polynomial for the Cp data. Explain if your results are good or bad.
Code to fit linear polynomial : a + bx + cx^2 shown below
%curve fit
clear all;
close all;
clc
%data preparation
cpdata = load(\'data\');
temp = cpdata(:,1);
cp = cpdata(:,2);
figure(1)
hold on
plot(temp,cp,\'linewidth\',2,\'color\',\'g\');
xlabel(\'Temperature\');
ylabel(\'Specific Heat\');
%fitting, assuming y = f(x) = at^2 + bt + c
coeff = polyfit(temp,cp,2); %BASED ON X,Y DATA AND DEGREE OF EQ, THIS FUNCTION APPROXIMATES n CONSTANTS
predicted_cp = polyval(coeff,temp);
plot(temp,predicted_cp,\'linewidth\',2,\'color\',\'r\');
xlabel(\'Temperature\');
ylabel(\'Specific Heat\');
legend(\'Actual\',\'Predicted\',\'Location\',\'NorthWest\');
hold off
error = (cp - predicted_cp);
figure(2)
hold on
plot(temp, error);
plot(temp,0,\'linewidth\',1,\'color\',\'r\');
xlabel(\'Temperature\');
ylabel(\'Difference bw actual and predicted CP\');
disp(\'Maximum error = \')
max(error)
Maxiumum error when approximated polynomial is of order 2 : 20.9318 ; -34.2904
Graphs (attached) :
When the same program is run by changing coeff = polyfit(temp,cp,2); to coeff = polyfit(temp,cp,3); i.e approximating a cubic polynomial for the given data, the maximum error obtained is : 9.6525 ; -13.4401
The following graphs are obtained :
As we can see from the graphs and error values, obviously the cubic approximation is a better fit than the linear approximation.
Q2. What needs to be done in order to make the curve fit perfect?
In order to make the fit perfect, we can increase the order of polynomial approximated to 4 or 5 or even more. But then matlab displays the following error :
Warning: Polynomial is badly conditioned. Add points with distinct X values, reduce the degree of the
polynomial, or try centering and scaling as described in HELP POLYFIT.
To avoid this we can divide the data into sub reigons of 5 (or more for a better fit) and approximate them individually, as shown below :
%curve fit
clear all;
close all;
clc
%data preparation
cpdata = load(\'data\');
temp = cpdata(:,1);
cp = cpdata(:,2);
temp1 = cpdata(1:640,1);
cp1 = cpdata(1:640,2);
temp2 = cpdata(640:1280,1);
cp2 = cpdata(640:1280,2);
temp3 = cpdata(1280:1920,1);
cp3 = cpdata(1280:1920,2);
temp4 = cpdata(1920:2560,1);
cp4 = cpdata(1920:2560,2);
temp5 = cpdata(2560:3200,1);
cp5 = cpdata(2560:3200,2);
figure(1)
hold on
plot(temp,cp,\'linewidth\',1,\'color\',\'r\');
xlabel(\'Temperature\');
ylabel(\'Specific Heat\');
%fitting, assuming y = f(x) = at^2 + bt + c
coeff1 = polyfit(temp1,cp1,2); %BASED ON X,Y DATA AND DEGREE OF EQ, THIS FUNCTION APPROXIMATES n CONSTANTS
coeff2 = polyfit(temp2,cp2,2);
coeff3 = polyfit(temp3,cp3,2);
coeff4 = polyfit(temp4,cp4,2);
coeff5 = polyfit(temp5,cp5,2);
predicted_cp1 = polyval(coeff1,temp1);
predicted_cp2 = polyval(coeff2,temp2);
predicted_cp3 = polyval(coeff3,temp3);
predicted_cp4 = polyval(coeff4,temp4);
predicted_cp5 = polyval(coeff5,temp5);
plot(temp1,predicted_cp1,\'linewidth\',1,\'color\',\'b\');
plot(temp2,predicted_cp2,\'linewidth\',1,\'color\',\'b\');
plot(temp3,predicted_cp3,\'linewidth\',1,\'color\',\'b\');
plot(temp4,predicted_cp4,\'linewidth\',1,\'color\',\'b\');
plot(temp5,predicted_cp5,\'linewidth\',1,\'color\',\'b\');
xlabel(\'Temperature\');
ylabel(\'Specific Heat\');
legend(\'Actual\',\'Approximated\',\'location\',\'northwest\');
hold off
The code is lengthier, however the fit obtained is far far better than approximating the entire data with the help of a single equation.
Graph attached :