1

I know there is a question
Fitting only one parameter of a function with many parameters in python
but I have a little bit different situation. Problem with parameters of lambda function.

I am trying to fit Lorentz func

def lorentz(ph, A, xc, w, f0):
    return f0 + A * w**2 / (w**2 + (ph - xc)**2)

if I am fitting only one parameter (xc) its working good.

p1, p2, p3, p4 = params
popt, pcov = curve_fit(lambda x, xc: lorentz(x, p1, xc, p3, p4), abjd, adata, bounds=param_bounds)

But if I try to fit only 2 parameters (a, xc) it fails

p1, p2, p3, p4 = params    
popt, pcov = curve_fit(lambda x, a, xc: lorentz(x, a, xc, p3, p4), abjd, adata, bounds=param_bounds)

Error message is

Traceback (most recent call last):
  File "template.py", line 294, in <module>
    popt, pcov = curve_fit(lambda x, a, xc: lorentz(x, a, xc, p3, p4), abjd, adata, bounds=param_bounds)
  File "/usr/local/lib/python2.7/dist-packages/scipy/optimize/minpack.py", line 683, in curve_fit
    **kwargs)
  File "/usr/local/lib/python2.7/dist-packages/scipy/optimize/_lsq/least_squares.py", line 769, in least_squares
    f0 = fun_wrapped(x0)
  File "/usr/local/lib/python2.7/dist-packages/scipy/optimize/_lsq/least_squares.py", line 764, in fun_wrapped
    return np.atleast_1d(fun(x, *args, **kwargs))
  File "/usr/local/lib/python2.7/dist-packages/scipy/optimize/minpack.py", line 455, in func_wrapped
    return func(xdata, *params) - ydata
TypeError: <lambda>() takes exactly 3 arguments (2 given)
Community
  • 1
  • 1
Viktor
  • 313
  • 2
  • 11

1 Answers1

2

Here is the solution for all 4 parameters of Lorentz function

import numpy as np
from scipy.optimize import curve_fit

def lorentz(ph, A, xc, w, f0):
    return f0 + A * w**2 / (w**2 + (ph - xc)**2)

A, xc, w, f0 = 2,2,2,2  # true values
ph = np.linspace(-5, 10, 100)
y = lorentz(ph, A, xc, w, f0)    
ydata = y + 0.15 * np.random.normal(size=len(ph)) # sample data
popt, pcov = curve_fit(lambda x, _A, _xc: lorentz(x, _A, _xc, w, f0), ph, ydata,bounds=([1,1], [3, 3]))
A, xc = popt # fitted values (only two)

You can easily add or remove parameters by putting them under the function lorentz() or with lambda

The result looks like this enter image description here

Sergey
  • 487
  • 3
  • 7
  • can't understent. Can you write example for fitting 2 params ? – Viktor Sep 21 '16 at 20:22
  • Yes, it works. thanks. The problem was in parameter `bounds=param_bounds` if I delete it its working good. But I realy need it – Viktor Sep 21 '16 at 20:40
  • I'v modified again. It's working correctly with bounds. – Sergey Sep 21 '16 at 20:46
  • I forgot to add bounds for second parameter. Its works from beginning, error mesage was not clear, I start to look for mistake in wrong place – Viktor Sep 21 '16 at 20:49