如何使用Java Math Commons CurveFitter? [英] How to use Java Math Commons CurveFitter?

查看:198
本文介绍了如何使用Java Math Commons CurveFitter?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何使用Math Commons CurveFitter将函数拟合到一组数据?我被告知使用CurveFitter和 LevenbergMarquardtOptimizer ParametricUnivariateFunction ,但我不知道在ParametricUnivariateFunction渐变和值方法中要写什么。另外,在写完之后,如何获得拟合的函数参数?我的功能:

How do I use Math Commons CurveFitter to fit a function to a set of data? I was told to use CurveFitter with LevenbergMarquardtOptimizer and ParametricUnivariateFunction, but I don't know what to write in the ParametricUnivariateFunction gradient and value methods. Besides, after writing them, how to get the fitted function parameters? My function:

public static double fnc(double t, double a, double b, double c){
  return a * Math.pow(t, b) * Math.exp(-c * t);
}


推荐答案

所以,这是一个旧的问题,但我最近遇到了同样的问题,最后不得不深入研究邮件列表和Apache Commons Math源代码来解决这个问题。

So, this is an old question, but I ran into the same issue recently, and ended up having to delve into mailing lists and the Apache Commons Math source code to figure it out.

这个API是记录非常糟糕,但在Apache公共数学(3.3+)的当前版本中,有两个部分,假设您有一个带有多个参数的变量:要适合的函数(实现ParametricUnivariateFunction)和曲线拟合器(扩展AbstractCurveFitter)。

This API is remarkably poorly documented, but in the current version of Apache Common Math (3.3+), there are two parts, assuming you have a single variable with multiple parameters: the function to fit with (which implements ParametricUnivariateFunction) and the curve fitter (which extends AbstractCurveFitter).

适合的功能


  • 公共双值(双t,双...参数)

    • 你的等式。这是您将 fnc 逻辑放在哪里。

    • public double value(double t, double... parameters)
      • Your equation. This is where you would put your fnc logic.

      • 返回上面关于的偏导数组每个参数。 这个计算器可能会有所帮助,如果(像我一样)你在你的微积分上生锈,但任何好处计算机代数系统可以计算出这些值。

      • Returns an array of partial derivative of the above with respect to each parameters. This calculator may be helpful if (like me) you're rusty on your calculus, but any good computer algebra system can calculate these values.

      Curve Fitter


      • 受保护LeastSquaresProblem getProblem(集合< WeightedObservedPoint>积分)

        • 设置一堆样板垃圾,并返回最小二乘问题供装配工使用。

        总而言之,这是您特定情况下的示例解决方案:

        Putting it all together, here's an example solution in your specific case:

        import java.util.*;
        import org.apache.commons.math3.analysis.ParametricUnivariateFunction;
        import org.apache.commons.math3.fitting.AbstractCurveFitter;
        import org.apache.commons.math3.fitting.leastsquares.LeastSquaresBuilder;
        import org.apache.commons.math3.fitting.leastsquares.LeastSquaresProblem;
        import org.apache.commons.math3.fitting.WeightedObservedPoint;
        import org.apache.commons.math3.linear.DiagonalMatrix;
        
        class MyFunc implements ParametricUnivariateFunction {
            public double value(double t, double... parameters) {
                return parameters[0] * Math.pow(t, parameters[1]) * Math.exp(-parameters[2] * t);
            }
        
            // Jacobian matrix of the above. In this case, this is just an array of
            // partial derivatives of the above function, with one element for each parameter.
            public double[] gradient(double t, double... parameters) {
                final double a = parameters[0];
                final double b = parameters[1];
                final double c = parameters[2];
        
                return new double[] {
                    Math.exp(-c*t) * Math.pow(t, b),
                    a * Math.exp(-c*t) * Math.pow(t, b) * Math.log(t),
                    a * (-Math.exp(-c*t)) * Math.pow(t, b+1)
                };
            }
        }
        
        public class MyFuncFitter extends AbstractCurveFitter {
            protected LeastSquaresProblem getProblem(Collection<WeightedObservedPoint> points) {
                final int len = points.size();
                final double[] target  = new double[len];
                final double[] weights = new double[len];
                final double[] initialGuess = { 1.0, 1.0, 1.0 };
        
                int i = 0;
                for(WeightedObservedPoint point : points) {
                    target[i]  = point.getY();
                    weights[i] = point.getWeight();
                    i += 1;
                }
        
                final AbstractCurveFitter.TheoreticalValuesFunction model = new
                    AbstractCurveFitter.TheoreticalValuesFunction(new MyFunc(), points);
        
                return new LeastSquaresBuilder().
                    maxEvaluations(Integer.MAX_VALUE).
                    maxIterations(Integer.MAX_VALUE).
                    start(initialGuess).
                    target(target).
                    weight(new DiagonalMatrix(weights)).
                    model(model.getModelFunction(), model.getModelFunctionJacobian()).
                    build();
            }
        
            public static void main(String[] args) {
                MyFuncFitter fitter = new MyFuncFitter();
                ArrayList<WeightedObservedPoint> points = new ArrayList<WeightedObservedPoint>();
        
                // Add points here; for instance,
                WeightedObservedPoint point = new WeightedObservedPoint(1.0,
                    1.0,
                    1.0);
                points.add(point);
        
                final double coeffs[] = fitter.fit(points);
                System.out.println(Arrays.toString(coeffs));
            }
        }
        

        这篇关于如何使用Java Math Commons CurveFitter?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆