title: Writing an error function to feed scipy.optimize.least_squares in python
body: <p>I am trying to fit some data to a non-linear function, and wanted to play with the model function to see if I could get a better fitting than the one I already have. As I was trying to figure things out, I came up with more questions. I have:</p>
  
  <pre><code>import numpy as np
  import matplotlib.pyplot as plt
  from scipy.optimize import least_squares
  from scipy.optimize import curve_fit
  
  temperature = [ 38., 40., 42., 44., 46., 48., 50., 52., 54., 56., 58., 60., 62., 64., 66., 68., 70., 71.9, 73.81, 75.69, 77.6, 79.49, 81.38, 83.29, 85.19, 87.11, 89., 90., 91., 92., 93., 94., 95., 96., 97., 98., 99., 100. ]
  exp_rate = [  8.71171203e-01, 1.15342914e+00, 1.39178845e+00, 1.66700007e+00, 1.96267002e+00, 2.32390602e+00, 2.68542886e+00, 3.13116448e+00, 3.60152705e+00, 4.12575295e+00, 4.67617489e+00, 5.29745193e+00, 6.06796117e+00, 6.99056274e+00, 8.40124338e+00, 1.04449551e+01, 1.38236107e+01, 1.96811651e+01, 2.91545190e+01, 4.67945718e+01, 7.36377025e+01, 1.19474313e+02, 1.91938580e+02, 3.07692308e+02, 4.92610837e+02, 7.87401575e+02, 1.20738388e+03, 1.51773627e+03, 1.89049140e+03, 2.33880380e+03, 2.90892166e+03, 3.53003887e+03, 4.28065700e+03, 5.15251443e+03, 6.18043152e+03, 7.49720729e+03, 9.57524225e+03, 1.17175325e+04]
  
  def Orbach_Raman(temperature, pre_1, U_1, C, n): # This is my model function
      return np.array( (1./pre_1)*np.exp(-U_1/(temperature)) + C*(temperature**n) )
  
  pre_1, U_1, C, n = np.array([1.17E-12, 1815, 1E-6, 3.77]) # Define the starting guess
  guess = pre_1, U_1, C, n
  popt_stret, pcov = curve_fit(Orbach_Raman, temperature, exp_rate, p0=guess)
  </code></pre>
  
  <p>But curve_fit() cannot find the optimal parameters and it raises</p>
  
  <pre><code>File "/usr/lib/python2.7/dist-packages/scipy/optimize/minpack.py", line 680, in curve_fit
  raise RuntimeError("Optimal parameters not found: " + errmsg)
  RuntimeError: Optimal parameters not found: Number of calls to function has reached maxfev = 1000.
  </code></pre>
  
  <p>which is very weird as the starting guess already provides a very good fit of the data</p>
  
  <pre><code>plt.loglog(temperature, exp_rate, '-o')
  plt.loglog(temperature, Orbach_Raman(temperature, pre_1, U_1, C, n ), '-*')
  plt.show()
  </code></pre>
  
  <p><a href="https://i.stack.imgur.com/vgYGz.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/vgYGz.png" alt="enter image description here"></a></p>
  
  <p>So I then tried to write my own error function to use least_square() instead of curve_fit(), for which I added to the previous code</p>
  
  <pre><code>def error(guess, rate):
      pre_1, U_1, C, n = guess
      return Orbach_Raman(temperature, pre_1, U_1, C, n) - rate
  
  least_squares(error(guess, exp_rate), guess, args=(exp_rate))
  </code></pre>
  
  <p>getting the following error</p>
  
  <pre><code>File "fit_experiment.py", line 46, in &lt;module&gt;
  least_squares(error(guess, exp_rate), guess, args=(exp_rate))
  File "/usr/lib/python2.7/dist-packages/scipy/optimize/_lsq/least_squares.py", line 769, in least_squares
  f0 = fun_wrapped(x0)
  File "/usr/lib/python2.7/dist-packages/scipy/optimize/_lsq/least_squares.py", line 764, in fun_wrapped
  return np.atleast_1d(fun(x, *args, **kwargs))
  TypeError: 'numpy.ndarray' object is not callable
  </code></pre>
  
  <p>Does anyone know</p>
  
  <ul>
  <li>Why curve_fit() fails even if the guess parameters are already giving a very good approximation to the data?</li>
  <li>Why do I get that error when calling least_squares(error(guess, exp_rate), guess, args=(exp_rate))?</li>
  <li>Why if I call least_squares(error, guess, args=(exp_rate)) instead, it raises 
  TypeError: error() takes exactly 2 arguments (39 given)</li>
  </ul>