简体   繁体   English

在Java中使用曲线拟合计算点

[英]Working out a point using curve fitting in java

The following code produces a curve that should fit fit the points 以下代码产生了一条曲线,该曲线应适合于这些点

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

I built this code based off the documentation here , however, I am not entirely sure how to use the data correctly for further calcuations and whether PolynomialCurveFitter.create(3) will affect the answers in these future calcuations. 我是根据此处的文档构建此代码的,但是,我不完全确定如何正确使用数据进行进一步的计算,以及PolynomialCurveFitter.create(3)是否会影响这些将来的计算结果。

For example, how would I use the data outputted to calculate what is the x value if the y value is 200 and how would the value differ if I had PolynomialCurveFitter.create(2) instead of 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));
    }
}

About what the consequences of changing d for your function 关于更改d对您的函数有何后果

PolynomialCurveFitter.create takes the degree of the polynomial as a parameter. PolynomialCurveFitter.create将多项式的次数作为参数。

Very (very) roughly speaking, the polynomial degree will describe the "complexity" of the curve you want to fit. 粗略地(非常)地说,多项式将描述您要拟合的曲线的“复杂性”。 A low-level degree will produce simple curves (just a parabola for d=2), whereas higher degrees will produce more intricate curves, with lots of peaks and valleys, of highly varying sizes, therefore more able to perfectly "fit" all your data points, at the expense of not necessarily being a good "prediction" of all other values. 较低的度数将生成简单的曲线(对于d = 2,仅是抛物线),而较高的度数将生成更复杂的曲线,具有许多高度变化的峰和谷,因此更能够完美地“拟合”您的所有曲线数据点,但这不一定是对所有其他值的良好“预测”。

Like the blue curve on this graphic: 就像该图形上的蓝色曲线:

在此处输入图片说明

You can see how the straight line would be a better "approximation", while not fitting the data point properly. 您会看到直线将是更好的“近似值”,而没有正确拟合数据点。

How to compute x for any y values in the computed function 如何为计算函数中的任何y值计算x

You "simply" need to solve the polynomial ! 您“仅”需要解多项式! Using the very same library. 使用完全相同的库。 Add the inverted y value to your coefficents list, and find its root. 将倒置的y值添加到系数列表中,并找到其根。

Let's say you chose a degree of 2. 假设您选择2度。

Your coefficients array coeffs will contains 3 factors {a0, a1, a2} which describes the equation as such: 您的系数阵列coeffs将包含3个因素{a0, a1, a2}它描述了方程这样:

a0 + a1 * x + a2 *x²

If you want to solve this for a particular value, like y= 600, you need to solve : 如果要解决特定值,例如y = 600,则需要解决:

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

So, basically, 所以基本上

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

So, just substract 600 to a0: 因此,只需将600减去a0:

coeffs[0] -= 600

and find the root of the polynomial using the dedicated function: 并使用专用函数找到多项式的根:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM