python - 将矩形函数拟合到实际数据点

标签 python signals curve-fitting least-squares periodic-task

我想将周期性矩形函数拟合到我的数据中。我已经使用 scipy.optimize 中的 curve_fit 用最小二乘法尝试了这一点。不幸的是,优化并没有收敛。

这是一个包含数据摘录的最小示例:

import numpy as np
from scipy import signal
from scipy.optimize import curve_fit
import matplotlib.pyplot as plt

x = np.array([0.00000e+00, 6.97000e-05, 1.38200e-04, 2.26700e-04, 3.09700e-04,
       4.38200e-04, 5.05000e-04, 5.66700e-04, 6.33400e-04, 8.41900e-04,
       9.43200e-04, 1.03100e-03, 1.18000e-03, 1.26450e-03, 1.34990e-03,
       2.11920e-03, 2.59670e-03, 4.61800e-03, 4.99820e-03, 5.06740e-03,
       5.14820e-03, 5.22640e-03, 5.31120e-03, 5.39800e-03, 5.46740e-03,
       5.55040e-03, 5.63120e-03, 5.72520e-03, 5.83990e-03, 5.91070e-03,
       6.00040e-03, 6.06850e-03, 6.17600e-03, 6.26270e-03, 6.32870e-03,
       6.50600e-03, 6.74950e-03, 6.85150e-03, 6.93870e-03, 7.06570e-03,
       7.12740e-03, 7.44270e-03, 7.59450e-03, 8.13300e-03, 9.61600e-03,
       9.99620e-03, 1.00592e-02, 1.01345e-02, 1.02170e-02, 1.03185e-02,
       1.03862e-02, 1.04760e-02, 1.05484e-02, 1.06410e-02, 1.07402e-02,
       1.08027e-02, 1.09087e-02, 1.09982e-02, 1.11092e-02, 1.11762e-02,
       1.12610e-02, 1.13267e-02, 1.14489e-02, 1.16935e-02, 1.17800e-02,
       1.21155e-02, 1.23132e-02, 1.24477e-02, 1.25500e-02, 1.37562e-02,
       1.41364e-02, 1.46140e-02])

y = np.array([-14.6564, -14.6564, -14.6564, -14.6795, -14.6795, -14.6938,
       -14.6938, -14.7025, -14.7025, -14.714 , -14.714 , -14.7226,
       -14.7284, -14.7284, -14.7284, -14.7571,  14.8909,  14.9701,
       -14.6751, -14.6751, -14.6751, -14.691 , -14.691 , -14.7082,
       -14.7082, -14.7082, -14.7169, -14.7169, -14.7255, -14.7255,
       -14.7341, -14.7341, -14.7399, -14.7399, -14.7399, -14.7485,
       -14.7528, -14.76  , -14.76  , -14.7687, -14.7687, -14.7787,
        14.8837,  14.9096,  14.96  , -14.6766, -14.6766, -14.6766,
       -14.6982, -14.6982, -14.7111, -14.7111, -14.7111, -14.7212,
       -14.7212, -14.7284, -14.7284, -14.737 , -14.737 , -14.7428,
       -14.7428, -14.7428, -14.7557, -14.7571, -14.76  , -14.7687,
       -14.7715, -14.7787, -14.7787,  14.9327,  14.9442,  14.96  ])


########## define rectangle function via heaviside step function ############

def rectangle_1(x,Amp,f,phi):
    
    return 2*Amp*np.heaviside(np.cos(2*np.pi*f*x+phi),1)-Amp

########## define rectangle function via signal package from scipy ###########

def rectangle_2(x,Amp,f,offset):
    
    return Amp*signal.square(2*np.pi*f*(x-offset))


########## Fitting of the data by using curvefit from scipy.optimize ############ 

popt, pcov = curve_fit(rectangle_1, x, y, p0=[15,200,np.pi/2],bounds=([0,0,0],[50,300,10]))


################## plot data points and rectangle function ###############

x_sig = np.linspace(min(x),max(x),10000)
y_sig = rectangle_1(x_sig,15,200,np.pi/2)   # for start parameters 
y_sig = rectangle_1(x_sig,*popt)            # for fit parameters

plt.figure()
plt.plot(x,y,color='b', marker='.',markerfacecolor='r',markeredgecolor='r',linewidth=0,label=r'detected Pulses')
plt.plot(x_sig,y_sig,color='b',linewidth=1,label='applied voltage')
plt.xlabel('x')
plt.ylabel('y')  
plt.legend(loc='upper center', bbox_to_anchor= (0.5, 1.13), ncol=2, frameon=False, fontsize=12)

我尝试了矩形函数的各种定义,并使用 ODR.run() 拟合它。没有任何效果。

另一种确定函数参数(例如边缘检测)的方法在这里不起作用,因为数据点不一定位于角点。

下面是可视化结果。

带有启动参数的数据和矩形函数:

Data and rectangular function with start parameters.

具有拟合参数的数据和矩形函数:

Data and rectangular function with fit parameters.

我真的很惊讶我还没有在网上找到这个问题的解决方案。我的意思是矩形信号非常流行。

最佳答案

要优化的参数集比您所做的要简单得多。
基本上,如果您有 Rect 函数的示例,您只需要估计级别和周期时间。

电平很容易估计,周期时间可以通过最大的ON或OFF段来估计。

关于python - 将矩形函数拟合到实际数据点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70564942/

相关文章:

linux - pthread_kill() 没有向主线程发送信号(主程序)

r - 使用一组样本插值新值

python - 如何在 numpy 数组中找到元组的索引?

python - 如何在 mako 模板中设置变量?

python - Django View : Count specific value from model

audio - 信号处理和音频节拍检测

python - import ... as ... 似乎失败, 'module' 没有属性

python - signal.spectrogram 返回太多赫兹

python - 对矩阵中的多个数组连续执行高斯拟合并保存结果

c - Levenberg–Marquardt 算法如何以一种易于理解的方式详细工作?