2323
2424
2525def brent_method (
26- f : Callable [[float ], float ],
27- a : float ,
28- b : float ,
26+ func : Callable [[float ], float ],
27+ left_bound : float ,
28+ right_bound : float ,
2929 tol : float = 1e-7 ,
3030 max_iter : int = 100 ,
3131) -> float :
3232 """
3333 Find a root of the function f in the interval [a, b] using Brent's method.
3434
3535 Args:
36- f : The function for which we are trying to find a root.
37- a : The start of the interval.
38- b : The end of the interval.
36+ func : The function for which we are trying to find a root.
37+ left_bound : The start of the interval.
38+ right_bound : The end of the interval.
3939 tol: The allowed error of the result.
4040 max_iter: Maximum number of iterations.
4141
@@ -46,55 +46,57 @@ def brent_method(
4646 ValueError: If f(a) and f(b) do not have opposite signs.
4747 RuntimeError: If the root is not found within max_iter iterations.
4848 """
49- fa = f ( a )
50- fb = f ( b )
49+ fa = func ( left_bound )
50+ fb = func ( right_bound )
5151 if fa * fb >= 0 :
5252 raise ValueError ("f(a) and f(b) must have different signs" )
5353
5454 if abs (fa ) < abs (fb ):
55- a , b = b , a
55+ left_bound , right_bound = right_bound , left_bound
5656 fa , fb = fb , fa
5757
58- c , fc = a , fa
59- d = e = b - a
58+ c , fc = left_bound , fa
59+ d = e = right_bound - left_bound
6060
6161 for _ in range (max_iter ):
6262 if fb == 0 :
63- return b
63+ return right_bound
6464 if fc not in (fa , fb ):
6565 # Inverse quadratic interpolation
6666 s = (
67- a * fb * fc / ((fa - fb ) * (fa - fc ))
68- + b * fa * fc / ((fb - fa ) * (fb - fc ))
67+ left_bound * fb * fc / ((fa - fb ) * (fa - fc ))
68+ + right_bound * fa * fc / ((fb - fa ) * (fb - fc ))
6969 + c * fa * fb / ((fc - fa ) * (fc - fb ))
7070 )
7171 else :
7272 # Secant Method
73- s = b - fb * (b - a ) / (fb - fa )
73+ s = right_bound - fb * (right_bound - left_bound ) / (fb - fa )
7474
7575 conditions = [
76- not ((3 * a + b ) / 4 < s < b ) if b > a else not (b < s < (3 * a + b ) / 4 ),
77- (e is not None and abs (s - b ) >= abs (e / 2 )),
76+ not ((3 * left_bound + right_bound ) / 4 < s < right_bound )
77+ if right_bound > left_bound
78+ else not (right_bound < s < (3 * left_bound + right_bound ) / 4 ),
79+ (e is not None and abs (s - right_bound ) >= abs (e / 2 )),
7880 (d is not None and abs (d ) >= abs (e / 2 )),
79- abs (b - a ) < tol ,
81+ abs (right_bound - left_bound ) < tol ,
8082 ]
8183 if any (conditions ):
82- s = (a + b ) / 2 # Bisection method
83- e = d = b - a
84+ s = (left_bound + right_bound ) / 2 # Bisection method
85+ e = d = right_bound - left_bound
8486 else :
8587 d = e
86- e = b - s
88+ e = right_bound - s
8789
88- fs = f (s )
89- c , fc = b , fb
90+ fs = func (s )
91+ c , fc = right_bound , fb
9092 if fa * fs < 0 :
91- b , fb = s , fs
93+ right_bound , fb = s , fs
9294 else :
93- a , fa = s , fs
95+ left_bound , fa = s , fs
9496 if abs (fa ) < abs (fb ):
95- a , b = b , a
97+ left_bound , right_bound = right_bound , left_bound
9698 fa , fb = fb , fa
97- if abs (b - a ) < tol :
98- return b
99+ if abs (right_bound - left_bound ) < tol :
100+ return right_bound
99101
100102 raise RuntimeError ("Maximum number of iterations reached without convergence" )
0 commit comments