View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) 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 ASF 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  
18  /*
19   * This is not the original file distributed by the Apache Software Foundation
20   * It has been modified by the Hipparchus project
21   */
22  package org.hipparchus.optim.univariate;
23  
24  import org.hipparchus.analysis.QuinticFunction;
25  import org.hipparchus.analysis.UnivariateFunction;
26  import org.hipparchus.analysis.function.Sin;
27  import org.hipparchus.exception.MathIllegalStateException;
28  import org.hipparchus.optim.MaxEval;
29  import org.hipparchus.optim.nonlinear.scalar.GoalType;
30  import org.hipparchus.random.JDKRandomGenerator;
31  import org.hipparchus.util.FastMath;
32  import org.junit.jupiter.api.Test;
33  
34  import static org.junit.jupiter.api.Assertions.assertEquals;
35  import static org.junit.jupiter.api.Assertions.assertNull;
36  import static org.junit.jupiter.api.Assertions.assertThrows;
37  import static org.junit.jupiter.api.Assertions.assertTrue;
38  import static org.junit.jupiter.api.Assertions.fail;
39  
40  class MultiStartUnivariateOptimizerTest {
41      @Test
42      void testMissingMaxEval() {
43          assertThrows(MathIllegalStateException.class, () -> {
44              UnivariateOptimizer underlying = new BrentOptimizer(1e-10, 1e-14);
45              JDKRandomGenerator g = new JDKRandomGenerator();
46              g.setSeed(44428400075l);
47              MultiStartUnivariateOptimizer optimizer = new MultiStartUnivariateOptimizer(underlying, 10, g);
48              optimizer.optimize(new UnivariateObjectiveFunction(new Sin()),
49                  GoalType.MINIMIZE,
50                  new SearchInterval(-1, 1));
51          });
52      }
53  
54      @Test
55      void testMissingSearchInterval() {
56          assertThrows(MathIllegalStateException.class, () -> {
57              UnivariateOptimizer underlying = new BrentOptimizer(1e-10, 1e-14);
58              JDKRandomGenerator g = new JDKRandomGenerator();
59              g.setSeed(44428400075l);
60              MultiStartUnivariateOptimizer optimizer = new MultiStartUnivariateOptimizer(underlying, 10, g);
61              optimizer.optimize(new MaxEval(300),
62                  new UnivariateObjectiveFunction(new Sin()),
63                  GoalType.MINIMIZE);
64          });
65      }
66  
67      @Test
68      void testSinMin() {
69          UnivariateFunction f = new Sin();
70          UnivariateOptimizer underlying = new BrentOptimizer(1e-10, 1e-14);
71          JDKRandomGenerator g = new JDKRandomGenerator();
72          g.setSeed(44428400075l);
73          MultiStartUnivariateOptimizer optimizer = new MultiStartUnivariateOptimizer(underlying, 10, g);
74          optimizer.optimize(new MaxEval(300),
75                             new UnivariateObjectiveFunction(f),
76                             GoalType.MINIMIZE,
77                             new SearchInterval(-100.0, 100.0));
78          UnivariatePointValuePair[] optima = optimizer.getOptima();
79          for (int i = 1; i < optima.length; ++i) {
80              double d = (optima[i].getPoint() - optima[i-1].getPoint()) / (2 * FastMath.PI);
81              assertTrue(FastMath.abs(d - FastMath.rint(d)) < 1.0e-8);
82              assertEquals(-1.0, f.value(optima[i].getPoint()), 1.0e-10);
83              assertEquals(f.value(optima[i].getPoint()), optima[i].getValue(), 1.0e-10);
84          }
85          assertTrue(optimizer.getEvaluations() > 200);
86          assertTrue(optimizer.getEvaluations() < 300);
87      }
88  
89      @Test
90      void testQuinticMin() {
91          // The quintic function has zeros at 0, +-0.5 and +-1.
92          // The function has extrema (first derivative is zero) at 0.27195613 and 0.82221643,
93          UnivariateFunction f = new QuinticFunction();
94          UnivariateOptimizer underlying = new BrentOptimizer(1e-9, 1e-14);
95          JDKRandomGenerator g = new JDKRandomGenerator();
96          g.setSeed(4312000053L);
97          MultiStartUnivariateOptimizer optimizer = new MultiStartUnivariateOptimizer(underlying, 5, g);
98  
99          UnivariatePointValuePair optimum
100             = optimizer.optimize(new MaxEval(300),
101                                  new UnivariateObjectiveFunction(f),
102                                  GoalType.MINIMIZE,
103                                  new SearchInterval(-0.3, -0.2));
104         assertEquals(-0.27195613, optimum.getPoint(), 1e-9);
105         assertEquals(-0.0443342695, optimum.getValue(), 1e-9);
106 
107         UnivariatePointValuePair[] optima = optimizer.getOptima();
108         for (int i = 0; i < optima.length; ++i) {
109             assertEquals(f.value(optima[i].getPoint()), optima[i].getValue(), 1e-9);
110         }
111         assertTrue(optimizer.getEvaluations() >= 50);
112         assertTrue(optimizer.getEvaluations() <= 100);
113     }
114 
115     @Test
116     void testBadFunction() {
117         UnivariateFunction f = new UnivariateFunction() {
118                 public double value(double x) {
119                     if (x < 0) {
120                         throw new LocalException();
121                     }
122                     return 0;
123                 }
124             };
125         UnivariateOptimizer underlying = new BrentOptimizer(1e-9, 1e-14);
126         JDKRandomGenerator g = new JDKRandomGenerator();
127         g.setSeed(4312000053L);
128         MultiStartUnivariateOptimizer optimizer = new MultiStartUnivariateOptimizer(underlying, 5, g);
129 
130         try {
131             optimizer.optimize(new MaxEval(300),
132                                new UnivariateObjectiveFunction(f),
133                                GoalType.MINIMIZE,
134                                new SearchInterval(-0.3, -0.2));
135             fail();
136         } catch (LocalException e) {
137             // Expected.
138         }
139 
140         // Ensure that the exception was thrown because no optimum was found.
141         assertNull(optimizer.getOptima()[0]);
142     }
143 
144     private static class LocalException extends RuntimeException {
145         private static final long serialVersionUID = 1194682757034350629L;
146     }
147 
148 }