Brent’s Method
4.4 Brent’s Method
Brent’s method 7 combines bisection and quadratic interpolation into an efficient root-finding algorithm. In most problems the method is much faster than bisection alone, but it can become sluggish if the function is not smooth. It is the recommended method of root finding if the derivative of the function is difficult or impossible to compute.
Old interval
Old interval
(a) Case of x<x 3 (b) Case of x>x 3 Figure 4.2. Inverse quadratic iteration.
Brent’s method assumes that a root of f (x) = 0 has been initially bracketed in the interval (x 1 , x 2 ). The root-finding process starts with a bisection step that halves
the interval to either (x 1 , x 3 ) or (x 3 , x 2 ), where x 3 = (x 1 +x 2 )/2, as shown in Figs. 4.2(a) and (b). In the course of bisection we had to compute f 1 = f (x 1 ), f 2 = f (x 2 ) and
f 3 = f (x 3 ), so that we now know three points on the f (x) curve (the open circles in the figure). These points allow us to carry out the next iteration of the root by inverse quadratic interpolation (viewing x as a quadratic function of f ). If the result x of the interpolation falls inside the latest bracket (as is the case in Figs. 4.2), we accept the result. Otherwise, another round of bisection is applied.
(a)
(b)
Figure 4.3. Relabeling points after an iteration.
The next step is to relabel x as x 3 and rename the limits of the new interval x 1 and x 2 (x 1 < x 3 < x 2 ), as indicated in Figs. 4.3. We have now recovered the orig- inal sequencing of points in Figs. 4.2, but the interval (x 1 , x 2 ) containing the root
7 Brent, R. P., Algorithms for Minimization without Derivatives, Prentice-Hall, 1973.
has been reduced. This completes the first iteration cycle. In the next cycle an- other inverse quadratic interpolation is attempted and the process is repeated un-
til the convergence criterion |x − x 3 | < ε is satisfied, where ε is a prescribed error tolerance.
The inverse quadratic interpolation is carried out with Lagrange’s three-point interpolant described in Art. 3.2. Interchanging the roles of x and f , we have
(f−f 1 )( f − f 2 ) x( f ) =
(f−f 2 )( f − f 3 )
(f−f 1 )( f − f 3 )
1 −f 2 1 −f 3 2 −f 1 2 −f 3 (f 3 −f 1 )( f 3 −f 2 ) 3 Setting f = 0 and simplifying, we obtain for the estimate of the root
f 2 f 3 x 1 (f 2 −f 3 )+f 3 f 1 x 2 (f 3 −f 1 )+f 1 f 2 x 3 (f 1 −f 2 ) x = x(0) = − (f 1 −f 2 )( f 2 −f 3 )( f 3 −f 1 )
The change in the root is x 3 (f 1 −f 2 )( f 2 −f 3 +f 1 )+f 2 x 1 (f 2 −f 3 )+f 1 x 2 (f 3 −f 1 )
x=x−x 3 =f 3
(4.2) (f 2 −f 1 )( f 3 −f 1 )( f 2 −f 3 )
The function brent listed below is a simplified version of the algorithm proposed by Brent. It omits some of Brent’s safeguards against slow convergence; it also uses a less sophisticated convergence criterion.
function root = brent(func,a,b,tol) % Finds a root of f(x) = 0 by combining quadratic % interpolation with bisection (Brent’s method). % USAGE: root = brent(func,a,b,tol) % INPUT: % func = handle of function that returns f(x). % a,b
= limits of the interval containing the root.
% tol = error tolerance (default is 1.0e6*eps). % OUTPUT: % root = zero of f(x) (root = NaN if failed to converge).
if nargin < 4; tol = 1.0e6*eps; end % First step is bisection x1 = a; f1 = feval(func,x1); if f1 == 0; root = x1; return; end x2 = b; f2 = feval(func,x2); if f2 == 0; root = x2; return; end if nargin < 4; tol = 1.0e6*eps; end % First step is bisection x1 = a; f1 = feval(func,x1); if f1 == 0; root = x1; return; end x2 = b; f2 = feval(func,x2); if f2 == 0; root = x2; return; end
f3 = feval(func,x3); if abs(f3) < tol
root = x3; return end % Tighten brackets (a,b) on the root. if f1*f3 < 0.0; b = x3; else; a = x3; end if (b - a) < tol*max(abs(b),1.0)
root = 0.5*(a + b); return end % Try quadratic interpolation. denom = (f2 - f1)*(f3 - f1)*(f2 - f3); numer = x3*(f1 - f2)*(f2 - f3 + f1)...
+ f2*x1*(f2 - f3) + f1*x2*(f3 - f1); % If division by zero, push x out of bracket % to force bisection. if denom == 0; dx = b - a; else; dx = f3*numer/denom; end x = x3 + dx; % If interpolation goes out of bracket, use bisection. if (b - x)*(x - a) < 0.0
dx = 0.5*(b - a); x = a + dx; end % Let x3 <-- x & choose new x1, x2 so that x1 < x3 < x2. if x < x3
x2 = x3; f2 = f3; else x1 = x3; f1 = f3; end x3 = x;
end root = NaN;
EXAMPLE 4.4 Determine the root of f (x) = x 3 − 10x 2 + 5 = 0 that lies in (0.6, 0.8) with Brent’s
method.
Solution
Bisection The starting points are
x 1 = 0.6
f 3 1 2 = 0.6 − 10(0.6) + 5 = 1.616
f 2 = 0.8 3 − 10(0.8) 2 + 5 = −0.888 Bisection yields the point
x 2 = 0.8
x 3 = 0.7
f 3 = 0.7 3 − 10(0.7) 2 + 5 = 0.443 By inspecting the signs of f we conclude that the new brackets on the root are (x 3 , x 2 )=
(0.7, 0.8). First interpolation cycle Substituting the above values of x and f into the numer-
ator of the quotient in Eq. (4.2), we get num = x 3 (f 1 −f 2 )( f 2 −f 3 +f 1 )+f 2 x 1 (f 2 −f 3 )+f 1 x 2 (f 3 −f 1 )
and the denominator becomes
x=f 3 = 0.443
Since the result is within the established brackets, we accept it.
Relabel points As x > x 3 , the points are relabeled as illustrated in Figs. 4.2(b) and 4.3(b):
x 1 ←x 3 = 0.7
f 1 ←f 3 = 0.443 f 1 ←f 3 = 0.443
f 3 = 0.734 87 3 − 10(0.734 87) 2 + 5 = −0.00348 The new brackets on the root are (x 1 , x 3 ) = (0.7, 0.734 87).
Second interpolation cycle Applying the interpolation in Eq. (4.2) again, we obtain (skipping the arithmetical details)
x = −0.000 27 x=x 3
Again x falls within the latest brackets, so the result is acceptable. At this stage, x is correct to five decimal places.
EXAMPLE 4.5 Compute the zero of
f (x) = x |cos x| − 1
that lies in the interval (0, 4) with Brent’s method.
The plot of f (x) shows that this is a rather nasty function within the specified interval, containing a slope discontinuity and two local maxima. The sensible approach is to avoid the potentially troublesome regions of the function by bracketing the root as tightly as possible from a visual inspection of the plot. In this case, the interval (a, b) = (2.0, 2.2) would be a good starting point for Brent’s algorithm.
Is Brent’s method robust enough to handle the problem with the original brackets (0, 4)? Well, here is the MATLAB command and its output:
>> brent(@fex4 _ 5,0.0,4.0) ans =
The result was obtained after six iterations. The function defining f (x) is function y = fex4 _ 5(x)
% Function used in Example 4.5 y = x*abs(cos(x)) - 1.0;