You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@commons.apache.org by "Daren Drummond (JIRA)" <ji...@apache.org> on 2009/10/19 23:20:59 UTC

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

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.


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

Posted by "Daren Drummond (JIRA)" <ji...@apache.org>.
     [ https://issues.apache.org/jira/browse/MATH-303?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Daren Drummond updated MATH-303:
--------------------------------

    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:
{code:title=CurveFitter with LevenbergMarquardtOptimizer and SimpleInverseFunction|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[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; 
        }
    }

{code} 

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)

  was:
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)

    Environment: Java, Linux Ubuntu 9.04 (64 bit)  (was: Java, Linux Ubuntu 9.04)

> 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 (64 bit)
>            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:
> {code:title=CurveFitter with LevenbergMarquardtOptimizer and SimpleInverseFunction|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[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; 
>         }
>     }
> {code} 
> 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.


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

Posted by "Luc Maisonobe (JIRA)" <ji...@apache.org>.
     [ https://issues.apache.org/jira/browse/MATH-303?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Luc Maisonobe resolved MATH-303.
--------------------------------

    Resolution: Invalid

The problem is not in the solver but in the implementation of the gradient method in your SimpleInverseFunction class. The length of the returned array must match the length of the second argument to the method (which is called parameters in the interface and doubles in your class). In your implementation, the array always has length 1 since it is created by statement:
{code}
double[]gradientVector = new double[1];
{code}

Also note that 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 two parameters p[0] / x + p[1], the gradient is { 1/x, 1 } and not { -p[0]/x^2, 0 }.

> 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 (64 bit)
>            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:
> {code:title=CurveFitter with LevenbergMarquardtOptimizer and SimpleInverseFunction|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[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; 
>         }
>     }
> {code} 
> 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.


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

Posted by "Phil Steitz (JIRA)" <ji...@apache.org>.
     [ https://issues.apache.org/jira/browse/MATH-303?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Phil Steitz closed MATH-303.
----------------------------


> 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 (64 bit)
>            Reporter: Daren Drummond
>             Fix For: 2.1
>
>
> 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:
> {code:title=CurveFitter with LevenbergMarquardtOptimizer and SimpleInverseFunction|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[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; 
>         }
>     }
> {code} 
> 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.
-
If you think it was sent incorrectly contact one of the administrators: https://issues.apache.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see: http://www.atlassian.com/software/jira

        

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

Posted by "Phil Steitz (JIRA)" <ji...@apache.org>.
     [ https://issues.apache.org/jira/browse/MATH-303?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Phil Steitz updated MATH-303:
-----------------------------

    Fix Version/s: 2.1

> 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 (64 bit)
>            Reporter: Daren Drummond
>             Fix For: 2.1
>
>
> 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:
> {code:title=CurveFitter with LevenbergMarquardtOptimizer and SimpleInverseFunction|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[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; 
>         }
>     }
> {code} 
> 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.
-
If you think it was sent incorrectly contact one of the administrators: https://issues.apache.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see: http://www.atlassian.com/software/jira