Curve fitting
Aim:
Curve fitting with different degrees of polynomials and calculating the error to find the best fit.
Objective:
Plotting the linear and cubic fit along the given raw data points and answering the following.
- How to make a curve fit perfectly?
- How to get the best fit?
- What could be done to improve the cubic fit?
Solutions:
Linear fit
close all
clear all
clc
cp_data=load('data'); % loading the data into matlab program
temperature= cp_data(:,1); % selecting the first column of data as temperature variable
cp= cp_data(:,2); % selecting the second column of data as cp(specific heat at constant volume) variable
%cp= a*T+ c, defining the linear polynomial
co_effi = polyfit(temperature,cp,1);% generating a polynomial of degree1 of best fit
predicted_cp= polyval(co_effi,temperature); %plug in the x values i.e temperature here in the polynomial 'co_effi' created above
n=length(cp); % calculating the number of elements into the data
%plotting and comparing the original data with the predicted model
plot(temperature,cp,'linewidth',3) % plotting the original data
hold on
plot(temperature,predicted_cp,'linewidth',3); %plotting the predicted model data or the curve fit
xlabel('Temperature [K]'); %labelling the x-axis
ylabel('Specific Heat [KJ/Kmol-K]') %labelling the y-axis
legend('original data','curve fit') %alloting the legend names
%calculating the toot mean square value of error
E1= sqrt(sum(abs(predicted_cp-cp).^2/n))
The calculated RMS error for linear fit is 25.9991
Creating a Cubic fit.
close all
clear all
clc
cp_data=load('data'); % loading the data into matlab program
temperature= cp_data(:,1); % selecting the first column of data as temperature variable
cp= cp_data(:,2); % selecting the second column of data as cp(specific heat at constant volume) variable
%cp= (a*T^3)+(b*t^2)+(c*t)+d, defining the cubic polynomial
co_effi = polyfit(temperature,cp,3);% generating a cubic polynomial of best fit
predicted_cp= polyval(co_effi,temperature); %plug in the x values i.e temperature here in the polynomial 'co_effi' created above
n=length(cp); % calculating the number of elements into the data
%plotting and comparing the original data with the predicted model
plot(temperature,cp,'linewidth',3) % plotting the original data
hold on
plot(temperature,predicted_cp,'linewidth',3); %plotting the predicted model data or the curve fit
xlabel('Temperature [K]'); %labelling the x-axis
ylabel('Specific Heat [KJ/Kmol-K]') %labelling the y-axis
legend('original data','curve fit') %alloting the legend names
%calculating the toot mean square value of error
E1= sqrt(sum(abs(predicted_cp-cp).^2/n))
The RMS error value is 5.4277
But there is an error in command window about the badly conditioned polynomial.
So, the steps taken to improve this badly conditioned polynomial is the use of [p,s,mu]= polyfit(x,y,n) command which is described as,
Refrence from MathWorks MATLAB Documentation-----------------------------------------------------------[1]
[ also returns p,S,mu] = polyfit(x,y,n)mu, which is a two-element vector with centering and scaling values. mu(1) is mean(x), and mu(2) is std(x). Using these values, polyfitcenters x at zero and scales it to have unit standard deviation,
`hatx=(x-barx)/sigma_x`
This centering and scaling transformation improves the numerical properties of both the polynomial and the fitting algorithm.[1]
close all
clear all
clc
cp_data=load('data'); % loading the data into matlab program
temperature= cp_data(:,1); % selecting the first column of data as temperature variable
cp= cp_data(:,2); % selecting the second column of data as cp(specific heat at constant volume) variable
%cp= (a*T^3)+(b*t^2)+(c*t)+d, defining the cubic polynomial
[co_effi,~,mu] = polyfit(temperature,cp,3);% generating a polynomial of degree3 of best fit
predicted_cp= polyval(co_effi,temperature,[],mu); %plug in the x values i.e temperature here in the polynomial 'co_effi' created above
n=length(cp); % calculating the number of elements into the data
%plotting and comparing the original data with the predicted model
plot(temperature,cp,'linewidth',3) % plotting the original data
hold on
plot(temperature,predicted_cp,'linewidth',3); %plotting the predicted model data or the curve fit
xlabel('Temperature [K]'); %labelling the x-axis
ylabel('Specific Heat [KJ/Kmol-K]') %labelling the y-axis
legend('original data','curve fit') %alloting the legend names
%calculating the toot mean square value of error
E1= sqrt(sum(abs(predicted_cp-cp).^2/n))
The RMS error value is same 5.4277 and there was no warning about badly conditioned polynomial as before.
Perfect fit
Now plotting the perfect fit curve on the basis of splitwise fitting of polynomial in which we have divided the data into 5 segments: 1 to 400 to 750 to 1150 to 1800 to 3200.
close all
clear all
clc
cp_data=load('data'); % loading the data into matlab program
temperature= cp_data(:,1); % selecting the first column of data as temperature variable
cp= cp_data(:,2); % selecting the second column of data as cp(specific heat at constant volume) variable
%spliiting the curve into five different polynomials
cp1=cp(1:400); % % from range 1 to 400
temperature1=temperature(1:400);
cp2=cp(401:750); % % from range 401 to 750
temperature2=temperature(401:750);
cp3=cp(751:1150); % from range 751 to 1150
temperature3=temperature(751:1150);
cp4=cp(1151:1800); % from range 1151 to 1800
temperature4=temperature(1151:1800);
cp5=cp(1801:3200); % from range 1801 to 3200
temperature5=temperature(1801:3200);
[co_effi1,s1,mu1] = polyfit(temperature1,cp1,3);% generating a polynomial of degree3 of best fit from range 1 to 400
predicted_cp1= polyval(co_effi1,temperature1,[],mu1); %plug in the x values i.e temperature1 here in the polynomial 'co_effi1' created above
[co_effi2,s2,mu2] = polyfit(temperature2,cp2,3);% generating a polynomial of degree3 of best fit from range 401 to 750
predicted_cp2= polyval(co_effi2,temperature2,[],mu2); %plug in the x values i.e temperature2 here in the polynomial 'co_effi2' created above
[co_effi3,s3,mu3] = polyfit(temperature3,cp3,3);% generating a polynomial of degree3 of best fit from range 751 to 1150
predicted_cp3= polyval(co_effi3,temperature3,[],mu3); %plug in the x values i.e temperature3 here in the polynomial 'co_effi3' created above
[co_effi4,s4,mu4] = polyfit(temperature4,cp4,3);% generating a polynomial of degree3 of best fit from range 1151 to 1800
predicted_cp4= polyval(co_effi4,temperature4,[],mu4); %plug in the x values i.e temperature4 here in the polynomial 'co_effi4' created above
[co_effi5,s5,mu5] = polyfit(temperature5,cp5,3);% generating a polynomial of degree3 of best fit from range 1801 to 3200
predicted_cp5= polyval(co_effi5,temperature5,[],mu5); %plug in the x values i.e temperature5 here in the polynomial 'co_effi5' created above
n=length(cp); % calculating the number of elements into the data
predicted_cp=[predicted_cp1;predicted_cp2;predicted_cp3;predicted_cp4;predicted_cp5]; % for calculation of error value
%plotting and comparing the original data with the predicted model
plot(temperature,cp,'linewidth',3) % plotting the original data
hold on
plot(temperature1,predicted_cp1,'linewidth',3); %plotting the predicted model data or the curve fit
plot(temperature2,predicted_cp2,'linewidth',3)
plot(temperature3,predicted_cp3,'linewidth',3)
plot(temperature4,predicted_cp4,'linewidth',3)
plot(temperature5,predicted_cp5,'linewidth',3)
xlabel('Temperature [K]'); %labelling the x-axis
ylabel('Specific Heat [KJ/Kmol-K]') %labelling the y-axis
legend('original data','curve fit') %alloting the legend names
%calculating the toot mean square value of error
E1= sqrt(sum(abs(predicted_cp-cp).^2/n))
The RMS error value is 0.0876
So, the answers of the asked question in the objective section are given below in respective manner.(these answers are best suited upto my research only)
1. To make a curve fit perfectly either we can increase the degree of polynomial or we can make a splitwise fit.
2. The only way way to get the best fit is to minimise the error upto the least possible value, as it has been reported in splitwise fit case.
3. The one possible way to improve the cubic fit is shown above in the proper fashion.
Reference:
[1] MathWorks MATLAB Documentation