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

标签 java math apache-commons

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

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

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

例如,如果 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 将多项式的次数作为参数。

非常(非常)粗略地说,多项式次数将描述您想要拟合的曲线的“复杂性”。低阶数会产生简单的曲线(只是 d=2 的抛物线),而较高阶数会产生更复杂的曲线,有很多峰和谷,大小变化很大,因此更能够完美地“拟合”您的所有曲线。数据点,代价是不一定是所有其他值的良好“预测”。

就像这个图形上的蓝色曲线一样:

enter image description here

您可以看到直线如何成为更好的“近似值”,同时无法正确拟合数据点。

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

您“简单地”需要求解多项式!使用完全相同的库。将反转的 y 值添加到系数列表中,并找到其根。

假设您选择的度数为 2。

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

a0 + a1 * x + a2 * x²

如果您想解决特定值(例如 y= 600)的问题,您需要解决:

a0 + a1 * x + a2 * x² = 600

所以,基本上,

a0 - 600 + a1 * x + a2 * x² = 0

所以,只需将 a0 减去 600:

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);

关于java - 在java中使用曲线拟合计算出一个点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41750723/

相关文章:

java - 如何使用 JDBC 从存储过程中获取*所有内容*

java - 构建此正则表达式 [1,2,3] 的问题

java - getParcelableArrayList 返回 null

python - 余弦函数的python sympy计算积分错误

Java byte to String Linux 上的编码问题

java - 如何使用 apache.commons 中的 Factory?

java - JProgressBar 在进程完成之前不会更新

javascript - 寻找余弦曲线上与另一个位置指定距离的位置 JS

javascript - 有没有办法逆转atan的影响?

java - Java中的HTML实体解码: apostrophe