问题
I'm using the Apache Commons Math package and I've got the following Sine Wave...
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
from the above data you can see that the wave has the following attributes...
- Amplitude =
.05
- Phase =
0
- Frequency =
5
However, when I add my sine wave to a HarmonicFitter
like so...
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;
The values returned are more like...
Amplitude: 5.19813329138371
Frequency: 4.69209750375546E-5
Phase: 1.405312649084833
Why has the curve fitting resulted in such drastically different attributes for a sinewave with 4 identical frequencies?
回答1:
You seem to be mixing up order of the output and not mapping it correctly to labels (fit
returns an array).
The values that you obtained really reflect your inputs:
Try to draw your values on paper and put a sinewave on them -- your assertions of 0.5 for amplitude and 5 for frequency are incorrect. The phase is Ok, which is confirmed by 4.69e-5. Your frequency is well above 5. The amplitude of 0.5 is what you want, not what the data shows, 1.4: because there are no points on the downslope of the sine the optimiser actuyally thinks that points 0.8, 0.83 and 0.89 all belong to the upslope of the sinewave with a much larger amplitude -- this reduces the error.
All in all, you are overfitting by trying to fit 3 values with essentially 5 points.
回答2:
@Marko Topolnik has the problem. The Fitter
is expecting a simple harmonic (i.e., a single cosine or sine), which has mean zero. So subtract 0.854
(the mean) from everything, and add that constant back to your resulting sine wave.
As things are, the tiny frequency is giving a flat sine wave, so the other numbers are irrelevant. Try plotting everything (including the resulting function).
Edit: Here are two plots. The first has your points along with three functions: your desired y=.05*cos(2πx/5)
, the same function plus .0854
(it appears your phase won't be zero), and the package's best fit function:

[-1e5,1e5]x[-8,8]
:

来源:https://stackoverflow.com/questions/20951640/sine-wave-curve-fitting-in-java