1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.math.analysis.solvers;
18
19 import org.apache.commons.math.ConvergenceException;
20 import org.apache.commons.math.FunctionEvaluationException;
21 import org.apache.commons.math.MaxIterationsExceededException;
22 import org.apache.commons.math.analysis.UnivariateRealFunction;
23 import org.apache.commons.math.util.MathUtils;
24
25
26
27
28
29
30
31
32
33
34
35
36
37 public class RiddersSolver extends UnivariateRealSolverImpl {
38
39
40
41
42
43
44
45
46
47
48 @Deprecated
49 public RiddersSolver(UnivariateRealFunction f) {
50 super(f, 100, 1E-6);
51 }
52
53
54
55
56 public RiddersSolver() {
57 super(100, 1E-6);
58 }
59
60
61 @Deprecated
62 public double solve(final double min, final double max)
63 throws ConvergenceException, FunctionEvaluationException {
64 return solve(f, min, max);
65 }
66
67
68 @Deprecated
69 public double solve(final double min, final double max, final double initial)
70 throws ConvergenceException, FunctionEvaluationException {
71 return solve(f, min, max, initial);
72 }
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89 public double solve(final UnivariateRealFunction f,
90 final double min, final double max, final double initial)
91 throws MaxIterationsExceededException, FunctionEvaluationException {
92
93
94 if (f.value(min) == 0.0) { return min; }
95 if (f.value(max) == 0.0) { return max; }
96 if (f.value(initial) == 0.0) { return initial; }
97
98 verifyBracketing(min, max, f);
99 verifySequence(min, initial, max);
100 if (isBracketing(min, initial, f)) {
101 return solve(f, min, initial);
102 } else {
103 return solve(f, initial, max);
104 }
105 }
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121 public double solve(final UnivariateRealFunction f,
122 final double min, final double max)
123 throws MaxIterationsExceededException, FunctionEvaluationException {
124
125
126
127
128 double x1, x2, x3, x, oldx, y1, y2, y3, y, delta, correction, tolerance;
129
130 x1 = min; y1 = f.value(x1);
131 x2 = max; y2 = f.value(x2);
132
133
134 if (y1 == 0.0) { return min; }
135 if (y2 == 0.0) { return max; }
136 verifyBracketing(min, max, f);
137
138 int i = 1;
139 oldx = Double.POSITIVE_INFINITY;
140 while (i <= maximalIterationCount) {
141
142 x3 = 0.5 * (x1 + x2);
143 y3 = f.value(x3);
144 if (Math.abs(y3) <= functionValueAccuracy) {
145 setResult(x3, i);
146 return result;
147 }
148 delta = 1 - (y1 * y2) / (y3 * y3);
149 correction = (MathUtils.sign(y2) * MathUtils.sign(y3)) *
150 (x3 - x1) / Math.sqrt(delta);
151 x = x3 - correction;
152 y = f.value(x);
153
154
155 tolerance = Math.max(relativeAccuracy * Math.abs(x), absoluteAccuracy);
156 if (Math.abs(x - oldx) <= tolerance) {
157 setResult(x, i);
158 return result;
159 }
160 if (Math.abs(y) <= functionValueAccuracy) {
161 setResult(x, i);
162 return result;
163 }
164
165
166
167 if (correction > 0.0) {
168 if (MathUtils.sign(y1) + MathUtils.sign(y) == 0.0) {
169 x2 = x; y2 = y;
170 } else {
171 x1 = x; x2 = x3;
172 y1 = y; y2 = y3;
173 }
174 } else {
175 if (MathUtils.sign(y2) + MathUtils.sign(y) == 0.0) {
176 x1 = x; y1 = y;
177 } else {
178 x1 = x3; x2 = x;
179 y1 = y3; y2 = y;
180 }
181 }
182 oldx = x;
183 i++;
184 }
185 throw new MaxIterationsExceededException(maximalIterationCount);
186 }
187 }