Challenge

Curve fitting using python

AIM

  • To fit a linear and cubic polynomial to the given c_p data
  • To plot the linear and cubic fit curves along with linear data point.

THEORY

Curve fitting

It is the process of constructing a curve or a mathematical function that fits to a series of data points subjected to constraints, as accurately as possible.

Best curve fit

A curve is said to be the best fit when it passes through a scatter plot of data while best expressing the relationships between the points. It is usually determined by finding the root mean square error pf the data points from the curve and then minimizing it. This involves a process known as linear regression.

Perfect curve fit

A curve is said to be the perfect fit when it fits the original data without showing any errors such as centring and scaling errors for that particular degree of polynomial. A perfect fit can always be a best fit but the vice versa is not true.

PROGRAM

# program to best fit given cp data
import math
import matplotlib.pyplot as plt
import numpy as np
from scipy.optimize import curve_fit

def linear_func(t,a,b):
	return a*t + b

def cubic_func(t,a,b,c,d):
	return a*pow(t,3) + b*pow(t,2) + c*t + d

def read_file():
	temperature = []
	cp = []
	for line in open('data','r'):
		values = line.split(',')
		temperature.append(float(values[0]))
		cp.append(float(values[1]))
	return [temperature,cp]

temperature,cp = read_file()
#linear fit
popt1,pcov1 = curve_fit(linear_func,temperature,cp)
fit_cp1 = linear_func(np.array(temperature),*popt1)

# cubic fit
popt2,pcov2 = curve_fit(cubic_func,temperature,cp)
fit_cp2 = cubic_func(np.array(temperature),*popt2)

#plotting
#linear fit
plt.figure(1)
plt.plot(temperature,cp,color='blue',linewidth=3)
plt.plot(temperature,fit_cp1,color='red',linewidth=3)
plt.title('linear curve fit')
plt.legend(['Actual data','curve fit'])
plt.xlabel('Temperature [K]')
plt.ylabel('Cp')
#cubic curve fit
plt.figure(2)
plt.plot(temperature,cp,color='blue',linewidth=3)
plt.plot(temperature,fit_cp2,color='red',linewidth=3)
plt.legend(['Actual data','curve fit'])
plt.xlabel('Temperature [K]')
plt.ylabel('Cp')
plt.title('cubic curve fit')

plt.show()

Popt and Pcov

Popt is an array returned by the curve fit function that contains the optimised value of the parameters of the function passed to curve_fit. In this case, it is an array containing the optimum values of the coefficients of the function in order to obtain the plot that best fits the given data.

Pcov is a matrix whose diagonal elements contain the variance of popt which can be extracted and its square root provides the standard deviation for error from the original data points.

np.array(temperature)

It is an operation possible through numpy module which passes the array containing the range of temperature to the desired function or operation.

*popt

The * here is used to refer to the values generated and stored in the popt array in order to obtain the curve fit.

Goodness of fit

The goodness of describes how well the curve fits the given data. Its measurement summarizes the discrepancy between the actual values and the expected values under the model in question. From the linear and the cubic curve fits, we can clearly see that the cubic curve fit is trying to be really close to the original data. On the other hand, the linear curve fit does not seem anywhere close to the original data. Thus, by visual inspection alone in this case, we can tell that the cubic fit is a good fit whereas the linear fit is the bad fit.

In cases where it is difficult to determine the goodness of a fit or decide which fit is better or more feasible, several mathematical techniques are used.

How to get the perfect fit

As described above, a perfect fit is the one which completely fits the data without any errors. Now, there could be several ways to obtain a perfect fit like using a higher degree polynomial. However, it is not always guaranteed that increasing the degree of the polynomial would give a perfect fit. Therefore, other methods like using the split-wise polynomial is used. In this, the range is divided into several sub-ranges and a polynomial of a suitable degree is assigned to each range in order to improve the goodness of fit. There is another way to obtain a perfect fit and that is by centering and scaling.

Split-wise curve fit

#split-wise polynomial curve fit program
import math
import matplotlib.pyplot as plt
import numpy as np
from scipy.optimize import curve_fit

def func1(t,a,b,c):
	return a*pow(t,2) + b*t + c
def func2(t,a,b,c,d):
	return a*pow(t,3) + b*pow(t,2) + c*t + d
def func3(t,a,b,c,d,e):
	return a*pow(t,4) + b*pow(t,3) + c*pow(t,2) + d*t + e
def func4(t,a,b,c,d,e,f):
	return a*pow(t,5) + b*pow(t,4) + c*pow(t,3) + d*pow(t,2) + e*t + f


def read_file():
	temperature = []
	cp = []
	for line in open('data','r'):
		values = line.split(',')
		temperature.append(float(values[0]))
		cp.append(float(values[1]))
	return [temperature,cp]

temperature,cp = read_file()
# generating domain for split-wise curve
temp1 = temperature[1:801]
cp1 = cp[1:801]
temp2 = temperature[801:1601]
cp2 = cp[801:1601]
temp3 = temperature[1601:2401]
cp3 = cp[1601:2401]
temp4 = temperature[2401:3201]
cp4 = cp[2401:3201]

popt1,pcov1 = curve_fit(func1,temp1,cp1)
fit_cp1 = func1(np.array(temp1),*popt1)
popt2,pcov2 = curve_fit(func2,temp2,cp2)
fit_cp2 = func2(np.array(temp2),*popt2)
popt3,pcov3 = curve_fit(func3,temp3,cp3)
fit_cp3 = func3(np.array(temp3),*popt3)
popt4,pcov4 = curve_fit(func4,temp4,cp4)
fit_cp4 = func4(np.array(temp4),*popt4)

# plotting
plt.figure()
plt.plot(temperature,cp,color='blue',linewidth=3)
plt.plot(temp1,fit_cp1,color='red',linewidth=3)
plt.plot(temp2,fit_cp2,color='green',linewidth=3)
plt.plot(temp3,fit_cp3,color='black',linewidth=3)
plt.plot(temp4,fit_cp4,color='yellow',linewidth=3)
plt.title('Split-wisecurve fit')
plt.xlabel('Temperature [K]')
plt.ylabel('Cp')
plt.show()

CONCLUSION

The goodness of fit increased significantly on using the split-wise polynomial. The curve fit almost exactly overlaps the original data. It is better to use such technique instead of just increasing the degree of the polynomial as it would be a lot more efficient.

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.