title: How do I get a periodic curve fit from discrete data in python?
body: <p>I wand to do integration on a dynamic system like to the ODE</p>
  
  <pre><code>x_ddot + d*x_dot + k*x = a*sin(omega*t)
  </code></pre>
  
  <p>with one modification: The external force a * sin(omega * t) must be replaced by another periodic signal which is based on some measurement data. That means: I need do curve fitting on my discrete measurement data and the resulting function must be periodic. I had two ideas how to solve the problem:</p>
  
  <p>1) Use Fourier Transform (numpy.fft). But its difficult to generate a continuous function from discrete data using discrete fourier transform.</p>
  
  <p>2) Use curve fitting, with a function like a1+a2*sin(omega*t)+a3*sin(2*omega*t)+a4*sin(.... where omega is 2*pi/(length of measurement data). Unfortunately this wasn't very successful as well. I've tried it with combination of sin and cos terms and went to very high order (...sin(10*omega*t)) which didn't make it better.</p>
  
  <p><a href="http://i.stack.imgur.com/riIm8.png" rel="nofollow">Plot</a></p>
  
  <p>I would really appreciate some hints, please see my code with example-data bellow:</p>
  
  <pre><code>import numpy as np
  from scipy.optimize import curve_fit
  import matplotlib.pyplot as plt
  import math as math
  import scipy.special as sp
  
  # create data
  f =    [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1.1,1.3,1.7,1.9,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2.1,2.3,2.9,4.1,4.3,4.4,4.5,4.4,4,3.6,3.2,2.8,2.4,2.0,1.6,1.3,1.2,1.1,1,1,1,1,1]
  alpha   = np.linspace(0,len(f),len(f))
  
  omega = 2*np.pi/len(f)
  
  def func(alpha, a1, ac2, ac3, ac4, ac5, ac6, ac7):
      fit     = a1 + ac2*np.sin(omega*alpha) + ac3*np.sin(omega*2*alpha) + ac4*np.sin(omega*3*alpha) + ac5*np.sin(omega*4*alpha) +      ac6*np.sin(omega*5*alpha) + ac7*np.sin(omega*6*alpha)
      return fit
  
  popt, pcov = curve_fit(func, alpha, f) 
  
  print popt
  
  y_fit= func(alpha,popt[0],popt[1],popt[2],popt[3],popt[4],popt[5],popt[6])
  
  plt.plot(alpha,f,'bo',label='discrete data')
  plt.plot(alpha,y_fit,'r',label='periodic fit')
  plt.legend()
  plt.show()
  </code></pre>