I met some problem when I make curve fitting program using LMFIT library in python.
My code is
#Make spectrum
def df_one_row(n_si=1, k_si=1, level=0):
# Structure
layer_air = make_layer(nk_air)
layer_si = make_layer(n_si + 1j*k_si, thickness=0.05, coherence=False)
structure = [
layer_air,
layer_si,
layer_air]
R_S = Multilayer(structure, 0, 's', wavenumbers).R()
R_P = Multilayer(structure, 0, 'p', wavenumbers).R()
Ref=(R_S + R_P)/2
Ref += level/100
return Ref
def df_one_row1(n_si=1, k_si=1, level=0):
# Structure
layer_air = make_layer(nk_air)
layer_si = make_layer(n_si + 1j*k_si, thickness=0.05, coherence=False)
#layer_sio2_2 = make_layer(nk_sio2, thickness=d_sio2_2*1e-7, coherence=True)
structure = [
layer_air,
layer_si,
layer_air]
T_S = Multilayer(structure, 0, 's', wavenumbers).T()
T_P = Multilayer(structure, 0, 'p', wavenumbers).T()
Trans=(T_S + T_P)/2
Trans += level/100
return Trans
def epsilon(wavenumbers, w_0, w_p, gamma):
ep=(np.power(w_p,2)/((np.power(w_0,2)-np.power(wavenumbers,2))-(1j*gamma*wavenumbers)))
return ep
def refractive_index(wavenumbers, pars=1 ):
e_inf=pars['e_inf']
e= e_inf + epsilon( wavenumbers, pars['w_01'], pars['w_p1'], pars['gamma_1'] )
n=np.real(np.sqrt(e))
k=np.imag(np.sqrt(e))
return n,k
def residual(pars, x, sigma=None, data1=None, data2=None):
n,k=refractive_index(wavenumbers, pars)
parameter_list=[n,k]
model1=df_one_row(*parameter_list , level=pars['level'])
model2=df_one_row1(*parameter_list , level=pars['level'])
if data1 is None and data2 is None:
return model1, model2
if sigma is None:
return ((model1-data1)+(model2-data2))/2
return ((model1-data1)+(model2-data2))/2*sigma
pfit=lmfit.Parameters()
pfit.add_many( ('e_inf', 12., True,1.5, 20),
('w_01', 0.,False,1, 2000),
('w_p1', 10.,True,1, 1300),
('gamma_1',10, True, 1, 75),
('level',0,False, -8., 8.),
)
#Call Data
R=pd.read_csv('R_si.dat', sep='\t', header=None)
R=R.iloc[2:,1].to_numpy()
T=pd.read_csv('T_si.dat', sep='\t', header=None)
T=T.iloc[2:,1].to_numpy()
#Curve fit part
sigma=None
myfit = lmfit.minimize(residual, pfit, method='Least_squares', args=(wavenumbers,), kws=
{'sigma':sigma, 'data1': R, 'data2':T })
Problem occured in
myfit = lmfit.minimize(residual, pfit, method='Least_squares', args=(wavenumbers,), kws=
{'sigma':sigma, 'data1': R, 'data2':T })
with this error
TypeError Traceback (most recent call last)
~\AppData\Local\Temp/ipykernel_15636/1802606526.py in <module>
1 sigma=None
----> 2 myfit = lmfit.minimize(residual, pfit, method='Least_squares', args=(wavenumbers,),
kws={'sigma':sigma, 'data1': R, 'data2':T })
~\anaconda3\lib\site-packages\lmfit\minimizer.py in minimize(fcn, params, method, args, kws,
iter_cb, scale_covar, nan_policy, reduce_fcn, calc_covar, max_nfev, **fit_kws)
2581 nan_policy=nan_policy, reduce_fcn=reduce_fcn,
2582 calc_covar=calc_covar, max_nfev=max_nfev, **fit_kws)
-> 2583 return fitter.minimize(method=method)
~\anaconda3\lib\site-packages\lmfit\minimizer.py in minimize(self, method, params, **kws)
2350 val.lower().startswith(user_method)):
2351 kwargs['method'] = val
-> 2352 return function(**kwargs)
2353
2354
~\anaconda3\lib\site-packages\lmfit\minimizer.py in least_squares(self, params, max_nfev,
**kws)
1572 result.call_kws = kws
1573 try:
-> 1574 ret = least_squares(self.__residual, start_vals,
1575 bounds=(lower_bounds, upper_bounds),
1576 kwargs=dict(apply_bounds_transformation=False),
~\anaconda3\lib\site-packages\scipy\optimize\_lsq\least_squares.py in least_squares(fun, x0,
jac, bounds, method, ftol, xtol, gtol, x_scale, loss, f_scale, diff_step, tr_solver,
tr_options, jac_sparsity, max_nfev, verbose, args, kwargs)
818 x0 = make_strictly_feasible(x0, lb, ub)
819
--> 820 f0 = fun_wrapped(x0)
821
822 if f0.ndim != 1:
~\anaconda3\lib\site-packages\scipy\optimize\_lsq\least_squares.py in fun_wrapped(x)
813
814 def fun_wrapped(x):
--> 815 return np.atleast_1d(fun(x, *args, **kwargs))
816
817 if method == 'trf':
~\anaconda3\lib\site-packages\lmfit\minimizer.py in __residual(self, fvars,
apply_bounds_transformation)
585 raise AbortFitException(f"fit aborted: too many function evaluations
{self.max_nfev}")
586
--> 587 out = self.userfcn(params, *self.userargs, **self.userkws)
588
589 if callable(self.iter_cb):
Error messages related in my code:
#Main error
~\AppData\Local\Temp/ipykernel_15636/2292999671.py in residual(pars, x, sigma, data1, data2)
---> 23 return ((model1-data1)+(model2-data2))/2
24 return ((model1-data1)+(model2-data2))/2*sigma
TypeError: unsupported operand type(s) for -: 'float' and 'str'
***
I thought the error occured in kws, but I don't have any idea how to correct it.
What should I do?
The error message
~\AppData\Local\Temp/ipykernel_15636/2292999671.py in residual(pars, x, sigma, data1, data2)
---> 23 return ((model1-data1)+(model2-data2))/2
24 return ((model1-data1)+(model2-data2))/2*sigma
TypeError: unsupported operand type(s) for -: 'float' and 'str' ***
is saying that some of model1
, model2
, data1
, and data2
are probably not the data types you assume they are.
You did not give enough to know what your model-generating code like df_one_row
will actually return.
I would suggest debugging the residual function -- calling it with expected values and maybe printing out intermediate results to find out where that TypeError is coming from.