如何从python中的离散数据中获得周期性曲线拟合?

时间:2016-06-29 17:38:01

标签: python numpy

我想在像ODE这样的动态系统上进行集成

x_ddot + d*x_dot + k*x = a*sin(omega*t)

进行一次修改:外力a * sin(ω* t)必须由另一个基于某些测量数据的周期信号代替。这意味着:我需要对离散测量数据进行曲线拟合,结果函数必须是周期性的。我有两个想法如何解决问题:

1)使用傅里叶变换(numpy.fft)。但很难用离散傅立叶变换从离散数据中生成连续函数。

2)使用曲线拟合,其函数类似于a1 + a2 * sin(ω* t)+ a3 * sin(2 * omega * t)+ a4 * sin(......其中omega为2 * pi / (测量数据的长度)。不幸的是,这也不是很成功。我用sin和cos术语的组合尝试了它并且达到了非常高的顺序(... sin(10 * omega * t))不会让它变得更好。

Plot

我真的很感激一些提示,请参阅示例数据下面的代码:

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()

1 个答案:

答案 0 :(得分:3)

如果您满足于数值函数,基于插值的简单方法如下:

步骤1:根据数据集定义插值函数,该函数确定函数的一个周期。 (我使用了Scipy的简单interp1d,Sci​​py也提供了更精细的替代品。)

from  scipy.interpolate import interp1d    
f_interp_one_period = interp1d(alpha, f, 'cubic')

步骤2:根据以上内容定义周期性函数(我根据数据使用值55作为期间)

def f_periodic(alpha):
        return f_interp_one_period(numpy.mod(alpha,55))

以下图表显示-100到200范围内的f_periodic和原始数据

enter image description here