有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

Java中的数学正弦波曲线拟合

我正在使用Apache Commons Math包,我得到了以下正弦波

  0.90, 0.85, 0.80, 0.83, 0.89
  0.90, 0.85, 0.80, 0.83, 0.89
  0.90, 0.85, 0.80, 0.83, 0.89
  0.90, 0.85, 0.80, 0.83, 0.89

从以上数据可以看出,波浪具有以下属性

  • 振幅=.05
  • 阶段=0
  • 频率=5

然而,当我把我的正弦波加到HarmonicFitter上时,就像这样

HarmonicFitter fitter = new HarmonicFitter(new LevenbergMarquardtOptimizer());

fitter.addObservedPoint(0, 0.90);
fitter.addObservedPoint(1, 0.85);
fitter.addObservedPoint(2, 0.80);
fitter.addObservedPoint(3, 0.83);
fitter.addObservedPoint(4, 0.89);

fitter.addObservedPoint(5, 0.90);
fitter.addObservedPoint(6, 0.85);
fitter.addObservedPoint(7, 0.80);
fitter.addObservedPoint(8, 0.83);
fitter.addObservedPoint(9, 0.89);

fitter.addObservedPoint(10, 0.90);
fitter.addObservedPoint(11, 0.85);
fitter.addObservedPoint(12, 0.80);
fitter.addObservedPoint(13, 0.83);
fitter.addObservedPoint(14, 0.89);

fitter.addObservedPoint(15, 0.90);
fitter.addObservedPoint(16, 0.85);
fitter.addObservedPoint(17, 0.80);
fitter.addObservedPoint(18, 0.83);
fitter.addObservedPoint(19, 0.89);

double[] vals = fitter.fit();

return vals;

返回的值更像

Amplitude: 5.19813329138371
Frequency: 4.69209750375546E-5
Phase: 1.405312649084833

为什么曲线拟合会导致4个相同频率的正弦波具有如此截然不同的属性


共 (2) 个答案

  1. # 1 楼答案

    您似乎混淆了输出的顺序,并没有将其正确映射到标签(fit返回一个数组)

    您获得的值真正反映了您的输入:

    试着在纸上画出你的值,并在上面画一个正弦波——你的振幅为0.5,频率为5——是不正确的。相位正常,由4.69e-5确认。你的频率远高于5。振幅0.5是你想要的,而不是数据显示的,1.4:因为在正弦的下坡上没有点,所以乐观主义者实际上认为点0.8、0.83和0.89都属于正弦波的上坡,具有更大的振幅,这减少了误差

    总而言之,试图用5个点拟合3个值,这是过度拟合

  2. # 2 楼答案

    @Marko Topolnik有问题。Fitter期望一个简单的谐波(即,单个余弦或正弦),其平均值为零。因此,从所有值中减去0.854(平均值),然后将该常数加回生成的正弦波

    事实上,微小的频率给出了一个平坦的正弦波,所以其他数字是无关的。尝试绘制所有内容(包括生成的函数)


    编辑:这里有两个图。第一个有你的观点和三个函数:你想要的y=.05*cos(2πx/5),相同的函数加上.0854(看起来你的相位不会为零),以及包的最佳拟合函数: picture of best fits 但只有将窗口缩小到[-1e5,1e5]x[-8,8]时,才能区分包的最佳功能: same picture, dramatically scaled out horizontally 这也意味着包的最佳拟合函数非常不稳定。点的微小变化将导致输出的巨大变化