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