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    *      http://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.apache.commons.math4.legacy.optim.univariate;
18  
19  import org.apache.commons.math4.legacy.analysis.QuinticFunction;
20  import org.apache.commons.math4.legacy.analysis.UnivariateFunction;
21  import org.apache.commons.math4.legacy.analysis.function.Sin;
22  import org.apache.commons.math4.legacy.exception.MathIllegalStateException;
23  import org.apache.commons.math4.legacy.optim.MaxEval;
24  import org.apache.commons.math4.legacy.optim.nonlinear.scalar.GoalType;
25  import org.apache.commons.rng.UniformRandomProvider;
26  import org.apache.commons.rng.simple.RandomSource;
27  import org.apache.commons.math4.core.jdkmath.JdkMath;
28  import org.junit.Assert;
29  import org.junit.Test;
30  
31  public class MultiStartUnivariateOptimizerTest {
32      @Test(expected=MathIllegalStateException.class)
33      public void testMissingMaxEval() {
34          UnivariateOptimizer underlying = new BrentOptimizer(1e-10, 1e-14);
35          UniformRandomProvider g = RandomSource.TWO_CMRES.create(44428400075L);
36          MultiStartUnivariateOptimizer optimizer = new MultiStartUnivariateOptimizer(underlying, 10, g);
37          optimizer.optimize(new UnivariateObjectiveFunction(new Sin()),
38                             GoalType.MINIMIZE,
39                             new SearchInterval(-1, 1));
40      }
41      @Test(expected=MathIllegalStateException.class)
42      public void testMissingSearchInterval() {
43          UnivariateOptimizer underlying = new BrentOptimizer(1e-10, 1e-14);
44          UniformRandomProvider g = RandomSource.TWO_CMRES.create(44428400075L);
45          MultiStartUnivariateOptimizer optimizer = new MultiStartUnivariateOptimizer(underlying, 10, g);
46          optimizer.optimize(new MaxEval(300),
47                             new UnivariateObjectiveFunction(new Sin()),
48                             GoalType.MINIMIZE);
49      }
50  
51      @Test
52      public void testSinMin() {
53          UnivariateFunction f = new Sin();
54          UnivariateOptimizer underlying = new BrentOptimizer(1e-10, 1e-14);
55          UniformRandomProvider g = RandomSource.TWO_CMRES.create(44428400075L);
56          MultiStartUnivariateOptimizer optimizer = new MultiStartUnivariateOptimizer(underlying, 10, g);
57          optimizer.optimize(new MaxEval(300),
58                             new UnivariateObjectiveFunction(f),
59                             GoalType.MINIMIZE,
60                             new SearchInterval(-100.0, 100.0));
61          UnivariatePointValuePair[] optima = optimizer.getOptima();
62          for (int i = 1; i < optima.length; ++i) {
63              double d = (optima[i].getPoint() - optima[i-1].getPoint()) / (2 * JdkMath.PI);
64              Assert.assertTrue(JdkMath.abs(d - JdkMath.rint(d)) < 1.0e-8);
65              Assert.assertEquals(-1.0, f.value(optima[i].getPoint()), 1.0e-10);
66              Assert.assertEquals(f.value(optima[i].getPoint()), optima[i].getValue(), 1.0e-10);
67          }
68          Assert.assertTrue(optimizer.getEvaluations() > 200);
69          Assert.assertTrue(optimizer.getEvaluations() < 300);
70      }
71  
72      @Test
73      public void testQuinticMin() {
74          UnivariateFunction f = new QuinticFunction();
75          UnivariateOptimizer underlying = new BrentOptimizer(1e-9, 1e-14);
76          UniformRandomProvider g = RandomSource.TWO_CMRES.create(4312000053L);
77          MultiStartUnivariateOptimizer optimizer = new MultiStartUnivariateOptimizer(underlying, 5, g);
78  
79          UnivariatePointValuePair optimum
80              = optimizer.optimize(new MaxEval(300),
81                                   new UnivariateObjectiveFunction(f),
82                                   GoalType.MINIMIZE,
83                                   new SearchInterval(-0.3, -0.2));
84          Assert.assertEquals(-0.2719561295, optimum.getPoint(), 1e-9);
85          Assert.assertEquals(-0.0443342695, optimum.getValue(), 1e-9);
86  
87          UnivariatePointValuePair[] optima = optimizer.getOptima();
88          for (int i = 0; i < optima.length; ++i) {
89              Assert.assertEquals(f.value(optima[i].getPoint()), optima[i].getValue(), 1e-9);
90          }
91          Assert.assertTrue(optimizer.getEvaluations() >= 50);
92          Assert.assertTrue(optimizer.getEvaluations() <= 100);
93      }
94  
95      @Test
96      public void testBadFunction() {
97          UnivariateFunction f = new UnivariateFunction() {
98                  @Override
99                  public double value(double x) {
100                     if (x < 0) {
101                         throw new LocalException();
102                     }
103                     return 0;
104                 }
105             };
106         UnivariateOptimizer underlying = new BrentOptimizer(1e-9, 1e-14);
107         UniformRandomProvider g = RandomSource.TWO_CMRES.create(4312000053L);
108         MultiStartUnivariateOptimizer optimizer = new MultiStartUnivariateOptimizer(underlying, 5, g);
109 
110         try {
111             optimizer.optimize(new MaxEval(300),
112                                new UnivariateObjectiveFunction(f),
113                                GoalType.MINIMIZE,
114                                new SearchInterval(-0.3, -0.2));
115             Assert.fail();
116         } catch (LocalException e) {
117             // Expected.
118         }
119 
120         // Ensure that the exception was thrown because no optimum was found.
121         Assert.assertNull(optimizer.getOptima()[0]);
122     }
123 
124     private static final class LocalException extends RuntimeException {
125         private static final long serialVersionUID = 1194682757034350629L;
126     }
127 }