I have the code below that works well to optimize parameters (sigma_0, k1 and k2) to a set of given data by fitting a function that contains a numerically calculated integer.
# Constants
M = 3
b = 0.254e-9
alpha = 0.4
G = 83000
def f(rho, x, D,k1,k2):
return M*(1/(b*D) + k1/b*(rho)**(1/2) - k2*rho)
def g(x, rho_0, D,k1,k2):
"""
Solution to the ODE rho'(x) = f(rho,x,D,k1,k2) with initial condition rho(x=0) = rho_0
"""
rho = odeint(f, rho_0, x, args=(D,k1,k2))
return rho
def iso(x, D,k1,k2):
return M*alpha*G*b*(g(x, rho_0, D,k1,k2))**(1/2)
def flow(x, sigma_0, D,k1,k2):
return sigma_0 + iso(x,D,k1,k2)
# Create the dataset
D=10e-6
sigma_0 = 300
k1 = 0.015
k2 = 1.4
x = np.linspace(0, 1, 101)
data = flow(x, sigma_0, D,k1,k2)
data += 10*np.random.normal(size=data.shape)
# Define the parameters to be optimized
pars = mod.make_params()
pars['D'].set(10e-6, vary=False)
pars['sigma_0'].set(value=300, min=200, max=500)
pars['k1'].set(value=0.01, min=0.001, max=0.1)
pars['k2'].set(value=4, min=1, max=9)
# Run the global fit to all the data sets
mod = Model(flow)
result = mod.fit(data,pars,x=x)
print(result.fit_report())
fig = plt.figure(figsize=(6,5))
plt.scatter(x, data, color='gray', s=80,zorder=1)
plt.plot(x, result.best_fit.transpose().flatten(), 'r-', label='best fit')
plt.show()
Now I would like to adapt my code to perform a global fit to find the best common parameters (sigma_0, k1 and k2) that fit best to multiple datasets related to different values of parameter D. Question: could you suggest an approach to achieve this goal?
# Create the dataset1
D_1=10e-6
sigma_0 = 300
k1 = 0.015
k2 = 1.4
x = np.linspace(0, 1, 101)
data_1 = flow(x, sigma_0, D_1,k1,k2)
data_1 += 10*np.random.normal(size=data.shape)
# Create the dataset2
D_2=50e-6
x = np.linspace(0, 1, 101)
data_2 = flow(x, sigma_0, D_2,k1,k2)
data_2 += 10*np.random.normal(size=data.shape)
# Run the global fit to all the data sets
# model1 = flow(x_global, params['sigma_0'], params['D_1'], params['k1'], params['k2'])
# model2 = flow(x_global, params['sigma_0'], params['D_2'], params['k1'], params['k2'])
fig = plt.figure(figsize=(6,5))
plt.scatter(x, data_1, color='gray', s=80)
plt.scatter(x, data_2, color='black', s=80)
#plt.plot(x, result.best_fit.transpose().flatten(), 'r-', label='best fit')
plt.show()
Thanks in advance for your help
Stéphane
--
You received this message because you are subscribed to the Google Groups "lmfit-py" group.
To unsubscribe from this group and stop receiving emails from it, send an email to lmfit-py+u...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/lmfit-py/f5b3cf63-b922-4561-8261-c28859e5e2e9n%40googlegroups.com.
On Aug 7, 2021, at 2:26 PM, Renee Otten <otten...@gmail.com> wrote:
Hi Stephane,
did you read the documentation? To me it seems you want to follow the approach described here:and an example is given here:
To view this discussion on the web visit https://groups.google.com/d/msgid/lmfit-py/B82C671A-9748-49C0-86E6-085ECCF56BD5%40gmail.com.
datasets = [data_1, data_2]
def residual(params, x, datasets):model1 = flow(x, params['sigma_0'], params['D_1'], params['k1'], params['k2'])model2 = flow(x, params['sigma_0'], params['D_2'], params['k1'], params['k2'])
resid1 = datasets[0] - model1resid2 = datasets[1] - model2return np.concatenate((resid1, resid2))
To view this discussion on the web visit https://groups.google.com/d/msgid/lmfit-py/bf2fd455-ea97-468f-bf3e-f2857b87e279n%40googlegroups.com.
Hi Stephane,Unfortunately the code you posted doesn’t seem to be a “minimal, working example” in the sense that I cannot run it here. The “import numpy as np” is easily fixed, but then I get "NameError: name 'rho_0' is not defined”.Just looking at your code, it seems to me that you probably don’t want to use “concatenate” on your data and then also the definition of your “residual” function should change. Perhaps the code below would work, but as I said I cannot test it since your example doesn’t run….datasets = [data_1, data_2]def residual(params, x, datasets):model1 = flow(x, params['sigma_0'], params['D_1'], params['k1'], params['k2'])model2 = flow(x, params['sigma_0'], params['D_2'], params['k1'], params['k2'])resid1 = datasets[0] - model1resid2 = datasets[1] - model2return np.concatenate((resid1, resid2))Best,Renee