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