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.analysis.solvers; 018 019 import org.apache.commons.math.MathException; 020 import org.apache.commons.math.analysis.Expm1Function; 021 import org.apache.commons.math.analysis.QuinticFunction; 022 import org.apache.commons.math.analysis.SinFunction; 023 import org.apache.commons.math.analysis.UnivariateRealFunction; 024 025 import junit.framework.TestCase; 026 027 /** 028 * Testcase for Ridders solver. 029 * <p> 030 * Ridders' method converges superlinearly, more specific, its rate of 031 * convergence is sqrt(2). Test runs show that for a default absolute 032 * accuracy of 1E-6, it generally takes less than 5 iterations for close 033 * initial bracket and 5 to 10 iterations for distant initial bracket 034 * to converge. 035 * 036 * @version $Revision: 799857 $ $Date: 2009-08-01 09:07:12 -0400 (Sat, 01 Aug 2009) $ 037 */ 038 public final class RiddersSolverTest extends TestCase { 039 040 /** 041 * Test the deprecated APIs. 042 */ 043 @Deprecated 044 public void testDeprecated() throws MathException { 045 UnivariateRealFunction f = new SinFunction(); 046 UnivariateRealSolver solver = new RiddersSolver(f); 047 double min, max, expected, result, tolerance; 048 049 min = 3.0; max = 4.0; expected = Math.PI; 050 tolerance = Math.max(solver.getAbsoluteAccuracy(), 051 Math.abs(expected * solver.getRelativeAccuracy())); 052 result = solver.solve(min, max); 053 assertEquals(expected, result, tolerance); 054 055 min = -1.0; max = 1.5; expected = 0.0; 056 tolerance = Math.max(solver.getAbsoluteAccuracy(), 057 Math.abs(expected * solver.getRelativeAccuracy())); 058 result = solver.solve(min, max); 059 assertEquals(expected, result, tolerance); 060 } 061 062 /** 063 * Test of solver for the sine function. 064 */ 065 public void testSinFunction() throws MathException { 066 UnivariateRealFunction f = new SinFunction(); 067 UnivariateRealSolver solver = new RiddersSolver(); 068 double min, max, expected, result, tolerance; 069 070 min = 3.0; max = 4.0; expected = Math.PI; 071 tolerance = Math.max(solver.getAbsoluteAccuracy(), 072 Math.abs(expected * solver.getRelativeAccuracy())); 073 result = solver.solve(f, min, max); 074 assertEquals(expected, result, tolerance); 075 076 min = -1.0; max = 1.5; expected = 0.0; 077 tolerance = Math.max(solver.getAbsoluteAccuracy(), 078 Math.abs(expected * solver.getRelativeAccuracy())); 079 result = solver.solve(f, min, max); 080 assertEquals(expected, result, tolerance); 081 } 082 083 /** 084 * Test of solver for the quintic function. 085 */ 086 public void testQuinticFunction() throws MathException { 087 UnivariateRealFunction f = new QuinticFunction(); 088 UnivariateRealSolver solver = new RiddersSolver(); 089 double min, max, expected, result, tolerance; 090 091 min = -0.4; max = 0.2; expected = 0.0; 092 tolerance = Math.max(solver.getAbsoluteAccuracy(), 093 Math.abs(expected * solver.getRelativeAccuracy())); 094 result = solver.solve(f, min, max); 095 assertEquals(expected, result, tolerance); 096 097 min = 0.75; max = 1.5; expected = 1.0; 098 tolerance = Math.max(solver.getAbsoluteAccuracy(), 099 Math.abs(expected * solver.getRelativeAccuracy())); 100 result = solver.solve(f, min, max); 101 assertEquals(expected, result, tolerance); 102 103 min = -0.9; max = -0.2; expected = -0.5; 104 tolerance = Math.max(solver.getAbsoluteAccuracy(), 105 Math.abs(expected * solver.getRelativeAccuracy())); 106 result = solver.solve(f, min, max); 107 assertEquals(expected, result, tolerance); 108 } 109 110 /** 111 * Test of solver for the exponential function. 112 */ 113 public void testExpm1Function() throws MathException { 114 UnivariateRealFunction f = new Expm1Function(); 115 UnivariateRealSolver solver = new RiddersSolver(); 116 double min, max, expected, result, tolerance; 117 118 min = -1.0; max = 2.0; expected = 0.0; 119 tolerance = Math.max(solver.getAbsoluteAccuracy(), 120 Math.abs(expected * solver.getRelativeAccuracy())); 121 result = solver.solve(f, min, max); 122 assertEquals(expected, result, tolerance); 123 124 min = -20.0; max = 10.0; expected = 0.0; 125 tolerance = Math.max(solver.getAbsoluteAccuracy(), 126 Math.abs(expected * solver.getRelativeAccuracy())); 127 result = solver.solve(f, min, max); 128 assertEquals(expected, result, tolerance); 129 130 min = -50.0; max = 100.0; expected = 0.0; 131 tolerance = Math.max(solver.getAbsoluteAccuracy(), 132 Math.abs(expected * solver.getRelativeAccuracy())); 133 result = solver.solve(f, min, max); 134 assertEquals(expected, result, tolerance); 135 } 136 137 /** 138 * Test of parameters for the solver. 139 */ 140 public void testParameters() throws Exception { 141 UnivariateRealFunction f = new SinFunction(); 142 UnivariateRealSolver solver = new RiddersSolver(); 143 144 try { 145 // bad interval 146 solver.solve(f, 1, -1); 147 fail("Expecting IllegalArgumentException - bad interval"); 148 } catch (IllegalArgumentException ex) { 149 // expected 150 } 151 try { 152 // no bracketing 153 solver.solve(f, 2, 3); 154 fail("Expecting IllegalArgumentException - no bracketing"); 155 } catch (IllegalArgumentException ex) { 156 // expected 157 } 158 } 159 }