Reputation: 1
To accurately fit a curve to my data using a fitting function, I need to follow a structured approach. The current fitting curve is incorrect, so how should I proceed to achieve a correct fit?
Here is my code:
import numpy as np
from scipy.optimize import curve_fit
import matplotlib.pyplot as plt
# Fit function
def fit_function(epsilon, T, Delta_E, hbar_omega):
term1 = np.exp(-(epsilon - Delta_E) / T)
term2 = np.exp((4 * np.pi * Delta_E / hbar_omega) * (np.sqrt(epsilon / Delta_E) - 1))
term3 = term2 + 1
return term1 * term2 / term3
# Define the function that generates your example data
def data(x, a, b, c, d):
return a * (1 - np.exp(-b * x)) * np.exp(-c * x) + d
# Example data (replace these arrays with your actual data)
epsilon_data = np.linspace(0.01, 10, 100) # Kinetic energy values
distribution_data = data(epsilon_data, 2.5e6, 10, 1, 0) # Example distribution
# Initial guess for T, Delta_E, hbar_omega
p0 = [1, 1, 1]
# Fit the fit_function to the distribution_data
popt, pcov = curve_fit(fit_function, epsilon_data, distribution_data, p0=p0, maxfev=8000)
# Plot the comparison of data and fitted curve
plt.scatter(epsilon_data, distribution_data, label='Data', color='blue')
plt.plot(epsilon_data, fit_function(epsilon_data, *popt), label='Fitted Curve', color='red')
plt.xlabel('Kinetic Energy (ε)')
plt.ylabel('Distribution')
plt.legend()
plt.show()
Upvotes: 0
Views: 63
Reputation: 11042
Providing an educated guess and bounds helps to improve fitness:
p0 = [1, 10, 10]
popt, pcov = curve_fit(
fit_function, epsilon_data, distribution_data, p0=p0,
bounds=[
(0., 0., 0.),
(np.inf, np.inf, np.inf)
]
)
But is clearly not satisfying. The problem is probably not linked to curve_fit
itself but more about the fact that you are fitting a known model data
with a totally different model fit_function
:
Models are just too different to agrees together.
Indeed your original function can be regressed:
popt2, pcov2 = curve_fit(data, epsilon_data, distribution_data)
Upvotes: 4