Merge branch 'master' of

https://luc@git-wip-us.apache.org/repos/asf/commons-math.git

Conflicts:
	src/changes/changes.xml
This commit is contained in:
Luc Maisonobe 2015-06-11 14:09:52 +02:00
commit 2990f6caad
4 changed files with 77 additions and 25 deletions

View File

@ -57,6 +57,11 @@ If the output is not quite correct, check for invisible trailing spaces!
<action dev="luc" type="fix" issue="MATH-1232"> <!-- backported to 3.6 -->
Fixed error message for unknown parameter name in ODE.
</action>
<action dev="tn" type="fix" issue="MATH-1230">
The "SimplexSolver" will now throw a "DimensionMismatchException"
when calling "optimize(...)" with linear constraints whose dimension
does not match the dimension of the objective function.
</action>
<action dev="luc" type="fix" issue="MATH-1226"> <!-- backported to 3.6 -->
Fixed wrong event detection in case of close events pairs.
</action>
@ -73,10 +78,6 @@ If the output is not quite correct, check for invisible trailing spaces!
<action dev="luc" type="fix" issue="MATH-1222" due-to="Benedikt Ritter">
Use Double.isNaN rather than x != x in FastMath.
</action>
<action dev="tn" type="fix"> <!-- backported to 3.6 -->
Fix potential branching errors in "FastMath#pow(double, double)" when
passing special values, i.e. infinity, due to erroneous JIT optimization.
</action>
<action dev="luc" type="fix" issue="MATH-1118" > <!-- backported to 3.6 -->
Fixed equals/hashcode contract failure for Dfp.
</action>

View File

@ -146,6 +146,8 @@ public class SimplexSolver extends LinearOptimizer {
*
* @return {@inheritDoc}
* @throws TooManyIterationsException if the maximal number of iterations is exceeded.
* @throws org.apache.commons.math4.exception.DimensionMismatchException if the dimension
* of the constraints does not match the dimension of the objective function
*/
@Override
public PointValuePair optimize(OptimizationData... optData)

View File

@ -28,6 +28,7 @@ import java.util.List;
import java.util.Set;
import java.util.TreeSet;
import org.apache.commons.math4.exception.DimensionMismatchException;
import org.apache.commons.math4.linear.Array2DRowRealMatrix;
import org.apache.commons.math4.linear.MatrixUtils;
import org.apache.commons.math4.linear.RealVector;
@ -112,6 +113,8 @@ class SimplexTableau implements Serializable {
* or {@link GoalType#MINIMIZE}.
* @param restrictToNonNegative Whether to restrict the variables to non-negative values.
* @param epsilon Amount of error to accept when checking for optimality.
* @throws DimensionMismatchException if the dimension of the constraints does not match the
* dimension of the objective function
*/
SimplexTableau(final LinearObjectiveFunction f,
final Collection<LinearConstraint> constraints,
@ -129,13 +132,16 @@ class SimplexTableau implements Serializable {
* @param restrictToNonNegative whether to restrict the variables to non-negative values
* @param epsilon amount of error to accept when checking for optimality
* @param maxUlps amount of error to accept in floating point comparisons
* @throws DimensionMismatchException if the dimension of the constraints does not match the
* dimension of the objective function
*/
SimplexTableau(final LinearObjectiveFunction f,
final Collection<LinearConstraint> constraints,
final GoalType goalType,
final boolean restrictToNonNegative,
final double epsilon,
final int maxUlps) {
final int maxUlps) throws DimensionMismatchException {
checkDimensions(f, constraints);
this.f = f;
this.constraints = normalizeConstraints(constraints);
this.restrictToNonNegative = restrictToNonNegative;
@ -153,6 +159,23 @@ class SimplexTableau implements Serializable {
initializeColumnLabels();
}
/**
* Checks that the dimensions of the objective function and the constraints match.
* @param objectiveFunction the objective function
* @param c the set of constraints
* @throws DimensionMismatchException if the constraint dimensions do not match with the
* dimension of the objective function
*/
private void checkDimensions(final LinearObjectiveFunction objectiveFunction,
final Collection<LinearConstraint> c) {
final int dimension = objectiveFunction.getCoefficients().getDimension();
for (final LinearConstraint constraint : c) {
final int constraintDimension = constraint.getCoefficients().getDimension();
if (constraintDimension != dimension) {
throw new DimensionMismatchException(constraintDimension, dimension);
}
}
}
/**
* Initialize the labels for the columns.
*/

View File

@ -20,6 +20,7 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.apache.commons.math4.exception.DimensionMismatchException;
import org.apache.commons.math4.exception.TooManyIterationsException;
import org.apache.commons.math4.optim.MaxIter;
import org.apache.commons.math4.optim.PointValuePair;
@ -793,6 +794,31 @@ public class SimplexSolverTest {
Assert.assertEquals(7.0, solution.getValue(), 1e-4);
}
@Test(expected=DimensionMismatchException.class)
public void testDimensionMatch() {
// min 2x1 +15x2 +18x3
// Subject to
// -x1 +2x2 -6x3 <=-10
// x2 +2x3 <= 6
// 2x1 +10x3 <= 19
// -x1 +x2 <= -2
// x1,x2,x3 >= 0
LinearObjectiveFunction f = new LinearObjectiveFunction(new double[] { 2, 15, 18 }, 0);
Collection<LinearConstraint> constraints = new ArrayList<LinearConstraint>();
// this constraint is wrong, the dimension is less than expected one
constraints.add(new LinearConstraint(new double[] { -1, 2 - 6 }, Relationship.LEQ, -10));
constraints.add(new LinearConstraint(new double[] { 0, 1, 2 }, Relationship.LEQ, 6));
constraints.add(new LinearConstraint(new double[] { 2, 0, 10 }, Relationship.LEQ, 19));
constraints.add(new LinearConstraint(new double[] { -1, 1, 0 }, Relationship.LEQ, -2));
SimplexSolver solver = new SimplexSolver();
solver.optimize(f,
new LinearConstraintSet(constraints),
new NonNegativeConstraint(true),
PivotSelectionRule.BLAND);
}
/**
* Converts a test string to a {@link LinearConstraint}.
* Ex: x0 + x1 + x2 + x3 - x12 = 0