当我尝试对数据进行傅立叶级数拟合时,为什么symfit会给我带来可怕的结果?

问题描述

我试图找到一个适合该图的傅立叶级数:

enter image description here

首先,我使用this website,发现以下傅立叶系数

unsigned char** hashes;
unsigned char* buff;

cudamallocManaged(&hashes,N * sizeof(unsigned char*));
cudamallocManaged(&buff,N * (32 * sizeof(unsigned char)));
cudamemset(buff,N * (32 * sizeof(unsigned char)));

for(i=0; i<N; i++) hashes[i] = &buff[i*32];

产生了以下结果

enter image description here

这很好,但是后来我决定尝试用python编写自己的曲线拟合器,并发现symfit库似乎是最好的选择。我什至在很少改动的情况下重新利用了文档中的一个示例。

可以肯定的是,当我运行代码时,在直接用fit对象制作的图形中,拟合度似乎非常好:

a = [0.983,0.292,0.110,0.006,-0.022,-0.018,0.006] b = [0.000,0.246,0.002,-0.021,0.017,0.046,0.019] omega = 0.045

enter image description here

但是后来我决定直接使用傅立叶系数,而不是依靠fit对象来尝试重现该函数代码就是这样打印这些系数的方式:

plt.plot(xdata,fit.model(x=xdata,**fit_result.params).y,color='green',ls=':')

标准偏差是一个巨大的危险信号,它们非常大,而且可以肯定,这就是结果

enter image description here

这似乎是个坏笑话。

那是使用10个系数完成的,如果我只使用6个系数,我得到的东西几乎是不能接受的。

enter image description here

最糟糕的是,直接用fit对象制作的图形必须表示代码确实产生了良好的拟合,但是由于某种原因,它给我的傅立叶系数只是谎言。

这是我的代码

首先,这就是我适合这些功能的方式

Parameter Value        Standard Deviation
a0        -1.206104e+03 nan
a1        1.799223e+03 1.087713e+05
a10       2.393892e+00 8.023119e+02
a2        -8.465307e+02 2.133670e+05
a3        6.798590e+02 nan
a4        -9.287399e+02 nan
a5        7.388156e+02 nan
a6        -2.099387e+02 1.376980e+05
a7        -9.838123e+01 9.799211e+04
a8        9.821148e+01 3.739932e+04
a9        -2.827002e+01 8.152094e+03
b1        -6.084419e+02 2.480938e+05
b10       4.586827e+01 3.396681e+02
b2        9.311030e+02 2.178771e+05
b3        -8.877734e+02 2.406878e+05
b4        8.810145e+02 4.462669e+05
b5        -1.288586e+03 4.376938e+05
b6        1.734395e+03 2.730319e+05
b7        -1.583775e+03 1.137506e+05
b8        9.115344e+02 3.084382e+04
b9        -3.045882e+02 4.905459e+03
w         -1.370387e-02 nan

这就是我采用这些系数并尝试重现图形的方式。我有b和omega数据的不同集合,以尝试重现其他傅立叶级数。阶梯楔形的一个(文档中的示例)是唯一可行的。

from symfit import parameters,variables,sin,cos,Fit
import numpy as np
import matplotlib.pyplot as plt
import math as m

def fourier_series(x,f,n=0):
    a0,*cos_a = parameters(','.join(['a{}'.format(i) for i in range(0,n + 1)]))
    sin_b = parameters(','.join(['b{}'.format(i) for i in range(1,n + 1)]))
    series = a0 + sum(ai * cos(i * f * x) + bi * sin(i * f * x)
                     for i,(ai,bi) in enumerate(zip(cos_a,sin_b),start=1))
    return series

x,y = variables('x,y')
w,= parameters('w')
model_dict = {y: fourier_series(x,f=w,n=10)}
print(model_dict)

#This is the graph I'm trying to fit turned into data points
xlist=[381.854,385.274,387.55,388.973,390.656,392.671,394.281,396.37,398.014,402.047,408.288,411.885,414.452,418.099,\
       423.493,426.901,428.014,430.068,433.114,438.699,445.023,448.562,453.307,458.014,463.663,467.877,474.536,\
       479.384,485.409,489.247,496.283,501.164,508.191,514.315,520.1]
ylist=[0.02816,0.09827,0.18838,0.2948,0.36316,0.46243,0.53795,0.60116,0.64162,0.68361,0.71676,0.79285,0.87861,0.94579,\
       0.99422,0.95307,0.89017,0.85549,0.76301,0.7273,0.65896,0.59621,0.53757,0.47969,0.43353,0.38501,\
       0.33526,0.28305,0.23121,0.14451,0.11555,0.08092,0.07185]

xdata = np.array(xlist)
ydata = np.array(ylist)

# Define a Fit object for this model and data
fit = Fit(model_dict,x=xdata,y=ydata)
fit_result = fit.execute()
print(fit_result)

# Plot the result
plt.plot(xdata,ydata)
plt.plot(xdata,ls=':')

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)