View Javadoc
1   /*
2    * Licensed to the Hipparchus project under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The Hipparchus project licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      https://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.hipparchus.optim.nonlinear.vector.constrained;
18  
19  import org.junit.Assert;
20  import org.hipparchus.linear.MatrixUtils;
21  import org.hipparchus.linear.RealVector;
22  import org.hipparchus.optim.InitialGuess;
23  import org.hipparchus.optim.OptimizationData;
24  import org.hipparchus.optim.nonlinear.scalar.ObjectiveFunction;
25  
26  public abstract class AbstractConstrainedOptimizerTest {
27  
28      /** Build the optimizer.
29       * @return built optimizer
30       */
31      protected abstract ConstraintOptimizer buildOptimizer();
32  
33      /** Test one problem.
34       * @param expectedSolution expected solution
35       * @param solutionTolerance tolerance on solution (L₁ norm)
36       * @param expectedMultipliers expected multipliers
37       * @param multipliersTolerance tolerance on multipliers  (L₁ norm)
38       * @param expectedValue expected objective function value
39       * @param valueTolerance tolerance on objective function value
40       * @param objectiveFunction objective function
41       * @param initialGuess initial guess (may be null)
42       * @param constraints contraints
43       */
44      protected void doTestProblem(final double[] expectedSolution,
45                                   final double solutionTolerance,
46                                   final double[] expectedMultipliers,
47                                   final double multipliersTolerance,
48                                   final double expectedValue,
49                                   final double valueTolerance,
50                                   final ObjectiveFunction objectiveFunction,
51                                   final double[] initialGuess,
52                                   final Constraint... constraints) {
53  
54          // find optimum solution
55          final ConstraintOptimizer optimizer = buildOptimizer();
56          final OptimizationData[] data = new OptimizationData[constraints.length + (initialGuess == null ? 1 : 2)];
57          data[0] = objectiveFunction;
58          System.arraycopy(constraints, 0, data, 1, constraints.length);
59          if (initialGuess != null) {
60              data[data.length - 1] = new InitialGuess(initialGuess);
61          }
62          final LagrangeSolution    solution  = optimizer.optimize(data);
63  
64          // check result
65          Assert.assertEquals(0.0,
66                              MatrixUtils.createRealVector(expectedSolution).subtract(solution.getX()).getL1Norm(),
67                              solutionTolerance);
68          Assert.assertEquals(0.0,
69                              MatrixUtils.createRealVector(expectedMultipliers).subtract(solution.getLambda()).getL1Norm(),
70                              multipliersTolerance);
71          Assert.assertEquals(expectedValue, solution.getValue(),                                  valueTolerance);
72  
73          // check neighboring points either violate constraints or have worst objective function
74          for (int i = 0; i < expectedSolution.length; ++i) {
75  
76              final RealVector plusShift = MatrixUtils.createRealVector(expectedSolution);
77              plusShift.addToEntry(i, 2 * solutionTolerance);
78              boolean plusIsFeasible = true;
79              for (final Constraint constraint : constraints) {
80                  plusIsFeasible &= constraint.overshoot(constraint.value(plusShift)) <= 0;
81              }
82              if (plusIsFeasible) {
83                  // the plusShift point fulfills all constraints,
84                  // so it must have worst objective function than the expected optimum
85                  Assert.assertTrue(objectiveFunction.getObjectiveFunction().value(plusShift.toArray()) > expectedValue);
86              }
87              
88              final RealVector minusShift = MatrixUtils.createRealVector(expectedSolution);
89              minusShift.addToEntry(i, -2 * solutionTolerance);
90              boolean minusIsFeasible = true;
91              for (final Constraint constraint : constraints) {
92                  minusIsFeasible &= constraint.overshoot(constraint.value(minusShift)) <= 0;
93              }
94              if (minusIsFeasible) {
95                  // the minusShift point fulfills all constraints,
96                  // so it must have worst objective function than the expected optimum
97                  Assert.assertTrue(objectiveFunction.getObjectiveFunction().value(minusShift.toArray()) > expectedValue);
98              }
99              
100         }
101 
102     }
103 
104 }