View Javadoc
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.math4.legacy.analysis.solvers;
18  
19  import org.apache.commons.math4.legacy.analysis.QuinticFunction;
20  import org.apache.commons.math4.legacy.analysis.UnivariateFunction;
21  import org.apache.commons.math4.legacy.analysis.function.Expm1;
22  import org.apache.commons.math4.legacy.analysis.function.Sin;
23  import org.apache.commons.math4.legacy.exception.NoBracketingException;
24  import org.apache.commons.math4.legacy.exception.NumberIsTooLargeException;
25  import org.apache.commons.math4.core.jdkmath.JdkMath;
26  import org.junit.Assert;
27  import org.junit.Test;
28  
29  /**
30   * Test case for {@link RiddersSolver Ridders} solver.
31   * <p>
32   * Ridders' method converges superlinearly, more specific, its rate of
33   * convergence is sqrt(2). Test runs show that for a default absolute
34   * accuracy of 1E-6, it generally takes less than 5 iterations for close
35   * initial bracket and 5 to 10 iterations for distant initial bracket
36   * to converge.
37   *
38   */
39  public final class RiddersSolverTest {
40      /**
41       * Test of solver for the sine function.
42       */
43      @Test
44      public void testSinFunction() {
45          UnivariateFunction f = new Sin();
46          UnivariateSolver solver = new RiddersSolver();
47          double min;
48          double max;
49          double expected;
50          double result;
51          double tolerance;
52  
53          min = 3.0; max = 4.0; expected = JdkMath.PI;
54          tolerance = JdkMath.max(solver.getAbsoluteAccuracy(),
55                      JdkMath.abs(expected * solver.getRelativeAccuracy()));
56          result = solver.solve(100, f, min, max);
57          Assert.assertEquals(expected, result, tolerance);
58  
59          min = -1.0; max = 1.5; expected = 0.0;
60          tolerance = JdkMath.max(solver.getAbsoluteAccuracy(),
61                      JdkMath.abs(expected * solver.getRelativeAccuracy()));
62          result = solver.solve(100, f, min, max);
63          Assert.assertEquals(expected, result, tolerance);
64      }
65  
66      /**
67       * Test of solver for the quintic function.
68       */
69      @Test
70      public void testQuinticFunction() {
71          UnivariateFunction f = new QuinticFunction();
72          UnivariateSolver solver = new RiddersSolver();
73          double min;
74          double max;
75          double expected;
76          double result;
77          double tolerance;
78  
79          min = -0.4; max = 0.2; expected = 0.0;
80          tolerance = JdkMath.max(solver.getAbsoluteAccuracy(),
81                      JdkMath.abs(expected * solver.getRelativeAccuracy()));
82          result = solver.solve(100, f, min, max);
83          Assert.assertEquals(expected, result, tolerance);
84  
85          min = 0.75; max = 1.5; expected = 1.0;
86          tolerance = JdkMath.max(solver.getAbsoluteAccuracy(),
87                      JdkMath.abs(expected * solver.getRelativeAccuracy()));
88          result = solver.solve(100, f, min, max);
89          Assert.assertEquals(expected, result, tolerance);
90  
91          min = -0.9; max = -0.2; expected = -0.5;
92          tolerance = JdkMath.max(solver.getAbsoluteAccuracy(),
93                      JdkMath.abs(expected * solver.getRelativeAccuracy()));
94          result = solver.solve(100, f, min, max);
95          Assert.assertEquals(expected, result, tolerance);
96      }
97  
98      /**
99       * Test of solver for the exponential function.
100      */
101     @Test
102     public void testExpm1Function() {
103         UnivariateFunction f = new Expm1();
104         UnivariateSolver solver = new RiddersSolver();
105         double min;
106         double max;
107         double expected;
108         double result;
109         double tolerance;
110 
111         min = -1.0; max = 2.0; expected = 0.0;
112         tolerance = JdkMath.max(solver.getAbsoluteAccuracy(),
113                     JdkMath.abs(expected * solver.getRelativeAccuracy()));
114         result = solver.solve(100, f, min, max);
115         Assert.assertEquals(expected, result, tolerance);
116 
117         min = -20.0; max = 10.0; expected = 0.0;
118         tolerance = JdkMath.max(solver.getAbsoluteAccuracy(),
119                     JdkMath.abs(expected * solver.getRelativeAccuracy()));
120         result = solver.solve(100, f, min, max);
121         Assert.assertEquals(expected, result, tolerance);
122 
123         min = -50.0; max = 100.0; expected = 0.0;
124         tolerance = JdkMath.max(solver.getAbsoluteAccuracy(),
125                     JdkMath.abs(expected * solver.getRelativeAccuracy()));
126         result = solver.solve(100, f, min, max);
127         Assert.assertEquals(expected, result, tolerance);
128     }
129 
130     /**
131      * Test of parameters for the solver.
132      */
133     @Test
134     public void testParameters() {
135         UnivariateFunction f = new Sin();
136         UnivariateSolver solver = new RiddersSolver();
137 
138         try {
139             // bad interval
140             solver.solve(100, f, 1, -1);
141             Assert.fail("Expecting NumberIsTooLargeException - bad interval");
142         } catch (NumberIsTooLargeException ex) {
143             // expected
144         }
145         try {
146             // no bracketing
147             solver.solve(100, f, 2, 3);
148             Assert.fail("Expecting NoBracketingException - no bracketing");
149         } catch (NoBracketingException ex) {
150             // expected
151         }
152     }
153 }