如何将正弦曲线拟合到 Java 中的数据?

How do I fit a sine curve to my data in Java?

我花了几天时间试图在 java 中获得完全相同的代码 运行:How do I fit a sine curve to my data with pylab and numpy?

基于这个答案:Sine Wave Curve Fitting in Java,我开始整理这段代码:

public double sine_fit(double[] current_sample){
        double[] half_cycle = Arrays.copyOfRange(current_sample, 175, 225);
        double amp = 3*ArrayUtils.std(half_cycle)/Math.sqrt(2);
        double freq = 0;
        double phase = 0;
        double[] guess = new double[]{amp, freq, phase};
        HarmonicCurveFitter curveFit = new HarmonicCurveFitter(new LevenbergMarquardtOptimizer());
        //curveFit.withStartPoint(guess);
        for (int i=0; i < half_cycle.length; i++) {
            curveFit.addObservedPoint(i, half_cycle[i]);
        }
        double[] vals = curveFit.fit();
        System.out.println(vals);
    }

它无法编译,也不是我想要的(即第一个 link 中的确切内容)

非常感谢您的帮助。无法在 Java 中完成我在 Python 中仅用几行代码就能完成的工作,这让我抓狂。

P.S.: 老 Python 程序员,新手 Java 程序员。

更新

基于@17slim 的回答:

    double[] half_cycle = Arrays.copyOfRange(current_sample, 175, 225);
    double amp = 3*ArrayUtils.std(half_cycle)/Math.sqrt(2);
    double freq = 0;
    double phase = 0;
    double[] guess = new double[]{amp, freq, phase};
    HarmonicCurveFitter curveFit = HarmonicCurveFitter.create();
    curveFit.withStartPoint(guess);
    List<WeightedObservedPoint> points = new ArrayList<WeightedObservedPoint>();
    for (int i=0; i < half_cycle.length; i++) {
        points.add(new WeightedObservedPoint(1.0, i, half_cycle[i]));
    }
    double[] vals = curveFit.fit(points);
    for (double val: vals){
        System.out.println(val);
    }

HarmonicCurveFitter 不扩展 CurveFitter;它扩展了 AbstractCurveFitter,它没有方法 addObservedPointGaussianFitterHarmonicFitterPolynomialFitterCurveFitter 的已知扩展程序,它具有所需的方法。使用 HarmonicFitter.

参见:CurveFitter and HarmonicCurveFitter

编辑: 由于不推荐使用 HarmonicFitter,因此使用 HarmonicCurveFitter 是正确的。由于它没有您需要的方法,请使用 fit(Collection<WeightedObservedPoint> points) 而不是 addObservedPoint.

改为:

HarmonicCurveFitter curveFit = new HarmonicCurveFitter.create();
List<WeightedObservedPoint> points = new ArrayList<WeightedObservedPoint>();
for (int i=0; i < half_cycle.length; i++) {
    points.add(new WeightedObservedPoint(1.0, i, half_cycle[i]));
}
double[] vals = curveFit.fit(points);

来自文档:

The default implementation uses a Levenberg-Marquardt optimizer.

确保导入 org.apache.commons.math3.fitting.WeightedObservedPointorg.apache.commons.math3.fittingHarmonicCurveFitterjava.util.Listjava.util.ArrayList

此外,打印 vals 并不像 Python 那样打印每个值,它打印一个指向数组的指针。使用 for (double val: vals) 并单独显示每个值。

问题是您必须使用 HarmonicFitter class 和 class - addObservedPoint 的方法。 class HarmonicCurveFitter 和他的父 AbstractCurveFitter 都不包含方法 addObservedPoint.