001 /*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017 package org.apache.commons.math.optimization.univariate;
018
019 import static org.junit.Assert.assertEquals;
020 import static org.junit.Assert.assertTrue;
021 import static org.junit.Assert.fail;
022
023 import org.apache.commons.math.FunctionEvaluationException;
024 import org.apache.commons.math.MathException;
025 import org.apache.commons.math.MaxIterationsExceededException;
026 import org.apache.commons.math.analysis.QuinticFunction;
027 import org.apache.commons.math.analysis.SinFunction;
028 import org.apache.commons.math.analysis.UnivariateRealFunction;
029 import org.apache.commons.math.optimization.GoalType;
030 import org.apache.commons.math.optimization.UnivariateRealOptimizer;
031 import org.junit.Test;
032
033 /**
034 * @version $Revision: 799857 $ $Date: 2009-08-01 09:07:12 -0400 (Sat, 01 Aug 2009) $
035 */
036 public final class BrentMinimizerTest {
037
038 @Test
039 public void testSinMin() throws MathException {
040 UnivariateRealFunction f = new SinFunction();
041 UnivariateRealOptimizer minimizer = new BrentOptimizer();
042 minimizer.setMaxEvaluations(200);
043 assertEquals(200, minimizer.getMaxEvaluations());
044 try {
045 minimizer.getResult();
046 fail("an exception should have been thrown");
047 } catch (IllegalStateException ise) {
048 // expected
049 } catch (Exception e) {
050 fail("wrong exception caught");
051 }
052 assertEquals(3 * Math.PI / 2, minimizer.optimize(f, GoalType.MINIMIZE, 4, 5), 70 * minimizer.getAbsoluteAccuracy());
053 assertTrue(minimizer.getIterationCount() <= 50);
054 assertEquals(3 * Math.PI / 2, minimizer.optimize(f, GoalType.MINIMIZE, 1, 5), 70 * minimizer.getAbsoluteAccuracy());
055 assertTrue(minimizer.getIterationCount() <= 50);
056 assertTrue(minimizer.getEvaluations() <= 100);
057 assertTrue(minimizer.getEvaluations() >= 90);
058 minimizer.setMaxEvaluations(50);
059 try {
060 minimizer.optimize(f, GoalType.MINIMIZE, 4, 5);
061 fail("an exception should have been thrown");
062 } catch (FunctionEvaluationException fee) {
063 // expected
064 } catch (Exception e) {
065 fail("wrong exception caught");
066 }
067 }
068
069 @Test
070 public void testQuinticMin() throws MathException {
071 // The quintic function has zeros at 0, +-0.5 and +-1.
072 // The function has extrema (first derivative is zero) at 0.27195613 and 0.82221643,
073 UnivariateRealFunction f = new QuinticFunction();
074 UnivariateRealOptimizer minimizer = new BrentOptimizer();
075 assertEquals(-0.27195613, minimizer.optimize(f, GoalType.MINIMIZE, -0.3, -0.2), 1.0e-8);
076 assertEquals( 0.82221643, minimizer.optimize(f, GoalType.MINIMIZE, 0.3, 0.9), 1.0e-8);
077 assertTrue(minimizer.getIterationCount() <= 50);
078
079 // search in a large interval
080 assertEquals(-0.27195613, minimizer.optimize(f, GoalType.MINIMIZE, -1.0, 0.2), 1.0e-8);
081 assertTrue(minimizer.getIterationCount() <= 50);
082
083 }
084
085 @Test
086 public void testQuinticMax() throws MathException {
087 // The quintic function has zeros at 0, +-0.5 and +-1.
088 // The function has extrema (first derivative is zero) at 0.27195613 and 0.82221643,
089 UnivariateRealFunction f = new QuinticFunction();
090 UnivariateRealOptimizer minimizer = new BrentOptimizer();
091 assertEquals(0.27195613, minimizer.optimize(f, GoalType.MAXIMIZE, 0.2, 0.3), 1.0e-8);
092 minimizer.setMaximalIterationCount(30);
093 try {
094 minimizer.optimize(f, GoalType.MAXIMIZE, 0.2, 0.3);
095 fail("an exception should have been thrown");
096 } catch (MaxIterationsExceededException miee) {
097 // expected
098 } catch (Exception e) {
099 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 }