Java中的正弦波曲线拟合

时间:2014-01-06 14:03:37

标签: java math apache-commons curve-fitting

我正在使用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

从上面的数据中你可以看到wave具有以下属性......

  • 幅度= .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 个答案:

答案 0 :(得分:2)

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

您获得的值确实反映了您的输入:

尝试在纸上绘制你的值并在它们上面放一个正弦波 - 你的断言为0.5,频率为5,这是不正确的。阶段是好的,由4.69e-5确认。你的频率远高于5. 0.5的幅度是你想要的,而不是数据所显示的,1.4:因为正弦的下坡没有点,优化者认为点0.8,0.83和0.89都属于正弦波的上升幅度大得多 - 这减少了误差。

总而言之,你试图通过基本上5点来拟合3个值来过度拟合。

答案 1 :(得分: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 这也意味着软件包的最佳匹配功能非常不稳定。点数的微小变化将导致输出发生很大变化。