Project

Polynomial Curve Fitting Using MATLAB

For root finding, we used a given function to identify where it crossed zero i.e, where does `f(x)=0`??
So where does this given function `f(x)`come from in the first place?

  1. Analytical models of phenomena e.g.( equations from physics.)
  2. Create an equation from observed data-This is precisely what we have done in this project.

The second method can be performed in two ways,

  • Interpolation (connect the data-dots)
    This is a piece-wise, group of small `f(x)` s, linear interpolation model that has limited use in generating a general function
  • Curve fitting - capturing the trend in the data by assigning a single function across the entire range.
    The example below uses a straight-line function

A straight line is described generically by f(x) = ax + b
The goal is to identify the coefficients ‘a’ and ‘b’ such that f(x) fits the data well.

For any given data set, the curve fit might generate a polynomial function of the form

when k=1, we get a

Linear curve fitting :
Given the general form of a straight line

`f(x)=ax+b`

  • How can we pick the coefficients that best fit the line to the data?
  • What makes a particular straight line a ‘good’ fit?
  • Why does the blue line appear to us to fit the trend better?
  1. Consider the distance between the data and points on the line
  2. Add up the length of all the red and blue verticle lines
  3. This is an expression of the ‘error’ between data and the fitted line
  4. The one line that provides a minimum error is then the ‘best’ straight line

GENERATING A CURVE BY CAREFULLY CHOOSING COEFFICIENTS
Assumptions:
1) positive or negative error has the same value (data point is above or below the line)
2) Weight greater errors more heavily
We can do both of these things by squaring the distance

  • denote data values as (x, y)
  • denote points on the fitted line as (x, f(x))

now, sum the square of errors at the four data points

Our fit is a straight line, so now substitute `f(x)=ax+b`

The ‘best’ line has a minimum error between line and data points
This is called the least-squares approach since we minimize the square of the error and generate the coefficients that give us an f(x).

To find the minimum of value of the sum of squared error(SSE)


We take the derivative of the SSE in the variable form with respect to a and b, and set each to zero

re-write these above two equations after differentiating we get,

put these into matrix form

we have the data points for `(x_i,y_i)` for i=(0,1,2.....n), so we have all the summation terms in the matrix, so unknows are a and b.

Now name these as,

`AX=B`

using inbuilt function MatLab solves the following for a and b,

`X=A^-1B`

So...what do we do when a straight line is not suitable for the data set?

EXAMPLE,

We started the linear curve fit by choosing a generic form of the straight line f(x) = ax + b. This is just one kind of polynomial.

Curve fitting - higher-order polynomials:

Consider the general form for a polynomial of order j

Just as was the case for linear regression, we ask:
How can we pick the coefficients that best fit the curve to the data?

We use the same idea:
Quantify the error for these two-second order curves...
• Add up the length of all the red and blue verticle lines
• pick curve with a minimum total error which is formulated via the same least-squares approach.

Now a MATLAB code to fit using Linear and Cubic Polynomial

clear all
close all
clc
%storing the contents of the file data into a matrix b
b = load('data');

%the first column is stored as an array named temperature
temp=b(:,1);
%the second column is stored as an array named c_p
c_p=b(:,2);

plot(temp,c_p,'linewidth',3);
hold on

%using an inbuilt function 'polyfit' to generate coefficients for
%polynomial of order 1
coeff1=polyfit(temp,c_p,1);

%the new values of for y axis based on coefficients and temperature(x axis)
%is generated using an inbuilt function polyval
c_p1=polyval(coeff1,temp);
plot(temp,c_p1,'color','r');

%a similar process as above is done for generating a cubic polynomial fit
coeff2=polyfit(temp,c_p,3);
c_p2=polyval(coeff2,temp);
plot(temp,c_p2,'color','g');


xlabel('TEMPERATURE [K]');
ylabel('SPECIFIC HEAT [KJ/kmol.K]');

legend('ACTUAL DATA','LINEAR','CUBIC POLYNOMIAL','location','northwest');

Results of the code:

But in the command window, a WARNING WAS displayed

The warning shows that the higher-order polynomial is badly conditioned i.e, for any small change in input the output changes drastically. We confine this drastic change via CENTERING AND SCALING operations which is performed by the inbuilt functions polyfit and polyval.

The CODE for which is displayed below,

%using an inbuilt function 'polyfit' to generate optional outputs for the higher order polynomial
[coeff2,s2,mu2]=polyfit(temp,c_p,3);

%the new values of for y axis based on coefficients and temperature(x axis)
%is generated using an inbuilt function polyval
c_p2=polyval(coeff2,temp,s2,mu2);
plot(temp,c_p2,'color','g');




Upon doing this modification the warning of badly conditioned curve disappears, which proves that centering and scaling is one of the parameters to optimize the curve characteristic.

To measure the fitness characteristics of the fit obtained is:

R SQUARE METHOD:

We use the least square method to obtain the `f(x)`. And used centering and scaling to improve the curve characteristics. Now we keep changing the algorithm by increasing the order of a polynomial to get a better fit. This r square is used as a measure to compare different curves and to point out the best fit among them. The higher the value this method prescribes to a curve the better the fit is.

CALCULATION INSIDE R SQUARE METHOD:

Ideally when `R^2=1`the curve is termed as a perfect fit. To obtain a perfect fit is impossible. But it is better to compare different curves of different order polynomials and compare their `R^2`values. The curve that generates the highest order of `R^2` is termed as the best fit.

THE CODE FOR CALCULATION FOR `R^2`:

%to check how accurate the fit is done w.r.t the raw data we use rsquare
%method

%below is the calculation done for r square 

%calculating the average of c_p (raw data) for using in ssr
y=mean(b);
avgc_p=y(2);

%calculation of ssr values for cubic polynomial
for i=1:length(b(:,1))
y1(i)=(c_p2(i)-avgc_p)^2;
end
ssr3=sum(y1);

%calculation of sse for cubic polynomial
for j=1:length(b(:,1))
y2(j)=(c_p(j)-c_p2(j))^2;
end
sse3=sum(y2);

% calculation of r square value for cubic polynomial
sst3=ssr3+sse3;
rsq3=(ssr3/sst3)

%similar r square calculation is done for linear ploynomial
for k=1:length(b(:,1))
y3(k)=(c_p1(k)-avgc_p)^2;
end
ssr1=sum(y3);


for n=1:length(b(:,1))
y4(n)=(c_p(n)-c_p1(n))^2;
end
sse1=sum(y4);


sst1=ssr1+sse1;
rsq1=(ssr1/sst1)

The output for the code is:

From the output, we see that the `R^2` value for the cubic polynomial is higher. Therefore we can say that cubic polynomial is the best fit as compared to the linear curve.

But increasing the order makes the curve badly conditioned i.e for any slight variation in input, the output varies significantly. Therefore it is always preferred to fit the curve with a lower-order polynomial. But from the above discussion, we can conclude that a lower order polynomial for the whole curve reduces `R^2` value and hence sacrifices the accuracy of the fit

Hence the solution is to split the entire curve into many lower-order curves so that it preserves the accuracy as well as solves the problem of bad conditioning.

The code for splitting the curve is:

clear all
close all
clc

b=load('data');
temp=b(:,1);
cp=b(:,2);
x=linspace(0,3200,5);
plot(temp,cp,'linewidth',3,'color','b')
hold on
for i=1:4
    
    y=x(i)+1;
    z=x(i+1);
    coeff(i,:)=polyfit(temp(y:z),cp(y:z),2);
    cpnew(i,:)=polyval(coeff(i,:),temp(y:z));
    plot(temp(y:z),cpnew(i,:),'linewidth',3)
    L(1,y:z)=cpnew(i,:); 
    
end

%calculation of mean of cp
y=mean(b);
avgcp=y(2);


%calculation of ssr values for polynomial
for i=1:length(L)
y1(i)=(L(i)-avgcp)^2;
end
ssr=sum(y1);

%calculation of sse for cubic polynomial
for j=1:length(L)
y2(j)=(cp(j)-L(j))^2;
end
sse=sum(y2);

% calculation of r square value for cubic polynomial
sst=ssr+sse;
rsq=(ssr/sst)

The result is

A better r square value suggests that this curve is more precise i.e best fit of all the curves that we have drawn so far.

And the fact that we have used a lower order polynomial also reduces the scope for bad conditioning.

INFERENCE:

What could be done to improve the cubic fit?

Split the curve using lower polynomials and stitch it.

How to get the best fit?

  • Try increasing the order of the polynomial OR
  • SPLIT the curve by stitching together lower-order polynomials-This is more recommended as it increases accuracy and also solves bad conditioning.

How to make a curve fit perfectly?

It is impossible to fit a curve perfectly unless we have loaded in data that is already taken from a predefined curve.

The reason why the `R^2` value obtained is so close to 1 is a testament to the fact that the data loaded in this project is from a predefined curve.

Explain the parameters used to measure the fitness characteristics for both the curves.

  • `R^2` value, if low, comments about the poorness of the fit.
Your portfolio, next

Ship work like this
in your own course.

Talk to a career counsellor

Free 20-minute call. We'll map the right course to where you want to work.

By submitting you agree to our Terms and Privacy Policy.

Talk to a career counsellor

Free 20-minute call. We'll map the right course to where you want to work.

By submitting you agree to our Terms and Privacy Policy.