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