How to use Java math Commons curvefitter?

How do I fit a function to a set of data using math Commons curvefitter? I was told to use curvefitter with Levenberg Marquardt optimizer and parametricunivariatefunction, but I don't know what to write in the gradient and value method of parametricunivariatefunction In addition, after writing, how to obtain the fitted function parameters? My features:

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

Solution

Therefore, this is an old problem, but I recently encountered the same problem, and finally had to go deep into the mailing list and Apache commons math source code to solve this problem

This API has very little documentation, but in the current version of Apache common math (3.3), there are two parts. Suppose you have a variable with multiple parameters: the fitting function (which implements parametricunivariatefunction) and the curve fitter (which extends abstractcurvefitter)

Suitable functions

>Common double value (double T, double... Parameters)

>Your equation This is where you place FNC logic

>Public double [] gradient (double T, double... Parameter)

>Returns an array of the above partial derivatives according to each parameter If (like me) your calculus is rusty, but any good computer algebra system can calculate these values, this calculator may help

Curve fitter

>Protected leastsquaresproblem getproblem (set < weightedobservedpoint > points)

>Set up a pile of template garbage and return the least square problem for the assembler

In summary, this is an example solution for your specific situation:

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);
        points.add(point);

        final double coeffs[] = fitter.fit(points);
        System.out.println(Arrays.toString(coeffs));
    }
}
The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>