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.Assert;
33  import org.junit.Test;
34  
35  public class MultiStartUnivariateOptimizerTest {
36      @Test(expected=MathIllegalStateException.class)
37      public void testMissingMaxEval() {
38          UnivariateOptimizer underlying = new BrentOptimizer(1e-10, 1e-14);
39          JDKRandomGenerator g = new JDKRandomGenerator();
40          g.setSeed(44428400075l);
41          MultiStartUnivariateOptimizer optimizer = new MultiStartUnivariateOptimizer(underlying, 10, g);
42          optimizer.optimize(new UnivariateObjectiveFunction(new Sin()),
43                             GoalType.MINIMIZE,
44                             new SearchInterval(-1, 1));
45      }
46      @Test(expected=MathIllegalStateException.class)
47      public void testMissingSearchInterval() {
48          UnivariateOptimizer underlying = new BrentOptimizer(1e-10, 1e-14);
49          JDKRandomGenerator g = new JDKRandomGenerator();
50          g.setSeed(44428400075l);
51          MultiStartUnivariateOptimizer optimizer = new MultiStartUnivariateOptimizer(underlying, 10, g);
52          optimizer.optimize(new MaxEval(300),
53                             new UnivariateObjectiveFunction(new Sin()),
54                             GoalType.MINIMIZE);
55      }
56  
57      @Test
58      public void testSinMin() {
59          UnivariateFunction f = new Sin();
60          UnivariateOptimizer underlying = new BrentOptimizer(1e-10, 1e-14);
61          JDKRandomGenerator g = new JDKRandomGenerator();
62          g.setSeed(44428400075l);
63          MultiStartUnivariateOptimizer optimizer = new MultiStartUnivariateOptimizer(underlying, 10, g);
64          optimizer.optimize(new MaxEval(300),
65                             new UnivariateObjectiveFunction(f),
66                             GoalType.MINIMIZE,
67                             new SearchInterval(-100.0, 100.0));
68          UnivariatePointValuePair[] optima = optimizer.getOptima();
69          for (int i = 1; i < optima.length; ++i) {
70              double d = (optima[i].getPoint() - optima[i-1].getPoint()) / (2 * FastMath.PI);
71              Assert.assertTrue(FastMath.abs(d - FastMath.rint(d)) < 1.0e-8);
72              Assert.assertEquals(-1.0, f.value(optima[i].getPoint()), 1.0e-10);
73              Assert.assertEquals(f.value(optima[i].getPoint()), optima[i].getValue(), 1.0e-10);
74          }
75          Assert.assertTrue(optimizer.getEvaluations() > 200);
76          Assert.assertTrue(optimizer.getEvaluations() < 300);
77      }
78  
79      @Test
80      public void testQuinticMin() {
81          // The quintic function has zeros at 0, +-0.5 and +-1.
82          // The function has extrema (first derivative is zero) at 0.27195613 and 0.82221643,
83          UnivariateFunction f = new QuinticFunction();
84          UnivariateOptimizer underlying = new BrentOptimizer(1e-9, 1e-14);
85          JDKRandomGenerator g = new JDKRandomGenerator();
86          g.setSeed(4312000053L);
87          MultiStartUnivariateOptimizer optimizer = new MultiStartUnivariateOptimizer(underlying, 5, g);
88  
89          UnivariatePointValuePair optimum
90              = optimizer.optimize(new MaxEval(300),
91                                   new UnivariateObjectiveFunction(f),
92                                   GoalType.MINIMIZE,
93                                   new SearchInterval(-0.3, -0.2));
94          Assert.assertEquals(-0.27195613, optimum.getPoint(), 1e-9);
95          Assert.assertEquals(-0.0443342695, optimum.getValue(), 1e-9);
96  
97          UnivariatePointValuePair[] optima = optimizer.getOptima();
98          for (int i = 0; i < optima.length; ++i) {
99              Assert.assertEquals(f.value(optima[i].getPoint()), optima[i].getValue(), 1e-9);
100         }
101         Assert.assertTrue(optimizer.getEvaluations() >= 50);
102         Assert.assertTrue(optimizer.getEvaluations() <= 100);
103     }
104 
105     @Test
106     public void testBadFunction() {
107         UnivariateFunction f = new UnivariateFunction() {
108                 public double value(double x) {
109                     if (x < 0) {
110                         throw new LocalException();
111                     }
112                     return 0;
113                 }
114             };
115         UnivariateOptimizer underlying = new BrentOptimizer(1e-9, 1e-14);
116         JDKRandomGenerator g = new JDKRandomGenerator();
117         g.setSeed(4312000053L);
118         MultiStartUnivariateOptimizer optimizer = new MultiStartUnivariateOptimizer(underlying, 5, g);
119 
120         try {
121             optimizer.optimize(new MaxEval(300),
122                                new UnivariateObjectiveFunction(f),
123                                GoalType.MINIMIZE,
124                                new SearchInterval(-0.3, -0.2));
125             Assert.fail();
126         } catch (LocalException e) {
127             // Expected.
128         }
129 
130         // Ensure that the exception was thrown because no optimum was found.
131         Assert.assertTrue(optimizer.getOptima()[0] == null);
132     }
133 
134     private static class LocalException extends RuntimeException {
135         private static final long serialVersionUID = 1194682757034350629L;
136     }
137 
138 }