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.math.optimization.univariate;
18  
19  import static org.junit.Assert.assertEquals;
20  import static org.junit.Assert.assertTrue;
21  import static org.junit.Assert.fail;
22  
23  import org.apache.commons.math.FunctionEvaluationException;
24  import org.apache.commons.math.MathException;
25  import org.apache.commons.math.MaxIterationsExceededException;
26  import org.apache.commons.math.analysis.QuinticFunction;
27  import org.apache.commons.math.analysis.SinFunction;
28  import org.apache.commons.math.analysis.UnivariateRealFunction;
29  import org.apache.commons.math.optimization.GoalType;
30  import org.apache.commons.math.optimization.UnivariateRealOptimizer;
31  import org.junit.Test;
32  
33  /**
34   * @version $Revision: 799857 $ $Date: 2009-08-01 09:07:12 -0400 (Sat, 01 Aug 2009) $ 
35   */
36  public final class BrentMinimizerTest {
37  
38      @Test
39      public void testSinMin() throws MathException {
40          UnivariateRealFunction f = new SinFunction();
41          UnivariateRealOptimizer minimizer = new BrentOptimizer();
42          minimizer.setMaxEvaluations(200);
43          assertEquals(200, minimizer.getMaxEvaluations());
44          try {
45              minimizer.getResult();
46              fail("an exception should have been thrown");
47          } catch (IllegalStateException ise) {
48              // expected
49          } catch (Exception e) {
50              fail("wrong exception caught");
51          }
52          assertEquals(3 * Math.PI / 2, minimizer.optimize(f, GoalType.MINIMIZE, 4, 5), 70 * minimizer.getAbsoluteAccuracy());
53          assertTrue(minimizer.getIterationCount() <= 50);
54          assertEquals(3 * Math.PI / 2, minimizer.optimize(f, GoalType.MINIMIZE, 1, 5), 70 * minimizer.getAbsoluteAccuracy());
55          assertTrue(minimizer.getIterationCount() <= 50);
56          assertTrue(minimizer.getEvaluations()    <= 100);
57          assertTrue(minimizer.getEvaluations()    >=  90);
58          minimizer.setMaxEvaluations(50);
59          try {
60              minimizer.optimize(f, GoalType.MINIMIZE, 4, 5);
61              fail("an exception should have been thrown");
62          } catch (FunctionEvaluationException fee) {
63              // expected
64          } catch (Exception e) {
65              fail("wrong exception caught");
66          }
67      }
68  
69      @Test
70      public void testQuinticMin() throws MathException {
71          // The quintic function has zeros at 0, +-0.5 and +-1.
72          // The function has extrema (first derivative is zero) at 0.27195613 and 0.82221643,
73          UnivariateRealFunction f = new QuinticFunction();
74          UnivariateRealOptimizer minimizer = new BrentOptimizer();
75          assertEquals(-0.27195613, minimizer.optimize(f, GoalType.MINIMIZE, -0.3, -0.2), 1.0e-8);
76          assertEquals( 0.82221643, minimizer.optimize(f, GoalType.MINIMIZE,  0.3,  0.9), 1.0e-8);
77          assertTrue(minimizer.getIterationCount() <= 50);
78  
79          // search in a large interval
80          assertEquals(-0.27195613, minimizer.optimize(f, GoalType.MINIMIZE, -1.0, 0.2), 1.0e-8);
81          assertTrue(minimizer.getIterationCount() <= 50);
82  
83      }
84  
85      @Test
86      public void testQuinticMax() throws MathException {
87          // The quintic function has zeros at 0, +-0.5 and +-1.
88          // The function has extrema (first derivative is zero) at 0.27195613 and 0.82221643,
89          UnivariateRealFunction f = new QuinticFunction();
90          UnivariateRealOptimizer minimizer = new BrentOptimizer();
91          assertEquals(0.27195613, minimizer.optimize(f, GoalType.MAXIMIZE, 0.2, 0.3), 1.0e-8);
92          minimizer.setMaximalIterationCount(30);
93          try {
94              minimizer.optimize(f, GoalType.MAXIMIZE, 0.2, 0.3);
95              fail("an exception should have been thrown");
96          } catch (MaxIterationsExceededException miee) {
97              // expected
98          } catch (Exception e) {
99              fail("wrong exception caught");
100         }
101     }
102 
103     @Test
104     public void testMinEndpoints() throws Exception {
105         UnivariateRealFunction f = new SinFunction();
106         UnivariateRealOptimizer solver = new BrentOptimizer();
107 
108         // endpoint is minimum
109         double result = solver.optimize(f, GoalType.MINIMIZE, 3 * Math.PI / 2, 5);
110         assertEquals(3 * Math.PI / 2, result, 70 * solver.getAbsoluteAccuracy());
111 
112         result = solver.optimize(f, GoalType.MINIMIZE, 4, 3 * Math.PI / 2);
113         assertEquals(3 * Math.PI / 2, result, 70 * solver.getAbsoluteAccuracy());
114 
115     }
116 
117 }