yunusk commited on
Commit
b7695e7
·
1 Parent(s): 0abbb50

Web ui with streamlit. requirements.txt added. Some minor updates.

Browse files
Files changed (7) hide show
  1. .gitignore +1 -0
  2. README.md +13 -0
  3. app.py +105 -0
  4. app_utils.py +23 -0
  5. requirements.txt +6 -0
  6. src/functions.py +5 -5
  7. src/main.py +117 -59
.gitignore CHANGED
@@ -1,4 +1,5 @@
1
  src/__pycache__/
 
2
  deneme.py
3
  results/*.png
4
  results/*.txt
 
1
  src/__pycache__/
2
+ __pycache__
3
  deneme.py
4
  results/*.png
5
  results/*.txt
README.md CHANGED
@@ -64,6 +64,19 @@ An example script (Runs adaptive hdmr): `python src/main.py --numSamples 1000 --
64
 
65
  If adaptive parameter is set, the output file will be additional parameters and will be starting with 'adaptive' key.
66
 
 
 
 
 
 
 
 
 
 
 
 
 
 
67
 
68
 
69
 
 
64
 
65
  If adaptive parameter is set, the output file will be additional parameters and will be starting with 'adaptive' key.
66
 
67
+ # Web UI Update
68
+ After you install all dependencies inside of the `requirements.txt` you can run the following code to run web ui on your browser.
69
+
70
+ You should be inside of the main folder. (Should be seeing results, src folder etc.)
71
+ 1. Open the terminal in this folder.
72
+ 2. Run `streamlit run app`
73
+
74
+ This basically runs the `app.py` which is the streamlit app folder. You can find the ui elements inside of this file.
75
+
76
+ As default it runs the app on the `http://localhost:8501/`
77
+
78
+ **NOTE:** 10d functions are currently disabled due to some errors on the presentation. They will be enabled with the next update.
79
+
80
 
81
 
82
 
app.py ADDED
@@ -0,0 +1,105 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import matplotlib.pyplot as plt
3
+ import src.main as main
4
+ import app_utils as utils
5
+
6
+ st.set_page_config(
7
+ page_title="HDMR-Opt",
8
+ page_icon=":tada:",
9
+ layout="wide"
10
+ )
11
+
12
+ st.markdown(
13
+ """
14
+ <style>
15
+ [data-testid="stSidebar"][aria-expanded="true"]{
16
+ min-width: 300px;
17
+ max-width: 400px;
18
+ }
19
+ """,
20
+ unsafe_allow_html=True,
21
+ )
22
+
23
+ # Header
24
+ page_text = """
25
+ This repository contains the codes to calculate global minimum points of the given functions.
26
+ In this code, we use two method to optimize and compare. In hdmr-opt method,
27
+ We get the one dimensional form of the given functions using HDMR. In other method,
28
+ we directly apply BFGS method to the function.
29
+ """
30
+ with st.container():
31
+ # st.subheader("HDMR Optimization")
32
+ st.title("HDMR Optimization")
33
+ st.write(page_text)
34
+
35
+ available_functions = ["testfunc_2d", "camel3_2d", "camel16_2d", "treccani_2d", "goldstein_2d", "branin_2d",
36
+ "rosenbrock_2d", "ackley_2d"]
37
+
38
+ # available_functions = ["testfunc_2d", "camel3_2d", "camel16_2d", "treccani_2d", "goldstein_2d", "branin_2d",
39
+ # "rosenbrock_2d", "ackley_2d", "rosenbrock_10d", "griewank_10d", "rastrigin_10d"]
40
+
41
+ st.sidebar.header('User Inputs')
42
+
43
+ interactive_plot = st.sidebar.checkbox("Interactive Plot")
44
+
45
+ N = st.sidebar.slider("Number of samples:", 100, 10000, 1000, 100)
46
+
47
+ # n = st.sidebar.slider("Number of variables: ", 1, 10, 2, 1)
48
+ function_name = st.sidebar.selectbox("Test function:", available_functions)
49
+ legendreDegree = st.sidebar.slider("Legendre Degree:", 1, 20, 7, 1)
50
+
51
+ st.sidebar.write("Function interval: ")
52
+ col1, col2 = st.sidebar.columns(2)
53
+ interval = utils.get_function_interval(function_name=function_name.split('_')[0])
54
+ with col1:
55
+ st.number_input("Min: ", value=interval[0], format="%.3f", step=1.0)
56
+ with col2:
57
+ st.number_input("Max: ", value=interval[1], format="%.3f", step=1.0)
58
+
59
+
60
+ random_init = st.sidebar.checkbox("Random Initialization")
61
+ st.sidebar.caption("Default is 0 initialization")
62
+
63
+ is_adaptive = st.sidebar.checkbox("Adaptive HDMR")
64
+
65
+ if is_adaptive:
66
+ num_closest_points = st.sidebar.number_input("Number of closest points:", 1, N, 100)
67
+ epsilon = st.sidebar.number_input("Epsilon:", value=0.1, min_value=0.0, step=0.1)
68
+ clip = st.sidebar.number_input("Clip:", 0.05, 1.0, 0.9, 0.05)
69
+
70
+ if st.sidebar.button("Calculate HDMR"):
71
+
72
+ n = utils.get_dims(function_name)
73
+ print("n is: ", n)
74
+
75
+ main.is_streamlit = interactive_plot
76
+ if is_adaptive:
77
+ status_hdmr, plt1, plt2, file_name = main.main_function(N, n, function_name, legendreDegree, interval[0], interval[1],
78
+ random_init, is_adaptive, num_closest_points, epsilon, clip)
79
+ else:
80
+ status_hdmr, plt1, plt2, file_name = main.main_function(N, n, function_name, legendreDegree, interval[0], interval[1],
81
+ random_init, is_adaptive)
82
+ st.subheader("Results")
83
+ st.write(f"hdmr_opt status Success: {status_hdmr.success} - X: {status_hdmr.x}")
84
+
85
+ with st.expander("Click to see the full result", expanded=False):
86
+ st.write(status_hdmr)
87
+
88
+ st.subheader("Plots")
89
+
90
+ if interactive_plot:
91
+ col3, col4 = st.columns(spec=[0.4, 0.6], gap='small')
92
+ else:
93
+ col3, col4 = st.columns(spec=2, gap='small')
94
+
95
+ with col3:
96
+ st.pyplot(plt1)
97
+ with col4:
98
+ if interactive_plot:
99
+ st.plotly_chart(plt2)
100
+ else:
101
+ st.pyplot(plt2)
102
+
103
+
104
+
105
+
app_utils.py ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ default_function_intervals = {
2
+ "testfunc": (-5.0, 5.0),
3
+ "camel3": (-5.0, 5.0),
4
+ "camel16": (-5.0, 5.0),
5
+ "treccani": (-5.0, 5.0),
6
+ "goldstein": (-2.0, 2.0),
7
+ "branin": (-5.0, 15.0),
8
+ "rosenbrock": (-2.048, 2.048),
9
+ "ackley": (-30.0, 30.0),
10
+ "griewank": (-600.0, 600.0),
11
+ "rastrigin": (-5.12, 5.12)
12
+ }
13
+
14
+ def get_function_interval(function_name):
15
+ try:
16
+ interval = default_function_intervals[function_name]
17
+ except:
18
+ raise KeyError("You have entered non existing funtion name.")
19
+
20
+ return interval
21
+
22
+ def get_dims(function_name):
23
+ return int(function_name.split('_')[1][:-1])
requirements.txt ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ matplotlib==3.5.2
2
+ numpy==1.21.5
3
+ pandas==1.4.4
4
+ plotly==5.9.0
5
+ scipy==1.9.1
6
+ streamlit==1.24.1
src/functions.py CHANGED
@@ -28,8 +28,8 @@ def camel16_2d(X):
28
  X = np.array([X])
29
  return (4*X[:, 0]**2 - 2.1*X[:, 0]**4 + (X[:, 0]**6)/3 + X[:, 0]*X[:, 1] - 4*X[:, 1]**2 + 4*X[:, 1]**4).reshape(-1, 1)
30
 
31
- # 2d Trecanni
32
- def trecanni_2d(X):
33
  try:
34
  X.shape[1]
35
  except:
@@ -119,9 +119,9 @@ if __name__ == "__main__":
119
  # Evaluate the function based on the provided name
120
  f = globals().get(function_name)
121
 
122
- if f == camel3_2d or f == camel16_2d or f == trecanni_2d:
123
- x1_min = x2_min = -3
124
- x1_max = x2_max = 3
125
  elif f == goldstein_2d:
126
  x1_min = x2_min = -2
127
  x1_max = x2_max = 2
 
28
  X = np.array([X])
29
  return (4*X[:, 0]**2 - 2.1*X[:, 0]**4 + (X[:, 0]**6)/3 + X[:, 0]*X[:, 1] - 4*X[:, 1]**2 + 4*X[:, 1]**4).reshape(-1, 1)
30
 
31
+ # 2d Treccani
32
+ def treccani_2d(X):
33
  try:
34
  X.shape[1]
35
  except:
 
119
  # Evaluate the function based on the provided name
120
  f = globals().get(function_name)
121
 
122
+ if f == camel3_2d or f == camel16_2d or f == treccani_2d:
123
+ x1_min = x2_min = -5
124
+ x1_max = x2_max = 5
125
  elif f == goldstein_2d:
126
  x1_min = x2_min = -2
127
  x1_max = x2_max = 2
src/main.py CHANGED
@@ -3,7 +3,10 @@ import numpy as np
3
  import math
4
  import matplotlib.pyplot as plt
5
  import pandas as pd
6
- import functions as f
 
 
 
7
  import argparse
8
 
9
  """
@@ -11,6 +14,8 @@ Test functions are available in https://www.sfu.ca/~ssurjano/optimization.html
11
 
12
  """
13
 
 
 
14
 
15
  def rastrigin(x):
16
  if len(x.shape) == 2:
@@ -58,6 +63,7 @@ def hdmr_opt(fun, x0, args=(), jac=None, callback=None,
58
  gtol=1e-5, maxiter=None,
59
  disp=False, return_all=False, finite_diff_rel_step=None,
60
  **unknown_options):
 
61
 
62
  def Pn(m, x):
63
  if m == 0:
@@ -104,8 +110,6 @@ def hdmr_opt(fun, x0, args=(), jac=None, callback=None,
104
  return f
105
 
106
  def plot_results():
107
- a = a_
108
- b = b_
109
  f = np.zeros((N,n))
110
  y = fun(xs)
111
  for idx in range(n):
@@ -139,22 +143,56 @@ def hdmr_opt(fun, x0, args=(), jac=None, callback=None,
139
  axs[jj-1, 0].legend()
140
  axs[jj-1, 1].legend()
141
  plt.subplots_adjust(hspace=0.6, wspace=0.3)
142
- plt.savefig(file_name + '.png')
143
 
144
  def plot_with_function():
145
- a = a_
146
- b = b_
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
147
  Y = fun(xs)
148
  yhat = evalute_hdmr(xs, np.mean(Y, axis=0), alpha)
149
 
150
  X1, X2 = zip(*xs)
151
  fig = plt.figure(figsize=(8, n*4))
152
  ax = fig.add_subplot(111, projection='3d')
153
-
154
  # Scatter plot
155
 
156
  # ax.scatter(X1, X2, Y, c='r', marker='o', alpha=0.6)
157
- ax.scatter(X1, X2, yhat, c='b', marker='o', alpha=0.6)
158
  x1_min, x1_max = np.array((np.min(X1), np.max(X1)))
159
  x2_min, x2_max = np.array((np.min(X2), np.max(X2)))
160
 
@@ -166,7 +204,7 @@ def hdmr_opt(fun, x0, args=(), jac=None, callback=None,
166
  x1, x2 = np.meshgrid(x1, x2)
167
  y = fun(np.column_stack((x1.ravel(), x2.ravel()))).reshape(x1.shape)
168
 
169
- ax.plot_surface(x1, x2, y, cmap='jet', alpha=0.5)
170
 
171
  # Limit the Y axis so scatter is easier to see.
172
  # ax.set_zlim(np.min(yhat), np.max(yhat))
@@ -175,7 +213,7 @@ def hdmr_opt(fun, x0, args=(), jac=None, callback=None,
175
  ax.set_xlabel('X1')
176
  ax.set_ylabel('X2')
177
  ax.set_zlabel('y')
178
- plt.show()
179
 
180
 
181
  def calculate_distances(x0, arr):
@@ -260,8 +298,8 @@ def hdmr_opt(fun, x0, args=(), jac=None, callback=None,
260
  old_b = new_b
261
  a_ = new_a
262
  b_ = new_b
263
- plot_results()
264
- plot_with_function()
265
  else:
266
  a_ = a
267
  b_ = b
@@ -269,79 +307,99 @@ def hdmr_opt(fun, x0, args=(), jac=None, callback=None,
269
  print('XS: ', xs.shape)
270
  alpha = calculate_alpha_coeff(xs)
271
  print("Alpha: ", alpha)
272
- plot_results()
273
  temp_status = []
274
  for i in range(n):
275
  status = minimize(one_dim_evaluate_hdmr, np.array(x0[i]), method='BFGS')
276
  temp_status.append(status.x[0])
277
  result = OptimizeResult(x=temp_status, fun=fun(x0, *args), success=True, message=" ", nfev=1, njev=0, nhev=0)
278
  result.nfev = N
279
- plot_with_function()
 
280
 
281
  return result
282
 
 
 
 
 
 
 
 
 
 
 
 
283
 
284
- parser = argparse.ArgumentParser(
285
- prog='HDMR',
286
- description='Program applies the hdmr-opt method and plots the results.')
287
- parser.add_argument('--numSamples', type=int, help='Number of samples to calculate alpha coefficients.', required=True)
288
- parser.add_argument('--numVariables', type=int, help='Number of variable of the test function.', required=True)
289
- parser.add_argument('--function', help='Test function name.', required=True)
290
- parser.add_argument('--min', type=float, help='Lower range of the test function.', required=True)
291
- parser.add_argument('--max', type=float, help='Upper range of the test function.', required=True)
292
- parser.add_argument('--randomInit', action='store_true', help='Initializes x0 as random numbers in the range of xs. Default is initializing as 0.')
293
- parser.add_argument('--legendreDegree', type=int, default=7, help='Number of legendre polynomial. Default is 7.')
294
- parser.add_argument('--adaptive', action='store_true', help='Uses iterative method when set.')
295
- parser.add_argument('--numClosestPoints', type=int, help='Number of closest points to x0. Default is 1000.', default=100)
296
- parser.add_argument('--epsilon', type=float, help='Epsilon value for convergence. Default is 0.1.', default=0.1)
297
- parser.add_argument('--clip', type=float, help='Clipping value for updating interval (a, b). Default is 0.9.', default=0.9)
298
-
299
- global_args = parser.parse_args()
300
-
301
- if __name__ == "__main__":
302
-
303
- # N = 100 # Number of samples to calculate alpha coefficients
304
- # n = 2 # Number of variable
305
- # m = 7 # Degree of the Legendre polynomial
306
- # a = -5 # Range of the function
307
- # b = 5 # Range of the function
308
- print('Args: ', global_args)
309
-
310
- N = global_args.numSamples # Number of samples to calculate alpha coefficients
311
- n = global_args.numVariables # Number of variable
312
- test_function = getattr(f, global_args.function)
313
- m = global_args.legendreDegree # Degree of the Legendre polynomial
314
- a = global_args.min # Range of the function
315
- b = global_args.max # Range of the function
316
- is_adaptive = global_args.adaptive
317
  if is_adaptive:
318
- k = global_args.numClosestPoints # Number of resampled points
319
- clip = global_args.clip
320
- epsilon = global_args.epsilon # Epsilon value for convergence
321
  if not (0 < clip <= 1):
322
  raise ValueError("Clipping value should be in the interval of (0, 1]")
323
- file_name = f"results/adaptive_{global_args.function}_a{a}_b{b}_N{N}_m{m}_k{k}_c{clip:.2f}"
324
  else:
325
- file_name = f"results/{global_args.function}_a{a}_b{b}_N{N}_m{m}"
326
 
327
- if not global_args.randomInit:
328
- if global_args.function.split('_')[1] == '2d':
329
  x0 = np.array([0.0, 0.0]) # Initial value of function for optimizing process
330
- elif global_args.function.split('_')[1] == '10d':
331
  x0 = np.zeros((10,))
332
  else:
333
  file_name += '_randomInit'
334
- if global_args.function.split('_')[1] == '2d':
335
  x0 = np.random.rand(2) * (b - a) + a # Initial value of function for optimizing process
336
- elif global_args.function.split('_')[1] == '10d':
337
  x0 = np.random.rand(10) * (b - a) + a
338
 
 
339
  # status_bfgs = minimize(test_function, x0, method="BFGS") # Applying direct optimization method to the function
340
  # print(f"BFGS status: {status_bfgs}")
341
- status_hdmr = minimize(test_function, x0, args=(), method=hdmr_opt) # Applying hdmr-opt method to the function
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
342
  print(f"hdmr_opt status: {status_hdmr}")
343
 
344
  with open(file_name + '.txt', 'w') as f:
345
  # f.write("BFGS Status\n" + str(status_bfgs) + "\n\n")
346
  f.write("HDMR Status\n" + str(status_hdmr))
347
- f.close()
 
 
 
3
  import math
4
  import matplotlib.pyplot as plt
5
  import pandas as pd
6
+ try:
7
+ import src.functions as functions
8
+ except:
9
+ import functions
10
  import argparse
11
 
12
  """
 
14
 
15
  """
16
 
17
+ is_streamlit = False
18
+
19
 
20
  def rastrigin(x):
21
  if len(x.shape) == 2:
 
63
  gtol=1e-5, maxiter=None,
64
  disp=False, return_all=False, finite_diff_rel_step=None,
65
  **unknown_options):
66
+ global plt1, plt2
67
 
68
  def Pn(m, x):
69
  if m == 0:
 
110
  return f
111
 
112
  def plot_results():
 
 
113
  f = np.zeros((N,n))
114
  y = fun(xs)
115
  for idx in range(n):
 
143
  axs[jj-1, 0].legend()
144
  axs[jj-1, 1].legend()
145
  plt.subplots_adjust(hspace=0.6, wspace=0.3)
146
+ return fig
147
 
148
  def plot_with_function():
149
+ global is_streamlit
150
+ if is_streamlit == True:
151
+ import plotly.graph_objects as go
152
+ Y = fun(xs)
153
+ yhat = evalute_hdmr(xs, np.mean(Y, axis=0), alpha)
154
+
155
+ X1, X2 = zip(*xs)
156
+ X1 = np.array(X1).flatten()
157
+ X2 = np.array(X2).flatten()
158
+ yhat = np.array(yhat).flatten()
159
+
160
+ # Scatter plot
161
+ scatter_trace = go.Scatter3d(x=X1, y=X2, z=yhat, mode='markers', marker=dict(color='blue', size=2), name='Data Points')
162
+
163
+ x1_min, x1_max = np.array((np.min(X1), np.max(X1)))
164
+ x2_min, x2_max = np.array((np.min(X2), np.max(X2)))
165
+
166
+ X1 = np.linspace(x1_min, x1_max, int(N/10))
167
+ X2 = np.linspace(x2_min, x2_max, int(N/10))
168
+
169
+ X1, X2 = np.meshgrid(X1, X2)
170
+ Y = fun(np.column_stack((X1.ravel(), X2.ravel()))).reshape(X1.shape)
171
+
172
+ # Surface plot
173
+ surface_trace = go.Surface(x=X1, y=X2, z=Y, colorscale='jet', opacity=0.6, name='Function Surface')
174
+
175
+ # Create the figure and add the traces
176
+ fig = go.Figure(data=[scatter_trace, surface_trace])
177
+
178
+ # Set labels for each axis
179
+ fig.update_layout(scene=dict(xaxis_title='X1', yaxis_title='X2', zaxis_title='y'), height=650, width=800,
180
+ title='HDMR Scatter & Original Function Surface Plot')
181
+
182
+ return fig
183
+
184
+
185
  Y = fun(xs)
186
  yhat = evalute_hdmr(xs, np.mean(Y, axis=0), alpha)
187
 
188
  X1, X2 = zip(*xs)
189
  fig = plt.figure(figsize=(8, n*4))
190
  ax = fig.add_subplot(111, projection='3d')
191
+ ax.set_title("HDMR Scatter & Original Function Surface Plot")
192
  # Scatter plot
193
 
194
  # ax.scatter(X1, X2, Y, c='r', marker='o', alpha=0.6)
195
+ ax.scatter(X1, X2, yhat, c='b', marker='o', alpha=0.6, s=2)
196
  x1_min, x1_max = np.array((np.min(X1), np.max(X1)))
197
  x2_min, x2_max = np.array((np.min(X2), np.max(X2)))
198
 
 
204
  x1, x2 = np.meshgrid(x1, x2)
205
  y = fun(np.column_stack((x1.ravel(), x2.ravel()))).reshape(x1.shape)
206
 
207
+ ax.plot_surface(x1, x2, y, cmap='jet', alpha=0.6)
208
 
209
  # Limit the Y axis so scatter is easier to see.
210
  # ax.set_zlim(np.min(yhat), np.max(yhat))
 
213
  ax.set_xlabel('X1')
214
  ax.set_ylabel('X2')
215
  ax.set_zlabel('y')
216
+ return fig
217
 
218
 
219
  def calculate_distances(x0, arr):
 
298
  old_b = new_b
299
  a_ = new_a
300
  b_ = new_b
301
+ plt1 = plot_results()
302
+ plt2 = plot_with_function()
303
  else:
304
  a_ = a
305
  b_ = b
 
307
  print('XS: ', xs.shape)
308
  alpha = calculate_alpha_coeff(xs)
309
  print("Alpha: ", alpha)
 
310
  temp_status = []
311
  for i in range(n):
312
  status = minimize(one_dim_evaluate_hdmr, np.array(x0[i]), method='BFGS')
313
  temp_status.append(status.x[0])
314
  result = OptimizeResult(x=temp_status, fun=fun(x0, *args), success=True, message=" ", nfev=1, njev=0, nhev=0)
315
  result.nfev = N
316
+ plt1 = plot_results()
317
+ plt2 = plot_with_function()
318
 
319
  return result
320
 
321
+ def main_function(N_, n_, function_name_, m_, a_, b_, random_init_, is_adaptive_, k_=None, epsilon_=None, clip_=None):
322
+ global N, n, function_name, m, a, b, random_init, is_adaptive, k, epsilon, clip
323
+
324
+ N = N_
325
+ n = n_
326
+ function_name = function_name_
327
+ m = m_
328
+ a = a_
329
+ b = b_
330
+ random_init = random_init_
331
+ is_adaptive = is_adaptive_
332
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
333
  if is_adaptive:
334
+ k = k_
335
+ epsilon = epsilon_
336
+ clip = clip_
337
  if not (0 < clip <= 1):
338
  raise ValueError("Clipping value should be in the interval of (0, 1]")
339
+ file_name = f"results/adaptive_{function_name}_a{a}_b{b}_N{N}_m{m}_k{k}_c{clip:.2f}"
340
  else:
341
+ file_name = f"results/{function_name}_a{a}_b{b}_N{N}_m{m}"
342
 
343
+ if not random_init:
344
+ if function_name.split('_')[1] == '2d':
345
  x0 = np.array([0.0, 0.0]) # Initial value of function for optimizing process
346
+ elif function_name.split('_')[1] == '10d':
347
  x0 = np.zeros((10,))
348
  else:
349
  file_name += '_randomInit'
350
+ if function_name.split('_')[1] == '2d':
351
  x0 = np.random.rand(2) * (b - a) + a # Initial value of function for optimizing process
352
+ elif function_name.split('_')[1] == '10d':
353
  x0 = np.random.rand(10) * (b - a) + a
354
 
355
+
356
  # status_bfgs = minimize(test_function, x0, method="BFGS") # Applying direct optimization method to the function
357
  # print(f"BFGS status: {status_bfgs}")
358
+ status_hdmr = minimize(getattr(functions, function_name), x0, args=(), method=hdmr_opt) # Applying hdmr-opt method to the function
359
+
360
+ return status_hdmr, plt1, plt2, file_name
361
+
362
+ plt1 = plt2 = None
363
+
364
+ if __name__ == "__main__":
365
+
366
+ parser = argparse.ArgumentParser(
367
+ prog='HDMR',
368
+ description='Program applies the hdmr-opt method and plots the results.')
369
+ parser.add_argument('--numSamples', type=int, help='Number of samples to calculate alpha coefficients.', required=True)
370
+ parser.add_argument('--numVariables', type=int, help='Number of variable of the test function.', required=True)
371
+ parser.add_argument('--function', help='Test function name.', required=True)
372
+ parser.add_argument('--min', type=float, help='Lower range of the test function.', required=True)
373
+ parser.add_argument('--max', type=float, help='Upper range of the test function.', required=True)
374
+ parser.add_argument('--randomInit', action='store_true', help='Initializes x0 as random numbers in the range of xs. Default is initializing as 0.')
375
+ parser.add_argument('--legendreDegree', type=int, default=7, help='Number of legendre polynomial. Default is 7.')
376
+ parser.add_argument('--adaptive', action='store_true', help='Uses iterative method when set.')
377
+ parser.add_argument('--numClosestPoints', type=int, help='Number of closest points to x0. Default is 1000.', default=100)
378
+ parser.add_argument('--epsilon', type=float, help='Epsilon value for convergence. Default is 0.1.', default=0.1)
379
+ parser.add_argument('--clip', type=float, help='Clipping value for updating interval (a, b). Default is 0.9.', default=0.9)
380
+
381
+ global_args = parser.parse_args()
382
+
383
+ print('Args: ', global_args)
384
+ N_ = global_args.numSamples # Number of samples to calculate alpha coefficients
385
+ n_ = global_args.numVariables # Number of variable
386
+ function_name_ = global_args.function
387
+ m_ = global_args.legendreDegree # Degree of the Legendre polynomial
388
+ a_ = global_args.min # Range of the function
389
+ b_ = global_args.max # Range of the function
390
+ is_adaptive_ = global_args.adaptive
391
+ random_init_ = global_args.randomInit
392
+ k_ = global_args.numClosestPoints
393
+ epsilon_ = global_args.epsilon
394
+ clip_ = global_args.clip
395
+
396
+ status_hdmr, _, _, file_name = main_function(N_, n_, function_name_, m_, a_, b_, random_init_,
397
+ is_adaptive_, k_, epsilon_, clip_)
398
  print(f"hdmr_opt status: {status_hdmr}")
399
 
400
  with open(file_name + '.txt', 'w') as f:
401
  # f.write("BFGS Status\n" + str(status_bfgs) + "\n\n")
402
  f.write("HDMR Status\n" + str(status_hdmr))
403
+ f.close()
404
+
405
+ plt.show()