Non-linear Least Squares Fitting (2-dimensional) in Python
<p>I was wondering what the correct approach to fitting datapoints to a non-linear function should be in python.</p>

<p>I am trying to fit a series of data-points</p>

<pre><code>t = [0., 0.5, 1., 1.5, ...., 4.]
y = [6.3, 4.5,.................]
</code></pre>

<p>using the following model function</p>

<pre><code>f(t, x) = x1*e^(x2*t)
</code></pre>

<p>I was mainly wondering which library routine is appropriate for this problem and how it should be setup. I tried using the following with unsuccessful results:</p>

<pre><code>t_data = np.array([0.5, 1.0, 1.5, 2.0,........])
y_data = np.array([6.8, 3., 1.5, 0.75........])

def func_nl_lsq(x, t, y):
    return [x[0]*np.exp(x[1]*t)] -  y

popt, pcov = scipy.optimize.curve_fit(func_nl_lsq, t_data, y_data)
</code></pre>

<p>I know it's unsuccessful because I am able to solve the "equivalent" linear least squares problem (simply obtained by taking the log of the model function) and its answer doesn't even come close to the one I am getting by doing the above.</p>

<p>Thank you</p>

<p>If you are using <code>curve_fit</code> you can simplify it quite a bit, with no need to compute the error inside your function:</p>

<pre><code>from scipy.optimize import curve_fit
import numpy as np
import matplotlib.pyplot as plt

t_data = np.array([0.5, 1.0, 1.5, 2.0, 2.5, 3.])
y_data = np.array([6.8, 3., 1.5, 0.75, 0.25, 0.1])
def func_nl_lsq(t, *args):
    a, b = args
    return a*np.exp(b*t)
popt, pcov = curve_fit(func_nl_lsq, t_data, y_data, p0=[1, 1])
plt.plot(t_data, y_data, 'o')
plt.plot(t_data, func_nl_lsq(t_data, *popt), '-')
plt.show()
</code></pre>

<h2>EDIT</h2>

<p>Note I'm using a general signature that accepts <code>*args</code>. In order for this to work you must pass <code>p0</code> to <code>curve_fit</code>.</p>

<p>The conventional approach is shown below:</p>

<pre><code>def func_nl_lsq(t, a, b):
        return a*np.exp(b*t)
    popt, pcov = curve_fit(func_nl_lsq, t_data, y_data)
    a, b = popt
    plt.plot(t_data, func_nl_lsq(t_data, a, b), '-')
</code></pre>

<p><a href="https://i.stack.imgur.com/idyoY.png" rel="nofollow"><img src="https://i.stack.imgur.com/idyoY.png" alt="Example"></a></p>

python numpy optimization scipy linear-algebra