CurveFitter.fit(ParametricRealFunction, double[]) used with 
LevenbergMarquardtOptimizer throws ArrayIndexOutOfBoundsException when double[] 
length > 1 (AbstractLeastSquaresOptimizer.java:187)
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

                 Key: MATH-303
                 URL: https://issues.apache.org/jira/browse/MATH-303
             Project: Commons Math
          Issue Type: Bug
    Affects Versions: 2.0
         Environment: Java, Linux Ubuntu 9.04
            Reporter: Daren Drummond


CurveFitter.fit(ParametricRealFunction, double[]) throws 
ArrayIndexOutOfBoundsException at AbstractLeastSquaresOptimizer.java:187 when 
used with the  LevenbergMarquardtOptimizer  and the length of the initial guess 
array is greater than 1.  The code will run if the initialGuess array is of 
length 1, but then CurveFitter.fit() just returns the same value as the 
initialGuess array (I'll file this as a separate issue).  Here is my example 
code:

  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[2];
  initialguess[0] = 1.0d;
  initialguess[1] = .5d;
  double[] bestCoefficients = fitter.fit(sif, initialguess); // <---- throws 
exception here

    /**
     * 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; 
        }
    }

This is the resulting stack trace:

java.lang.ArrayIndexOutOfBoundsException: 1
        at 
org.apache.commons.math.optimization.general.AbstractLeastSquaresOptimizer.updateJacobian(AbstractLeastSquaresOptimizer.java:187)
        at 
org.apache.commons.math.optimization.general.LevenbergMarquardtOptimizer.doOptimize(LevenbergMarquardtOptimizer.java:241)
        at 
org.apache.commons.math.optimization.general.AbstractLeastSquaresOptimizer.optimize(AbstractLeastSquaresOptimizer.java:346)
        at 
org.apache.commons.math.optimization.fitting.CurveFitter.fit(CurveFitter.java:134)
        at 
com.yieldsoftware.analyticstest.tasks.ppcbidder.CurveFittingTest.testFitnessRankCurveIntercept(CurveFittingTest.java:181)

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.

Reply via email to