Performing Curve Fitting Using Python
OBJECTIVE:
To write a python program to perform curve fitting for different equations and to determine the best fit.
1. What does popt and pcov mean?
popt is an array with the best estimated values for the coefficients in the equation.
For example, for the equation:
at^3+bt^2+ct+d=0
popt stores the values of the parameters a,b,c,d
pcov is the covariance matrix. It has the estimated values of co-variance in the parameters of popt. It can be used to find the deviation of the parameters from the mean value.
2. What does np.array(temperature) do?
The function np.array() used to perform mathematical and logical operations to each values in the array. It is mainly used to perform various matix operations.
For example:
temperature*2 is used to increase the size of the array by two times with the elements of temperature array. Its almost similar to concatination.
while np.array(temperature)*2 will consider the array as a matrix so that each and every elements in the temperture array gets multiplied by 2.
3. What does the * in *popt mean?
The popt variable has the all the best estimated coefficient values of the equation used for the curve fit. The '*' in popt is used to unpack all the values in popt in order to pass multiple variables to the function.
4. Write code to fit a linear and cubic polynomial for the Cp data.
EQUATIONS USED:
- Linear equation: at+b=0
- Quadratic equation: at^2+bt+c=0
- Cubic equation: at^3+bt^2+ct+d=0
- Quartic equation: at^4+bt^3+ct^2+dt+e=0
PROGRAM:
import math
import matplotlib.pyplot as plt
import numpy as np
from scipy.optimize import curve_fit
from prettytable import PrettyTable
table=PrettyTable()
#CURVE FIT FUNCTION
def linear_curve(t,a,b):
return a*t+b
def quadratic_curve(t,a,b,c):
return a*t**2+b*t+c
def cubic_curve(t,a,b,c,d):
return a*t**3+b*t**2+c*t+d
def quartic_curve(t,a,b,c,d,e):
return a*t**4+b*t**3+c*t**2+d*t+e
#Reading the date file
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]
#Main Program
temperature, cp = read_file()
#linear curve
popt,pcov= curve_fit(linear_curve,temperature,cp)
fit_cp=linear_curve(np.array(temperature), *popt)
#ploting the linear curve
plt.plot(temperature,cp,color='blue')
plt.plot(temperature,fit_cp,color='r',linewidth=3)
plt.legend(["Actual Data","Curve Fit"])
plt.xlabel("Temperature")
plt.ylabel("Cp")
plt.grid(True)
plt.title("Curve Fit of Liner Polynomial")
plt.savefig("Linear_curve.png")
plt.show()
#Quadratic curve
popt_2,pcov_2= curve_fit(quadratic_curve,temperature,cp)
fit_cp_2=quadratic_curve(np.array(temperature), *popt_2)
#ploting the Quadratic curve
plt.plot(temperature,cp,color='blue')
plt.plot(temperature,fit_cp_2,color='r',linewidth=3)
plt.legend(["Actual Data","Curve Fit"])
plt.xlabel("Temperature")
plt.ylabel("Cp")
plt.grid(True)
plt.title("Curve Fit of Quadratic Polynomial")
plt.savefig("Quadratic_curve.png")
plt.show()
#Cubic curve
popt_3,pcov_3= curve_fit(cubic_curve,temperature,cp)
fit_cp_3=cubic_curve(np.array(temperature), *popt_3)
#ploting the Cubic curve
plt.plot(temperature,cp,color='blue')
plt.plot(temperature,fit_cp_3,color='r',linewidth=3)
plt.legend(["Actual Data","Curve Fit"])
plt.xlabel("Temperature")
plt.ylabel("Cp")
plt.grid(True)
plt.title("Curve Fit of Cubic Polynomial")
plt.savefig("Cubic_curve.png")
plt.show()
#Quartic curve
popt_4,pcov_4= curve_fit(quartic_curve,temperature,cp)
fit_cp_4=quartic_curve(np.array(temperature), *popt_4)
#ploting the Quadratic curve
plt.plot(temperature,cp,color='blue')
plt.plot(temperature,fit_cp_4,color='r',linewidth=3)
plt.legend(["Actual Data","Curve Fit"])
plt.xlabel("Temperature")
plt.ylabel("Cp")
plt.grid(True)
plt.title("Curve Fit of Quartic Polynomial")
plt.savefig("quartic_curve.png")
plt.show()
#checking the quality of the fit using R-square method
table.field_names=["Curve", "R_square", "RMSE" ]
curve=["Linear","Quadratic","Cubic","Quartic"]
def r_sq(fit,i):
mean=sum(fit)/(len(fit))
SSR=sum((np.array(fit)-mean)**2)
SSE=sum((np.array(cp)-np.array(fit))**2)
SST=SSR+SSE
R_square=SSR/SST
RMSE=math.sqrt(SSE/(len(fit)))
table.add_row([curve[i], round(R_square,4),round(RMSE,4)])
r_sq(np.array(fit_cp),0)
r_sq(np.array(fit_cp_2),1)
r_sq(np.array(fit_cp_3),2)
r_sq(np.array(fit_cp_4),3)
print(table)
CODE EXPLANATION:
After importing all the necessary modules, 4 functions with the curve equation are defined.
The read_file function is defined to read and store the column wise data in temperature and Cp variables. Split function is used to split the line wherever the ',' is found and are stored as two different elements in the values variable.
The curve_fit function is used to find the best estimated values for the coefficients in the equation along with their covariance. The values of the coefficients are then passed to the equation along with the temperature values to find the suitable value of Cp.By this, the new value of Cp is found.
OUTPUT:
- Curve fit using Linear equation:
- Curve fit using Quadratic equation:
- Curve fit using Cubic equation:
- Curve fit using Quartic equation:
- Table showing the R-square and Root mean square error:
5. What needs to be done in order to make the curve fit perfect?
Generally,perfect fit curves are obtained from higher order equations. Increasing the order of the equation is one of the method to improve the accuracy of the curve.
CONCLUSION:
- The curve fiting was completed for the four different equations.
- It is clear from the graph that the quartic equation has the best fit.
- R-square value greater than 0.95 is assumed to have good fit.
- From the results, it is clear that the curve obtained from higher order equations has the best fit.
- The value for RMSE is the lowest in the quartic curve. Since the errors are lower it is the best fit.