Curve fitting using MATLAB
AIM : To perform a curve fitting for the given dataset and to find the best fit and perfect fit for that particular dataset using Matlab.
OBJECTIVE :
- To write code to fit a linear and cubic polynomial for the Specific Heat (Cp) data.
- To plot the linear and cubic fit curves along with the raw data points.
- To study about the parameters used to measure the fitness characteristics for both the curves.
CURVE FITTING :
Curve Fitting is a process of constructing a curve or mathematical functions, which possess the closest proximity to the original or real series of data. By curve fitting, we can mathematically construct the functional relationship between the observed dataset and parameter values. It is a statistical technique used to drive coefficient values for equations that express the value of one (dependent) variable as a function of another (independent variable). It is highly effective in the mathematical modelling of some natural processes. By curve fitting we can actually study and manipulate the data for different problems and different conditions.

How to fit a curve?
To fit a curve the parameters of the real dataset is a function of undefined constants of 'nth' order polynomial.
- The first degree polynomial equation,is a line with slope `a`. A line will connect any two points, so a first degree polynomial equation is an exact fit through any two points with distinct coordinates. It is also called as equation for linear fit.
`y = ax+b`
- If the order of the equation is increased to a second degree polynomial, the following results,
`y = ax^2+bx+c`
This will exactly fit a simple curve to three points.
- If the order of the equation is increased to a third degree polynomial, the following is obtained,
`y=ax^3+bx^2+cx+d`
This is also called as cubic fit and it will fit the curve in exactly four points.
So as we increase the order of polynomial, the nature of curve changes accordingly.
Parameters used to measure the Fitness Characteristics :
After finding the curve which satisfies the given data points, we need to check the fitness characteristics of the curve or how well the equation is representing the data points. This can be done by 4 quantities which help us measure the goodness of fit criteria. They are,
- The sum of squares due to error (SSE)
- R-square
- Adjusted R-square
- Root mean squared error (RMSE)
- Sum of squares due to error (SSE) – Sum of squared errors (SSE), is the sum of the squares of results or deviations predicted from actual values of data. It is a measure of the discrepancy between the data and an estimation model. A small SSE indicates a tight fit of the model to the data. (SSE)Sum of squared errors `sum_(i=1)^n Error(i)^2`
- R-square – R-square is a statistical measure of how close the data are to the fitted regression line. R-squared is always between 0 and 1,
- 0 indicates that the model explains none of the variability of the response data around its mean.
- 1 indicates that the model explains all the variability of the response data around its mean.
In general, the higher the R-squared, the better the model fits the real data
`R^2=frac{SSR}{SST}`
where,
SSR = Sum of squares of the regression
SST = SSR + SSE
- Adjusted R-square – Adjusted R-square is a normalizing variation of R-square due to insignificant independent variables. Adjusted R-square disregards infinitesimally small increments to R-square, and only considers the variables which actually contribute to the output of the system in a drastic way.
- Root mean squared error (RMSE) – It is an estimate of the standard deviation of the random component in the data, and is defined as,
RMSE = `sqrt frac{SSE}{n}`
MATLAB code for Linear and Cubic fit:
clear all
close all
clc
% Preparing the data
cp_data = load('data');
temperature = cp_data(:,1); % first clumn is temperature data
cp = cp_data(:,2); % second column is Cp data
%LinearCurve fit
%Considering first order polynomial;Y = aX + b
[co_effs1,S,mu] = polyfit(temperature,cp,1); %polyfit command to estimate coefficients
predicted_cp1 = polyval(co_effs1, temperature,[],mu); %polyval to calculate predicted value of Cp
% Compare my curve fit with the original data
figure(1)
plot(temperature, cp, 'linewidth',3)%plotting curve for original observed data
hold on
plot(temperature, predicted_cp1,'linewidth',3,'color','r') %plotting curve for predicted data
xlabel('Temperature [K]') % labelling x axis as temperature
ylabel('Specific Heat [KJ/Kmol-k]') % labelling y axis as Cp
axis([0 4000 900 1500]) %defining axis limits
legend('Original dataset','curve fit data','Location','northwest') %providing legends to curves
title('Linear Curve Fit')
grid on
%Cubic Curve fit
% cp = a*T^3 + b*T^2 + c*T + d
[co_effs3,S,mu] = polyfit(temperature,cp,3); %polyfit command to estimate coefficients
predicted_cp3 = polyval(co_effs3, temperature,[],mu); %polyval to calculate predicted value of Cp
% Compare my curve fit with the original data
figure(2)
plot(temperature, cp, 'linewidth',3)%plotting curve for original observed data
hold on
plot(temperature, predicted_cp3,'linewidth',3,'color','r') %plotting curve for predicted data
xlabel('Temperature [K]') % labelling x axis as temperature
ylabel('Specific Heat [KJ/Kmol-k]') % labelling y axis as Cp
axis([0 4000 900 1500]) %defining axis limits
legend('Original dataset','curve fit data','Location','northwest') %providing legends to curves
title('Cubic Curve Fit')
grid on
%R^2 method to find the Fitness Characteristics of the curve
M = mean(cp);
for i = 1:length(cp)
SSR1 = sum((predicted_cp1(i)-M)^2);
SSE1 = sum((cp(i)-predicted_cp1(i))^2);
end
SST1 = SSR1 + SSE1;
R1 = SSR1/SST1
for i = 1:length(cp)
SSR3 = sum((predicted_cp3(i)-M)^2);
SSE3 = sum((cp(i)-predicted_cp3(i))^2);
end
SST3 = SSR3 + SSE3;
R3 = SSR3/SST3
EXPLANATION OF CODE:-
- The code starts with clear all, close all and clc where,
- ‘clear all’ command is used to clear the data stored in the workspace.
- ‘close all’ command is used to close all plots and figures.
- ‘clc’ command is used to clear the command window.
- Then the data of specific heat is loaded with ‘load’ command and ‘Temperature’ as well as ‘Cp’ array is defined.
- Then curve fitting is performed by using two functions,
- polyfit - p = polyfit (x,y,n)returns the coefficients for a polynomial p(x) of degree ‘n’ that is a best fit (in a least-squares sense) for the data in y. The coefficients in p are in descending powers, and the length of p is n+1. Here, the value on ‘n’ is 1 for linear and 3 for cubic, ‘x’ is ‘temperature’ and ‘y’ is 'cp' data. So [co_eff,S,mu] = polyfit (x,y,n) also returns 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, polyfit centers ‘x’ at zero and scales it to have unit standard deviation. This centering and scaling transformation improves the numerical properties of both the polynomial and the fitting algorithm.
- polyval - polyval (co_eff, temperature) returns the value of a polynomial of degree ‘n’ evaluated at ‘temperature’. The input argument ‘co_eff’ is a vector of whose elements are the coefficients in descending powers of the polynomial to be evaluated. ‘polyval’ evaluates ‘co_eff’ at each element of ‘temperature’. Here polyval (co_eff,temperature,[ ],mu) is used for centering and scaling parameters of ‘mu’ which is computed by polyfit.
- Then the curve fit data is compared with original data by plotting the curves for get linear and cubic curve fitting. The axis is shifted by using ‘axis’ command and the legend is provided for the plot.
- Here we are using R-square method to evaluate the Fitness characteristics of linear and cubic curve respectively, as mentioned above.
- M = mean(cp)returns the mean of the elements of ‘cp’ along the first array dimension.
- The values of SSR, SSE, SST and R-square for linear and cubic polynomial is calculated in a ‘for’ loop and the values of R-square are to be displayed on command window.
Values for workspace:-

Linear Curve Fit:-

Cubic Curve Fit:-

RESULTS for Linear and Cubic fit :
The value of R-square for Linear fit is found to be 0.9592 and that of Cubic fit is found to be 0.9907. As we know that the higher the value of R-square, better the fitness characteristics. Here the value of Cubic fit is higher than the value of Linear fit. So cubic curvefit has better fitness characteristics than linear curvefit. Also from both the graphs we can see that cubic curvefit has better resemblance to the original curve compared to linear curvefit.
What could be done to improve the cubic fit?
When ‘polyfit’ and ‘polyval’ command for cubic fit is used as,
co_eff3 = polyfit(temperature,cp,3);
predicted_cp3 = polyval(co_eff3,temperature);
we get a warning as “The polynomial is badly condition”. This problem can be solved by centering and scaling the points of the curve fiiting equation to get better results. Centering a variable is subtracting the mean of the variable from each data point so that the new variable's mean is 0; Scaling a variable is multiplying each data point by a constant in order to alter the range of the data. As discussed earlier, ‘mu’ which is a two element vector with centering and scaling values is entered into the code.
Best fit and Perfect fit:
Best fit – Best fit simply means that the differences between the actual measured values and the values predicted by the model equation are minimized. It does not mean the ‘Perfect Fit’. In most cases a least squares best fit does not go through all the points in the data set.
Perfect fit – Perfect fit means the curve should fit the original curve without showing any errors or residual values. In other words, if the R-square value of the curve is exactly 1.0000, then the curve is said to be Perfect fit. Perfect fit can be the best fit but best fit cannot be a Perfect fit. This is the basic difference between Best fit and Perfect fit.
How to get the Best fit?
- To get the Best fit, we should increase the degree of polynomial of the equation and reduce the residual errors.
- By doing so, we can get values of R-square close to 1.
- As stated in the results, the best curve fit from the above program is Cubic curve fit as its value of R-square = 0.9907
How to make a curve fit perfectly?
In order to make perfect fit, we must consider error estimates as well. Perfect fit means, the curve should fit the original curve without showing any errors (such as centering and scaling errors) in that perticular degree of polynomial. Perfect fit can always be a best fit but best fit can not be a perfect fit. So, in the 3rd order polynomial I have eliminated the errors, that means curve fit we got using 'Linear regression with error estimates' is perfect fit for 3rd order polynomial. But it is still not the best fit. To calculate best fit, we must increase the order or use splitwise method.
Program to Split the data and plot curve fitting :
%Program to Split the data and plot the curve.
clear all
close all
clc
%Data Preparation
cp_data = load('data');
temperature = cp_data(:,1);
cp = cp_data(:,2);
%Data Splitting
temperature1 = cp_data(1:400,1);
cp1 = cp_data(1:400,2);
temperature2 = cp_data(401:800,1);
cp2 = cp_data(401:800,2);
temperature3 = cp_data(801:1200,1);
cp3 = cp_data(801:1200,2);
temperature4 = cp_data(1201:1600,1);
cp4 = cp_data(1201:1600,2);
temperature5 = cp_data(1601:2000,1);
cp5 = cp_data(1601:2000,2);
temperature6 = cp_data(2001:2400,1);
cp6 = cp_data(2001:2400,2);
temperature7 = cp_data(2401:2800,1);
cp7 = cp_data(2401:2800,2);
temperature8 = cp_data(2801:3200,1);
cp8 = cp_data(2801:3200,2);
%Cubic Fit with Centering and Scaling
[co_eff1,S,mu] = polyfit(temperature1,cp1,3);
predicted_cp1 = polyval(co_eff1,temperature1,[],mu);
[co_eff2,S,mu] = polyfit(temperature2,cp2,3);
predicted_cp2 = polyval(co_eff2,temperature2,[],mu);
[co_eff3,S,mu] = polyfit(temperature3,cp3,3);
predicted_cp3 = polyval(co_eff3,temperature3,[],mu);
[co_eff4,S,mu] = polyfit(temperature4,cp4,3);
predicted_cp4 = polyval(co_eff4,temperature4,[],mu);
[co_eff5,S,mu] = polyfit(temperature5,cp5,3);
predicted_cp5 = polyval(co_eff5,temperature5,[],mu);
[co_eff6,S,mu] = polyfit(temperature6,cp6,3);
predicted_cp6 = polyval(co_eff6,temperature6,[],mu);
[co_eff7,S,mu] = polyfit(temperature7,cp7,3);
predicted_cp7 = polyval(co_eff7,temperature7,[],mu);
[co_eff8,S,mu] = polyfit(temperature8,cp8,3);
predicted_cp8 = polyval(co_eff8,temperature8,[],mu);
%Compare curve fit with the original data
plot(temperature,cp,'linewidth',3,'color','b')
hold on
plot(temperature1,predicted_cp1,'linewidth',3,'color','r')
hold on
plot(temperature2,predicted_cp2,'linewidth',3,'color','r')
hold on
plot(temperature3,predicted_cp3,'linewidth',3,'color','r')
hold on
plot(temperature4,predicted_cp4,'linewidth',3,'color','r')
hold on
plot(temperature5,predicted_cp5,'linewidth',3,'color','r')
hold on
plot(temperature6,predicted_cp6,'linewidth',3,'color','r')
hold on
plot(temperature7,predicted_cp7,'linewidth',3,'color','r')
hold on
plot(temperature8,predicted_cp8,'linewidth',3,'color','r')
axis([0 4000 900 1500])
xlabel('Temperature [K]')
ylabel('Specific Heat [KJ/Kmol-K]')
legend('Original Data','Splitwise data Curvefit','Location','Northwest')
title('Cubic Curve Fit with Splitted Data')
grid on
Here in this code, we have splitted the ‘cp’ data into 8 equal data sets and for each data set we have assumed the degree of polynomial as ‘3’.
Program Output :

From the above curve plot, we can say that the curve for ‘Original data’ is not visible as the ‘Splitwise data Curvefit’ has perfectly fitted the original curve.
CONCLUSION :
- From this report, we can state that there are different ways to perform Curve Fitting.
- We need to have high order polynomial equations to achieve best fit. The higher the order of the polynomial, the better is the curve.
- Splitwise method helps in getting a perfect fit for the original curve. The main factor in splitting the data is the “number of splits’. More the number of splits, better the output curve.
- With the help of these methods, we can predict and manipulate the different problems and conditions for future study.
REFERENCES:
https://in.mathworks.com/help/matlab/ref/polyfit.html?s_tid=srchtitle