Skip to content

Commit 34f2ea5

Browse files
author
Gilles Sadowski
committed
MATH-933
Throw exception when bounds are passed to an algorithm that does not support them. git-svn-id: https://svn.apache.org/repos/asf/commons/proper/math/trunk@1442377 13f79535-47bb-0310-9956-ffa450edef68
1 parent 007b4c1 commit 34f2ea5

7 files changed

Lines changed: 66 additions & 2 deletions

File tree

src/main/java/org/apache/commons/math3/exception/util/LocalizedFormats.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ public enum LocalizedFormats implements Localizable {
7272
CLOSEST_ORTHOGONAL_MATRIX_HAS_NEGATIVE_DETERMINANT("the closest orthogonal matrix has a negative determinant {0}"),
7373
COLUMN_INDEX_OUT_OF_RANGE("column index {0} out of allowed range [{1}, {2}]"),
7474
COLUMN_INDEX("column index ({0})"), /* keep */
75+
CONSTRAINT("constraint"), /* keep */
7576
CONTINUED_FRACTION_INFINITY_DIVERGENCE("Continued fraction convergents diverged to +/- infinity for value {0}"),
7677
CONTINUED_FRACTION_NAN_DIVERGENCE("Continued fraction diverged to NaN for value {0}"),
7778
CONTRACTION_CRITERIA_SMALLER_THAN_EXPANSION_FACTOR("contraction criteria ({0}) smaller than the expansion factor ({1}). This would lead to a never ending loop of expansion and contraction as a newly expanded internal storage array would immediately satisfy the criteria for contraction."),

src/main/java/org/apache/commons/math3/optim/nonlinear/vector/jacobian/GaussNewtonOptimizer.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import org.apache.commons.math3.exception.ConvergenceException;
2020
import org.apache.commons.math3.exception.NullArgumentException;
2121
import org.apache.commons.math3.exception.MathInternalError;
22+
import org.apache.commons.math3.exception.MathUnsupportedOperationException;
2223
import org.apache.commons.math3.exception.util.LocalizedFormats;
2324
import org.apache.commons.math3.linear.ArrayRealVector;
2425
import org.apache.commons.math3.linear.BlockRealMatrix;
@@ -32,6 +33,11 @@
3233

3334
/**
3435
* Gauss-Newton least-squares solver.
36+
* <br/>
37+
* Constraints are not supported: the call to
38+
* {@link #optimize(OptimizationData[]) optimize} will throw
39+
* {@link MathUnsupportedOperationException} if bounds are passed to it.
40+
*
3541
* <p>
3642
* This class solve a least-square problem by solving the normal equations
3743
* of the linearized problem at each iteration. Either LU decomposition or
@@ -72,6 +78,8 @@ public GaussNewtonOptimizer(final boolean useLU,
7278
/** {@inheritDoc} */
7379
@Override
7480
public PointVectorValuePair doOptimize() {
81+
checkParameters();
82+
7583
final ConvergenceChecker<PointVectorValuePair> checker
7684
= getConvergenceChecker();
7785

@@ -159,4 +167,15 @@ public PointVectorValuePair doOptimize() {
159167
// Must never happen.
160168
throw new MathInternalError();
161169
}
170+
171+
/**
172+
* @throws MathUnsupportedOperationException if bounds were passed to the
173+
* {@link #optimize(OptimizationData[]) optimize} method.
174+
*/
175+
private void checkParameters() {
176+
if (getLowerBound() != null ||
177+
getUpperBound() != null) {
178+
throw new MathUnsupportedOperationException(LocalizedFormats.CONSTRAINT);
179+
}
180+
}
162181
}

src/main/java/org/apache/commons/math3/optim/nonlinear/vector/jacobian/LevenbergMarquardtOptimizer.java

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
import java.util.Arrays;
2020
import org.apache.commons.math3.exception.ConvergenceException;
21+
import org.apache.commons.math3.exception.MathUnsupportedOperationException;
2122
import org.apache.commons.math3.exception.util.LocalizedFormats;
2223
import org.apache.commons.math3.optim.PointVectorValuePair;
2324
import org.apache.commons.math3.optim.ConvergenceChecker;
@@ -27,7 +28,12 @@
2728

2829

2930
/**
30-
* This class solves a least-squares problem using the Levenberg-Marquardt algorithm.
31+
* This class solves a least-squares problem using the Levenberg-Marquardt
32+
* algorithm.
33+
* <br/>
34+
* Constraints are not supported: the call to
35+
* {@link #optimize(OptimizationData[]) optimize} will throw
36+
* {@link MathUnsupportedOperationException} if bounds are passed to it.
3137
*
3238
* <p>This implementation <em>should</em> work even for over-determined systems
3339
* (i.e. systems having more point than equations). Over-determined systems
@@ -276,6 +282,8 @@ public LevenbergMarquardtOptimizer(double initialStepBoundFactor,
276282
/** {@inheritDoc} */
277283
@Override
278284
protected PointVectorValuePair doOptimize() {
285+
checkParameters();
286+
279287
final int nR = getTarget().length; // Number of observed data.
280288
final double[] currentPoint = getStartPoint();
281289
final int nC = currentPoint.length; // Number of parameters.
@@ -936,4 +944,15 @@ private void qTy(double[] y) {
936944
}
937945
}
938946
}
947+
948+
/**
949+
* @throws MathUnsupportedOperationException if bounds were passed to the
950+
* {@link #optimize(OptimizationData[]) optimize} method.
951+
*/
952+
private void checkParameters() {
953+
if (getLowerBound() != null ||
954+
getUpperBound() != null) {
955+
throw new MathUnsupportedOperationException(LocalizedFormats.CONSTRAINT);
956+
}
957+
}
939958
}

src/main/resources/assets/org/apache/commons/math3/exception/util/LocalizedFormats_fr.properties

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ CLASS_DOESNT_IMPLEMENT_COMPARABLE = la classe ({0}) n''implante pas l''interface
4444
CLOSEST_ORTHOGONAL_MATRIX_HAS_NEGATIVE_DETERMINANT = la matrice orthogonale la plus proche a un d\u00e9terminant n\u00e9gatif {0}
4545
COLUMN_INDEX_OUT_OF_RANGE = l''index de colonne {0} est hors du domaine autoris\u00e9 [{1}, {2}]
4646
COLUMN_INDEX = index de colonne ({0})
47+
CONSTRAINT = contrainte
4748
CONTINUED_FRACTION_INFINITY_DIVERGENCE = Divergence de fraction continue \u00e0 l''infini pour la valeur {0}
4849
CONTINUED_FRACTION_NAN_DIVERGENCE = Divergence de fraction continue \u00e0 NaN pour la valeur {0}
4950
CONTRACTION_CRITERIA_SMALLER_THAN_EXPANSION_FACTOR = crit\u00e8re de contraction ({0}) inf\u00e9rieur au facteur d''extension ({1}). Ceci induit une boucle infinie d''extensions/contractions car tout tableau de stockage fra\u00eechement \u00e9tendu respecte imm\u00e9diatement le crit\u00e8re de contraction.

src/test/java/org/apache/commons/math3/exception/util/LocalizedFormatsTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ public class LocalizedFormatsTest {
3030

3131
@Test
3232
public void testMessageNumber() {
33-
Assert.assertEquals(312, LocalizedFormats.values().length);
33+
Assert.assertEquals(313, LocalizedFormats.values().length);
3434
}
3535

3636
@Test

src/test/java/org/apache/commons/math3/optim/nonlinear/vector/jacobian/GaussNewtonOptimizerTest.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,11 @@
2020
import java.io.IOException;
2121
import org.apache.commons.math3.exception.ConvergenceException;
2222
import org.apache.commons.math3.exception.TooManyEvaluationsException;
23+
import org.apache.commons.math3.exception.MathUnsupportedOperationException;
2324
import org.apache.commons.math3.optim.SimpleVectorValueChecker;
2425
import org.apache.commons.math3.optim.InitialGuess;
2526
import org.apache.commons.math3.optim.MaxEval;
27+
import org.apache.commons.math3.optim.SimpleBounds;
2628
import org.apache.commons.math3.optim.nonlinear.vector.Target;
2729
import org.apache.commons.math3.optim.nonlinear.vector.Weight;
2830
import org.apache.commons.math3.optim.nonlinear.vector.ModelFunction;
@@ -99,6 +101,16 @@ public AbstractLeastSquaresOptimizer createOptimizer() {
99101
return new GaussNewtonOptimizer(new SimpleVectorValueChecker(1.0e-6, 1.0e-6));
100102
}
101103

104+
@Test(expected=MathUnsupportedOperationException.class)
105+
public void testConstraintsUnsupported() {
106+
createOptimizer().optimize(new MaxEval(100),
107+
new Target(new double[] { 2 }),
108+
new Weight(new double[] { 1 }),
109+
new InitialGuess(new double[] { 1, 2 }),
110+
new SimpleBounds(new double[] { -10, 0 },
111+
new double[] { 20, 30 }));
112+
}
113+
102114
@Override
103115
@Test(expected = ConvergenceException.class)
104116
public void testMoreEstimatedParametersSimple() {

src/test/java/org/apache/commons/math3/optim/nonlinear/vector/jacobian/LevenbergMarquardtOptimizerTest.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import org.apache.commons.math3.optim.PointVectorValuePair;
2424
import org.apache.commons.math3.optim.InitialGuess;
2525
import org.apache.commons.math3.optim.MaxEval;
26+
import org.apache.commons.math3.optim.SimpleBounds;
2627
import org.apache.commons.math3.optim.nonlinear.vector.Target;
2728
import org.apache.commons.math3.optim.nonlinear.vector.Weight;
2829
import org.apache.commons.math3.optim.nonlinear.vector.ModelFunction;
@@ -32,6 +33,7 @@
3233
import org.apache.commons.math3.exception.ConvergenceException;
3334
import org.apache.commons.math3.exception.DimensionMismatchException;
3435
import org.apache.commons.math3.exception.TooManyEvaluationsException;
36+
import org.apache.commons.math3.exception.MathUnsupportedOperationException;
3537
import org.apache.commons.math3.geometry.euclidean.twod.Vector2D;
3638
import org.apache.commons.math3.linear.SingularMatrixException;
3739
import org.apache.commons.math3.util.FastMath;
@@ -109,6 +111,16 @@ public AbstractLeastSquaresOptimizer createOptimizer() {
109111
return new LevenbergMarquardtOptimizer();
110112
}
111113

114+
@Test(expected=MathUnsupportedOperationException.class)
115+
public void testConstraintsUnsupported() {
116+
createOptimizer().optimize(new MaxEval(100),
117+
new Target(new double[] { 2 }),
118+
new Weight(new double[] { 1 }),
119+
new InitialGuess(new double[] { 1, 2 }),
120+
new SimpleBounds(new double[] { -10, 0 },
121+
new double[] { 20, 30 }));
122+
}
123+
112124
@Override
113125
@Test(expected=SingularMatrixException.class)
114126
public void testNonInvertible() {

0 commit comments

Comments
 (0)