title: Applying bounds to Scipy Optimise Curvefit
body: <p>I am trying to fit a simple sinewave to data and applying bounds to help constrain the fit.</p>
  
  <p>I am using the 2nd answer posted <a href="https://stackoverflow.com/questions/16716302/how-do-i-fit-a-sine-curve-to-my-data-with-pylab-and-numpy">here</a> which is working perfectly, however when I apply bounds as per convention, e.g.:</p>
  
  <pre><code>def fit_sin(tt, yy):
      import scipy.optimize
      import numpy as np
      '''
      Fit sin to the input time sequence, and return dict of fitting parameters:
      "amp", "omega", "phase", "offset", "freq", "period" and "fitfunc"
      '''
      tt = np.array(tt)
      yy = np.array(yy)
      ff = np.fft.fftfreq(len(tt), (tt[1]-tt[0]))   # assume uniform spacing
      Fyy = abs(np.fft.fft(yy))
      guess_freq = abs(ff[np.argmax(Fyy[1:])+1])   # excluding the zero frequency "peak", which is related to offset
      guess_amp = np.std(yy) * 2.**0.5
      guess_offset = np.mean(yy)
      guess = np.array([guess_amp, 2.*np.pi*guess_freq, 0., guess_offset])
  
      def sinfunc(t, A, w, p, c):  return A * np.sin(w*t + p) + c
      boundary = ([-np.inf, -np.inf, -np.pi, -np.inf],[np.inf, np.inf, np.pi, np.inf])
      popt, pcov = scipy.optimize.curve_fit(sinfunc, tt, yy, p0=guess, bounds=boundary)
      A, w, p, c = popt
      f = w/(2.*np.pi)
      fitfunc = lambda t: A * np.sin(w*t + p) + c
      return {"amp": A, "omega": w, "phase": p, "offset": c, "freq": f, "period": 1./f, "fitfunc": fitfunc, "maxcov": np.max(pcov), "rawres": (guess,popt,pcov)}
  </code></pre>
  
  <p>I am getting the following error:</p>
  
  <pre><code>RuntimeError: Optimal parameters not found: The maximum number of function evaluations is exceeded.
  </code></pre>
  
  <p>If I set the bounds to infinity and I change the boundary line to simply,</p>
  
  <pre><code>boundary = ([-np.inf, -np.inf, -np.inf, -np.inf],[np.inf, np.inf, np.inf, np.inf])
  </code></pre>
  
  <p>the function works.</p>
  
  <p>To test the function you can do:</p>
  
  <pre><code>import pylab as plt
  
  N, amp, omega, phase, offset, noise = 500, 1., 2., .5, 4., 3
  #N, amp, omega, phase, offset, noise = 50, 1., .4, .5, 4., .2
  #N, amp, omega, phase, offset, noise = 200, 1., 20, .5, 4., 1
  tt = numpy.linspace(0, 10, N)
  tt2 = numpy.linspace(0, 10, 10*N)
  yy = amp*numpy.sin(omega*tt + phase) + offset
  yynoise = yy + noise*(numpy.random.random(len(tt))-0.5)
  
  res = fit_sin(tt, yynoise)
  print( "Amplitude=%(amp)s, Angular freq.=%(omega)s, phase=%(phase)s, offset=%(offset)s, Max. Cov.=%(maxcov)s" % res )
  
  plt.plot(tt, yy, "-k", label="y", linewidth=2)
  plt.plot(tt, yynoise, "ok", label="y with noise")
  plt.plot(tt2, res["fitfunc"](tt2), "r-", label="y fit curve", linewidth=2)
  plt.legend(loc="best")
  plt.show()
  </code></pre>
  
  <p>In particular I am just trying to constrain the phase <code>p</code> of the fit to be between <code>-np.pi</code> and <code>np.pi</code>, the others can be infinity.</p>
  
  <p>The actual data I'm using this function on is clean and the fit is quick and really accurate, but it's sometimes fitting the phase a whole cycle 'out of step' when the data starts at or near +/- <code>np.pi</code>, it will fit it <code>2*np.pi</code> out phase.</p>
  
  <p>I can't manually catch this either as it's fitting to many thousands of data sets and I'm looking at relative phase differences between them all.</p>
  
  <p>Any help appreciated, thanks.</p>