Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- def min_brent(func, a, b, tol=1e-5, max_iter=500, disp=False, trace=False):
- hist = {'x': [], 'f': [], 'n_evals': []}
- a, c = a, b
- K = (3 - 5 ** 0.5) / 2
- x = w = v = a + K * (c - a)
- fx = fw = fv = func(x)
- hist['n_evals'].append(1)
- d = e = c - a
- I = np.zeros(max_iter + 1)
- I[0] = c - a
- u = 0
- for i in range(max_iter):
- g, e = e, d
- t = tol * abs(x) + tol / 10.
- if abs(x - (a + c) / 2) + (c - a) / 2 <= 2 * t:
- return get_result(hist, 0, trace)
- parabolic_flag = True
- if abs(x - v) > tol and abs(x - w) > tol \
- and abs(v - w) > tol and abs(fx - fw) > tol \
- and abs(fx - fv) > tol and abs(fw - fv) > tol:
- u = get_min_parabolas(fx, fv, fw, x, v, w)
- if a <= u <= c and abs(u - x) < g / 2.:
- if u - a < 2 * t or c - u < 2 * t:
- u = x - np.sign(x - (a + c) / 2) * t
- else:
- parabolic_flag = False
- else:
- parabolic_flag = False
- if not parabolic_flag:
- if x < (a + c) / 2:
- u = x + K * (c - x)
- e = c - x
- else:
- u = x - K * (x - a)
- e = x - a
- if abs(x - u) < t:
- u = x + np.sign(u - x) * t
- d = abs(u - x)
- fu = func(u)
- hist['x'].append(u)
- hist['f'].append(fu)
- if disp:
- if parabolic_flag:
- print("{0} iteration, interval's length = {1}, function's min = {2}, parabolic".format(*(i + 1, I[i], hist['f'][-1])))
- else:
- print("{0} iteration, interval's length = {1}, function's min = {2}, golden".format(*(i + 1, I[i], hist['f'][-1])))
- hist['n_evals'].append(hist['n_evals'][-1] + 1)
- if fu <= fx:
- if u >= x:
- a = x
- else:
- c = x
- v, w, x, fv, fw, fx = w, x, u, fw, fx, fu
- else:
- if u >= x:
- c = u
- else:
- a = u
- if fu <= fw or abs(x - w) <= tol:
- v, w, fv, fw = w, u, fw, fu
- elif fu <= fv or abs(v - x) <= tol or abs(v - w) <= tol:
- v, fv = u, fu
- I[i + 1] = c - a
- return get_result(hist, 1, trace)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement