1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 package org.hipparchus.analysis.solvers;
23
24 import org.hipparchus.analysis.FunctionUtils;
25 import org.hipparchus.analysis.MonitoredFunction;
26 import org.hipparchus.analysis.QuinticFunction;
27 import org.hipparchus.analysis.UnivariateFunction;
28 import org.hipparchus.analysis.differentiation.DSFactory;
29 import org.hipparchus.analysis.differentiation.UnivariateDifferentiableFunction;
30 import org.hipparchus.analysis.function.Constant;
31 import org.hipparchus.analysis.function.Inverse;
32 import org.hipparchus.analysis.function.Sin;
33 import org.hipparchus.analysis.function.Sqrt;
34 import org.hipparchus.exception.MathIllegalArgumentException;
35 import org.hipparchus.exception.MathIllegalStateException;
36 import org.hipparchus.util.FastMath;
37 import org.junit.Assert;
38 import org.junit.Test;
39
40
41
42
43
44
45
46
47
48
49
50 public final class BrentSolverTest {
51 @Test
52 public void testSinZero() {
53
54
55
56 UnivariateFunction f = new Sin();
57 double result;
58 UnivariateSolver solver = new BrentSolver();
59
60 result = solver.solve(100, f, 3, 4);
61
62
63 Assert.assertEquals(result, FastMath.PI, solver.getAbsoluteAccuracy());
64 Assert.assertTrue(solver.getEvaluations() <= 7);
65
66 result = solver.solve(100, f, 1, 4);
67
68
69 Assert.assertEquals(result, FastMath.PI, solver.getAbsoluteAccuracy());
70 Assert.assertTrue(solver.getEvaluations() <= 8);
71 }
72
73 @Test
74 public void testQuinticZero() {
75
76
77
78
79
80
81
82 UnivariateFunction f = new QuinticFunction();
83 double result;
84
85 UnivariateSolver solver = new BrentSolver();
86
87
88 result = solver.solve(100, f, -0.2, 0.2);
89
90
91 Assert.assertEquals(result, 0, solver.getAbsoluteAccuracy());
92 Assert.assertTrue(solver.getEvaluations() <= 3);
93
94
95 result = solver.solve(100, f, -0.1, 0.3);
96
97
98 Assert.assertEquals(result, 0, solver.getAbsoluteAccuracy());
99
100 Assert.assertTrue(solver.getEvaluations() <= 7);
101
102 result = solver.solve(100, f, -0.3, 0.45);
103
104
105 Assert.assertEquals(result, 0, solver.getAbsoluteAccuracy());
106
107 Assert.assertTrue(solver.getEvaluations() <= 8);
108
109 result = solver.solve(100, f, 0.3, 0.7);
110
111
112 Assert.assertEquals(result, 0.5, solver.getAbsoluteAccuracy());
113
114 Assert.assertTrue(solver.getEvaluations() <= 9);
115
116 result = solver.solve(100, f, 0.2, 0.6);
117
118
119 Assert.assertEquals(result, 0.5, solver.getAbsoluteAccuracy());
120 Assert.assertTrue(solver.getEvaluations() <= 10);
121
122 result = solver.solve(100, f, 0.05, 0.95);
123
124
125 Assert.assertEquals(result, 0.5, solver.getAbsoluteAccuracy());
126 Assert.assertTrue(solver.getEvaluations() <= 11);
127
128
129 result = solver.solve(100, f, 0.85, 1.25);
130
131
132 Assert.assertEquals(result, 1.0, solver.getAbsoluteAccuracy());
133 Assert.assertTrue(solver.getEvaluations() <= 11);
134
135 result = solver.solve(100, f, 0.8, 1.2);
136
137
138 Assert.assertEquals(result, 1.0, solver.getAbsoluteAccuracy());
139 Assert.assertTrue(solver.getEvaluations() <= 11);
140
141 result = solver.solve(100, f, 0.85, 1.75);
142
143
144 Assert.assertEquals(result, 1.0, solver.getAbsoluteAccuracy());
145 Assert.assertTrue(solver.getEvaluations() <= 13);
146
147 result = solver.solve(100, f, 0.55, 1.45);
148
149
150 Assert.assertEquals(result, 1.0, solver.getAbsoluteAccuracy());
151 Assert.assertTrue(solver.getEvaluations() <= 10);
152
153 result = solver.solve(100, f, 0.85, 5);
154
155
156 Assert.assertEquals(result, 1.0, solver.getAbsoluteAccuracy());
157 Assert.assertTrue(solver.getEvaluations() <= 15);
158
159 try {
160 result = solver.solve(5, f, 0.85, 5);
161 Assert.fail("Expected MathIllegalStateException");
162 } catch (MathIllegalStateException e) {
163
164 }
165 }
166
167 @Test
168 public void testRootEndpoints() {
169 UnivariateFunction f = new Sin();
170 BrentSolver solver = new BrentSolver();
171
172
173 double result = solver.solve(100, f, FastMath.PI, 4);
174 Assert.assertEquals(FastMath.PI, result, solver.getAbsoluteAccuracy());
175
176 result = solver.solve(100, f, 3, FastMath.PI);
177 Assert.assertEquals(FastMath.PI, result, solver.getAbsoluteAccuracy());
178
179 result = solver.solve(100, f, FastMath.PI, 4, 3.5);
180 Assert.assertEquals(FastMath.PI, result, solver.getAbsoluteAccuracy());
181
182 result = solver.solve(100, f, 3, FastMath.PI, 3.07);
183 Assert.assertEquals(FastMath.PI, result, solver.getAbsoluteAccuracy());
184 }
185
186 @Test
187 public void testBadEndpoints() {
188 UnivariateFunction f = new Sin();
189 BrentSolver solver = new BrentSolver();
190 try {
191 solver.solve(100, f, 1, -1);
192 Assert.fail("Expecting MathIllegalArgumentException - bad interval");
193 } catch (MathIllegalArgumentException ex) {
194
195 }
196 try {
197 solver.solve(100, f, 1, 1.5);
198 Assert.fail("Expecting MathIllegalArgumentException - non-bracketing");
199 } catch (MathIllegalArgumentException ex) {
200
201 }
202 try {
203 solver.solve(100, f, 1, 1.5, 1.2);
204 Assert.fail("Expecting MathIllegalArgumentException - non-bracketing");
205 } catch (MathIllegalArgumentException ex) {
206
207 }
208 }
209
210 @Test
211 public void testInitialGuess() {
212 MonitoredFunction f = new MonitoredFunction(new QuinticFunction());
213 BrentSolver solver = new BrentSolver();
214 double result;
215
216
217 result = solver.solve(100, f, 0.6, 7.0);
218 Assert.assertEquals(result, 1.0, solver.getAbsoluteAccuracy());
219 int referenceCallsCount = f.getCallsCount();
220 Assert.assertTrue(referenceCallsCount >= 13);
221
222
223 try {
224 result = solver.solve(100, f, 0.6, 7.0, 0.0);
225 Assert.fail("a MathIllegalArgumentException was expected");
226 } catch (MathIllegalArgumentException iae) {
227
228 }
229
230
231 f.setCallsCount(0);
232 result = solver.solve(100, f, 0.6, 7.0, 0.61);
233 Assert.assertEquals(result, 1.0, solver.getAbsoluteAccuracy());
234 Assert.assertTrue(f.getCallsCount() > referenceCallsCount);
235
236
237 f.setCallsCount(0);
238 result = solver.solve(100, f, 0.6, 7.0, 0.999999);
239 Assert.assertEquals(result, 1.0, solver.getAbsoluteAccuracy());
240 Assert.assertTrue(f.getCallsCount() < referenceCallsCount);
241
242
243 f.setCallsCount(0);
244 result = solver.solve(100, f, 0.6, 7.0, 1.0);
245 Assert.assertEquals(result, 1.0, solver.getAbsoluteAccuracy());
246 Assert.assertEquals(1, solver.getEvaluations());
247 Assert.assertEquals(1, f.getCallsCount());
248 }
249
250 @Test
251 public void testMath832() {
252 final UnivariateFunction f = new UnivariateFunction() {
253 private final UnivariateDifferentiableFunction sqrt = new Sqrt();
254 private final UnivariateDifferentiableFunction inv = new Inverse();
255 private final UnivariateDifferentiableFunction func
256 = FunctionUtils.add(FunctionUtils.multiply(new Constant(1e2), sqrt),
257 FunctionUtils.multiply(new Constant(1e6), inv),
258 FunctionUtils.multiply(new Constant(1e4),
259 FunctionUtils.compose(inv, sqrt)));
260 private final DSFactory factory = new DSFactory(1, 1);
261
262 public double value(double x) {
263 return func.value(factory.variable(0, x)).getPartialDerivative(1);
264 }
265
266 };
267
268 BrentSolver solver = new BrentSolver();
269 final double result = solver.solve(99, f, 1, 1e30, 1 + 1e-10);
270 Assert.assertEquals(804.93558250, result, 1e-8);
271 }
272 }