Fitting only 2 paramter of a function with many parameters in python
<p>I know there is a question <br>
<a href="http://stackoverflow.com/questions/12208634/fitting-only-one-paramter-of-a-function-with-many-parameters-in-python">Fitting only one paramter of a function with many parameters in python</a> <br>
but I have a little bit different situation. Problem with parameters of lambda function.</p>

<p>I am trying to fit Lorentz func</p>

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

<p>if I am fitting only one parameter (xc) its working good.</p>

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

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

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

<p>Error message is</p>

<pre><code>Traceback (most recent call last):
  File "template.py", line 294, in &lt;module&gt;
    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: &lt;lambda&gt;() takes exactly 3 arguments (2 given)
</code></pre>

<p>Here is the solution for all 4 parameters of Lorentz function</p>

<pre><code>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)
</code></pre>

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

<p>The result looks like this
<a href="http://i.stack.imgur.com/TNhV0.png" rel="nofollow"><img src="http://i.stack.imgur.com/TNhV0.png" alt="enter image description here"></a></p>

python lambda scipy curve-fitting