Project

Curve-Fitting by Piece-wise Curves and Spline Function in MatLab

Curve fitting is a process of determining a possible curve for a given set of values. This is useful in order to estimate any value that is not in the given range. In other words, it can be used to interpolate or extrapolate data.

We can fit a curve either by using the polynomial regression (check out: Polynomial Curve-fitting, RMS Error and Goodness of the Curve Fit (Order = 1 - 10)), by defining piecewise curves, or by using the spline function. [https://projects.skill-lync.com/projects/Polynomial-Curve-fitting-and-RMS-Errors-at-Different-Indices-1-10-41511]

(Data File link) [https://drive.google.com/file/d/1vWi9Vj3AdQf0gqUK1u9jwS8zg92BHGR0/view]

The MatLab code for piecewise curve-fitting and spline curve-fitting along with the explanations are below:

% Curvefitting By Piece-wise curves and Spline Function

%PIECEWISE CURVE FITTING
clear all 
close all 
clc

cp_data = load('data'); %loads a file
cp_only = cp_data(:,2); % extracting the cp values only from the data
temp_only = cp_data(:,1);


%Based on the curve, we can divide it into many curves each with its
%own polynomial equation. The curve is generally broken into a set of linear,
%sqaure or cubic polynomial for simplicity. 
%In the given data set, the polynomial-fit can be split into many parts.
%It is because at each of these data sets. the curve seems to deviate from a general polynomial function

%BREAKING THE DATE INTO PIECES

%Curve 300 - 350
cp300_350 = cp_only(1:50);   
%The temperature starts from 300 which is the first row in the file 'data'.
%Thus for every temperature range, the data input must be subtracted by 300.
%forexample temperature range of 500 to 650 would mean 200th to 350th rows
temp300_350 = temp_only(1:50);

%polyfit is an inbuilt Matlab Function which returns the coefficients
%of the polynomial 'n', based on the given values of independent and the
%dependent variables. 
Coeff300_350= polyfit(temp300_350,cp300_350,2);

%Here, selecting the degree of the polynomial is as per the choice.
%However, if MatLab warns you of the bad conditioning of the polynomial, it
%is better to lower the degree of the polynomial OR further break the curve
%into parts.

F300_350 = polyval(Coeff300_350,temp300_350);

%Creating line space for the curve

C300_350 = linspace(300,350,50);

%C300_350 is the range on the X-axis. In curve-fitting, we need to make a
%curve in such a way that we can get the value of the function at any
%point (mainly for interpolation). If we choose temp300_350 for the x-axis 
%range, we will only be finding values only at the given temperature
%values. By creating a separate line space, we obtain a curve which will give
%values for the function at any point. 

%Curve 350 - 400
cp350_400 = cp_only(51:100);
temp350_400 = temp_only(51:100);

Coeff350_400= polyfit(temp350_400,cp350_400,2);
F350_400 = polyval(Coeff350_400,temp350_400);

C350_400 = linspace(350,400,50);

%Curve 401 - 450
cp400_450 = cp_only(101:150);
temp400_450 = temp_only(101:150);

Coeff400_450= polyfit(temp400_450,cp400_450,2);
F400_450 = polyval(Coeff400_450,temp400_450);

C400_450 = linspace(400,450,50);

%Curve 451 - 750
cp450_750 = cp_only(151:450);
temp450_750 = temp_only(151:450);

Coeff450_750= polyfit(temp450_750,cp450_750,2);
F450_750 = polyval(Coeff450_750,temp450_750);

C450_750 = linspace(450,750,300);

%Curve 751 - 950
cp750_950 = cp_only(451:650);
temp750_950 = temp_only(451:650);

Coeff750_950= polyfit(temp750_950,cp750_950,2);
F750_950 = polyval(Coeff750_950,temp750_950);

C750_950 = linspace(750,950,200);

%Curve 951 - 1000
cp950_1000 = cp_only(651:700);
temp950_1000 = temp_only(651:700);

Coeff950_1000= polyfit(temp950_1000,cp950_1000,2);
F950_1000 = polyval(Coeff950_1000,temp950_1000);

C950_1000 = linspace(950,1000,50);

%Curve 1001 - 1500
cp1000_1500 = cp_only(701:1200);
temp1000_1500 = temp_only(701:1200);

Coeff1000_1500= polyfit(temp1000_1500,cp1000_1500,2);
F1000_1500 = polyval(Coeff1000_1500,temp1000_1500);

C1000_1500 = linspace(1000,1500,500);

%Curve 1501 - 1600 
cp1500_1600 = cp_only(1201:1300);
temp1500_1600 = temp_only(1201:1300);

Coeff1500_1600= polyfit(temp1500_1600,cp1500_1600,2);
F1500_1600 = polyval(Coeff1500_1600,temp1500_1600);

C1500_1600 = linspace(1500,1600,100);

%Curve 1601 - 1700
cp1600_1700 = cp_only(1301:1400);
temp1600_1700 = temp_only(1301:1400);

Coeff1600_1700= polyfit(temp1600_1700,cp1600_1700,2);
F1600_1700 = polyval(Coeff1600_1700,temp1600_1700);

C1600_1700 = linspace(1600,1700,100);

%Curve 1701 - 3000
cp1700_3000 = cp_only(1401:2700);
temp1700_3000 = temp_only(1401:2700);

Coeff1700_3000= polyfit(temp1700_3000,cp1700_3000,2);
F1700_3000 = polyval(Coeff1700_3000,temp1700_3000);

C1700_3000 = linspace(1700,3000,1300);

%Curve 3001 - 3200
cp3000_3200 = cp_only(2701:2900);
temp3000_3200 = temp_only(2701:2900);

Coeff3000_3200= polyfit(temp3000_3200,cp3000_3200,1); %Matlab returns bad conditioning at degree 2
F3000_3200 = polyval(Coeff3000_3200,temp3000_3200);

C3000_3200 = linspace(3000,3200,200);

%Curve 3201 - 3500
cp3200_3500 = cp_only(2901:3200);
temp3200_3500 = temp_only(2901:3200);

Coeff3200_3500= polyfit(temp3200_3500,cp3200_3500,1);
F3200_3500 = polyval(Coeff3200_3500,temp3200_3500);

C3200_3500 = linspace(3200,3500,300);

%PLOTTING THE PIECES

plot(temp_only,cp_only,'or') %displays each point from the dataset as red circles
hold on

plot(C300_350,F300_350,C350_400,F350_400,C400_450,F400_450,C450_750,F450_750,C750_950,F750_950,C950_1000,F950_1000,C1000_1500,F1000_1500,C1500_1600,F1500_1600,C1600_1700,F1600_1700,C1700_3000,F1700_3000,C3000_3200,F3000_3200,C3200_3500,F3200_3500,'color','k','linewidth',2)
title('Piece-wise Curve Fitting')
legend('Data Set','Piece-Wise Curves')

%I have used red points for the data set and black line for the curve-fit
%for better visuals
%If we zoom in at the curve, we can see that the curve is trying to be as
%close to the data points as possible. But, even with few breaks of
%functions, the curve does not pass into all the pints.


% The curve can be broken into as many pieces as there are spaces between
% each data point. E.g., we have 3200 points in the given data. So, there
% are 3200 - 2 = 3198 spaces between each data points. However, it is not efficient to break the
% curve into such large polynomials as it will consume a lot of time and
% efforts. In MatLab, the spline function (Cubic spline data interpolation)
% uses a cubic spline interpolation to fit a curve to a given dataset

%USING SPLINE FUNCTION

%the spline function fits a curve by defining a cubic polynomial
%bewtween each set of points. Also, spline matches the derivatives at each
%points so that a smooth curve is generated. In the spline curve fitting, each
%data point is the maxima and minima, and the curve cannot exceed them.

C  = linspace(300,3500,3200); %line space for the function
A = spline(temp_only,cp_only,C); %storing the values from spline function into A

figure(2)
hold on
plot(temp_only,cp_only,'ob')
plot(C,A,'r','linewidth',2)
title('Spline Curve Fitting')
legend('Data Set','Spline Fit')

%If we zoom into the figure, we will be able to see that the curve is
%passing through all the points of the given data. Hence, spline function
%is one of the easiest ways of curve fitting wherever there is a possibility
%of (up to) cubic interpolation

I have broken the curve into 11 piecewise curves, which seem to quite fit the curve.

However, when zoomed enough, we can see that the curve is not passing through all the data points. Also, there are some breaks and mismatch in the curve.

The curve can be broken into as many pieces as there are spaces between each data point. E.g., we have 3200 points in the given data. So, there are 3200 - 2 = 3198 spaces between each data points. However, it is not efficient to break the curve into such large polynomials as it will consume a lot of time and efforts.

In MatLab, the spline function (Cubic spline data interpolation) uses a cubic spline interpolation to fit a curve to a given dataset. the spline function actually fits a curve by defining a cubic polynomial%bewtween each set of points. Also, spline matches the derivatives at each%points so that a smooth curve is generated. In the spline curve fitting, each data point is the maxima and minima and the curve cannot exceed them.

When zoomed in, we can see that the spline fit passes through all the data points.

To get the best fit curve, spline function proves to be a very efficient tool. However, in the practical terms, a spline cannot estimate an equation for use. Spline actually defines (n-2) different equations for (n-2) gaps between data points.

For a usable process, the goodness of fit is used. [Check Polynomial Curve-fitting, RMS Error and Goodness of the Curve Fit (Order = 1 - 10)) in MatLab, [https://projects.skill-lync.com/projects/Polynomial-Curve-fitting-and-RMS-Errors-at-Different-Indices-1-10-41511]

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.