Skip to content

Commit 1b06def

Browse files
Add files via upload
1 parent 0677548 commit 1b06def

File tree

1 file changed

+137
-0
lines changed

1 file changed

+137
-0
lines changed

Codes/Function_Optimization.py

Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
# Implementing the task
2+
# Optimization of smooth and non-smooth functions
3+
4+
5+
import numpy as np
6+
import matplotlib.pyplot as plt
7+
from scipy import optimize
8+
9+
10+
# Task 1 - smooth function
11+
# Initial smooth function
12+
# f(x) = sin(x / 5) * exp(x / 10) + 5 * exp(-x / 2)
13+
# Function returns array with 'y' results from input array of 'x' for plotting by using 'np' instead of 'math'
14+
def f_array(k):
15+
return np.sin(k / 5) * np.exp(k / 10) + 5 * np.exp(-k / 2)
16+
17+
18+
# Finding minimum of smooth function with 'BFGS' method
19+
# Setting initial point in form of 'ndarray' as 'minimize' function requires it in form of 'ndarray'
20+
x0_start = np.array([2])
21+
# print(type(x)) --> <class 'numpy.ndarray'>
22+
# print(x.shape) --> (1,)
23+
# Finding minimum of the function from starting point 'x_start = 2'
24+
# Using 'minimize' function from 'scipy.optimize' library
25+
y0_min = optimize.minimize(f_array, x0_start, method='BFGS')
26+
print(y0_min) # fun = 1.7452682903449388, iterations = 6
27+
print()
28+
29+
30+
# Setting initial point in form of 'ndarray' as 'minimize' function requires it in form of 'ndarray'
31+
x1_start = np.array([30])
32+
# print(type(x)) --> <class 'numpy.ndarray'>
33+
# print(x.shape) --> (1,)
34+
# Finding minimum of smooth function from starting point 'x_start = 30'
35+
# Using 'minimize' function from 'scipy.optimize' library
36+
y1_min = optimize.minimize(f_array, x1_start, method='BFGS')
37+
print(y1_min) # fun = -11.898894665981285, iterations = 6
38+
print()
39+
40+
41+
# Finding minimum of smooth function with 'differential evolution' method
42+
# Searching in the range [1, 30]
43+
# Setting the range for searching in form of tuple inside list as function requires it
44+
x2_range = [(1, 30)] # tuple inside list
45+
# Finding minimum of smooth function
46+
y2_min = optimize.differential_evolution(f_array, [(1, 30)])
47+
print(y2_min) # fun = -11.89889467, iterations = 5
48+
print()
49+
50+
51+
# Task 2 - non-smooth function
52+
# Initial non-smooth function
53+
# We take here the same function but only with integer results
54+
# By using 'np.int_' we return 'numpy.ndarray' of integer numbers
55+
def h_array(k):
56+
return np.int_(f_array(k))
57+
58+
59+
# Finding minimum of non-smooth function with 'BFGS' method
60+
# Setting initial point in form of 'ndarray' as 'minimize' function requires it in form of 'ndarray'
61+
x3_start = np.array([30])
62+
# print(type(x)) --> <class 'numpy.ndarray'>
63+
# print(x.shape) --> (1,)
64+
# Finding minimum of the function from starting point 'x_start = 30'
65+
# Using 'minimize' function from 'scipy.optimize' library
66+
y3_min = optimize.minimize(h_array, x3_start, method='BFGS')
67+
print(y3_min) # fun = -5, iterations = 0
68+
print()
69+
70+
# Finding minimum of non-smooth function with 'differential evolution' method
71+
# Searching in the range [1, 30]
72+
# Setting the range for searching in form of tuple inside list as function requires it
73+
x4_range = [(1, 30)] # tuple inside list
74+
# Finding minimum of smooth function
75+
y4_min = optimize.differential_evolution(h_array, [(1, 30)])
76+
print(y4_min) # fun = -11.0, iterations = 3
77+
print()
78+
79+
# Plotting smooth and non-smooth functions with found points
80+
# Creating a figure with subplots
81+
figure, ax = plt.subplots(nrows=1, ncols=2)
82+
# ax is (1, 2) np array and to make it easier to read we use 'flatten' function
83+
# Or we can call each time ax[0, 0]
84+
ax0, ax1 = ax.flatten()
85+
86+
# Preparing data for plotting smooth function
87+
# Creating list with numpy method 'arange'
88+
x0 = np.arange(1, 30, 0.1)
89+
y0 = f_array(x0)
90+
91+
# Plotting smooth function in range [1, 30]
92+
# Giving title to the figure and axises
93+
ax0.set_title('Smooth function f(x)')
94+
ax0.set_xlabel('x')
95+
ax0.set_ylabel('y')
96+
# Showing dashed lines to the found minimums
97+
# By defining 'ymax' or 'xmax' we limit the end of the lines
98+
# 'ymax' or 'xmax' can be in range between 0 and 1
99+
ax0.axvline(x=4.1362, ymax=0.85, color='c', linestyle='--', linewidth=0.8)
100+
ax0.axhline(y=1.7452, xmax=0.14, color='c', linestyle='--', linewidth=0.8)
101+
ax0.axvline(x=25.8801, ymax=0.05, color='r', linestyle='--', linewidth=0.8)
102+
ax0.axhline(y=-11.8988, xmax=0.83, color='r', linestyle='--', linewidth=0.8)
103+
# Another way to draw the limited line is as following:
104+
# ax0.plot(np.arange(1, 10, 2), np.array([2]*5)) # arrays fo axises 'x' and 'y' has to have the same dimensions
105+
# Creating the figure for smooth function
106+
ax0.plot(x0, y0, 'b', 4.1362, 1.7452, 'co', 25.8801, -11.8988, 'ro')
107+
108+
109+
# Preparing data for plotting non-smooth function
110+
# Creating list with numpy method 'arange'
111+
x1 = np.arange(1, 30, 0.1)
112+
y1 = h_array(x1)
113+
114+
# Plotting non-smooth function in range [1, 30]
115+
# Giving title to the figure and axises
116+
ax1.set_title('Non-smooth function h(int(f(x)))')
117+
ax1.set_xlabel('x')
118+
ax1.set_ylabel('y')
119+
# Showing dashed lines to the found minimum
120+
# By defining 'ymax' or 'xmax' we limit the end of the lines
121+
# 'ymax' or 'xmax' can be in range between 0 and 1
122+
ax1.axvline(x=25.0463, ymax=0.05, color='r', linestyle='--', linewidth=0.8)
123+
ax1.axhline(y=-11, xmax=0.85, color='r', linestyle='--', linewidth=0.8)
124+
ax1.axvline(x=30, ymax=0.43, color='c', linestyle='--', linewidth=0.8)
125+
ax1.axhline(y=-5, xmax=0.95, color='c', linestyle='--', linewidth=0.8)
126+
# Another way to draw the limited line is as following:
127+
# ax0.plot(np.arange(1, 10, 2), np.array([2]*5)) # arrays fo axises 'x' and 'y' has to have the same dimensions
128+
# Creating the figure for non-smooth function
129+
ax1.plot(x1, y1, 'b', 30, -5, 'co', 25.0463, -11.0, 'ro')
130+
131+
132+
# Function to make distance between figures
133+
plt.tight_layout()
134+
# Giving the name to the window with figures
135+
figure.canvas.set_window_title('Smooth and non-smooth functions to be optimized')
136+
# Showing result
137+
plt.show()

0 commit comments

Comments
 (0)