在 java 中使用曲线拟合计算出一个点

Working out a point using curve fitting in java

以下代码生成一条曲线,该曲线应适合点

1, 1
150, 250
10000, 500
100000, 750
100000, 1000

我根据文档 here 构建了此代码,但是,我不完全确定如何正确使用数据进行进一步计算以及 PolynomialCurveFitter.create(3) 是否会影响这些未来计算的答案.

例如,如果 y 值为 200,我将如何使用输出的数据来计算什么是 x 值,如果我有 PolynomialCurveFitter.create(2) 而不是 PolynomialCurveFitter.create(3)?

import java.util.ArrayList;
import java.util.Arrays;

import org.apache.commons.math3.fitting.PolynomialCurveFitter;
import org.apache.commons.math3.fitting.WeightedObservedPoints;

public class MyFuncFitter {
    public static void main(String[] args) {
        ArrayList<Integer> keyPoints = new ArrayList<Integer>();
        keyPoints.add(1);
        keyPoints.add(150);
        keyPoints.add(10000);
        keyPoints.add(100000);
        keyPoints.add(1000000);

        WeightedObservedPoints obs = new WeightedObservedPoints();
        if(keyPoints != null && keyPoints.size() != 1) {
            int size = keyPoints.size();
            int sectionSize = (int) (1000 / (size - 1));
            for(int i = 0; i < size; i++) {
                if(i != 0)
                    obs.add(keyPoints.get(i),  i * sectionSize);
                else
                    obs.add(keyPoints.get(0),  1);
            }
        } else if(keyPoints.size() == 1 && keyPoints.get(0) >= 1) {
            obs.add(1,  1);
            obs.add(keyPoints.get(0),  1000);
        }

        PolynomialCurveFitter fitter = PolynomialCurveFitter.create(3);
        fitter.withStartPoint(new double[] {keyPoints.get(0), 1});
        double[] coeff = fitter.fit(obs.toList());
        System.out.println(Arrays.toString(coeff));
    }
}

关于改变 d 对你的函数有什么影响

PolynomialCurveFitter.create取多项式的次数作为参数。

非常(非常)粗略地说,多项式的次数将描述你想要拟合的曲线的"complexity"。 low-level 度将产生简单的曲线(对于 d=2 只是抛物线),而更高的度将产生更复杂的曲线,有很多峰谷,大小变化很大,因此更能够完美 "fit" 你所有的数据点,以不一定是所有其他值的好 "prediction" 为代价。

喜欢这张图上的蓝色曲线:

您可以看到直线会更好 "approximation",但不能正确拟合数据点。

如何为计算函数中的任何 y 值计算 x

你"simply"需要解多项式!使用完全相同的库。将反转的 y 值添加到系数列表中,并找到它的根。

假设您选择了 2 度。

您的系数数组 coeffs 将包含 3 个因子 {a0, a1, a2},它们描述了方程式:

如果你想解决一个特定的值,比如 y=600,你需要解决:

所以,基本上,

所以,只需将 600 减去 a0:

coeffs[0] -= 600

并使用专用函数求多项式的根:

PolynomialFunction polynomial = new PolynomialFunction(coeffs);
LaguerreSolver laguerreSolver = new LaguerreSolver();
double x = laguerreSolver.solve(100, polynomial, 0, 1000000);
System.out.println("For y = 600, we found x = " + x);