如何在Java中为我的数据拟合正弦曲线?

时间:2017-07-13 17:49:21

标签: java least-squares sine

我花了几天的时间尝试在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);
    }

它没有编译,并且它不是我想要的(即,第一个链接中的确切内容)

我真的很感激一些帮助。在Java中无法做到我用Python中只有几行可以做的事情让我疯狂。

P.S。:长期Python编码器,newbee 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);
    }

2 个答案:

答案 0 :(得分:0)

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

请参阅:CurveFitterHarmonicCurveFitter

编辑: 由于不推荐使用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);

来自文档:

  

默认实现使用Levenberg-Marquardt优化器。

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

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

答案 1 :(得分:0)

问题是你必须使用HarmonicFitter类和该类的方法 - addObservedPoint。 班级HarmonicCurveFitter和家长AbstractCurveFitter都不包含方法addObservedPoint