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 }