[
https://issues.apache.org/jira/browse/MATH-304?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Luc Maisonobe resolved MATH-304.
--------------------------------
Resolution: Invalid
The problem is not in the solver but in the implementation of the gradient
method in your SimpleInverseFunction class. The value of the gradient is wrong.
The gradient vector is computed with respect to the parameters (which is the
reason why lengths must match), not with respect to the independent variable x.
So for a function with one parameter p[0] / x, the gradient is { 1/x } and not
{ -p[0]/x^2 }.
> CurveFitter.fit(ParametricRealFunction, double[]) always returns the same
> value as the initial guess when used with the LevenbergMarquardtOptimizer
> ---------------------------------------------------------------------------------------------------------------------------------------------------
>
> Key: MATH-304
> URL: https://issues.apache.org/jira/browse/MATH-304
> Project: Commons Math
> Issue Type: Bug
> Affects Versions: 2.0
> Environment: Java, Ubuntu 9.04 (64 bit)
> Reporter: Daren Drummond
>
> CurveFitter.fit(ParametricRealFunction, double[]) always returns the same
> value as the initial guess when used with the LevenbergMarquardtOptimizer and
> the length of the initial guess array is 1. Here is my example code:
> {code:title=CurveFitter with LevenbergMarquardtOptimizer|borderStyle=solid}
> LevenbergMarquardtOptimizer optimizer = new LevenbergMarquardtOptimizer();
> CurveFitter fitter = new CurveFitter(optimizer);
> fitter.addObservedPoint(2.805d, 0.6934785852953367d);
> fitter.addObservedPoint(2.74333333333333d, 0.6306772025518496d);
> fitter.addObservedPoint(1.655d, 0.9474675497289684);
> fitter.addObservedPoint(1.725d, 0.9013594835804194d);
> SimpleInverseFunction sif = new SimpleInverseFunction(); // Class provided
> below
> double[] initialguess = new double[1];
> initialguess[0] = 1.0d;
> double[] bestCoefficients = fitter.fit(sif, initialguess); // <---- ALWAYS
> RETURNS A VALUE OF initialguess !
> /**
> * This is my implementation of ParametricRealFunction
> * Implements y = ax^-1 + b for use with an Apache CurveFitter
> implementation
> */
> private class SimpleInverseFunction implements ParametricRealFunction
> {
> public double value(double x, double[] doubles) throws
> FunctionEvaluationException
> {
> //y = ax^-1 + b
> //"double[] must include at least 1 but not more than 2
> coefficients."
> if(doubles == null || doubles.length ==0 || doubles.length > 2)
> throw new FunctionEvaluationException(doubles);
> double a = doubles[0];
> double b = 0;
> if(doubles.length >= 2) b = doubles[1];
> return a * Math.pow(x, -1d) + b;
> }
> public double[] gradient(double x, double[] doubles) throws
> FunctionEvaluationException
> {
> //derivative: -ax^-2
> //"double[] must include at least 1 but not more than 2
> coefficients."
> if(doubles == null || doubles.length ==0 || doubles.length > 2)
> throw new FunctionEvaluationException(doubles);
> double a = doubles[0];
> double b = 0;
> if(doubles.length >= 2) b = doubles[1];
> double derivative = -a * Math.pow(x, -2d);
> double[]gradientVector = new double[1];
> gradientVector[0] = derivative;
> return gradientVector;
> }
> }
> {code}
--
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.