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)

1 Answer 1

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

Sign up to request clarification or add additional context in comments.

4 Comments

can't understent. Can you write example for fitting 2 params ?
Yes, it works. thanks. The problem was in parameter bounds=param_bounds if I delete it its working good. But I realy need it
I'v modified again. It's working correctly with bounds.
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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.