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 }