用 gnuplot 拟合阻尼正弦波数据集,得到很多错误

opi*_*lax 2 plot gnuplot curve-fitting data-fitting

我试图适应这个数据集:

#Mydataset damped sine wave data
#X ---- Y
45.80   320.0
91.60   -254.0
137.4   198.0
183.2   -156.0
229.0   126.0
274.8   -100.0
320.6   80.0
366.4   -64.0 
412.2   52.0
458.0   -40.0
503.8   34.0
549.6   -26.0
595.4   22.0
641.2   -18.0
Run Code Online (Sandbox Code Playgroud)

如下图所示,它具有阻尼正弦波的经典趋势: 在此处输入图片说明

所以我首先设置了适合的宏

f(x) = exp(-a*x)*sin(b*x)
Run Code Online (Sandbox Code Playgroud)

然后我做了适当的合身

fit f(x) 'data.txt' via a,b
iter      chisq       delta/lim  lambda   a             b            
   0 2.7377200000e+05   0.00e+00  1.10e-19    1.000000e+00   1.000000e+00

Current data point
=========================
#               = 1 out of 14
x               = -5.12818e+20   
z               = 320            

Current set of parameters
=========================
a               = -5.12818e+20   
b               = -1.44204e+20   

         Function evaluation yields NaN ("not a number")
Run Code Online (Sandbox Code Playgroud)

得到一个NaN结果。所以我环顾了 STackOverflow,我记得我过去已经遇到过拟合指数的问题,因为它们的快速增长/衰减需要您设置初始参数以免出现此错误(正如我在这里问的那样))。所以,我想通过设置为启动参数a,并b 为那些预期a = 9000b=146000但结果还是比前一个更令人沮丧的:

fit f(x) 'data.txt' via a,b
iter      chisq       delta/lim  lambda   a             b            
   0 2.7377200000e+05   0.00e+00  0.00e+00    9.000000e+03   1.460000e+05
         Singular matrix in Givens()
Run Code Online (Sandbox Code Playgroud)

我想:“这些数字太大了,让我们尝试使用较小的数字”。所以我输入了a和的值并b再次开始拟合

a = 0.01
b = 2
fit f(x) 'data.txt' via a,b
iter      chisq       delta/lim  lambda   a             b            
   0 2.7429059500e+05   0.00e+00  1.71e+01    1.000000e-02   2.000000e+00
   1 2.7346318324e+05  -3.03e+02  1.71e+00    1.813940e-02  -9.254913e-02
   * 1.0680927157e+137  1.00e+05  1.71e+01   -2.493611e-01   5.321099e+00
   2 2.7344431789e+05  -6.90e+00  1.71e+00    1.542835e-02   4.310193e+00
   * 6.1148639318e+81   1.00e+05  1.71e+01   -1.481123e-01  -1.024914e+01
   3 2.7337226343e+05  -2.64e+01  1.71e+00    1.349852e-02  -9.008087e+00
   * 6.4751980241e+136  1.00e+05  1.71e+01   -2.458835e-01  -4.089511e+00
   4 2.7334273482e+05  -1.08e+01  1.71e+00    1.075319e-02  -4.346296e+00
   * 1.8228530731e+121  1.00e+05  1.71e+01   -2.180542e-01  -1.407646e+00
   * 2.7379223634e+05   1.64e+02  1.71e+02    8.277720e-03  -1.440256e+00
   * 2.7379193486e+05   1.64e+02  1.71e+03    1.072342e-02  -3.706519e+00
   5 2.7326800742e+05  -2.73e+01  1.71e+02    1.075288e-02  -4.338196e+00
   * 2.7344116255e+05   6.33e+01  1.71e+03    1.069793e-02  -3.915375e+00
   * 2.7327905718e+05   4.04e+00  1.71e+04    1.075232e-02  -4.332930e+00
   6 2.7326776014e+05  -9.05e-02  1.71e+03    1.075288e-02  -4.338144e+00
iter      chisq       delta/lim  lambda   a             b            

After 6 iterations the fit converged.
final sum of squares of residuals : 273268
rel. change during last iteration : -9.0493e-07

degrees of freedom    (FIT_NDF)                        : 12
rms of residuals      (FIT_STDFIT) = sqrt(WSSR/ndf)    : 150.905
variance of residuals (reduced chisquare) = WSSR/ndf   : 22772.3

Final set of parameters            Asymptotic Standard Error
=======================            ==========================
a               = 0.0107529        +/- 3.114        (2.896e+04%)
b               = -4.33814         +/- 3.678        (84.78%)

correlation matrix of the fit parameters:
                a      b      
a               1.000 
b               0.274  1.000 
Run Code Online (Sandbox Code Playgroud)

我看到它产生了一些结果,所以我认为一切正常,但我的快乐持续了几秒钟,直到我绘制了输出:在此处输入图片说明 哇。一个非常好的。

我仍然想知道出了什么问题以及如何使用 gnuplot 正确拟合阻尼正弦波数据集。希望有人知道答案:)

use*_*153 5

您拟合数据的函数与数据不匹配。数据的包络是一个衰减函数,因此您需要一个正阻尼参数 a。但是,与您的数据不同,对于正 x,您的拟合函数不能大于 1。此外,通过在拟合中使用正弦函数,您可以对相位行为做出一些假设——拟合函数在 x=0 处始终为零。但是,您的数据看起来应该具有较大的负幅度。

因此,让我们选择一个更好的拟合函数,并通过为参数选择一些合理的初始猜测来帮助 gnuplot:

f(x)=c*exp(-a*x)*cos(b*x)
a=1./500
b=2*pi/100.
c=-400.
fit f(x) 'data.txt' via a,b,c
plot f(x), "data.txt" w p
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明

  • 1/a 是指数的“衰减长度”,因此查看您的数据,几百个值似乎是正确的。余弦曲线的振荡周期似乎约为 100,b 应为 2*pi 除以该数字。在 x=0 时,人们会期望一个大的负振幅,而 -400 看起来是正确的。 (2认同)