Brent's method

Brent's method

In numerical analysis, Brent's method is a complicated but popular root-finding algorithm combining the bisection method, the secant method and inverse quadratic interpolation. It has the reliability of bisection but it can be as quick as some of the less reliable methods. The idea is to use the secant method or inverse quadratic interpolation if possible, because they converge faster, but to fall back to the more robust bisection method if necessary. Brent's method is due to Richard Brent (1973) and builds on an earlier algorithm of Theodorus Dekker (1969).

Jack Crenshaw says a variation on Brent's method -- one that alternates between bisection and attempting inverse quadratic interpolation -- is the best root finder he has found. [ [http://www.embedded.com/columns/programmerstoolbox/18901336?_requestid=141832 "A root-finding algorithm"] by Jack W. Crenshaw, "Embedded Systems Design" 2004]

A variation on Brent's method was implemented in one of the first available software libraries. [ [http://www.embedded.com/story/OEG20030508S0030 "A root finder's roots"] by Jack W. Crenshaw, "Embedded Systems Design" 2003]

Dekker's method

The idea to combine the bisection method with the secant method goes back to Dekker.

Suppose that we want to solve the equation "f"("x") = 0. As with the bisection method, we need to initialize Dekker's method with two points, say "a"0 and "b"0, such that "f"("a"0) and "f"("b"0) have opposite signs. If "f" is continuous on ["a"0, "b"0] , the intermediate value theorem guarantees the existence of a solution between "a"0 and "b"0.

Three points are involved in every iteration:
* "b""k" is the current iterate, i.e., the current guess for the root of "f".
* "a""k" is the "contrapoint," i.e., a point such that "f"("a""k") and "f"("b""k") have opposite signs, so the interval ["a""k", "b""k"] contains the solution. Furthermore, |"f"("b""k")| should be less than or equal to |"f"("a""k")|, so that "b""k" is a better guess for the unknown solution than "a""k".
* "b""k"−1 is the previous iterate (for the first iteration, we set "b"−1 = "a"0).

Two provisional values for the next iterate are computed. The first one is given by the secant method:: s = b_k - frac{b_k-b_{k-1{f(b_k)-f(b_{k-1})} f(b_k), and the second one is given by the bisection method: m = frac{a_k+b_k}{2}. If the result of the secant method, "s", lies between "b""k" and "m", then it becomes the next iterate ("b""k"+1 = "s"), otherwise the midpoint is used ("b""k"+1 = "m").

Then, the value of the new contrapoint is chosen such that "f"("a""k"+1) and "f"("b""k"+1) have opposite signs. If "f"("a""k") and "f"("b""k"+1) have opposite signs, then the contrapoint remains the same: "a""k"+1 = "a""k". Otherwise, "f"("b""k"+1) and "f"("b""k") have opposite signs, so the new contrapoint becomes "a""k"+1 = "b""k".

Finally, if |"f"("a""k"+1)| < |"f"("b""k"+1)|, then "a""k"+1 is probably a better guess for the solution than "b""k"+1, and hence the values of "a""k"+1 and "b""k"+1 are exchanged.

This ends the description of a single iteration of Dekker's method.

Brent's method

Dekker's method performs well if the function "f" is reasonably well-behaved. However, there are circumstances in which every iteration employs the secant method, but the iterates "b""k" converge very slowly (in particular, |"b""k" − "b""k"−1| may be arbitrarily small). Dekker's method requires far more iterations than the bisection method in this case.

Brent proposed a small modification to avoid this problem. He inserted an additional test which must be satisfied before the result of the secant method is accepted as the next iterate. Two inequalities must be simultaneously satisfied:
* given a specific numerical tolerance delta, if the previous step used the bisection method, the inequality:: |delta| < |b_k - b_{k-1}| :must hold, otherwise the bisection method is performed and its result used for the next iteration. If the previous step performed interpolation, then the inequality:: |delta| < |b_{k-1} - b_{k-2}| :is used instead.
* Also, if the previous step used the bisection method, the inequality:: |s-b_k| < egin{matrix} frac12 end{matrix} |b_k - b_{k-1}|:must hold, otherwise the bisection method is performed and its result used for the next iteration. If the previous step performed interpolation, then the inequality:: |s-b_k| < egin{matrix} frac12 end{matrix} |b_{k-1} - b_{k-2}|:is used instead.This modification ensures that at the kth iteration, a bisection step will be performed in at most 2log_2(|b_{k-1}-b_{k-2}|/delta) additional iterations, because the above conditions force consecutive interpolation step sizes to halve every two iterations, and after at most 2log_2(|b_{k-1}-b_{k-2}|/delta) iterations, the step size will be smaller than delta, which invokes a bisection step. Brent proved that his method requires at most "N"2 iterations, where "N" denotes the number of iterations for the bisection method. If the function "f" is well-behaved, then Brent's method will usually proceed by either inverse quadratic or linear interpolation, in which case it will converge superlinearly.

Furthermore, Brent's method uses inverse quadratic interpolation instead of linear interpolation (as used by the secant method) if "f"("b""k"), "f"("a""k") and "f"("b""k"−1) are distinct. This slightly increases the efficiency. As a consequence, the condition for accepting "s" (the value proposed by either linear interpolation or inverse quadratic interpolation) has to be changed: "s" has to lie between (3"a""k" + "b""k") / 4 and "b""k".

Example

Suppose that we are seeking a zero of the function defined by "f"("x") = ("x" + 3)("x" − 1)2. We take ["a"0, "b"0] = [−4, 4/3] as our initial interval. We have "f"("a"0) = −25 and "f"("b"0) = 0.48148 (all numbers in this section are rounded), so the conditions "f"("a"0) "f"("b"0) < 0 and |"f"("b"0)| &le; |"f"("a"0)| are satisfied.

# In the first iteration, we use linear interpolation between ("b"−1, "f"("b"−1)) = ("a"0, "f"("a"0)) = (−4, −25) and ("b"0, "f"("b"0)) = (1.33333, 0.48148), which yields "s" = 1.23256. This lies between (3"a"0 + "b"0) / 4 and "b"0, so this value is accepted. Furthermore, "f"(1.23256) = 0.22891, so we set "a"1 = "a"0 and "b"1 = "s" = 1.23256.
# In the second iteration, we use inverse quadratic interpolation between ("a"1, "f"("a"1)) = (−4, −25) and ("b"0, "f"("b"0)) = (1.33333, 0.48148) and ("b"1, "f"("b"1)) = (1.23256, 0.22891). This yields 1.14205, which lies between (3"a"1 + "b"1) / 4 and "b"1. Furthermore, the inequality |1.14205 − "b"1| &le; |"b"0 − "b"−1| / 2 is satisfied, so this value is accepted. Furthermore, "f"(1.14205) = 0.083582, so we set "a"2 = "a"1 and "b"2 = 1.14205.
# In the third iteration, we use inverse quadratic interpolation between ("a"2, "f"("a"2)) = (−4, −25) and ("b"1, "f"("b"1)) = (1.23256, 0.22891) and ("b"2, "f"("b"2)) = (1.14205, 0.083582). This yields 1.09032, which lies between (3"a"2 + "b"2) / 4 and "b"2. But here Brent's additional condition kicks in: the inequality |1.09032 − "b"2| &le; |"b"1 − "b"0| / 2 is not satisfied, so this value is rejected. Instead, the midpoint "m" = −1.42897 of the interval ["a"2, "b"2] is computed. We have "f"("m") = 9.26891, so we set "a"3 = "a"2 and "b"3 = −1.42897.
# In the fourth iteration, we use inverse quadratic interpolation between ("a"3, "f"("a"3)) = (−4, −25) and ("b"2, "f"("b"2)) = (1.14205, 0.083582) and ("b"3, "f"("b"3)) = (−1.42897, 9.26891). This yields 1.15448, which is not in the interval between (3"a"3 + "b"3) / 4 and "b"3). Hence, it is replaced by the midpoint "m" = −2.71449. We have "f"("m") = 3.93934, so we set "a"4 = "a"3 and "b"4 = −2.71449.
# In the fifth iteration, inverse quadratic interpolation yields −3.45500, which lies in the required interval. However, the previous iteration was a bisection step, so the inequality |−3.45500 − "b"4| &le; |"b"4 − "b"3| / 2 need to be satisfied. This inequality is false, so we use the midpoint "m" = −3.35724. We have "f"("m") = −6.78239, so "m" becomes the new contrapoint ("a"5 = −3.35724) and the iterate remains the same ("b"5 = "b"4).
# In the sixth iteration, we cannot use inverse quadratic interpolation because "b"5 = "b"4. Hence, we use linear interpolation between ("a"5, "f"("a"5)) = (−3.35724, −6.78239) and ("b"5, "f"("b"5)) = (−2.71449, 3.93934). The result is "s" = −2.95064, which satisfies all the conditions. We calculate "f"("s") = 0.77032, so we set "a"6 = "a"5 and "b"6 = −2.95064.
# In the seventh iteration, we can again use inverse quadratic interpolation. The result is "s" = −3.00219, which satisfies all the conditions. Now, "f"("s") = −0.03515, so we set "a"7 = "b"6 and "b"7 = −3.00219 ("a"7 and "b"7 are exchanged so that the condition |"f"("b"7)| &le; |"f"("a"7)| is satisfied).
# In the eighth iteration, we cannot use inverse quadratic interpolation because "a"7 = "b"6. Linear interpolation yields "s" = −2.99994, which is accepted.
# In the following iterations, the root "x" = −3 is approached rapidly: "b"9 = −3 + 6&middot;10−8 and "b"10 = −3 − 3&middot;10−15.

Algorithm

* input "a", "b", and a pointer to a subroutine for "f"
* calculate "f"("a")
* calculate "f"("b")
* if "f"("a") "f"("b") >= 0 then error-exit end if
* if |"f"("a")| < |"f"("b")| then swap ("a","b") end if
* "c" := "a"
* set mflag
* repeat until "f"("b") = 0 or |"b" − "a"| is small enough "(convergence)"
** if "f"("a") &ne; "f"("c") and "f"("b") &ne; "f"("c") then
*** s := frac{af(b)f(c)}{(f(a)-f(b))(f(a)-f(c))} + frac{bf(a)f(c)}{(f(b)-f(a))(f(b)-f(c))} + frac{cf(a)f(b)}{(f(c)-f(a))(f(c)-f(b))} "(inverse quadratic interpolation)"
** else
*** s := b - f(b) frac{b-a}{f(b)-f(a)} "(secant rule)"
** end if
** if "s" is not between (3"a" + "b")/4 and "b" or (mflag is set and |"s"−"b"| ≥ |"b"−"c"| / 2) or (mflag is cleared and |"s"−"b"| ≥ |"c"−"d"| / 2) then
*** s := frac{a+b}{2}
*** set mflag
** else
*** if (mflag is set and |"b"−"c"| < |delta|) or (mflag is cleared and |"c"−"d"| < |delta|) then
**** s := frac{a+b}{2}
**** set mflag
*** else
**** clear mflag
*** end if
** end if
** calculate "f"("s")
** "d" := "c"
** "c" := "b"
** if "f"("a") "f"("s") < 0 then "b" := "s" else "a" := "s" end if
** if |"f"("a")| < |"f"("b")| then swap ("a","b") end if
* end repeat
* output "b" "(return the root)"

Implementations

Brent (1973) published an Algol 60 implementation. Netlib contains a Fortran translation of this implementation with slight modifications. The MATLAB function fzero also implements Brent's method, as does the PARI/GP method solve. Other implementations of the algorithm (in C++, C, and Fortran) can be found in the Numerical Recipes books.

References

* Atkinson (1989). "An Introduction to Numerical Analysis" (2nd ed.), Section 2.8. John Wiley and Sons. ISBN 0-471-50023-2.
* R.P. Brent (1973). "Algorithms for Minimization without Derivatives," Chapter 4. Prentice-Hall, Englewood Cliffs, NJ. ISBN 0-13-022335-2.
* T.J. Dekker (1969). "Finding a zero by means of successive linear interpolation." In B. Dejon and P. Henrici (eds), "Constructive Aspects of the Fundamental Theorem of Algebra", Wiley-Interscience, London. SBN 471-28300-9.

External links

* [http://www.netlib.org/go/zeroin.f zeroin.f] at Netlib.
* [http://math.fullerton.edu/mathews/n2003/BrentMethodMod.html Module for Brent's Method] by John H. Mathews


Wikimedia Foundation. 2010.

Игры ⚽ Поможем решить контрольную работу

Look at other dictionaries:

  • Brent (disambiguation) — For the origin of the name see Brent Articles on Brent include:Place names*the London Borough of Brent *the River Brent which runs through the Boroughs of Barnet, Brent, Ealing and Hounslow. *the Brent oilfield (named after the goose) in the… …   Wikipedia

  • Brent Spar — or Brent E, was a North Sea oil storage and tanker loading buoy in the Brent oilfield, operated by Shell UK. With the completion of a pipeline connection to the oil terminal at Sullom Voe in Shetland, the storage facility had continued in use but …   Wikipedia

  • Method Fest Independent Film Festival — Method Fest International Film Festival Location Calabasas, California, U.S. Language International Official website Method Fest Independent Film Festival is an independent film festival that has cu …   Wikipedia

  • Méthode de Brent — En analyse numérique, la méthode de Brent est un algorithme de recherche d un zéro d une fonction combinant la méthode de dichotomie, la méthode de la sécante et l’interpolation quadratique inverse. À chaque itération, elle décide laquelle de ces …   Wikipédia en Français

  • Methode de Brent — Méthode de Brent En analyse numérique, la méthode de Brent est un algorithme de recherche d un zéro d une fonction combinant la méthode de dichotomie, la méthode de la sécante et l’interpolation quadratique inverse. À chaque itération, elle… …   Wikipédia en Français

  • Méthode De Brent — En analyse numérique, la méthode de Brent est un algorithme de recherche d un zéro d une fonction combinant la méthode de dichotomie, la méthode de la sécante et l’interpolation quadratique inverse. À chaque itération, elle décide laquelle de ces …   Wikipédia en Français

  • Méthode de brent — En analyse numérique, la méthode de Brent est un algorithme de recherche d un zéro d une fonction combinant la méthode de dichotomie, la méthode de la sécante et l’interpolation quadratique inverse. À chaque itération, elle décide laquelle de ces …   Wikipédia en Français

  • Richard Brent (scientist) — Richard Peirce Brent is an Australian mathematician and computer scientist, born in 1946. As of October 2005 he is an ARC Federation Fellow at the Australian National University. His research interests include number theory (in particular… …   Wikipedia

  • Bisection method — A few steps of the bisection method applied over the starting range [a1;b1]. The bigger red dot is the root of the function. The bisection method in mathematics is a root finding method which repeatedly bisects an interval and then selects a… …   Wikipedia

  • Ridders' method — In numerical analysis, Ridders method is a root finding algorithm based on the false position method and the use of an exponential function to successively approximate a root of a function f .Ridders method is simpler than Brent s method but… …   Wikipedia

Share the article and excerpts

Direct link
Do a right-click on the link above
and select “Copy Link”