Uploaded image for project: 'Commons Math'
  1. Commons Math
  2. MATH-303

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

    XMLWordPrintableJSON

Details

    • Bug
    • Status: Closed
    • Major
    • Resolution: Invalid
    • 2.0
    • 2.1
    • None
    • Java, Linux Ubuntu 9.04 (64 bit)

    Description

      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:

      CurveFitter with LevenbergMarquardtOptimizer and SimpleInverseFunction
        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)

      Attachments

        Activity

          People

            Unassigned Unassigned
            ddrummond Daren Drummond
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved: