-
Notifications
You must be signed in to change notification settings - Fork 0
/
Max.py
93 lines (71 loc) · 2.83 KB
/
Max.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
# Python function that calculates the local extreme point of curvature (vortex)
# in a specified interval of a unimodal function.
# Simply change the target_function argument to the function
# you'd like to test and set the parameters of max_golden_search.
# ---WORKS ONLY FOR ONE VARIABLE FUNCTIONS----
# --- IT IS RECOMMENDED TO USE 'x' AS THE VARIABLE---
"""
# References
https://en.wikipedia.org/wiki/Golden-section_search
https://en.wikipedia.org/wiki/Vertex
"""
from matplotlib import pyplot as plt # import module to plot the result
import numpy as np
target_function = (
lambda x: x ** 3 - 6 * x ** 2 + 4 * x + 12
) # type the function of interest here
def max_golden_search(
func_to_max, upper: float, lower: float, tol: float = 1e-8
) -> float:
"""
Function in python that calculates the maximum
point of function in a specified interval
:param func_to_max : the function to maximize (target_function)
:param upper: upper boundary of interval
:param lower: lower boundary of interval
:param tol: set an appropriate tolerance value
:returns maximum of specified interval
>>> max_golden_search(target_function, -2, 4)
count = 43
0.3670068499227286
>>> max_golden_search(target_function, 'm', 4)
Traceback (most recent call last):
...
ValueError: give numerical values for upper, lower limits
"""
if type(upper) is str or type(lower) is str:
raise ValueError("give numerical values for upper, lower limits")
inv_gr = (np.sqrt(5) - 1) * 0.5 # ~ 0.618, this is the inverse golden ratio
d_max = (upper - lower) * inv_gr # # Sets initial value for d
q1 = lower + d_max # Sets initial value for q1
q2 = upper - d_max # and q2
count = 0 # Creates a count variable with initial value zero
while (
abs(upper - lower) > tol
): # Sets the tolerance condition. Will stop running once |u -l| < tol
if func_to_max(q1) > func_to_max(q2):
lower = q2
else:
upper = q1
d_max = (upper - lower) * inv_gr
q1 = lower + d_max
q2 = upper - d_max
count += 1 # Adds one to the count per iteration
print("count =", count) # Prints the count number
return (q1 + q2) * 0.5 # Returns the midpoint of the
# final interval as the maximum point in the range
max_point = max_golden_search(target_function, -2, 4)
def plot_point(
maximum_point: float = max_point,
x_axis_linspace: np.linspace = np.linspace(-5, 5, 200),
) -> None:
"""
Plots function and maximum point
"""
fmt = "bo" # format string for the color of the point
plt.plot(x_axis_linspace, target_function(x_axis_linspace))
plt.plot(maximum_point, target_function(maximum_point), fmt)
plt.show()
if __name__ == "__main__":
import doctest
doctest.testmod()