yunusk commited on
Commit
6f91ed5
·
1 Parent(s): e1ec402

Basis function family selection added.

Browse files
Files changed (2) hide show
  1. app.py +9 -4
  2. src/main.py +37 -17
app.py CHANGED
@@ -38,6 +38,8 @@ with st.container():
38
  available_functions = ["testfunc_2d", "rastrigin_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")
@@ -46,6 +48,7 @@ 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: ")
@@ -61,6 +64,8 @@ random_init = st.sidebar.checkbox("Random Initialization")
61
  if not random_init:
62
  default_x0 = utils.get_function_x0(function_name=function_name.split('_')[0])
63
  x0 = st.sidebar.text_input("required format: x1,x2,...,xn",str(default_x0))
 
 
64
 
65
  is_adaptive = st.sidebar.checkbox("Adaptive HDMR")
66
 
@@ -76,11 +81,11 @@ if st.sidebar.button("Calculate HDMR"):
76
 
77
  main.is_streamlit = interactive_plot
78
  if is_adaptive:
79
- status_hdmr, runtime, plt1, plt2, plt3, file_name = main.main_function(N, n, function_name, legendreDegree, interval[0], interval[1],
80
- random_init, x0, is_adaptive, num_closest_points, epsilon, clip)
81
  else:
82
- status_hdmr, runtime, plt1, plt2, plt3, file_name = main.main_function(N, n, function_name, legendreDegree, interval[0], interval[1],
83
- random_init, x0, is_adaptive)
84
  st.subheader("Results")
85
  st.write(f"hdmr_opt status Success: {status_hdmr.success} - X: {status_hdmr.x}")
86
  st.write("Runtime: {runtime} seconds")
 
38
  available_functions = ["testfunc_2d", "rastrigin_2d", "camel3_2d", "camel16_2d", "treccani_2d", "goldstein_2d", "branin_2d",
39
  "rosenbrock_2d", "ackley_2d", "rosenbrock_10d", "griewank_10d", "rastrigin_10d"]
40
 
41
+ basis_functions = ["Legendre", "Cosine"]
42
+
43
  st.sidebar.header('User Inputs')
44
 
45
  interactive_plot = st.sidebar.checkbox("Interactive Plot")
 
48
 
49
  # n = st.sidebar.slider("Number of variables: ", 1, 10, 2, 1)
50
  function_name = st.sidebar.selectbox("Test function:", available_functions)
51
+ basis_funtion = st.sidebar.selectbox("Legendre Basis", basis_functions)
52
  legendreDegree = st.sidebar.slider("Legendre Degree:", 1, 20, 7, 1)
53
 
54
  st.sidebar.write("Function interval: ")
 
64
  if not random_init:
65
  default_x0 = utils.get_function_x0(function_name=function_name.split('_')[0])
66
  x0 = st.sidebar.text_input("required format: x1,x2,...,xn",str(default_x0))
67
+ else:
68
+ x0 = None
69
 
70
  is_adaptive = st.sidebar.checkbox("Adaptive HDMR")
71
 
 
81
 
82
  main.is_streamlit = interactive_plot
83
  if is_adaptive:
84
+ status_hdmr, runtime, plt1, plt2, plt3, file_name = main.main_function(N, n, function_name, basis_funtion, legendreDegree,
85
+ interval[0], interval[1], random_init, x0, is_adaptive, num_closest_points, epsilon, clip)
86
  else:
87
+ status_hdmr, runtime, plt1, plt2, plt3, file_name = main.main_function(N, n, function_name, basis_funtion, legendreDegree,
88
+ interval[0], interval[1], random_init, x0, is_adaptive)
89
  st.subheader("Results")
90
  st.write(f"hdmr_opt status Success: {status_hdmr.success} - X: {status_hdmr.x}")
91
  st.write("Runtime: {runtime} seconds")
src/main.py CHANGED
@@ -60,23 +60,31 @@ def test_func(x):
60
  y = np.sum(x**2, axis=axis, keepdims=True)
61
  return y
62
 
63
- def hdmr_opt(fun, x0, args=(), jac=None, callback=None,
64
- gtol=1e-5, maxiter=None,
65
- disp=False, return_all=False, finite_diff_rel_step=None,
66
- **unknown_options):
67
- global plt1, plt2, plt3, a, b, xs
68
-
69
- def Pn(m, x):
70
  if m == 0:
71
  return np.ones_like(x)
72
  elif m == 1:
73
  return x
74
  else:
75
  return (2*m-1)*x*Pn(m-1, x)/m - (m-1)*Pn(m-2, x)/m
76
-
77
- def L(a,b,m,x):
78
  return np.sqrt((2*m+1)/(b-a))*Pn(m, 2*(x-b)/(b-a)+1)
79
 
 
 
 
 
 
 
 
 
 
 
 
 
 
80
  def calculate_alpha_coeff(xs):
81
  N, n = xs.shape
82
  alpha = np.zeros((m, n))
@@ -84,7 +92,7 @@ def hdmr_opt(fun, x0, args=(), jac=None, callback=None,
84
  f0 = np.mean(y)
85
  for r in range(m): # Iterate degree of the Legendre polynomial
86
  for i in range(n): # Iterate number of variable
87
- alpha[r, i] = (b - a) * np.mean((y-f0) * L(a, b, r+1, np.array(xs[:, [i]])))
88
  return alpha
89
 
90
  def evalute_hdmr(x, f0, alpha):
@@ -93,21 +101,21 @@ def hdmr_opt(fun, x0, args=(), jac=None, callback=None,
93
  y = f0 * np.ones((N,1))
94
  for r in range(m):
95
  for i in range(n):
96
- y = y + alpha[r, i] * L(a, b, r+1, np.array(x[:, [i]])) # Meta-model
97
  return y
98
 
99
  def one_dim_evaluate_hdmr(x):
100
  m, _ = alpha.shape
101
  f = 0
102
  for r in range(m):
103
- f = f + alpha[r,i] * L(a, b, r+1, x) # One dimensional functions
104
  return f
105
 
106
  def one_dim_evaluate_hdmr_for_test(x, idx_var):
107
  m, _ = alpha.shape
108
  f = np.zeros((N,1))
109
  for r in range(m):
110
- f = f + alpha[r,idx_var] * L(a, b, r+1, x)
111
  return f
112
 
113
  def plot_results():
@@ -359,18 +367,27 @@ def hdmr_opt(fun, x0, args=(), jac=None, callback=None,
359
  plt2 = None
360
  return result
361
 
362
- def main_function(N_, n_, function_name_, m_, a_, b_, random_init_, x0_, is_adaptive_, k_=None, epsilon_=None, clip_=None):
363
- global N, n, function_name, m, a, b, random_init, is_adaptive, k, epsilon, clip
 
 
 
364
 
365
  N = N_
366
  n = n_
367
  function_name = function_name_
 
368
  m = m_
369
  a = a_
370
  b = b_
371
  random_init = random_init_
372
  is_adaptive = is_adaptive_
373
 
 
 
 
 
 
374
  if is_adaptive:
375
  k = k_
376
  epsilon = epsilon_
@@ -387,9 +404,10 @@ def main_function(N_, n_, function_name_, m_, a_, b_, random_init_, x0_, is_adap
387
  file_name += '_randomInit'
388
  if function_name.split('_')[1] == '2d':
389
  x0 = np.random.rand(2) * (b - a) + a # Initial value of function for optimizing process
 
390
  elif function_name.split('_')[1] == '10d':
391
  x0 = np.random.rand(10) * (b - a) + a
392
-
393
 
394
  # status_bfgs = minimize(test_function, x0, method="BFGS") # Applying direct optimization method to the function
395
  # print(f"BFGS status: {status_bfgs}")
@@ -412,6 +430,7 @@ if __name__ == "__main__":
412
  parser.add_argument('--min', type=float, help='Lower range of the test function.', required=True)
413
  parser.add_argument('--max', type=float, help='Upper range of the test function.', required=True)
414
  parser.add_argument('--randomInit', action='store_true', help='Initializes x0 as random numbers in the range of xs. Default is initializing as 0.')
 
415
  parser.add_argument('--legendreDegree', type=int, default=7, help='Number of legendre polynomial. Default is 7.')
416
  parser.add_argument('--adaptive', action='store_true', help='Uses iterative method when set.')
417
  parser.add_argument('--numClosestPoints', type=int, help='Number of closest points to x0. Default is 1000.', default=100)
@@ -424,6 +443,7 @@ if __name__ == "__main__":
424
  N_ = global_args.numSamples # Number of samples to calculate alpha coefficients
425
  n_ = global_args.numVariables # Number of variable
426
  function_name_ = global_args.function
 
427
  m_ = global_args.legendreDegree # Degree of the Legendre polynomial
428
  a_ = global_args.min # Range of the function
429
  b_ = global_args.max # Range of the function
@@ -433,7 +453,7 @@ if __name__ == "__main__":
433
  epsilon_ = global_args.epsilon
434
  clip_ = global_args.clip
435
 
436
- status_hdmr, runtime, _, _, _, file_name = main_function(N_, n_, function_name_, m_, a_, b_, random_init_,
437
  is_adaptive_, k_, epsilon_, clip_)
438
  print(f"{runtime} seconds")
439
  print(f"hdmr_opt status: {status_hdmr}")
 
60
  y = np.sum(x**2, axis=axis, keepdims=True)
61
  return y
62
 
63
+ ## ------------------ BASIS FUNCTIONS START ------------------ ##
64
+ def Pn(m, x):
 
 
 
 
 
65
  if m == 0:
66
  return np.ones_like(x)
67
  elif m == 1:
68
  return x
69
  else:
70
  return (2*m-1)*x*Pn(m-1, x)/m - (m-1)*Pn(m-2, x)/m
71
+
72
+ def Legendre(a,b,m,x):
73
  return np.sqrt((2*m+1)/(b-a))*Pn(m, 2*(x-b)/(b-a)+1)
74
 
75
+ def Cosine(a,b,m,x):
76
+ square_root_term = np.sqrt(1 / (b-a) * 8 * math.pi * m / (math.sin(4 * math.pi * m) + 4 * math.pi * m))
77
+ outer_term = np.cos(2 * math.pi * m * (x - a) / (b - a))
78
+ return square_root_term * outer_term
79
+
80
+ ## ------------------ BASIS FUNCTIONS END ------------------ ##
81
+
82
+ def hdmr_opt(fun, x0, args=(), jac=None, callback=None,
83
+ gtol=1e-5, maxiter=None,
84
+ disp=False, return_all=False, finite_diff_rel_step=None,
85
+ **unknown_options):
86
+ global plt1, plt2, plt3, a, b, xs
87
+
88
  def calculate_alpha_coeff(xs):
89
  N, n = xs.shape
90
  alpha = np.zeros((m, n))
 
92
  f0 = np.mean(y)
93
  for r in range(m): # Iterate degree of the Legendre polynomial
94
  for i in range(n): # Iterate number of variable
95
+ alpha[r, i] = (b - a) * np.mean((y-f0) * BasisFunction(a, b, r+1, np.array(xs[:, [i]])))
96
  return alpha
97
 
98
  def evalute_hdmr(x, f0, alpha):
 
101
  y = f0 * np.ones((N,1))
102
  for r in range(m):
103
  for i in range(n):
104
+ y = y + alpha[r, i] * BasisFunction(a, b, r+1, np.array(x[:, [i]])) # Meta-model
105
  return y
106
 
107
  def one_dim_evaluate_hdmr(x):
108
  m, _ = alpha.shape
109
  f = 0
110
  for r in range(m):
111
+ f = f + alpha[r,i] * BasisFunction(a, b, r+1, x) # One dimensional functions
112
  return f
113
 
114
  def one_dim_evaluate_hdmr_for_test(x, idx_var):
115
  m, _ = alpha.shape
116
  f = np.zeros((N,1))
117
  for r in range(m):
118
+ f = f + alpha[r,idx_var] * BasisFunction(a, b, r+1, x)
119
  return f
120
 
121
  def plot_results():
 
367
  plt2 = None
368
  return result
369
 
370
+ def main_function(N_, n_, function_name_, basis_function_, m_, a_, b_, random_init_, x0_, is_adaptive_, k_=None, epsilon_=None, clip_=None):
371
+ global N, n, function_name, basis_function, BasisFunction, m, a, b, random_init, is_adaptive, k, epsilon, clip
372
+
373
+ if basis_function_ not in ["Legendre", "Cosine"]:
374
+ raise ValueError("basis_function should be Cosine or Legendre.")
375
 
376
  N = N_
377
  n = n_
378
  function_name = function_name_
379
+ basis_function = basis_function_
380
  m = m_
381
  a = a_
382
  b = b_
383
  random_init = random_init_
384
  is_adaptive = is_adaptive_
385
 
386
+ if basis_function == "Legendre":
387
+ BasisFunction = Legendre
388
+ elif basis_function == "Cosine":
389
+ BasisFunction = Cosine
390
+
391
  if is_adaptive:
392
  k = k_
393
  epsilon = epsilon_
 
404
  file_name += '_randomInit'
405
  if function_name.split('_')[1] == '2d':
406
  x0 = np.random.rand(2) * (b - a) + a # Initial value of function for optimizing process
407
+ x0_ = x0
408
  elif function_name.split('_')[1] == '10d':
409
  x0 = np.random.rand(10) * (b - a) + a
410
+ x0_ = x0
411
 
412
  # status_bfgs = minimize(test_function, x0, method="BFGS") # Applying direct optimization method to the function
413
  # print(f"BFGS status: {status_bfgs}")
 
430
  parser.add_argument('--min', type=float, help='Lower range of the test function.', required=True)
431
  parser.add_argument('--max', type=float, help='Upper range of the test function.', required=True)
432
  parser.add_argument('--randomInit', action='store_true', help='Initializes x0 as random numbers in the range of xs. Default is initializing as 0.')
433
+ parser.add_argument('--basisFunction', type=int, default="Cosine", help='Basis function that will be used in HDMR. Legendre or Cosine. Default is Cosine.')
434
  parser.add_argument('--legendreDegree', type=int, default=7, help='Number of legendre polynomial. Default is 7.')
435
  parser.add_argument('--adaptive', action='store_true', help='Uses iterative method when set.')
436
  parser.add_argument('--numClosestPoints', type=int, help='Number of closest points to x0. Default is 1000.', default=100)
 
443
  N_ = global_args.numSamples # Number of samples to calculate alpha coefficients
444
  n_ = global_args.numVariables # Number of variable
445
  function_name_ = global_args.function
446
+ basis_function_ = global_args.basis_function
447
  m_ = global_args.legendreDegree # Degree of the Legendre polynomial
448
  a_ = global_args.min # Range of the function
449
  b_ = global_args.max # Range of the function
 
453
  epsilon_ = global_args.epsilon
454
  clip_ = global_args.clip
455
 
456
+ status_hdmr, runtime, _, _, _, file_name = main_function(N_, n_, function_name_, basis_function_, m_, a_, b_, random_init_,
457
  is_adaptive_, k_, epsilon_, clip_)
458
  print(f"{runtime} seconds")
459
  print(f"hdmr_opt status: {status_hdmr}")