commons-issues mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Daren Drummond (JIRA)" <j...@apache.org>
Subject [jira] Updated: (MATH-303) CurveFitter.fit(ParametricRealFunction, double[]) used with LevenbergMarquardtOptimizer throws ArrayIndexOutOfBoundsException when double[] length > 1 (AbstractLeastSquaresOptimizer.java:187)
Date Mon, 19 Oct 2009 21:32:59 GMT

     [ 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.


Mime
View raw message