# Curve Fitting
"""
Questions and answers
1.What does popt and pcov mean?
The popt argument are the best-fit paramters for the coefficients
The pcov variable contains the covariance matrix, which indicates the uncertainties and correlations between parameters. This is mostly useful when the data has uncertainties.
2. What does np.array(temperature) do?
np.array(temperature) complies the temperature list from the data as an array
3. What does the * in *popt mean?
It refers to the coefficient values stored in the popt
5. What needs to be done in order to make the curve fit perfect?
In other to mae the curve fit perfect, we need to fix the data to a curve of higher degree
"""
import numpy as np
from scipy.optimize import curve_fit
import matplotlib.pyplot as plt
# Reading thermodynamic data file
def read_file(fileName):
temperature = []
cp = []
for line in open('data','r'):
values = line.split(',')
temperature.append(float(values[0]))
cp.append(float(values[1]))
return [temperature, cp]
# Linear Curve fit function
def linearFunc(t,a,b):
return a*t + b
# Cubic Curve fit function
def cubicFunc(t,a,b,c,d):
return a*pow(t,3)+b*pow(t,2)+c*t+d
# Fit function
def fitCurve(fitFunction,temperature,cp):
popt,pcov = curve_fit(fitFunction,temperature,cp)
fit_cp = fitFunction(np.array(temperature),*popt)
return fit_cp
# Get sum of squares of residuals
def sumSquareResiduals(cp,fit_cp):
return np.sum(pow(np.array(cp)-np.array(fit_cp),2))
# Plot curves
def plotCurves(temperature,cp):
plt.plot(temperature,cp,color='blue',linewidth=3,label='original data')
cp_fit_linear = fitCurve(linearFunc,temperature,cp)
plt.plot(temperature,cp_fit_linear,color='yellow',linewidth=3,label='linear fit')
cp_fit_cubic = fitCurve(cubicFunc,temperature,cp)
plt.plot(temperature,cp_fit_cubic,color='red',linewidth=3,label='cubic fit')
# Compare residuals
def compareResiduals(temperature,cp):
cp_fit_linear = fitCurve(linearFunc,temperature,cp)
cp_fit_cubic = fitCurve(cubicFunc,temperature,cp)
residualSquareSum_linear = sumSquareResiduals(cp,cp_fit_linear)
residualSquareSum_cubic = sumSquareResiduals(cp,cp_fit_cubic)
print("Sum of squares of residuals:")
print("For linear fit: {}".format(residualSquareSum_linear))
print("For cubic fit: {}".format(residualSquareSum_cubic))
def main():
fileName="data"
temperature, cp = read_file(fileName)
plt.figure(figsize=(15,10))
plotCurves(temperature,cp)
plt.legend(loc='best')
plt.xlabel("Temperature")
plt.ylabel('Cp')
plt.savefig("CurveFit.png")
compareResiduals(temperature,cp)
if __name__ =="__main__":
main()