commons-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From er...@apache.org
Subject svn commit: r1420684 [10/15] - in /commons/proper/math/trunk/src: main/java/org/apache/commons/math3/exception/ main/java/org/apache/commons/math3/exception/util/ main/java/org/apache/commons/math3/fitting/ main/java/org/apache/commons/math3/optim/ mai...
Date Wed, 12 Dec 2012 14:11:04 GMT
Added: commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optim/linear/SimplexSolverTest.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optim/linear/SimplexSolverTest.java?rev=1420684&view=auto
==============================================================================
--- commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optim/linear/SimplexSolverTest.java (added)
+++ commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optim/linear/SimplexSolverTest.java Wed Dec 12 14:10:38 2012
@@ -0,0 +1,664 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.math3.optim.linear;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import org.apache.commons.math3.optim.MaxIter;
+import org.apache.commons.math3.optim.GoalType;
+import org.apache.commons.math3.optim.PointValuePair;
+import org.apache.commons.math3.util.Precision;
+import org.junit.Test;
+import org.junit.Assert;
+
+public class SimplexSolverTest {
+    private static final MaxIter DEFAULT_MAX_ITER = new MaxIter(100);
+
+    @Test
+    public void testMath828() {
+        LinearObjectiveFunction f = new LinearObjectiveFunction(
+                new double[] { 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, 0.0);
+        
+        ArrayList <LinearConstraint>constraints = new ArrayList<LinearConstraint>();
+
+        constraints.add(new LinearConstraint(new double[] {0.0, 39.0, 23.0, 96.0, 15.0, 48.0, 9.0, 21.0, 48.0, 36.0, 76.0, 19.0, 88.0, 17.0, 16.0, 36.0,}, Relationship.GEQ, 15.0));
+        constraints.add(new LinearConstraint(new double[] {0.0, 59.0, 93.0, 12.0, 29.0, 78.0, 73.0, 87.0, 32.0, 70.0, 68.0, 24.0, 11.0, 26.0, 65.0, 25.0,}, Relationship.GEQ, 29.0));
+        constraints.add(new LinearConstraint(new double[] {0.0, 74.0, 5.0, 82.0, 6.0, 97.0, 55.0, 44.0, 52.0, 54.0, 5.0, 93.0, 91.0, 8.0, 20.0, 97.0,}, Relationship.GEQ, 6.0));
+        constraints.add(new LinearConstraint(new double[] {8.0, -3.0, -28.0, -72.0, -8.0, -31.0, -31.0, -74.0, -47.0, -59.0, -24.0, -57.0, -56.0, -16.0, -92.0, -59.0,}, Relationship.GEQ, 0.0));
+        constraints.add(new LinearConstraint(new double[] {25.0, -7.0, -99.0, -78.0, -25.0, -14.0, -16.0, -89.0, -39.0, -56.0, -53.0, -9.0, -18.0, -26.0, -11.0, -61.0,}, Relationship.GEQ, 0.0));
+        constraints.add(new LinearConstraint(new double[] {33.0, -95.0, -15.0, -4.0, -33.0, -3.0, -20.0, -96.0, -27.0, -13.0, -80.0, -24.0, -3.0, -13.0, -57.0, -76.0,}, Relationship.GEQ, 0.0));
+        constraints.add(new LinearConstraint(new double[] {7.0, -95.0, -39.0, -93.0, -7.0, -94.0, -94.0, -62.0, -76.0, -26.0, -53.0, -57.0, -31.0, -76.0, -53.0, -52.0,}, Relationship.GEQ, 0.0));
+        
+        double epsilon = 1e-6;
+        PointValuePair solution = new SimplexSolver().optimize(DEFAULT_MAX_ITER, f, new LinearConstraintSet(constraints),
+                                                               GoalType.MINIMIZE, new NonNegativeConstraint(true));
+        Assert.assertEquals(1.0d, solution.getValue(), epsilon);
+        Assert.assertTrue(validSolution(solution, constraints, epsilon));
+    }
+
+    @Test
+    public void testMath828Cycle() {
+        LinearObjectiveFunction f = new LinearObjectiveFunction(
+                new double[] { 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, 0.0);
+        
+        ArrayList <LinearConstraint>constraints = new ArrayList<LinearConstraint>();
+
+        constraints.add(new LinearConstraint(new double[] {0.0, 16.0, 14.0, 69.0, 1.0, 85.0, 52.0, 43.0, 64.0, 97.0, 14.0, 74.0, 89.0, 28.0, 94.0, 58.0, 13.0, 22.0, 21.0, 17.0, 30.0, 25.0, 1.0, 59.0, 91.0, 78.0, 12.0, 74.0, 56.0, 3.0, 88.0,}, Relationship.GEQ, 91.0));
+        constraints.add(new LinearConstraint(new double[] {0.0, 60.0, 40.0, 81.0, 71.0, 72.0, 46.0, 45.0, 38.0, 48.0, 40.0, 17.0, 33.0, 85.0, 64.0, 32.0, 84.0, 3.0, 54.0, 44.0, 71.0, 67.0, 90.0, 95.0, 54.0, 99.0, 99.0, 29.0, 52.0, 98.0, 9.0,}, Relationship.GEQ, 54.0));
+        constraints.add(new LinearConstraint(new double[] {0.0, 41.0, 12.0, 86.0, 90.0, 61.0, 31.0, 41.0, 23.0, 89.0, 17.0, 74.0, 44.0, 27.0, 16.0, 47.0, 80.0, 32.0, 11.0, 56.0, 68.0, 82.0, 11.0, 62.0, 62.0, 53.0, 39.0, 16.0, 48.0, 1.0, 63.0,}, Relationship.GEQ, 62.0));
+        constraints.add(new LinearConstraint(new double[] {83.0, -76.0, -94.0, -19.0, -15.0, -70.0, -72.0, -57.0, -63.0, -65.0, -22.0, -94.0, -22.0, -88.0, -86.0, -89.0, -72.0, -16.0, -80.0, -49.0, -70.0, -93.0, -95.0, -17.0, -83.0, -97.0, -31.0, -47.0, -31.0, -13.0, -23.0,}, Relationship.GEQ, 0.0));
+        constraints.add(new LinearConstraint(new double[] {41.0, -96.0, -41.0, -48.0, -70.0, -43.0, -43.0, -43.0, -97.0, -37.0, -85.0, -70.0, -45.0, -67.0, -87.0, -69.0, -94.0, -54.0, -54.0, -92.0, -79.0, -10.0, -35.0, -20.0, -41.0, -41.0, -65.0, -25.0, -12.0, -8.0, -46.0,}, Relationship.GEQ, 0.0));
+        constraints.add(new LinearConstraint(new double[] {27.0, -42.0, -65.0, -49.0, -53.0, -42.0, -17.0, -2.0, -61.0, -31.0, -76.0, -47.0, -8.0, -93.0, -86.0, -62.0, -65.0, -63.0, -22.0, -43.0, -27.0, -23.0, -32.0, -74.0, -27.0, -63.0, -47.0, -78.0, -29.0, -95.0, -73.0,}, Relationship.GEQ, 0.0));
+        constraints.add(new LinearConstraint(new double[] {15.0, -46.0, -41.0, -83.0, -98.0, -99.0, -21.0, -35.0, -7.0, -14.0, -80.0, -63.0, -18.0, -42.0, -5.0, -34.0, -56.0, -70.0, -16.0, -18.0, -74.0, -61.0, -47.0, -41.0, -15.0, -79.0, -18.0, -47.0, -88.0, -68.0, -55.0,}, Relationship.GEQ, 0.0));
+        
+        double epsilon = 1e-6;
+        PointValuePair solution = new SimplexSolver().optimize(DEFAULT_MAX_ITER, f, new LinearConstraintSet(constraints),
+                                                               GoalType.MINIMIZE, new NonNegativeConstraint(true));
+        Assert.assertEquals(1.0d, solution.getValue(), epsilon);
+        Assert.assertTrue(validSolution(solution, constraints, epsilon));        
+    }
+
+    @Test
+    public void testMath781() {
+        LinearObjectiveFunction f = new LinearObjectiveFunction(new double[] { 2, 6, 7 }, 0);
+
+        ArrayList<LinearConstraint> constraints = new ArrayList<LinearConstraint>();
+        constraints.add(new LinearConstraint(new double[] { 1, 2, 1 }, Relationship.LEQ, 2));
+        constraints.add(new LinearConstraint(new double[] { -1, 1, 1 }, Relationship.LEQ, -1));
+        constraints.add(new LinearConstraint(new double[] { 2, -3, 1 }, Relationship.LEQ, -1));
+
+        double epsilon = 1e-6;
+        SimplexSolver solver = new SimplexSolver();
+        PointValuePair solution = solver.optimize(DEFAULT_MAX_ITER, f, new LinearConstraintSet(constraints),
+                                                  GoalType.MAXIMIZE, new NonNegativeConstraint(false));
+
+        Assert.assertTrue(Precision.compareTo(solution.getPoint()[0], 0.0d, epsilon) > 0);
+        Assert.assertTrue(Precision.compareTo(solution.getPoint()[1], 0.0d, epsilon) > 0);
+        Assert.assertTrue(Precision.compareTo(solution.getPoint()[2], 0.0d, epsilon) < 0);
+        Assert.assertEquals(2.0d, solution.getValue(), epsilon);
+    }
+
+    @Test
+    public void testMath713NegativeVariable() {
+        LinearObjectiveFunction f = new LinearObjectiveFunction(new double[] {1.0, 1.0}, 0.0d);
+        ArrayList<LinearConstraint> constraints = new ArrayList<LinearConstraint>();
+        constraints.add(new LinearConstraint(new double[] {1, 0}, Relationship.EQ, 1));
+
+        double epsilon = 1e-6;
+        SimplexSolver solver = new SimplexSolver();
+        PointValuePair solution = solver.optimize(DEFAULT_MAX_ITER, f, new LinearConstraintSet(constraints),
+                                                  GoalType.MINIMIZE, new NonNegativeConstraint(true));
+
+        Assert.assertTrue(Precision.compareTo(solution.getPoint()[0], 0.0d, epsilon) >= 0);
+        Assert.assertTrue(Precision.compareTo(solution.getPoint()[1], 0.0d, epsilon) >= 0);
+    }
+
+    @Test
+    public void testMath434NegativeVariable() {
+        LinearObjectiveFunction f = new LinearObjectiveFunction(new double[] {0.0, 0.0, 1.0}, 0.0d);
+        ArrayList<LinearConstraint> constraints = new ArrayList<LinearConstraint>();
+        constraints.add(new LinearConstraint(new double[] {1, 1, 0}, Relationship.EQ, 5));
+        constraints.add(new LinearConstraint(new double[] {0, 0, 1}, Relationship.GEQ, -10));
+
+        double epsilon = 1e-6;
+        SimplexSolver solver = new SimplexSolver();
+        PointValuePair solution = solver.optimize(DEFAULT_MAX_ITER, f, new LinearConstraintSet(constraints),
+                                                  GoalType.MINIMIZE, new NonNegativeConstraint(false));
+
+        Assert.assertEquals(5.0, solution.getPoint()[0] + solution.getPoint()[1], epsilon);
+        Assert.assertEquals(-10.0, solution.getPoint()[2], epsilon);
+        Assert.assertEquals(-10.0, solution.getValue(), epsilon);
+
+    }
+
+    @Test(expected = NoFeasibleSolutionException.class)
+    public void testMath434UnfeasibleSolution() {
+        double epsilon = 1e-6;
+
+        LinearObjectiveFunction f = new LinearObjectiveFunction(new double[] {1.0, 0.0}, 0.0);
+        ArrayList<LinearConstraint> constraints = new ArrayList<LinearConstraint>();
+        constraints.add(new LinearConstraint(new double[] {epsilon/2, 0.5}, Relationship.EQ, 0));
+        constraints.add(new LinearConstraint(new double[] {1e-3, 0.1}, Relationship.EQ, 10));
+
+        SimplexSolver solver = new SimplexSolver();
+        // allowing only non-negative values, no feasible solution shall be found
+        solver.optimize(DEFAULT_MAX_ITER, f, new LinearConstraintSet(constraints),
+                        GoalType.MINIMIZE, new NonNegativeConstraint(true));
+    }
+
+    @Test
+    public void testMath434PivotRowSelection() {
+        LinearObjectiveFunction f = new LinearObjectiveFunction(new double[] {1.0}, 0.0);
+
+        double epsilon = 1e-6;
+        ArrayList<LinearConstraint> constraints = new ArrayList<LinearConstraint>();
+        constraints.add(new LinearConstraint(new double[] {200}, Relationship.GEQ, 1));
+        constraints.add(new LinearConstraint(new double[] {100}, Relationship.GEQ, 0.499900001));
+
+        SimplexSolver solver = new SimplexSolver();
+        PointValuePair solution = solver.optimize(DEFAULT_MAX_ITER, f, new LinearConstraintSet(constraints),
+                                                  GoalType.MINIMIZE, new NonNegativeConstraint(false));
+        
+        Assert.assertTrue(Precision.compareTo(solution.getPoint()[0] * 200.d, 1.d, epsilon) >= 0);
+        Assert.assertEquals(0.0050, solution.getValue(), epsilon);
+    }
+
+    @Test
+    public void testMath434PivotRowSelection2() {
+        LinearObjectiveFunction f = new LinearObjectiveFunction(new double[] {0.0d, 1.0d, 1.0d, 0.0d, 0.0d, 0.0d, 0.0d}, 0.0d);
+
+        ArrayList<LinearConstraint> constraints = new ArrayList<LinearConstraint>();
+        constraints.add(new LinearConstraint(new double[] {1.0d, -0.1d, 0.0d, 0.0d, 0.0d, 0.0d, 0.0d}, Relationship.EQ, -0.1d));
+        constraints.add(new LinearConstraint(new double[] {1.0d, 0.0d, 0.0d, 0.0d, 0.0d, 0.0d, 0.0d}, Relationship.GEQ, -1e-18d));
+        constraints.add(new LinearConstraint(new double[] {0.0d, 1.0d, 0.0d, 0.0d, 0.0d, 0.0d, 0.0d}, Relationship.GEQ, 0.0d));
+        constraints.add(new LinearConstraint(new double[] {0.0d, 0.0d, 0.0d, 1.0d, 0.0d, -0.0128588d, 1e-5d}, Relationship.EQ, 0.0d));
+        constraints.add(new LinearConstraint(new double[] {0.0d, 0.0d, 0.0d, 0.0d, 1.0d, 1e-5d, -0.0128586d}, Relationship.EQ, 1e-10d));
+        constraints.add(new LinearConstraint(new double[] {0.0d, 0.0d, 1.0d, -1.0d, 0.0d, 0.0d, 0.0d}, Relationship.GEQ, 0.0d));
+        constraints.add(new LinearConstraint(new double[] {0.0d, 0.0d, 1.0d, 1.0d, 0.0d, 0.0d, 0.0d}, Relationship.GEQ, 0.0d));
+        constraints.add(new LinearConstraint(new double[] {0.0d, 0.0d, 1.0d, 0.0d, -1.0d, 0.0d, 0.0d}, Relationship.GEQ, 0.0d));
+        constraints.add(new LinearConstraint(new double[] {0.0d, 0.0d, 1.0d, 0.0d, 1.0d, 0.0d, 0.0d}, Relationship.GEQ, 0.0d));
+
+        double epsilon = 1e-7;
+        SimplexSolver simplex = new SimplexSolver();
+        PointValuePair solution = simplex.optimize(DEFAULT_MAX_ITER, f, new LinearConstraintSet(constraints),
+                                                   GoalType.MINIMIZE, new NonNegativeConstraint(false));
+        
+        Assert.assertTrue(Precision.compareTo(solution.getPoint()[0], -1e-18d, epsilon) >= 0);
+        Assert.assertEquals(1.0d, solution.getPoint()[1], epsilon);        
+        Assert.assertEquals(0.0d, solution.getPoint()[2], epsilon);
+        Assert.assertEquals(1.0d, solution.getValue(), epsilon);
+    }
+    
+    @Test
+    public void testMath272() {
+        LinearObjectiveFunction f = new LinearObjectiveFunction(new double[] { 2, 2, 1 }, 0);
+        Collection<LinearConstraint> constraints = new ArrayList<LinearConstraint>();
+        constraints.add(new LinearConstraint(new double[] { 1, 1, 0 }, Relationship.GEQ,  1));
+        constraints.add(new LinearConstraint(new double[] { 1, 0, 1 }, Relationship.GEQ,  1));
+        constraints.add(new LinearConstraint(new double[] { 0, 1, 0 }, Relationship.GEQ,  1));
+
+        SimplexSolver solver = new SimplexSolver();
+        PointValuePair solution = solver.optimize(DEFAULT_MAX_ITER, f, new LinearConstraintSet(constraints),
+                                                  GoalType.MINIMIZE, new NonNegativeConstraint(true));
+
+        Assert.assertEquals(0.0, solution.getPoint()[0], .0000001);
+        Assert.assertEquals(1.0, solution.getPoint()[1], .0000001);
+        Assert.assertEquals(1.0, solution.getPoint()[2], .0000001);
+        Assert.assertEquals(3.0, solution.getValue(), .0000001);
+    }
+
+    @Test
+    public void testMath286() {
+        LinearObjectiveFunction f = new LinearObjectiveFunction(new double[] { 0.8, 0.2, 0.7, 0.3, 0.6, 0.4 }, 0 );
+        Collection<LinearConstraint> constraints = new ArrayList<LinearConstraint>();
+        constraints.add(new LinearConstraint(new double[] { 1, 0, 1, 0, 1, 0 }, Relationship.EQ, 23.0));
+        constraints.add(new LinearConstraint(new double[] { 0, 1, 0, 1, 0, 1 }, Relationship.EQ, 23.0));
+        constraints.add(new LinearConstraint(new double[] { 1, 0, 0, 0, 0, 0 }, Relationship.GEQ, 10.0));
+        constraints.add(new LinearConstraint(new double[] { 0, 0, 1, 0, 0, 0 }, Relationship.GEQ, 8.0));
+        constraints.add(new LinearConstraint(new double[] { 0, 0, 0, 0, 1, 0 }, Relationship.GEQ, 5.0));
+
+        SimplexSolver solver = new SimplexSolver();
+        PointValuePair solution = solver.optimize(DEFAULT_MAX_ITER, f, new LinearConstraintSet(constraints),
+                                                  GoalType.MAXIMIZE, new NonNegativeConstraint(true));
+
+        Assert.assertEquals(25.8, solution.getValue(), .0000001);
+        Assert.assertEquals(23.0, solution.getPoint()[0] + solution.getPoint()[2] + solution.getPoint()[4], 0.0000001);
+        Assert.assertEquals(23.0, solution.getPoint()[1] + solution.getPoint()[3] + solution.getPoint()[5], 0.0000001);
+        Assert.assertTrue(solution.getPoint()[0] >= 10.0 - 0.0000001);
+        Assert.assertTrue(solution.getPoint()[2] >= 8.0 - 0.0000001);
+        Assert.assertTrue(solution.getPoint()[4] >= 5.0 - 0.0000001);
+    }
+
+    @Test
+    public void testDegeneracy() {
+        LinearObjectiveFunction f = new LinearObjectiveFunction(new double[] { 0.8, 0.7 }, 0 );
+        Collection<LinearConstraint> constraints = new ArrayList<LinearConstraint>();
+        constraints.add(new LinearConstraint(new double[] { 1, 1 }, Relationship.LEQ, 18.0));
+        constraints.add(new LinearConstraint(new double[] { 1, 0 }, Relationship.GEQ, 10.0));
+        constraints.add(new LinearConstraint(new double[] { 0, 1 }, Relationship.GEQ, 8.0));
+
+        SimplexSolver solver = new SimplexSolver();
+        PointValuePair solution = solver.optimize(DEFAULT_MAX_ITER, f, new LinearConstraintSet(constraints),
+                                                  GoalType.MINIMIZE, new NonNegativeConstraint(true));
+        Assert.assertEquals(13.6, solution.getValue(), .0000001);
+    }
+
+    @Test
+    public void testMath288() {
+        LinearObjectiveFunction f = new LinearObjectiveFunction(new double[] { 7, 3, 0, 0 }, 0 );
+        Collection<LinearConstraint> constraints = new ArrayList<LinearConstraint>();
+        constraints.add(new LinearConstraint(new double[] { 3, 0, -5, 0 }, Relationship.LEQ, 0.0));
+        constraints.add(new LinearConstraint(new double[] { 2, 0, 0, -5 }, Relationship.LEQ, 0.0));
+        constraints.add(new LinearConstraint(new double[] { 0, 3, 0, -5 }, Relationship.LEQ, 0.0));
+        constraints.add(new LinearConstraint(new double[] { 1, 0, 0, 0 }, Relationship.LEQ, 1.0));
+        constraints.add(new LinearConstraint(new double[] { 0, 1, 0, 0 }, Relationship.LEQ, 1.0));
+
+        SimplexSolver solver = new SimplexSolver();
+        PointValuePair solution = solver.optimize(DEFAULT_MAX_ITER, f, new LinearConstraintSet(constraints),
+                                                  GoalType.MAXIMIZE, new NonNegativeConstraint(true));
+        Assert.assertEquals(10.0, solution.getValue(), .0000001);
+    }
+
+    @Test
+    public void testMath290GEQ() {
+        LinearObjectiveFunction f = new LinearObjectiveFunction(new double[] { 1, 5 }, 0 );
+        Collection<LinearConstraint> constraints = new ArrayList<LinearConstraint>();
+        constraints.add(new LinearConstraint(new double[] { 2, 0 }, Relationship.GEQ, -1.0));
+        SimplexSolver solver = new SimplexSolver();
+        PointValuePair solution = solver.optimize(DEFAULT_MAX_ITER, f, new LinearConstraintSet(constraints),
+                                                  GoalType.MINIMIZE, new NonNegativeConstraint(true));
+        Assert.assertEquals(0, solution.getValue(), .0000001);
+        Assert.assertEquals(0, solution.getPoint()[0], .0000001);
+        Assert.assertEquals(0, solution.getPoint()[1], .0000001);
+    }
+
+    @Test(expected=NoFeasibleSolutionException.class)
+    public void testMath290LEQ() {
+        LinearObjectiveFunction f = new LinearObjectiveFunction(new double[] { 1, 5 }, 0 );
+        Collection<LinearConstraint> constraints = new ArrayList<LinearConstraint>();
+        constraints.add(new LinearConstraint(new double[] { 2, 0 }, Relationship.LEQ, -1.0));
+        SimplexSolver solver = new SimplexSolver();
+        solver.optimize(DEFAULT_MAX_ITER, f, new LinearConstraintSet(constraints),
+                        GoalType.MINIMIZE, new NonNegativeConstraint(true));
+    }
+
+    @Test
+    public void testMath293() {
+      LinearObjectiveFunction f = new LinearObjectiveFunction(new double[] { 0.8, 0.2, 0.7, 0.3, 0.4, 0.6}, 0 );
+      Collection<LinearConstraint> constraints = new ArrayList<LinearConstraint>();
+      constraints.add(new LinearConstraint(new double[] { 1, 0, 1, 0, 1, 0 }, Relationship.EQ, 30.0));
+      constraints.add(new LinearConstraint(new double[] { 0, 1, 0, 1, 0, 1 }, Relationship.EQ, 30.0));
+      constraints.add(new LinearConstraint(new double[] { 0.8, 0.2, 0.0, 0.0, 0.0, 0.0 }, Relationship.GEQ, 10.0));
+      constraints.add(new LinearConstraint(new double[] { 0.0, 0.0, 0.7, 0.3, 0.0, 0.0 }, Relationship.GEQ, 10.0));
+      constraints.add(new LinearConstraint(new double[] { 0.0, 0.0, 0.0, 0.0, 0.4, 0.6 }, Relationship.GEQ, 10.0));
+
+      SimplexSolver solver = new SimplexSolver();
+      PointValuePair solution1 = solver.optimize(DEFAULT_MAX_ITER, f, new LinearConstraintSet(constraints),
+                                                 GoalType.MAXIMIZE, new NonNegativeConstraint(true));
+
+      Assert.assertEquals(15.7143, solution1.getPoint()[0], .0001);
+      Assert.assertEquals(0.0, solution1.getPoint()[1], .0001);
+      Assert.assertEquals(14.2857, solution1.getPoint()[2], .0001);
+      Assert.assertEquals(0.0, solution1.getPoint()[3], .0001);
+      Assert.assertEquals(0.0, solution1.getPoint()[4], .0001);
+      Assert.assertEquals(30.0, solution1.getPoint()[5], .0001);
+      Assert.assertEquals(40.57143, solution1.getValue(), .0001);
+
+      double valA = 0.8 * solution1.getPoint()[0] + 0.2 * solution1.getPoint()[1];
+      double valB = 0.7 * solution1.getPoint()[2] + 0.3 * solution1.getPoint()[3];
+      double valC = 0.4 * solution1.getPoint()[4] + 0.6 * solution1.getPoint()[5];
+
+      f = new LinearObjectiveFunction(new double[] { 0.8, 0.2, 0.7, 0.3, 0.4, 0.6}, 0 );
+      constraints = new ArrayList<LinearConstraint>();
+      constraints.add(new LinearConstraint(new double[] { 1, 0, 1, 0, 1, 0 }, Relationship.EQ, 30.0));
+      constraints.add(new LinearConstraint(new double[] { 0, 1, 0, 1, 0, 1 }, Relationship.EQ, 30.0));
+      constraints.add(new LinearConstraint(new double[] { 0.8, 0.2, 0.0, 0.0, 0.0, 0.0 }, Relationship.GEQ, valA));
+      constraints.add(new LinearConstraint(new double[] { 0.0, 0.0, 0.7, 0.3, 0.0, 0.0 }, Relationship.GEQ, valB));
+      constraints.add(new LinearConstraint(new double[] { 0.0, 0.0, 0.0, 0.0, 0.4, 0.6 }, Relationship.GEQ, valC));
+
+      PointValuePair solution2 = solver.optimize(DEFAULT_MAX_ITER, f, new LinearConstraintSet(constraints),
+                                                 GoalType.MAXIMIZE, new NonNegativeConstraint(true));
+      Assert.assertEquals(40.57143, solution2.getValue(), .0001);
+    }
+
+    @Test
+    public void testSimplexSolver() {
+        LinearObjectiveFunction f =
+            new LinearObjectiveFunction(new double[] { 15, 10 }, 7);
+        Collection<LinearConstraint> constraints = new ArrayList<LinearConstraint>();
+        constraints.add(new LinearConstraint(new double[] { 1, 0 }, Relationship.LEQ, 2));
+        constraints.add(new LinearConstraint(new double[] { 0, 1 }, Relationship.LEQ, 3));
+        constraints.add(new LinearConstraint(new double[] { 1, 1 }, Relationship.EQ, 4));
+
+        SimplexSolver solver = new SimplexSolver();
+        PointValuePair solution = solver.optimize(DEFAULT_MAX_ITER, f, new LinearConstraintSet(constraints),
+                                                  GoalType.MAXIMIZE, new NonNegativeConstraint(true));
+        Assert.assertEquals(2.0, solution.getPoint()[0], 0.0);
+        Assert.assertEquals(2.0, solution.getPoint()[1], 0.0);
+        Assert.assertEquals(57.0, solution.getValue(), 0.0);
+    }
+
+    @Test
+    public void testSingleVariableAndConstraint() {
+        LinearObjectiveFunction f = new LinearObjectiveFunction(new double[] { 3 }, 0);
+        Collection<LinearConstraint> constraints = new ArrayList<LinearConstraint>();
+        constraints.add(new LinearConstraint(new double[] { 1 }, Relationship.LEQ, 10));
+
+        SimplexSolver solver = new SimplexSolver();
+        PointValuePair solution = solver.optimize(DEFAULT_MAX_ITER, f, new LinearConstraintSet(constraints),
+                                                  GoalType.MAXIMIZE, new NonNegativeConstraint(false));
+        Assert.assertEquals(10.0, solution.getPoint()[0], 0.0);
+        Assert.assertEquals(30.0, solution.getValue(), 0.0);
+    }
+
+    /**
+     * With no artificial variables needed (no equals and no greater than
+     * constraints) we can go straight to Phase 2.
+     */
+    @Test
+    public void testModelWithNoArtificialVars() {
+        LinearObjectiveFunction f = new LinearObjectiveFunction(new double[] { 15, 10 }, 0);
+        Collection<LinearConstraint> constraints = new ArrayList<LinearConstraint>();
+        constraints.add(new LinearConstraint(new double[] { 1, 0 }, Relationship.LEQ, 2));
+        constraints.add(new LinearConstraint(new double[] { 0, 1 }, Relationship.LEQ, 3));
+        constraints.add(new LinearConstraint(new double[] { 1, 1 }, Relationship.LEQ, 4));
+
+        SimplexSolver solver = new SimplexSolver();
+        PointValuePair solution = solver.optimize(DEFAULT_MAX_ITER, f, new LinearConstraintSet(constraints),
+                                                  GoalType.MAXIMIZE, new NonNegativeConstraint(false));
+        Assert.assertEquals(2.0, solution.getPoint()[0], 0.0);
+        Assert.assertEquals(2.0, solution.getPoint()[1], 0.0);
+        Assert.assertEquals(50.0, solution.getValue(), 0.0);
+    }
+
+    @Test
+    public void testMinimization() {
+        LinearObjectiveFunction f = new LinearObjectiveFunction(new double[] { -2, 1 }, -5);
+        Collection<LinearConstraint> constraints = new ArrayList<LinearConstraint>();
+        constraints.add(new LinearConstraint(new double[] { 1, 2 }, Relationship.LEQ, 6));
+        constraints.add(new LinearConstraint(new double[] { 3, 2 }, Relationship.LEQ, 12));
+        constraints.add(new LinearConstraint(new double[] { 0, 1 }, Relationship.GEQ, 0));
+
+        SimplexSolver solver = new SimplexSolver();
+        PointValuePair solution = solver.optimize(DEFAULT_MAX_ITER, f, new LinearConstraintSet(constraints),
+                                                  GoalType.MINIMIZE, new NonNegativeConstraint(false));
+        Assert.assertEquals(4.0, solution.getPoint()[0], 0.0);
+        Assert.assertEquals(0.0, solution.getPoint()[1], 0.0);
+        Assert.assertEquals(-13.0, solution.getValue(), 0.0);
+    }
+
+    @Test
+    public void testSolutionWithNegativeDecisionVariable() {
+        LinearObjectiveFunction f = new LinearObjectiveFunction(new double[] { -2, 1 }, 0);
+        Collection<LinearConstraint> constraints = new ArrayList<LinearConstraint>();
+        constraints.add(new LinearConstraint(new double[] { 1, 1 }, Relationship.GEQ, 6));
+        constraints.add(new LinearConstraint(new double[] { 1, 2 }, Relationship.LEQ, 14));
+
+        SimplexSolver solver = new SimplexSolver();
+        PointValuePair solution = solver.optimize(DEFAULT_MAX_ITER, f, new LinearConstraintSet(constraints),
+                                                  GoalType.MAXIMIZE, new NonNegativeConstraint(false));
+        Assert.assertEquals(-2.0, solution.getPoint()[0], 0.0);
+        Assert.assertEquals(8.0, solution.getPoint()[1], 0.0);
+        Assert.assertEquals(12.0, solution.getValue(), 0.0);
+    }
+
+    @Test(expected = NoFeasibleSolutionException.class)
+    public void testInfeasibleSolution() {
+        LinearObjectiveFunction f = new LinearObjectiveFunction(new double[] { 15 }, 0);
+        Collection<LinearConstraint> constraints = new ArrayList<LinearConstraint>();
+        constraints.add(new LinearConstraint(new double[] { 1 }, Relationship.LEQ, 1));
+        constraints.add(new LinearConstraint(new double[] { 1 }, Relationship.GEQ, 3));
+
+        SimplexSolver solver = new SimplexSolver();
+        solver.optimize(DEFAULT_MAX_ITER, f, new LinearConstraintSet(constraints),
+                        GoalType.MAXIMIZE, new NonNegativeConstraint(false));
+    }
+
+    @Test(expected = UnboundedSolutionException.class)
+    public void testUnboundedSolution() {
+        LinearObjectiveFunction f = new LinearObjectiveFunction(new double[] { 15, 10 }, 0);
+        Collection<LinearConstraint> constraints = new ArrayList<LinearConstraint>();
+        constraints.add(new LinearConstraint(new double[] { 1, 0 }, Relationship.EQ, 2));
+
+        SimplexSolver solver = new SimplexSolver();
+        solver.optimize(DEFAULT_MAX_ITER, f, new LinearConstraintSet(constraints),
+                        GoalType.MAXIMIZE, new NonNegativeConstraint(false));
+    }
+
+    @Test
+    public void testRestrictVariablesToNonNegative() {
+        LinearObjectiveFunction f = new LinearObjectiveFunction(new double[] { 409, 523, 70, 204, 339 }, 0);
+        Collection<LinearConstraint> constraints = new ArrayList<LinearConstraint>();
+        constraints.add(new LinearConstraint(new double[] {    43,   56, 345,  56,    5 }, Relationship.LEQ,  4567456));
+        constraints.add(new LinearConstraint(new double[] {    12,   45,   7,  56,   23 }, Relationship.LEQ,    56454));
+        constraints.add(new LinearConstraint(new double[] {     8,  768,   0,  34, 7456 }, Relationship.LEQ,  1923421));
+        constraints.add(new LinearConstraint(new double[] { 12342, 2342,  34, 678, 2342 }, Relationship.GEQ,     4356));
+        constraints.add(new LinearConstraint(new double[] {    45,  678,  76,  52,   23 }, Relationship.EQ,    456356));
+
+        SimplexSolver solver = new SimplexSolver();
+        PointValuePair solution = solver.optimize(DEFAULT_MAX_ITER, f, new LinearConstraintSet(constraints),
+                                                  GoalType.MAXIMIZE, new NonNegativeConstraint(true));
+        Assert.assertEquals(2902.92783505155, solution.getPoint()[0], .0000001);
+        Assert.assertEquals(480.419243986254, solution.getPoint()[1], .0000001);
+        Assert.assertEquals(0.0, solution.getPoint()[2], .0000001);
+        Assert.assertEquals(0.0, solution.getPoint()[3], .0000001);
+        Assert.assertEquals(0.0, solution.getPoint()[4], .0000001);
+        Assert.assertEquals(1438556.7491409, solution.getValue(), .0000001);
+    }
+
+    @Test
+    public void testEpsilon() {
+      LinearObjectiveFunction f =
+          new LinearObjectiveFunction(new double[] { 10, 5, 1 }, 0);
+      Collection<LinearConstraint> constraints = new ArrayList<LinearConstraint>();
+      constraints.add(new LinearConstraint(new double[] {  9, 8, 0 }, Relationship.EQ,  17));
+      constraints.add(new LinearConstraint(new double[] {  0, 7, 8 }, Relationship.LEQ,  7));
+      constraints.add(new LinearConstraint(new double[] { 10, 0, 2 }, Relationship.LEQ, 10));
+
+      SimplexSolver solver = new SimplexSolver();
+      PointValuePair solution = solver.optimize(DEFAULT_MAX_ITER, f, new LinearConstraintSet(constraints),
+                                                GoalType.MAXIMIZE, new NonNegativeConstraint(false));
+      Assert.assertEquals(1.0, solution.getPoint()[0], 0.0);
+      Assert.assertEquals(1.0, solution.getPoint()[1], 0.0);
+      Assert.assertEquals(0.0, solution.getPoint()[2], 0.0);
+      Assert.assertEquals(15.0, solution.getValue(), 0.0);
+  }
+
+    @Test
+    public void testTrivialModel() {
+        LinearObjectiveFunction f = new LinearObjectiveFunction(new double[] { 1, 1 }, 0);
+        Collection<LinearConstraint> constraints = new ArrayList<LinearConstraint>();
+        constraints.add(new LinearConstraint(new double[] { 1, 1 }, Relationship.EQ,  0));
+
+        SimplexSolver solver = new SimplexSolver();
+        PointValuePair solution = solver.optimize(DEFAULT_MAX_ITER, f, new LinearConstraintSet(constraints),
+                                                  GoalType.MAXIMIZE, new NonNegativeConstraint(true));
+        Assert.assertEquals(0, solution.getValue(), .0000001);
+    }
+
+    @Test
+    public void testLargeModel() {
+        double[] objective = new double[] {
+                                           1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+                                           1, 1, 12, 1, 1, 1, 1, 1, 1, 1,
+                                           1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+                                           1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+                                           12, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+                                           1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+                                           1, 1, 1, 1, 1, 1, 1, 1, 12, 1,
+                                           1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+                                           1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+                                           1, 1, 1, 1, 1, 1, 12, 1, 1, 1,
+                                           1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+                                           1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+                                           1, 1, 1, 1, 12, 1, 1, 1, 1, 1,
+                                           1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+                                           1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+                                           1, 1, 12, 1, 1, 1, 1, 1, 1, 1,
+                                           1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+                                           1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+                                           1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+                                           1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+                                           1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+                                           1, 1, 1, 1, 1, 1};
+
+        LinearObjectiveFunction f = new LinearObjectiveFunction(objective, 0);
+        Collection<LinearConstraint> constraints = new ArrayList<LinearConstraint>();
+        constraints.add(equationFromString(objective.length, "x0 + x1 + x2 + x3 - x12 = 0"));
+        constraints.add(equationFromString(objective.length, "x4 + x5 + x6 + x7 + x8 + x9 + x10 + x11 - x13 = 0"));
+        constraints.add(equationFromString(objective.length, "x4 + x5 + x6 + x7 + x8 + x9 + x10 + x11 >= 49"));
+        constraints.add(equationFromString(objective.length, "x0 + x1 + x2 + x3 >= 42"));
+        constraints.add(equationFromString(objective.length, "x14 + x15 + x16 + x17 - x26 = 0"));
+        constraints.add(equationFromString(objective.length, "x18 + x19 + x20 + x21 + x22 + x23 + x24 + x25 - x27 = 0"));
+        constraints.add(equationFromString(objective.length, "x14 + x15 + x16 + x17 - x12 = 0"));
+        constraints.add(equationFromString(objective.length, "x18 + x19 + x20 + x21 + x22 + x23 + x24 + x25 - x13 = 0"));
+        constraints.add(equationFromString(objective.length, "x28 + x29 + x30 + x31 - x40 = 0"));
+        constraints.add(equationFromString(objective.length, "x32 + x33 + x34 + x35 + x36 + x37 + x38 + x39 - x41 = 0"));
+        constraints.add(equationFromString(objective.length, "x32 + x33 + x34 + x35 + x36 + x37 + x38 + x39 >= 49"));
+        constraints.add(equationFromString(objective.length, "x28 + x29 + x30 + x31 >= 42"));
+        constraints.add(equationFromString(objective.length, "x42 + x43 + x44 + x45 - x54 = 0"));
+        constraints.add(equationFromString(objective.length, "x46 + x47 + x48 + x49 + x50 + x51 + x52 + x53 - x55 = 0"));
+        constraints.add(equationFromString(objective.length, "x42 + x43 + x44 + x45 - x40 = 0"));
+        constraints.add(equationFromString(objective.length, "x46 + x47 + x48 + x49 + x50 + x51 + x52 + x53 - x41 = 0"));
+        constraints.add(equationFromString(objective.length, "x56 + x57 + x58 + x59 - x68 = 0"));
+        constraints.add(equationFromString(objective.length, "x60 + x61 + x62 + x63 + x64 + x65 + x66 + x67 - x69 = 0"));
+        constraints.add(equationFromString(objective.length, "x60 + x61 + x62 + x63 + x64 + x65 + x66 + x67 >= 51"));
+        constraints.add(equationFromString(objective.length, "x56 + x57 + x58 + x59 >= 44"));
+        constraints.add(equationFromString(objective.length, "x70 + x71 + x72 + x73 - x82 = 0"));
+        constraints.add(equationFromString(objective.length, "x74 + x75 + x76 + x77 + x78 + x79 + x80 + x81 - x83 = 0"));
+        constraints.add(equationFromString(objective.length, "x70 + x71 + x72 + x73 - x68 = 0"));
+        constraints.add(equationFromString(objective.length, "x74 + x75 + x76 + x77 + x78 + x79 + x80 + x81 - x69 = 0"));
+        constraints.add(equationFromString(objective.length, "x84 + x85 + x86 + x87 - x96 = 0"));
+        constraints.add(equationFromString(objective.length, "x88 + x89 + x90 + x91 + x92 + x93 + x94 + x95 - x97 = 0"));
+        constraints.add(equationFromString(objective.length, "x88 + x89 + x90 + x91 + x92 + x93 + x94 + x95 >= 51"));
+        constraints.add(equationFromString(objective.length, "x84 + x85 + x86 + x87 >= 44"));
+        constraints.add(equationFromString(objective.length, "x98 + x99 + x100 + x101 - x110 = 0"));
+        constraints.add(equationFromString(objective.length, "x102 + x103 + x104 + x105 + x106 + x107 + x108 + x109 - x111 = 0"));
+        constraints.add(equationFromString(objective.length, "x98 + x99 + x100 + x101 - x96 = 0"));
+        constraints.add(equationFromString(objective.length, "x102 + x103 + x104 + x105 + x106 + x107 + x108 + x109 - x97 = 0"));
+        constraints.add(equationFromString(objective.length, "x112 + x113 + x114 + x115 - x124 = 0"));
+        constraints.add(equationFromString(objective.length, "x116 + x117 + x118 + x119 + x120 + x121 + x122 + x123 - x125 = 0"));
+        constraints.add(equationFromString(objective.length, "x116 + x117 + x118 + x119 + x120 + x121 + x122 + x123 >= 49"));
+        constraints.add(equationFromString(objective.length, "x112 + x113 + x114 + x115 >= 42"));
+        constraints.add(equationFromString(objective.length, "x126 + x127 + x128 + x129 - x138 = 0"));
+        constraints.add(equationFromString(objective.length, "x130 + x131 + x132 + x133 + x134 + x135 + x136 + x137 - x139 = 0"));
+        constraints.add(equationFromString(objective.length, "x126 + x127 + x128 + x129 - x124 = 0"));
+        constraints.add(equationFromString(objective.length, "x130 + x131 + x132 + x133 + x134 + x135 + x136 + x137 - x125 = 0"));
+        constraints.add(equationFromString(objective.length, "x140 + x141 + x142 + x143 - x152 = 0"));
+        constraints.add(equationFromString(objective.length, "x144 + x145 + x146 + x147 + x148 + x149 + x150 + x151 - x153 = 0"));
+        constraints.add(equationFromString(objective.length, "x144 + x145 + x146 + x147 + x148 + x149 + x150 + x151 >= 59"));
+        constraints.add(equationFromString(objective.length, "x140 + x141 + x142 + x143 >= 42"));
+        constraints.add(equationFromString(objective.length, "x154 + x155 + x156 + x157 - x166 = 0"));
+        constraints.add(equationFromString(objective.length, "x158 + x159 + x160 + x161 + x162 + x163 + x164 + x165 - x167 = 0"));
+        constraints.add(equationFromString(objective.length, "x154 + x155 + x156 + x157 - x152 = 0"));
+        constraints.add(equationFromString(objective.length, "x158 + x159 + x160 + x161 + x162 + x163 + x164 + x165 - x153 = 0"));
+        constraints.add(equationFromString(objective.length, "x83 + x82 - x168 = 0"));
+        constraints.add(equationFromString(objective.length, "x111 + x110 - x169 = 0"));
+        constraints.add(equationFromString(objective.length, "x170 - x182 = 0"));
+        constraints.add(equationFromString(objective.length, "x171 - x183 = 0"));
+        constraints.add(equationFromString(objective.length, "x172 - x184 = 0"));
+        constraints.add(equationFromString(objective.length, "x173 - x185 = 0"));
+        constraints.add(equationFromString(objective.length, "x174 - x186 = 0"));
+        constraints.add(equationFromString(objective.length, "x175 + x176 - x187 = 0"));
+        constraints.add(equationFromString(objective.length, "x177 - x188 = 0"));
+        constraints.add(equationFromString(objective.length, "x178 - x189 = 0"));
+        constraints.add(equationFromString(objective.length, "x179 - x190 = 0"));
+        constraints.add(equationFromString(objective.length, "x180 - x191 = 0"));
+        constraints.add(equationFromString(objective.length, "x181 - x192 = 0"));
+        constraints.add(equationFromString(objective.length, "x170 - x26 = 0"));
+        constraints.add(equationFromString(objective.length, "x171 - x27 = 0"));
+        constraints.add(equationFromString(objective.length, "x172 - x54 = 0"));
+        constraints.add(equationFromString(objective.length, "x173 - x55 = 0"));
+        constraints.add(equationFromString(objective.length, "x174 - x168 = 0"));
+        constraints.add(equationFromString(objective.length, "x177 - x169 = 0"));
+        constraints.add(equationFromString(objective.length, "x178 - x138 = 0"));
+        constraints.add(equationFromString(objective.length, "x179 - x139 = 0"));
+        constraints.add(equationFromString(objective.length, "x180 - x166 = 0"));
+        constraints.add(equationFromString(objective.length, "x181 - x167 = 0"));
+        constraints.add(equationFromString(objective.length, "x193 - x205 = 0"));
+        constraints.add(equationFromString(objective.length, "x194 - x206 = 0"));
+        constraints.add(equationFromString(objective.length, "x195 - x207 = 0"));
+        constraints.add(equationFromString(objective.length, "x196 - x208 = 0"));
+        constraints.add(equationFromString(objective.length, "x197 - x209 = 0"));
+        constraints.add(equationFromString(objective.length, "x198 + x199 - x210 = 0"));
+        constraints.add(equationFromString(objective.length, "x200 - x211 = 0"));
+        constraints.add(equationFromString(objective.length, "x201 - x212 = 0"));
+        constraints.add(equationFromString(objective.length, "x202 - x213 = 0"));
+        constraints.add(equationFromString(objective.length, "x203 - x214 = 0"));
+        constraints.add(equationFromString(objective.length, "x204 - x215 = 0"));
+        constraints.add(equationFromString(objective.length, "x193 - x182 = 0"));
+        constraints.add(equationFromString(objective.length, "x194 - x183 = 0"));
+        constraints.add(equationFromString(objective.length, "x195 - x184 = 0"));
+        constraints.add(equationFromString(objective.length, "x196 - x185 = 0"));
+        constraints.add(equationFromString(objective.length, "x197 - x186 = 0"));
+        constraints.add(equationFromString(objective.length, "x198 + x199 - x187 = 0"));
+        constraints.add(equationFromString(objective.length, "x200 - x188 = 0"));
+        constraints.add(equationFromString(objective.length, "x201 - x189 = 0"));
+        constraints.add(equationFromString(objective.length, "x202 - x190 = 0"));
+        constraints.add(equationFromString(objective.length, "x203 - x191 = 0"));
+        constraints.add(equationFromString(objective.length, "x204 - x192 = 0"));
+
+        SimplexSolver solver = new SimplexSolver();
+        PointValuePair solution = solver.optimize(DEFAULT_MAX_ITER, f, new LinearConstraintSet(constraints),
+                                                  GoalType.MINIMIZE, new NonNegativeConstraint(true));
+        Assert.assertEquals(7518.0, solution.getValue(), .0000001);
+    }
+
+    /**
+     * Converts a test string to a {@link LinearConstraint}.
+     * Ex: x0 + x1 + x2 + x3 - x12 = 0
+     */
+    private LinearConstraint equationFromString(int numCoefficients, String s) {
+        Relationship relationship;
+        if (s.contains(">=")) {
+            relationship = Relationship.GEQ;
+        } else if (s.contains("<=")) {
+            relationship = Relationship.LEQ;
+        } else if (s.contains("=")) {
+            relationship = Relationship.EQ;
+        } else {
+            throw new IllegalArgumentException();
+        }
+
+        String[] equationParts = s.split("[>|<]?=");
+        double rhs = Double.parseDouble(equationParts[1].trim());
+
+        double[] lhs = new double[numCoefficients];
+        String left = equationParts[0].replaceAll(" ?x", "");
+        String[] coefficients = left.split(" ");
+        for (String coefficient : coefficients) {
+            double value = coefficient.charAt(0) == '-' ? -1 : 1;
+            int index = Integer.parseInt(coefficient.replaceFirst("[+|-]", "").trim());
+            lhs[index] = value;
+        }
+        return new LinearConstraint(lhs, relationship, rhs);
+    }
+
+    private static boolean validSolution(PointValuePair solution, List<LinearConstraint> constraints, double epsilon) {
+        double[] vals = solution.getPoint();
+        for (LinearConstraint c : constraints) {
+            double[] coeffs = c.getCoefficients().toArray();
+            double result = 0.0d;
+            for (int i = 0; i < vals.length; i++) {
+                result += vals[i] * coeffs[i];
+            }
+            
+            switch (c.getRelationship()) {
+            case EQ:
+                if (!Precision.equals(result, c.getValue(), epsilon)) {
+                    return false;
+                }
+                break;
+                
+            case GEQ:
+                if (Precision.compareTo(result, c.getValue(), epsilon) < 0) {
+                    return false;
+                }
+                break;
+                
+            case LEQ:
+                if (Precision.compareTo(result, c.getValue(), epsilon) > 0) {
+                    return false;
+                }
+                break;
+            }
+        }
+        
+        return true;
+    }
+}

Propchange: commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optim/linear/SimplexSolverTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optim/linear/SimplexTableauTest.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optim/linear/SimplexTableauTest.java?rev=1420684&view=auto
==============================================================================
--- commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optim/linear/SimplexTableauTest.java (added)
+++ commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optim/linear/SimplexTableauTest.java Wed Dec 12 14:10:38 2012
@@ -0,0 +1,108 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.math3.optim.linear;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import org.apache.commons.math3.TestUtils;
+import org.apache.commons.math3.optim.GoalType;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class SimplexTableauTest {
+
+    @Test
+    public void testInitialization() {
+        LinearObjectiveFunction f = createFunction();
+        Collection<LinearConstraint> constraints = createConstraints();
+        SimplexTableau tableau =
+            new SimplexTableau(f, constraints, GoalType.MAXIMIZE, false, 1.0e-6);
+        double[][] expectedInitialTableau = {
+                                             {-1, 0,  -1,  -1,  2, 0, 0, 0, -4},
+                                             { 0, 1, -15, -10, 25, 0, 0, 0,  0},
+                                             { 0, 0,   1,   0, -1, 1, 0, 0,  2},
+                                             { 0, 0,   0,   1, -1, 0, 1, 0,  3},
+                                             { 0, 0,   1,   1, -2, 0, 0, 1,  4}
+        };
+        assertMatrixEquals(expectedInitialTableau, tableau.getData());
+    }
+
+    @Test
+    public void testDropPhase1Objective() {
+        LinearObjectiveFunction f = createFunction();
+        Collection<LinearConstraint> constraints = createConstraints();
+        SimplexTableau tableau =
+            new SimplexTableau(f, constraints, GoalType.MAXIMIZE, false, 1.0e-6);
+        double[][] expectedTableau = {
+                                      { 1, -15, -10, 0, 0, 0, 0},
+                                      { 0,   1,   0, 1, 0, 0, 2},
+                                      { 0,   0,   1, 0, 1, 0, 3},
+                                      { 0,   1,   1, 0, 0, 1, 4}
+        };
+        tableau.dropPhase1Objective();
+        assertMatrixEquals(expectedTableau, tableau.getData());
+    }
+
+    @Test
+    public void testTableauWithNoArtificialVars() {
+        LinearObjectiveFunction f = new LinearObjectiveFunction(new double[] {15, 10}, 0);
+        Collection<LinearConstraint> constraints = new ArrayList<LinearConstraint>();
+        constraints.add(new LinearConstraint(new double[] {1, 0}, Relationship.LEQ, 2));
+        constraints.add(new LinearConstraint(new double[] {0, 1}, Relationship.LEQ, 3));
+        constraints.add(new LinearConstraint(new double[] {1, 1}, Relationship.LEQ, 4));
+        SimplexTableau tableau =
+            new SimplexTableau(f, constraints, GoalType.MAXIMIZE, false, 1.0e-6);
+        double[][] initialTableau = {
+                                     {1, -15, -10, 25, 0, 0, 0, 0},
+                                     {0,   1,   0, -1, 1, 0, 0, 2},
+                                     {0,   0,   1, -1, 0, 1, 0, 3},
+                                     {0,   1,   1, -2, 0, 0, 1, 4}
+        };
+        assertMatrixEquals(initialTableau, tableau.getData());
+    }
+
+    @Test
+    public void testSerial() {
+        LinearObjectiveFunction f = createFunction();
+        Collection<LinearConstraint> constraints = createConstraints();
+        SimplexTableau tableau =
+            new SimplexTableau(f, constraints, GoalType.MAXIMIZE, false, 1.0e-6);
+        Assert.assertEquals(tableau, TestUtils.serializeAndRecover(tableau));
+    }
+
+    private LinearObjectiveFunction createFunction() {
+        return new LinearObjectiveFunction(new double[] {15, 10}, 0);
+    }
+
+    private Collection<LinearConstraint> createConstraints() {
+        Collection<LinearConstraint> constraints = new ArrayList<LinearConstraint>();
+        constraints.add(new LinearConstraint(new double[] {1, 0}, Relationship.LEQ, 2));
+        constraints.add(new LinearConstraint(new double[] {0, 1}, Relationship.LEQ, 3));
+        constraints.add(new LinearConstraint(new double[] {1, 1}, Relationship.EQ, 4));
+        return constraints;
+    }
+
+    private void assertMatrixEquals(double[][] expected, double[][] result) {
+        Assert.assertEquals("Wrong number of rows.", expected.length, result.length);
+        for (int i = 0; i < expected.length; i++) {
+            Assert.assertEquals("Wrong number of columns.", expected[i].length, result[i].length);
+            for (int j = 0; j < expected[i].length; j++) {
+                Assert.assertEquals("Wrong value at position [" + i + "," + j + "]", expected[i][j], result[i][j], 1.0e-15);
+            }
+        }
+    }
+}

Propchange: commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optim/linear/SimplexTableauTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optim/nonlinear/scalar/MultiStartMultivariateOptimizerTest.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optim/nonlinear/scalar/MultiStartMultivariateOptimizerTest.java?rev=1420684&view=auto
==============================================================================
--- commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optim/nonlinear/scalar/MultiStartMultivariateOptimizerTest.java (added)
+++ commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optim/nonlinear/scalar/MultiStartMultivariateOptimizerTest.java Wed Dec 12 14:10:38 2012
@@ -0,0 +1,127 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.math3.optim.nonlinear.scalar;
+
+import org.apache.commons.math3.analysis.MultivariateFunction;
+import org.apache.commons.math3.geometry.euclidean.twod.Vector2D;
+import org.apache.commons.math3.optim.MaxEval;
+import org.apache.commons.math3.optim.GoalType;
+import org.apache.commons.math3.optim.InitialGuess;
+import org.apache.commons.math3.optim.ObjectiveFunction;
+import org.apache.commons.math3.optim.PointValuePair;
+import org.apache.commons.math3.optim.SimpleValueChecker;
+import org.apache.commons.math3.optim.nonlinear.scalar.gradient.CircleScalar;
+import org.apache.commons.math3.optim.nonlinear.scalar.gradient.NonLinearConjugateGradientOptimizer;
+import org.apache.commons.math3.optim.nonlinear.scalar.noderiv.NelderMeadSimplex;
+import org.apache.commons.math3.optim.nonlinear.scalar.noderiv.SimplexOptimizer;
+import org.apache.commons.math3.random.GaussianRandomGenerator;
+import org.apache.commons.math3.random.JDKRandomGenerator;
+import org.apache.commons.math3.random.RandomVectorGenerator;
+import org.apache.commons.math3.random.UncorrelatedRandomVectorGenerator;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class MultiStartMultivariateOptimizerTest {
+    @Test
+    public void testCircleFitting() {
+        CircleScalar circle = new CircleScalar();
+        circle.addPoint( 30.0,  68.0);
+        circle.addPoint( 50.0,  -6.0);
+        circle.addPoint(110.0, -20.0);
+        circle.addPoint( 35.0,  15.0);
+        circle.addPoint( 45.0,  97.0);
+        // TODO: the wrapper around NonLinearConjugateGradientOptimizer is a temporary hack for
+        // version 3.1 of the library. It should be removed when NonLinearConjugateGradientOptimizer
+        // will officially be declared as implementing MultivariateDifferentiableOptimizer
+        GradientMultivariateOptimizer underlying
+            = new NonLinearConjugateGradientOptimizer(NonLinearConjugateGradientOptimizer.Formula.POLAK_RIBIERE,
+                                                      new SimpleValueChecker(1e-10, 1e-10));
+        JDKRandomGenerator g = new JDKRandomGenerator();
+        g.setSeed(753289573253l);
+        RandomVectorGenerator generator
+            = new UncorrelatedRandomVectorGenerator(new double[] { 50, 50 },
+                                                    new double[] { 10, 10 },
+                                                    new GaussianRandomGenerator(g));
+        MultiStartMultivariateOptimizer optimizer
+            = new MultiStartMultivariateOptimizer(underlying, 10, generator);
+        PointValuePair optimum
+            = optimizer.optimize(new MaxEval(200),
+                                 circle.getObjectiveFunction(),
+                                 circle.getObjectiveFunctionGradient(),
+                                 GoalType.MINIMIZE,
+                                 new InitialGuess(new double[] { 98.680, 47.345 }));
+        Assert.assertEquals(200, optimizer.getMaxEvaluations());
+        PointValuePair[] optima = optimizer.getOptima();
+        for (PointValuePair o : optima) {
+            Vector2D center = new Vector2D(o.getPointRef()[0], o.getPointRef()[1]);
+            Assert.assertEquals(69.960161753, circle.getRadius(center), 1e-8);
+            Assert.assertEquals(96.075902096, center.getX(), 1e-8);
+            Assert.assertEquals(48.135167894, center.getY(), 1e-8);
+        }
+        Assert.assertTrue(optimizer.getEvaluations() > 70);
+        Assert.assertTrue(optimizer.getEvaluations() < 90);
+        Assert.assertEquals(3.1267527, optimum.getValue(), 1e-8);
+    }
+
+    @Test
+    public void testRosenbrock() {
+        Rosenbrock rosenbrock = new Rosenbrock();
+        SimplexOptimizer underlying
+            = new SimplexOptimizer(new SimpleValueChecker(-1, 1e-3));
+        NelderMeadSimplex simplex = new NelderMeadSimplex(new double[][] {
+                { -1.2,  1.0 },
+                { 0.9, 1.2 } ,
+                {  3.5, -2.3 }
+            });
+        JDKRandomGenerator g = new JDKRandomGenerator();
+        g.setSeed(16069223052l);
+        RandomVectorGenerator generator
+            = new UncorrelatedRandomVectorGenerator(2, new GaussianRandomGenerator(g));
+        MultiStartMultivariateOptimizer optimizer
+            = new MultiStartMultivariateOptimizer(underlying, 10, generator);
+        PointValuePair optimum
+            = optimizer.optimize(new MaxEval(1100),
+                                 new ObjectiveFunction(rosenbrock),
+                                 GoalType.MINIMIZE,
+                                 simplex,
+                                 new InitialGuess(new double[] { -1.2, 1.0 }));
+
+        Assert.assertEquals(rosenbrock.getCount(), optimizer.getEvaluations());
+        Assert.assertTrue(optimizer.getEvaluations() > 900);
+        Assert.assertTrue(optimizer.getEvaluations() < 1200);
+        Assert.assertTrue(optimum.getValue() < 8e-4);
+    }
+
+    private static class Rosenbrock implements MultivariateFunction {
+        private int count;
+
+        public Rosenbrock() {
+            count = 0;
+        }
+
+        public double value(double[] x) {
+            ++count;
+            double a = x[1] - x[0] * x[0];
+            double b = 1 - x[0];
+            return 100 * a * a + b * b;
+        }
+
+        public int getCount() {
+            return count;
+        }
+    }
+}

Propchange: commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optim/nonlinear/scalar/MultiStartMultivariateOptimizerTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optim/nonlinear/scalar/MultivariateFunctionMappingAdapterTest.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optim/nonlinear/scalar/MultivariateFunctionMappingAdapterTest.java?rev=1420684&view=auto
==============================================================================
--- commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optim/nonlinear/scalar/MultivariateFunctionMappingAdapterTest.java (added)
+++ commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optim/nonlinear/scalar/MultivariateFunctionMappingAdapterTest.java Wed Dec 12 14:10:38 2012
@@ -0,0 +1,195 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.math3.optim.nonlinear.scalar;
+
+import org.apache.commons.math3.analysis.MultivariateFunction;
+import org.apache.commons.math3.optim.MaxEval;
+import org.apache.commons.math3.optim.GoalType;
+import org.apache.commons.math3.optim.InitialGuess;
+import org.apache.commons.math3.optim.PointValuePair;
+import org.apache.commons.math3.optim.ObjectiveFunction;
+import org.apache.commons.math3.optim.SimplePointChecker;
+import org.apache.commons.math3.optim.nonlinear.scalar.noderiv.SimplexOptimizer;
+import org.apache.commons.math3.optim.nonlinear.scalar.noderiv.AbstractSimplex;
+import org.apache.commons.math3.optim.nonlinear.scalar.noderiv.NelderMeadSimplex;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class MultivariateFunctionMappingAdapterTest {
+    @Test
+    public void testStartSimplexInsideRange() {
+        final BiQuadratic biQuadratic = new BiQuadratic(2.0, 2.5, 1.0, 3.0, 2.0, 3.0);
+        final MultivariateFunctionMappingAdapter wrapped
+            = new MultivariateFunctionMappingAdapter(biQuadratic,
+                                                     biQuadratic.getLower(),
+                                                     biQuadratic.getUpper());
+
+        SimplexOptimizer optimizer = new SimplexOptimizer(1e-10, 1e-30);
+        final AbstractSimplex simplex = new NelderMeadSimplex(new double[][] {
+                wrapped.boundedToUnbounded(new double[] { 1.5, 2.75 }),
+                wrapped.boundedToUnbounded(new double[] { 1.5, 2.95 }),
+                wrapped.boundedToUnbounded(new double[] { 1.7, 2.90 })
+            });
+
+        final PointValuePair optimum
+            = optimizer.optimize(new MaxEval(300),
+                                 new ObjectiveFunction(wrapped),
+                                 simplex,
+                                 GoalType.MINIMIZE,
+                                 new InitialGuess(wrapped.boundedToUnbounded(new double[] { 1.5, 2.25 })));
+        final double[] bounded = wrapped.unboundedToBounded(optimum.getPoint());
+
+        Assert.assertEquals(biQuadratic.getBoundedXOptimum(), bounded[0], 2e-7);
+        Assert.assertEquals(biQuadratic.getBoundedYOptimum(), bounded[1], 2e-7);
+    }
+
+    @Test
+    public void testOptimumOutsideRange() {
+        final BiQuadratic biQuadratic = new BiQuadratic(4.0, 0.0, 1.0, 3.0, 2.0, 3.0);
+        final MultivariateFunctionMappingAdapter wrapped
+            = new MultivariateFunctionMappingAdapter(biQuadratic,
+                                                     biQuadratic.getLower(),
+                                                     biQuadratic.getUpper());
+
+        SimplexOptimizer optimizer = new SimplexOptimizer(1e-10, 1e-30);
+        final AbstractSimplex simplex = new NelderMeadSimplex(new double[][] {
+                wrapped.boundedToUnbounded(new double[] { 1.5, 2.75 }),
+                wrapped.boundedToUnbounded(new double[] { 1.5, 2.95 }),
+                wrapped.boundedToUnbounded(new double[] { 1.7, 2.90 })
+            });
+
+        final PointValuePair optimum
+            = optimizer.optimize(new MaxEval(100),
+                                 new ObjectiveFunction(wrapped),
+                                 simplex,
+                                 GoalType.MINIMIZE,
+                                 new InitialGuess(wrapped.boundedToUnbounded(new double[] { 1.5, 2.25 })));
+        final double[] bounded = wrapped.unboundedToBounded(optimum.getPoint());
+
+        Assert.assertEquals(biQuadratic.getBoundedXOptimum(), bounded[0], 2e-7);
+        Assert.assertEquals(biQuadratic.getBoundedYOptimum(), bounded[1], 2e-7);
+    }
+
+    @Test
+    public void testUnbounded() {
+        final BiQuadratic biQuadratic = new BiQuadratic(4.0, 0.0,
+                                                        Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY,
+                                                        Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY);
+        final MultivariateFunctionMappingAdapter wrapped
+            = new MultivariateFunctionMappingAdapter(biQuadratic,
+                                                     biQuadratic.getLower(),
+                                                     biQuadratic.getUpper());
+
+        SimplexOptimizer optimizer = new SimplexOptimizer(1e-10, 1e-30);
+        final AbstractSimplex simplex = new NelderMeadSimplex(new double[][] {
+                wrapped.boundedToUnbounded(new double[] { 1.5, 2.75 }),
+                wrapped.boundedToUnbounded(new double[] { 1.5, 2.95 }),
+                wrapped.boundedToUnbounded(new double[] { 1.7, 2.90 })
+            });
+
+        final PointValuePair optimum
+            = optimizer.optimize(new MaxEval(300),
+                                 new ObjectiveFunction(wrapped),
+                                 simplex,
+                                 GoalType.MINIMIZE,
+                                 new InitialGuess(wrapped.boundedToUnbounded(new double[] { 1.5, 2.25 })));
+        final double[] bounded = wrapped.unboundedToBounded(optimum.getPoint());
+
+        Assert.assertEquals(biQuadratic.getBoundedXOptimum(), bounded[0], 2e-7);
+        Assert.assertEquals(biQuadratic.getBoundedYOptimum(), bounded[1], 2e-7);
+    }
+
+    @Test
+    public void testHalfBounded() {
+        final BiQuadratic biQuadratic = new BiQuadratic(4.0, 4.0,
+                                                        1.0, Double.POSITIVE_INFINITY,
+                                                        Double.NEGATIVE_INFINITY, 3.0);
+        final MultivariateFunctionMappingAdapter wrapped
+            = new MultivariateFunctionMappingAdapter(biQuadratic,
+                                                     biQuadratic.getLower(),
+                                                     biQuadratic.getUpper());
+
+        SimplexOptimizer optimizer = new SimplexOptimizer(1e-13, 1e-30);
+        final AbstractSimplex simplex = new NelderMeadSimplex(new double[][] {
+                wrapped.boundedToUnbounded(new double[] { 1.5, 2.75 }),
+                wrapped.boundedToUnbounded(new double[] { 1.5, 2.95 }),
+                wrapped.boundedToUnbounded(new double[] { 1.7, 2.90 })
+            });
+
+        final PointValuePair optimum
+            = optimizer.optimize(new MaxEval(200),
+                                 new ObjectiveFunction(wrapped),
+                                 simplex,
+                                 GoalType.MINIMIZE,
+                                 new InitialGuess(wrapped.boundedToUnbounded(new double[] { 1.5, 2.25 })));
+        final double[] bounded = wrapped.unboundedToBounded(optimum.getPoint());
+
+        Assert.assertEquals(biQuadratic.getBoundedXOptimum(), bounded[0], 1e-7);
+        Assert.assertEquals(biQuadratic.getBoundedYOptimum(), bounded[1], 1e-7);
+    }
+
+    private static class BiQuadratic implements MultivariateFunction {
+
+        private final double xOptimum;
+        private final double yOptimum;
+
+        private final double xMin;
+        private final double xMax;
+        private final double yMin;
+        private final double yMax;
+
+        public BiQuadratic(final double xOptimum, final double yOptimum,
+                           final double xMin, final double xMax,
+                           final double yMin, final double yMax) {
+            this.xOptimum = xOptimum;
+            this.yOptimum = yOptimum;
+            this.xMin     = xMin;
+            this.xMax     = xMax;
+            this.yMin     = yMin;
+            this.yMax     = yMax;
+        }
+
+        public double value(double[] point) {
+            // the function should never be called with out of range points
+            Assert.assertTrue(point[0] >= xMin);
+            Assert.assertTrue(point[0] <= xMax);
+            Assert.assertTrue(point[1] >= yMin);
+            Assert.assertTrue(point[1] <= yMax);
+
+            final double dx = point[0] - xOptimum;
+            final double dy = point[1] - yOptimum;
+            return dx * dx + dy * dy;
+
+        }
+
+        public double[] getLower() {
+            return new double[] { xMin, yMin };
+        }
+
+        public double[] getUpper() {
+            return new double[] { xMax, yMax };
+        }
+
+        public double getBoundedXOptimum() {
+            return (xOptimum < xMin) ? xMin : ((xOptimum > xMax) ? xMax : xOptimum);
+        }
+
+        public double getBoundedYOptimum() {
+            return (yOptimum < yMin) ? yMin : ((yOptimum > yMax) ? yMax : yOptimum);
+        }
+    }
+}

Propchange: commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optim/nonlinear/scalar/MultivariateFunctionMappingAdapterTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optim/nonlinear/scalar/MultivariateFunctionPenaltyAdapterTest.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optim/nonlinear/scalar/MultivariateFunctionPenaltyAdapterTest.java?rev=1420684&view=auto
==============================================================================
--- commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optim/nonlinear/scalar/MultivariateFunctionPenaltyAdapterTest.java (added)
+++ commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optim/nonlinear/scalar/MultivariateFunctionPenaltyAdapterTest.java Wed Dec 12 14:10:38 2012
@@ -0,0 +1,204 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.math3.optim.nonlinear.scalar;
+
+import org.apache.commons.math3.analysis.MultivariateFunction;
+import org.apache.commons.math3.optim.MaxEval;
+import org.apache.commons.math3.optim.GoalType;
+import org.apache.commons.math3.optim.InitialGuess;
+import org.apache.commons.math3.optim.PointValuePair;
+import org.apache.commons.math3.optim.ObjectiveFunction;
+import org.apache.commons.math3.optim.SimplePointChecker;
+import org.apache.commons.math3.optim.nonlinear.scalar.noderiv.SimplexOptimizer;
+import org.apache.commons.math3.optim.nonlinear.scalar.noderiv.AbstractSimplex;
+import org.apache.commons.math3.optim.nonlinear.scalar.noderiv.NelderMeadSimplex;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class MultivariateFunctionPenaltyAdapterTest {
+    @Test
+    public void testStartSimplexInsideRange() {
+        final BiQuadratic biQuadratic = new BiQuadratic(2.0, 2.5, 1.0, 3.0, 2.0, 3.0);
+        final MultivariateFunctionPenaltyAdapter wrapped
+              = new MultivariateFunctionPenaltyAdapter(biQuadratic,
+                                                       biQuadratic.getLower(),
+                                                       biQuadratic.getUpper(),
+                                                       1000.0, new double[] { 100.0, 100.0 });
+
+        SimplexOptimizer optimizer = new SimplexOptimizer(1e-10, 1e-30);
+        final AbstractSimplex simplex = new NelderMeadSimplex(new double[] { 1.0, 0.5 });
+
+        final PointValuePair optimum
+            = optimizer.optimize(new MaxEval(300),
+                                 new ObjectiveFunction(wrapped),
+                                 simplex,
+                                 GoalType.MINIMIZE,
+                                 new InitialGuess(new double[] { 1.5, 2.25 }));
+
+        Assert.assertEquals(biQuadratic.getBoundedXOptimum(), optimum.getPoint()[0], 2e-7);
+        Assert.assertEquals(biQuadratic.getBoundedYOptimum(), optimum.getPoint()[1], 2e-7);
+    }
+
+    @Test
+    public void testStartSimplexOutsideRange() {
+        final BiQuadratic biQuadratic = new BiQuadratic(2.0, 2.5, 1.0, 3.0, 2.0, 3.0);
+        final MultivariateFunctionPenaltyAdapter wrapped
+              = new MultivariateFunctionPenaltyAdapter(biQuadratic,
+                                                       biQuadratic.getLower(),
+                                                       biQuadratic.getUpper(),
+                                                       1000.0, new double[] { 100.0, 100.0 });
+
+        SimplexOptimizer optimizer = new SimplexOptimizer(1e-10, 1e-30);
+        final AbstractSimplex simplex = new NelderMeadSimplex(new double[] { 1.0, 0.5 });
+
+        final PointValuePair optimum
+            = optimizer.optimize(new MaxEval(300),
+                                 new ObjectiveFunction(wrapped),
+                                 simplex,
+                                 GoalType.MINIMIZE,
+                                 new InitialGuess(new double[] { -1.5, 4.0 }));
+
+        Assert.assertEquals(biQuadratic.getBoundedXOptimum(), optimum.getPoint()[0], 2e-7);
+        Assert.assertEquals(biQuadratic.getBoundedYOptimum(), optimum.getPoint()[1], 2e-7);
+    }
+
+    @Test
+    public void testOptimumOutsideRange() {
+        final BiQuadratic biQuadratic = new BiQuadratic(4.0, 0.0, 1.0, 3.0, 2.0, 3.0);
+        final MultivariateFunctionPenaltyAdapter wrapped
+            =  new MultivariateFunctionPenaltyAdapter(biQuadratic,
+                                                      biQuadratic.getLower(),
+                                                      biQuadratic.getUpper(),
+                                                      1000.0, new double[] { 100.0, 100.0 });
+
+        SimplexOptimizer optimizer = new SimplexOptimizer(new SimplePointChecker<PointValuePair>(1.0e-11, 1.0e-20));
+        final AbstractSimplex simplex = new NelderMeadSimplex(new double[] { 1.0, 0.5 });
+
+        final PointValuePair optimum
+            = optimizer.optimize(new MaxEval(600),
+                                 new ObjectiveFunction(wrapped),
+                                 simplex,
+                                 GoalType.MINIMIZE,
+                                 new InitialGuess(new double[] { -1.5, 4.0 }));
+
+        Assert.assertEquals(biQuadratic.getBoundedXOptimum(), optimum.getPoint()[0], 2e-7);
+        Assert.assertEquals(biQuadratic.getBoundedYOptimum(), optimum.getPoint()[1], 2e-7);
+    }
+
+    @Test
+    public void testUnbounded() {
+        final BiQuadratic biQuadratic = new BiQuadratic(4.0, 0.0,
+                                                        Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY,
+                                                        Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY);
+        final MultivariateFunctionPenaltyAdapter wrapped
+            = new MultivariateFunctionPenaltyAdapter(biQuadratic,
+                                                     biQuadratic.getLower(),
+                                                     biQuadratic.getUpper(),
+                                                     1000.0, new double[] { 100.0, 100.0 });
+
+        SimplexOptimizer optimizer = new SimplexOptimizer(1e-10, 1e-30);
+        final AbstractSimplex simplex = new NelderMeadSimplex(new double[] { 1.0, 0.5 });
+
+        final PointValuePair optimum
+            = optimizer.optimize(new MaxEval(300),
+                                 new ObjectiveFunction(wrapped),
+                                 simplex,
+                                 GoalType.MINIMIZE,
+                                 new InitialGuess(new double[] { -1.5, 4.0 }));
+
+        Assert.assertEquals(biQuadratic.getBoundedXOptimum(), optimum.getPoint()[0], 2e-7);
+        Assert.assertEquals(biQuadratic.getBoundedYOptimum(), optimum.getPoint()[1], 2e-7);
+    }
+
+    @Test
+    public void testHalfBounded() {
+        final BiQuadratic biQuadratic = new BiQuadratic(4.0, 4.0,
+                                                        1.0, Double.POSITIVE_INFINITY,
+                                                        Double.NEGATIVE_INFINITY, 3.0);
+        final MultivariateFunctionPenaltyAdapter wrapped
+              = new MultivariateFunctionPenaltyAdapter(biQuadratic,
+                                                       biQuadratic.getLower(),
+                                                       biQuadratic.getUpper(),
+                                                       1000.0, new double[] { 100.0, 100.0 });
+
+        SimplexOptimizer optimizer = new SimplexOptimizer(new SimplePointChecker<PointValuePair>(1.0e-10, 1.0e-20));
+        final AbstractSimplex simplex = new NelderMeadSimplex(new double[] { 1.0, 0.5 });
+
+        final PointValuePair optimum
+            = optimizer.optimize(new MaxEval(400),
+                                 new ObjectiveFunction(wrapped),
+                                 simplex,
+                                 GoalType.MINIMIZE,
+                                 new InitialGuess(new double[] { -1.5, 4.0 }));
+
+        Assert.assertEquals(biQuadratic.getBoundedXOptimum(), optimum.getPoint()[0], 2e-7);
+        Assert.assertEquals(biQuadratic.getBoundedYOptimum(), optimum.getPoint()[1], 2e-7);
+    }
+
+    private static class BiQuadratic implements MultivariateFunction {
+
+        private final double xOptimum;
+        private final double yOptimum;
+
+        private final double xMin;
+        private final double xMax;
+        private final double yMin;
+        private final double yMax;
+
+        public BiQuadratic(final double xOptimum, final double yOptimum,
+                           final double xMin, final double xMax,
+                           final double yMin, final double yMax) {
+            this.xOptimum = xOptimum;
+            this.yOptimum = yOptimum;
+            this.xMin     = xMin;
+            this.xMax     = xMax;
+            this.yMin     = yMin;
+            this.yMax     = yMax;
+        }
+
+        public double value(double[] point) {
+            // the function should never be called with out of range points
+            Assert.assertTrue(point[0] >= xMin);
+            Assert.assertTrue(point[0] <= xMax);
+            Assert.assertTrue(point[1] >= yMin);
+            Assert.assertTrue(point[1] <= yMax);
+
+            final double dx = point[0] - xOptimum;
+            final double dy = point[1] - yOptimum;
+            return dx * dx + dy * dy;
+
+        }
+
+        public double[] getLower() {
+            return new double[] { xMin, yMin };
+        }
+
+        public double[] getUpper() {
+            return new double[] { xMax, yMax };
+        }
+
+        public double getBoundedXOptimum() {
+            return (xOptimum < xMin) ? xMin : ((xOptimum > xMax) ? xMax : xOptimum);
+        }
+
+        public double getBoundedYOptimum() {
+            return (yOptimum < yMin) ? yMin : ((yOptimum > yMax) ? yMax : yOptimum);
+        }
+
+    }
+
+}

Propchange: commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optim/nonlinear/scalar/MultivariateFunctionPenaltyAdapterTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optim/nonlinear/scalar/gradient/CircleScalar.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optim/nonlinear/scalar/gradient/CircleScalar.java?rev=1420684&view=auto
==============================================================================
--- commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optim/nonlinear/scalar/gradient/CircleScalar.java (added)
+++ commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optim/nonlinear/scalar/gradient/CircleScalar.java Wed Dec 12 14:10:38 2012
@@ -0,0 +1,85 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.commons.math3.optim.nonlinear.scalar.gradient;
+
+import java.util.ArrayList;
+
+import org.apache.commons.math3.analysis.MultivariateFunction;
+import org.apache.commons.math3.analysis.MultivariateVectorFunction;
+import org.apache.commons.math3.geometry.euclidean.twod.Vector2D;
+import org.apache.commons.math3.optim.ObjectiveFunction;
+import org.apache.commons.math3.optim.nonlinear.scalar.ObjectiveFunctionGradient;
+
+/**
+ * Class used in the tests.
+ */
+public class CircleScalar {
+    private ArrayList<Vector2D> points;
+
+    public CircleScalar() {
+        points  = new ArrayList<Vector2D>();
+    }
+
+    public void addPoint(double px, double py) {
+        points.add(new Vector2D(px, py));
+    }
+
+    public double getRadius(Vector2D center) {
+        double r = 0;
+        for (Vector2D point : points) {
+            r += point.distance(center);
+        }
+        return r / points.size();
+    }
+
+    public ObjectiveFunction getObjectiveFunction() {
+        return new ObjectiveFunction(new MultivariateFunction() {
+                public double value(double[] params)  {
+                    Vector2D center = new Vector2D(params[0], params[1]);
+                    double radius = getRadius(center);
+                    double sum = 0;
+                    for (Vector2D point : points) {
+                        double di = point.distance(center) - radius;
+                        sum += di * di;
+                    }
+                    return sum;
+                }
+            });
+    }
+
+    public ObjectiveFunctionGradient getObjectiveFunctionGradient() {
+        return new ObjectiveFunctionGradient(new MultivariateVectorFunction() {
+                public double[] value(double[] params) {
+                    Vector2D center = new Vector2D(params[0], params[1]);
+                    double radius = getRadius(center);
+                    // gradient of the sum of squared residuals
+                    double dJdX = 0;
+                    double dJdY = 0;
+                    for (Vector2D pk : points) {
+                        double dk = pk.distance(center);
+                        dJdX += (center.getX() - pk.getX()) * (dk - radius) / dk;
+                        dJdY += (center.getY() - pk.getY()) * (dk - radius) / dk;
+                    }
+                    dJdX *= 2;
+                    dJdY *= 2;
+
+                    return new double[] { dJdX, dJdY };
+                }
+            });
+    }
+}

Propchange: commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optim/nonlinear/scalar/gradient/CircleScalar.java
------------------------------------------------------------------------------
    svn:eol-style = native



Mime
View raw message