Saya
Saya

Reputation: 1

Trying to fit a curve for the data function

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

Answers (1)

jlandercy
jlandercy

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)
    ]
)

enter image description here

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:

enter image description here

Models are just too different to agrees together.

Indeed your original function can be regressed:

popt2, pcov2 = curve_fit(data, epsilon_data, distribution_data)

enter image description here

Upvotes: 4

Related Questions