使用Apache Common Math确定指数函数的系数

时间:2017-01-21 19:49:33

标签: java apache math wolfram-mathematica curve-fitting

我有以下数据。

x = [10
     20
     30 
     40
     50
     60
     70
     80
     90
     100
     110
     120
     130
     140
     150
     160]

y = [86.5
     43.9
     25.4
     17.2
     12
     10.5
     8
     7.8
     6.5
     6.8
     6.1
     6.1
     6
     5.4
     5.7
     5.2]

形式为指数:

y = A + Be (cx)

How to find coefficients for a possible exponential approximation

Least squares Levenburg Marquardt with Apache commons

我想找到这个函数的系数。上面提到的链接使我得出结论,我需要线性化函数并使用PolynomialCurveFitter来确定系数。我使用下面的函数执行了一个测试并进行了回溯,以确定此过程是否适用于我的数据,方法是使用10到70之间的x值并将其作为相应的log(y-16)。

y = 16 + 200e -x / 14

import java.util.Arrays;

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

public class CurveFitting {
    public static void main(String[] args) {
        final WeightedObservedPoints obs = new WeightedObservedPoints();
        obs.add(10, 4.58);
        obs.add(20, 3.87);
        obs.add(30, 3.16);
        obs.add(40, 2.44);
        obs.add(50, 1.73);
        obs.add(60, 1.01);
        obs.add(70, 0.29);

        // Instantiate a first-degree polynomial fitter.
        final PolynomialCurveFitter fitter = PolynomialCurveFitter.create(1);

        // Retrieve fitted parameters (coefficients of the polynomial function).
        final double[] coeff = fitter.fit(obs.toList());
        System.out.println(Arrays.toString(coeff));
    }
}

生成以下值:[5.299999999999998,-0.07149999999999994]。即B = exp 5.3 = 200且C = -1/14。这是唯一可能的,因为我事先了解了A,如果我事先不知道常数,我该如何计算这些系数呢?

使用wolfram mathematica,A,B和C的值分别为6.381,161.144和-0.0706。我希望我能在java中获得这些值的指导。感谢。

1 个答案:

答案 0 :(得分:1)

常数A无关紧要。

您可以重新排列功能:

y = A + Be(cx)

看起来像这样:

z = y-A = B*exp(c*x)

采取双方的自然记录:

ln(z) = ln(B) + c*x

您可以使用ln(B)对来计算c(x, ln(z))的最小二乘拟合。

您可以将A任意设置为零以进行拟合。

当你有系数时,你可以重写函数以获得y的值。

你可以看到所有的A都是上下移动曲线。我的建议是推断回计算x = 0函数的值并从中设置A的值:

y(0) = A + B => A = B - y(0)

您的数据为x = 10提供了斜率:

y'(x = 10) ~ (43.9 - 86.5)/(20 - 10) = -4.26

使用它推断回x = 0