moospread 0.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (63) hide show
  1. moospread/__init__.py +3 -0
  2. moospread/core.py +1881 -0
  3. moospread/problem.py +193 -0
  4. moospread/tasks/__init__.py +4 -0
  5. moospread/tasks/dtlz_torch.py +139 -0
  6. moospread/tasks/mw_torch.py +274 -0
  7. moospread/tasks/re_torch.py +394 -0
  8. moospread/tasks/zdt_torch.py +112 -0
  9. moospread/utils/__init__.py +8 -0
  10. moospread/utils/constraint_utils/__init__.py +2 -0
  11. moospread/utils/constraint_utils/gradient.py +72 -0
  12. moospread/utils/constraint_utils/mgda_core.py +69 -0
  13. moospread/utils/constraint_utils/pmgda_solver.py +308 -0
  14. moospread/utils/constraint_utils/prefs.py +64 -0
  15. moospread/utils/ditmoo.py +127 -0
  16. moospread/utils/lhs.py +74 -0
  17. moospread/utils/misc.py +28 -0
  18. moospread/utils/mobo_utils/__init__.py +11 -0
  19. moospread/utils/mobo_utils/evolution/__init__.py +0 -0
  20. moospread/utils/mobo_utils/evolution/dom.py +60 -0
  21. moospread/utils/mobo_utils/evolution/norm.py +40 -0
  22. moospread/utils/mobo_utils/evolution/utils.py +97 -0
  23. moospread/utils/mobo_utils/learning/__init__.py +0 -0
  24. moospread/utils/mobo_utils/learning/model.py +40 -0
  25. moospread/utils/mobo_utils/learning/model_init.py +33 -0
  26. moospread/utils/mobo_utils/learning/model_update.py +51 -0
  27. moospread/utils/mobo_utils/learning/prediction.py +116 -0
  28. moospread/utils/mobo_utils/learning/utils.py +143 -0
  29. moospread/utils/mobo_utils/lhs_for_mobo.py +243 -0
  30. moospread/utils/mobo_utils/mobo/__init__.py +0 -0
  31. moospread/utils/mobo_utils/mobo/acquisition.py +209 -0
  32. moospread/utils/mobo_utils/mobo/algorithms.py +91 -0
  33. moospread/utils/mobo_utils/mobo/factory.py +86 -0
  34. moospread/utils/mobo_utils/mobo/mobo.py +132 -0
  35. moospread/utils/mobo_utils/mobo/selection.py +182 -0
  36. moospread/utils/mobo_utils/mobo/solver/__init__.py +5 -0
  37. moospread/utils/mobo_utils/mobo/solver/moead.py +17 -0
  38. moospread/utils/mobo_utils/mobo/solver/nsga2.py +10 -0
  39. moospread/utils/mobo_utils/mobo/solver/parego/__init__.py +1 -0
  40. moospread/utils/mobo_utils/mobo/solver/parego/parego.py +62 -0
  41. moospread/utils/mobo_utils/mobo/solver/parego/utils.py +34 -0
  42. moospread/utils/mobo_utils/mobo/solver/pareto_discovery/__init__.py +1 -0
  43. moospread/utils/mobo_utils/mobo/solver/pareto_discovery/buffer.py +364 -0
  44. moospread/utils/mobo_utils/mobo/solver/pareto_discovery/pareto_discovery.py +571 -0
  45. moospread/utils/mobo_utils/mobo/solver/pareto_discovery/utils.py +168 -0
  46. moospread/utils/mobo_utils/mobo/solver/solver.py +74 -0
  47. moospread/utils/mobo_utils/mobo/surrogate_model/__init__.py +2 -0
  48. moospread/utils/mobo_utils/mobo/surrogate_model/base.py +36 -0
  49. moospread/utils/mobo_utils/mobo/surrogate_model/gaussian_process.py +177 -0
  50. moospread/utils/mobo_utils/mobo/surrogate_model/thompson_sampling.py +79 -0
  51. moospread/utils/mobo_utils/mobo/surrogate_problem.py +44 -0
  52. moospread/utils/mobo_utils/mobo/transformation.py +106 -0
  53. moospread/utils/mobo_utils/mobo/utils.py +65 -0
  54. moospread/utils/mobo_utils/spread_mobo_utils.py +854 -0
  55. moospread/utils/offline_utils/__init__.py +10 -0
  56. moospread/utils/offline_utils/handle_task.py +203 -0
  57. moospread/utils/offline_utils/proxies.py +338 -0
  58. moospread/utils/spread_utils.py +91 -0
  59. moospread-0.1.0.dist-info/METADATA +75 -0
  60. moospread-0.1.0.dist-info/RECORD +63 -0
  61. moospread-0.1.0.dist-info/WHEEL +5 -0
  62. moospread-0.1.0.dist-info/licenses/LICENSE +10 -0
  63. moospread-0.1.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,243 @@
1
+ """
2
+ This code was originally published by the following individuals for use with
3
+ Scilab:
4
+ Copyright (C) 2012 - 2013 - Michael Baudin
5
+ Copyright (C) 2012 - Maria Christopoulou
6
+ Copyright (C) 2010 - 2011 - INRIA - Michael Baudin
7
+ Copyright (C) 2009 - Yann Collette
8
+ Copyright (C) 2009 - CEA - Jean-Marc Martinez
9
+
10
+ website: forge.scilab.org/index.php/p/scidoe/sourcetree/master/macros
11
+ Much thanks goes to these individuals. It has been converted to Python by
12
+ Abraham Lee.
13
+ """
14
+
15
+ import numpy as np
16
+ from scipy import spatial
17
+ from scipy import stats
18
+ from scipy import linalg
19
+ from numpy import ma
20
+
21
+ __all__ = ['lhs']
22
+
23
+
24
+ def lhs_no_evaluation(n, samples=None, criterion=None, iterations=None, correlation_matrix=None):
25
+ """
26
+ Generate a latin-hypercube design
27
+ Parameters
28
+ ----------
29
+ n : int
30
+ The number of factors to generate samples for
31
+ Optional
32
+ --------
33
+ samples : int
34
+ The number of samples to generate for each factor (Default: n)
35
+ criterion : str
36
+ Allowable values are "center" or "c", "maximin" or "m",
37
+ "centermaximin" or "cm", and "correlation" or "corr". If no value
38
+ given, the design is simply randomized.
39
+ iterations : int
40
+ The number of iterations in the maximin and correlations algorithms
41
+ (Default: 5).
42
+ NOTE: the randomstate argument and related computation are replaced
43
+ randomstate : np.random.RandomState, int
44
+ Random state (or seed-number) which controls the seed and random draws
45
+ correlation_matrix : ndarray
46
+ Enforce correlation between factors (only used in lhsmu)
47
+ Returns
48
+ -------
49
+ H : 2d-array
50
+ An n-by-samples design matrix that has been normalized so factor values
51
+ are uniformly spaced between zero and one.
52
+ Example
53
+ -------
54
+ A 3-factor design (defaults to 3 samples)::
55
+ >>> lhs(3, random_state=42)
56
+ array([[ 0.12484671, 0.95539205, 0.24399798],
57
+ [ 0.53288616, 0.38533955, 0.86703834],
58
+ [ 0.68602787, 0.31690477, 0.38533151]])
59
+ A 4-factor design with 6 samples::
60
+ >>> lhs(4, samples=6, random_state=42)
61
+ array([[ 0.06242335, 0.19266575, 0.88202411, 0.89439364],
62
+ [ 0.19266977, 0.53538985, 0.53030416, 0.49498498],
63
+ [ 0.71737371, 0.75412607, 0.17634727, 0.71520486],
64
+ [ 0.63874044, 0.85658231, 0.33676408, 0.31102936],
65
+ [ 0.43351917, 0.45134543, 0.12199899, 0.53056742],
66
+ [ 0.93530882, 0.15845238, 0.7386575 , 0.09977641]])
67
+ A 2-factor design with 5 centered samples::
68
+ >>> lhs(2, samples=5, criterion='center', random_state=42)
69
+ array([[ 0.1, 0.9],
70
+ [ 0.5, 0.5],
71
+ [ 0.7, 0.1],
72
+ [ 0.3, 0.7],
73
+ [ 0.9, 0.3]])
74
+ A 3-factor design with 4 samples where the minimum distance between
75
+ all samples has been maximized::
76
+ >>> lhs(3, samples=4, criterion='maximin', random_state=42)
77
+ array([[ 0.69754389, 0.2997106 , 0.96250964],
78
+ [ 0.10585037, 0.09872038, 0.73157522],
79
+ [ 0.25351996, 0.65148999, 0.07337204],
80
+ [ 0.91276926, 0.97873992, 0.42783549]])
81
+ A 4-factor design with 5 samples where the samples are as uncorrelated
82
+ as possible (within 10 iterations)::
83
+ >>> lhs(4, samples=5, criterion='correlation', iterations=10, random_state=42)
84
+ array([[ 0.72088348, 0.05121366, 0.97609357, 0.92487081],
85
+ [ 0.49507404, 0.51265511, 0.00808672, 0.37915272],
86
+ [ 0.22217816, 0.2878673 , 0.24034384, 0.42786629],
87
+ [ 0.91977309, 0.93895699, 0.64061224, 0.14213258],
88
+ [ 0.04719698, 0.70796822, 0.53910322, 0.78857071]])
89
+ """
90
+ H = None
91
+
92
+ if samples is None:
93
+ samples = n
94
+
95
+ if criterion is not None:
96
+ if not criterion.lower() in ('center', 'c', 'maximin', 'm',
97
+ 'centermaximin', 'cm', 'correlation',
98
+ 'corr','lhsmu'):
99
+ raise ValueError('Invalid value for "criterion": {}'.format(criterion))
100
+
101
+ else:
102
+ H = _lhsclassic(n, samples)
103
+
104
+ if criterion is None:
105
+ criterion = 'center'
106
+ if iterations is None:
107
+ iterations = 5
108
+
109
+ if H is None:
110
+ if criterion.lower() in ('center', 'c'):
111
+ H = _lhscentered(n, samples)
112
+ elif criterion.lower() in ('maximin', 'm'):
113
+ H = _lhsmaximin(n, samples, iterations, 'maximin')
114
+ elif criterion.lower() in ('centermaximin', 'cm'):
115
+ H = _lhsmaximin(n, samples, iterations, 'centermaximin')
116
+ elif criterion.lower() in ('correlation', 'corr'):
117
+ H = _lhscorrelate(n, samples, iterations)
118
+ elif criterion.lower() in ('lhsmu'):
119
+ # as specified by the paper. M is set to 5
120
+ H = _lhsmu(n, samples, correlation_matrix, M=5)
121
+
122
+ return H
123
+
124
+ def _lhsclassic(n, samples):
125
+ # Generate the intervals
126
+ cut = np.linspace(0, 1, samples + 1)
127
+
128
+ # Fill points uniformly in each interval
129
+ u = np.random.random((samples, n))
130
+ a = cut[:samples]
131
+ b = cut[1:samples + 1]
132
+ rdpoints = np.zeros_like(u)
133
+ for j in range(n):
134
+ rdpoints[:, j] = u[:, j]*(b-a) + a
135
+
136
+ # Make the random pairings
137
+ H = np.zeros_like(rdpoints)
138
+ for j in range(n):
139
+ order = np.random.permutation(range(samples))
140
+ H[:, j] = rdpoints[order, j]
141
+
142
+ return H
143
+
144
+ def _lhscentered(n, samples):
145
+ # Generate the intervals
146
+ cut = np.linspace(0, 1, samples + 1)
147
+
148
+ # Fill points uniformly in each interval
149
+ u = np.random.random((samples, n))
150
+ a = cut[:samples]
151
+ b = cut[1:samples + 1]
152
+ _center = (a + b)/2
153
+
154
+ # Make the random pairings
155
+ H = np.zeros_like(u)
156
+ for j in range(n):
157
+ H[:, j] = np.random.permutation(_center)
158
+
159
+ return H
160
+
161
+ def _lhsmaximin(n, samples, iterations, lhstype):
162
+ maxdist = 0
163
+
164
+ # Maximize the minimum distance between points
165
+ for i in range(iterations):
166
+ if lhstype=='maximin':
167
+ Hcandidate = _lhsclassic(n, samples)
168
+ else:
169
+ Hcandidate = _lhscentered(n, samples)
170
+
171
+ d = spatial.distance.pdist(Hcandidate, 'euclidean')
172
+ if maxdist<np.min(d):
173
+ maxdist = np.min(d)
174
+ H = Hcandidate.copy()
175
+
176
+ return H
177
+
178
+ def _lhscorrelate(n, samples, iterations):
179
+ mincorr = np.inf
180
+
181
+ # Minimize the components correlation coefficients
182
+ for i in range(iterations):
183
+ # Generate a random LHS
184
+ Hcandidate = _lhsclassic(n, samples)
185
+ R = np.corrcoef(Hcandidate.T)
186
+ if np.max(np.abs(R[R!=1]))<mincorr:
187
+ mincorr = np.max(np.abs(R-np.eye(R.shape[0])))
188
+ H = Hcandidate.copy()
189
+
190
+ return H
191
+
192
+ def _lhsmu(N, samples=None, corr=None, M=5):
193
+
194
+ if samples is None:
195
+ samples = N
196
+
197
+ I = M*samples
198
+
199
+ rdpoints = np.random.uniform(size=(I, N))
200
+
201
+ dist = spatial.distance.cdist(rdpoints, rdpoints, metric='euclidean')
202
+ D_ij = ma.masked_array(dist, mask=np.identity(I))
203
+
204
+ index_rm = np.zeros(I-samples, dtype=int)
205
+ i = 0
206
+ while i < I-samples:
207
+ order = ma.sort(D_ij, axis=1)
208
+
209
+ avg_dist = ma.mean(order[:, 0:2], axis=1)
210
+ min_l = ma.argmin(avg_dist)
211
+
212
+ D_ij[min_l, :] = ma.masked
213
+ D_ij[:, min_l] = ma.masked
214
+
215
+ index_rm[i] = min_l
216
+ i += 1
217
+
218
+ rdpoints = np.delete(rdpoints, index_rm, axis=0)
219
+
220
+ if(corr is not None):
221
+ #check if covariance matrix is valid
222
+ assert type(corr) == np.ndarray
223
+ assert corr.ndim == 2
224
+ assert corr.shape[0] == corr.shape[1]
225
+ assert corr.shape[0] == N
226
+
227
+ norm_u = stats.norm().ppf(rdpoints)
228
+ L = linalg.cholesky(corr, lower=True)
229
+
230
+ norm_u = np.matmul(norm_u, L)
231
+
232
+ H = stats.norm().cdf(norm_u)
233
+ else:
234
+ H = np.zeros_like(rdpoints, dtype=float)
235
+ rank = np.argsort(rdpoints, axis=0)
236
+
237
+ for l in range(samples):
238
+ low = float(l)/samples
239
+ high = float(l+1)/samples
240
+
241
+ l_pos = rank == l
242
+ H[l_pos] = np.random.uniform(low, high, size=N)
243
+ return H
File without changes
@@ -0,0 +1,209 @@
1
+ from abc import ABC, abstractmethod
2
+ import numpy as np
3
+ from scipy.stats import norm
4
+ from moospread.utils.mobo_utils.mobo.utils import safe_divide, expand
5
+
6
+ '''
7
+ Acquisition functions that define the objectives for surrogate multi-objective problem
8
+ '''
9
+
10
+ class Acquisition(ABC):
11
+ '''
12
+ Base class of acquisition function
13
+ '''
14
+ requires_std = False # whether requires std output from surrogate model, set False to avoid unnecessary computation
15
+
16
+ def __init__(self, *args, **kwargs):
17
+ pass
18
+
19
+ def fit(self, X, Y):
20
+ '''
21
+ Fit the parameters of acquisition function from data
22
+ '''
23
+ pass
24
+
25
+ @abstractmethod
26
+ def evaluate(self, val, calc_gradient=False, calc_hessian=False):
27
+ '''
28
+ Evaluate the output from surrogate model using acquisition function
29
+ Input:
30
+ val: output from surrogate model, storing mean and std of prediction, and their derivatives
31
+ val['F']: mean, shape (N, n_obj)
32
+ val['dF']: gradient of mean, shape (N, n_obj, n_var)
33
+ val['hF']: hessian of mean, shape (N, n_obj, n_var, n_var)
34
+ val['S']: std, shape (N, n_obj)
35
+ val['dS']: gradient of std, shape (N, n_obj, n_var)
36
+ val['hS']: hessian of std, shape (N, n_obj, n_var, n_var)
37
+ Output:
38
+ F: acquisition value, shape (N, n_obj)
39
+ dF: gradient of F, shape (N, n_obj, n_var)
40
+ hF: hessian of F, shape (N, n_obj, n_var, n_var)
41
+ '''
42
+ pass
43
+
44
+
45
+ class IdentityFunc(Acquisition):
46
+ '''
47
+ Identity function
48
+ '''
49
+ def evaluate(self, val, calc_gradient=False, calc_hessian=False):
50
+ F, dF, hF = val['F'], val['dF'], val['hF']
51
+ return F, dF, hF
52
+
53
+
54
+ class PI(Acquisition):
55
+ '''
56
+ Probability of Improvement
57
+ '''
58
+ requires_std = True
59
+
60
+ def __init__(self, *args, **kwargs):
61
+ self.y_min = None
62
+
63
+ def fit(self, X, Y):
64
+ self.y_min = np.min(Y, axis=0)
65
+
66
+ def evaluate(self, val, calc_gradient=False, calc_hessian=False):
67
+ y_mean, y_std = val['F'], val['S']
68
+ z = safe_divide(self.y_min - y_mean, y_std)
69
+ cdf_z = norm.cdf(z)
70
+ F = -cdf_z
71
+
72
+ dF, hF = None, None
73
+ dy_mean, hy_mean, dy_std, hy_std = val['dF'], val['hF'], val['dS'], val['hS']
74
+
75
+ if calc_gradient or calc_hessian:
76
+ dz_y_mean = -safe_divide(1, y_std)
77
+ dz_y_std = -safe_divide(self.y_min - y_mean, y_std ** 2)
78
+
79
+ pdf_z = norm.pdf(z)
80
+ dF_y_mean = -pdf_z * dz_y_mean
81
+ dF_y_std = -pdf_z * dz_y_std
82
+
83
+ dF_y_mean, dF_y_std = expand(dF_y_mean), expand(dF_y_std)
84
+
85
+ if calc_gradient:
86
+ dF = dF_y_mean * dy_mean + dF_y_std * dy_std
87
+
88
+ if calc_hessian:
89
+ dpdf_z_z = -z * pdf_z
90
+ dpdf_z_y_mean = dpdf_z_z * dz_y_mean
91
+ dpdf_z_y_std = dpdf_z_z * dz_y_std
92
+ hz_y_std = safe_divide(self.y_min - y_mean, y_std ** 3)
93
+
94
+ hF_y_mean = -dpdf_z_y_mean * dz_y_mean
95
+ hF_y_std = -dpdf_z_y_std * dz_y_std - pdf_z * hz_y_std
96
+
97
+ dy_mean, dy_std = expand(dy_mean), expand(dy_std)
98
+ dy_mean_T, dy_std_T = dy_mean.transpose(0, 1, 3, 2), dy_std.transpose(0, 1, 3, 2)
99
+ dF_y_mean, dF_y_std = expand(dF_y_mean), expand(dF_y_std)
100
+ hF_y_mean, hF_y_std = expand(hF_y_mean, (-1, -2)), expand(hF_y_std, (-1, -2))
101
+
102
+ hF = dF_y_mean * hy_mean + dF_y_std * hy_std + \
103
+ hF_y_mean * dy_mean * dy_mean_T + hF_y_std * dy_std * dy_std_T
104
+
105
+ return F, dF, hF
106
+
107
+
108
+ class EI(Acquisition):
109
+ '''
110
+ Expected Improvement
111
+ '''
112
+ requires_std = True
113
+
114
+ def __init__(self, *args, **kwargs):
115
+ self.y_min = None
116
+
117
+ def fit(self, X, Y):
118
+ self.y_min = np.min(Y, axis=0)
119
+
120
+ def evaluate(self, val, calc_gradient=False, calc_hessian=False):
121
+ y_mean, y_std = val['F'], val['S']
122
+ z = safe_divide(self.y_min - y_mean, y_std)
123
+ pdf_z = norm.pdf(z)
124
+ cdf_z = norm.cdf(z)
125
+ F = -(self.y_min - y_mean) * cdf_z - y_std * pdf_z
126
+
127
+ dF, hF = None, None
128
+ dy_mean, hy_mean, dy_std, hy_std = val['dF'], val['hF'], val['dS'], val['hS']
129
+
130
+ if calc_gradient or calc_hessian:
131
+ dz_y_mean = -safe_divide(1, y_std)
132
+ dz_y_std = -safe_divide(self.y_min - y_mean, y_std ** 2)
133
+ dpdf_z_z = -z * pdf_z
134
+
135
+ dF_y_mean = cdf_z - (self.y_min - y_mean) * pdf_z * dz_y_mean - y_std * dpdf_z_z * dz_y_mean
136
+ dF_y_std = (self.y_min - y_mean) * pdf_z * dz_y_std + pdf_z + y_std * dpdf_z_z * dz_y_std
137
+
138
+ dF_y_mean, dF_y_std = expand(dF_y_mean), expand(dF_y_std)
139
+
140
+ if calc_gradient:
141
+ dF = dF_y_mean * dy_mean + dF_y_std * dy_std
142
+
143
+ if calc_hessian:
144
+ dpdf_z_y_mean = dpdf_z_z * dz_y_mean
145
+ dpdf_z_y_std = dpdf_z_z * dz_y_std
146
+ ddpdf_z_z_y_mean = -z * dpdf_z_y_mean - dz_y_mean * pdf_z
147
+ ddpdf_z_z_y_std = -z * dpdf_z_y_std - dz_y_std * pdf_z
148
+ ddz_y_std_y_std = safe_divide(self.y_min - y_mean, y_std ** 3)
149
+
150
+ hF_y_mean = -pdf_z * dz_y_mean - \
151
+ dz_y_mean * pdf_z + (self.y_min - y_mean) * dpdf_z_z * dz_y_mean ** 2 + \
152
+ y_std * dz_y_mean * ddpdf_z_z_y_mean
153
+ hF_y_std = (self.y_min - y_mean) * (dz_y_std * dpdf_z_y_std + pdf_z * ddz_y_std_y_std) + \
154
+ dpdf_z_y_std + \
155
+ dpdf_z_z * dz_y_std + y_std * dz_y_std * ddpdf_z_z_y_std + y_std * dpdf_z_z * ddz_y_std_y_std
156
+
157
+ dy_mean, dy_std = expand(dy_mean), expand(dy_std)
158
+ dy_mean_T, dy_std_T = dy_mean.transpose(0, 1, 3, 2), dy_std.transpose(0, 1, 3, 2)
159
+ dF_y_mean, dF_y_std = expand(dF_y_mean), expand(dF_y_std)
160
+ hF_y_mean, hF_y_std = expand(hF_y_mean, (-1, -2)), expand(hF_y_std, (-1, -2))
161
+
162
+ hF = dF_y_mean * hy_mean + dF_y_std * hy_std + \
163
+ hF_y_mean * dy_mean * dy_mean_T + hF_y_std * dy_std * dy_std_T
164
+
165
+ return F, dF, hF
166
+
167
+
168
+ class UCB(Acquisition):
169
+ '''
170
+ Upper Confidence Bound
171
+ '''
172
+ requires_std = True
173
+
174
+ def __init__(self, *args, **kwargs):
175
+ self.n_sample = None
176
+
177
+ def fit(self, X, Y):
178
+ self.n_sample = X.shape[0]
179
+
180
+ def evaluate(self, val, calc_gradient=False, calc_hessian=False):
181
+ lamda = np.sqrt(np.log(self.n_sample) / self.n_sample)
182
+
183
+ y_mean, y_std = val['F'], val['S']
184
+ F = y_mean - lamda * y_std
185
+
186
+ dF, hF = None, None
187
+ dy_mean, hy_mean, dy_std, hy_std = val['dF'], val['hF'], val['dS'], val['hS']
188
+
189
+ if calc_gradient or calc_hessian:
190
+ dF_y_mean = np.ones_like(y_mean)
191
+ dF_y_std = -lamda * np.ones_like(y_std)
192
+
193
+ dF_y_mean, dF_y_std = expand(dF_y_mean), expand(dF_y_std)
194
+
195
+ if calc_gradient:
196
+ dF = dF_y_mean * dy_mean + dF_y_std * dy_std
197
+
198
+ if calc_hessian:
199
+ hF_y_mean = 0
200
+ hF_y_std = 0
201
+
202
+ dy_mean, dy_std = expand(dy_mean), expand(dy_std)
203
+ dy_mean_T, dy_std_T = dy_mean.transpose(0, 1, 3, 2), dy_std.transpose(0, 1, 3, 2)
204
+ dF_y_mean, dF_y_std = expand(dF_y_mean), expand(dF_y_std)
205
+
206
+ hF = dF_y_mean * hy_mean + dF_y_std * hy_std + \
207
+ hF_y_mean * dy_mean * dy_mean_T + hF_y_std * dy_std * dy_std_T
208
+
209
+ return F, dF, hF
@@ -0,0 +1,91 @@
1
+ from moospread.utils.mobo_utils.mobo.mobo import MOBO
2
+
3
+ '''
4
+ High-level algorithm specifications by providing config
5
+ '''
6
+
7
+ class DGEMO(MOBO):
8
+ '''
9
+ DGEMO
10
+ '''
11
+ config = {
12
+ 'surrogate': 'gp',
13
+ 'acquisition': 'identity',
14
+ 'solver': 'discovery',
15
+ 'selection': 'dgemo',
16
+ }
17
+
18
+
19
+ class TSEMO(MOBO):
20
+ '''
21
+ TSEMO
22
+ '''
23
+ config = {
24
+ 'surrogate': 'ts',
25
+ 'acquisition': 'identity',
26
+ 'solver': 'nsga2',
27
+ 'selection': 'hvi',
28
+ }
29
+
30
+
31
+ class USEMO_EI(MOBO):
32
+ '''
33
+ USeMO, using EI as acquisition
34
+ '''
35
+ config = {
36
+ 'surrogate': 'gp',
37
+ 'acquisition': 'ei',
38
+ 'solver': 'nsga2',
39
+ 'selection': 'uncertainty',
40
+ }
41
+
42
+
43
+ class MOEAD_EGO(MOBO):
44
+ '''
45
+ MOEA/D-EGO
46
+ '''
47
+ config = {
48
+ 'surrogate': 'gp',
49
+ 'acquisition': 'ei',
50
+ 'solver': 'moead',
51
+ 'selection': 'moead',
52
+ }
53
+
54
+
55
+ class ParEGO(MOBO):
56
+ '''
57
+ ParEGO
58
+ '''
59
+ config = {
60
+ 'surrogate': 'gp',
61
+ 'acquisition': 'ei',
62
+ 'solver': 'parego',
63
+ 'selection': 'random',
64
+ }
65
+
66
+
67
+ '''
68
+ Define new algorithms here
69
+ '''
70
+
71
+
72
+ class Custom(MOBO):
73
+ '''
74
+ Totally rely on user arguments to specify each component
75
+ '''
76
+ config = None
77
+
78
+
79
+ def get_algorithm(name):
80
+ '''
81
+ Get class of algorithm by name
82
+ '''
83
+ algo = {
84
+ 'dgemo': DGEMO,
85
+ 'tsemo': TSEMO,
86
+ 'usemo-ei': USEMO_EI,
87
+ 'moead-ego': MOEAD_EGO,
88
+ 'parego': ParEGO,
89
+ 'custom': Custom,
90
+ }
91
+ return algo[name]
@@ -0,0 +1,86 @@
1
+ '''
2
+ Factory for importing different components of the MOBO framework by name
3
+ '''
4
+
5
+ def get_surrogate_model(name):
6
+ from moospread.utils.mobo_utils.mobo.surrogate_model import GaussianProcess, ThompsonSampling
7
+
8
+ surrogate_model = {
9
+ 'gp': GaussianProcess,
10
+ 'ts': ThompsonSampling,
11
+ }
12
+
13
+ surrogate_model['default'] = GaussianProcess
14
+
15
+ return surrogate_model[name]
16
+
17
+
18
+ def get_acquisition(name):
19
+ from moospread.utils.mobo_utils.mobo.acquisition import IdentityFunc, PI, EI, UCB
20
+
21
+ acquisition = {
22
+ 'identity': IdentityFunc,
23
+ 'pi': PI,
24
+ 'ei': EI,
25
+ 'ucb': UCB,
26
+ }
27
+
28
+ acquisition['default'] = IdentityFunc
29
+
30
+ return acquisition[name]
31
+
32
+
33
+ def get_solver(name):
34
+ from moospread.utils.mobo_utils.mobo.solver import NSGA2Solver, MOEADSolver, ParetoDiscoverySolver, ParEGOSolver
35
+
36
+ solver = {
37
+ 'nsga2': NSGA2Solver,
38
+ 'moead': MOEADSolver,
39
+ 'discovery': ParetoDiscoverySolver,
40
+ 'parego': ParEGOSolver,
41
+ }
42
+
43
+ solver['default'] = NSGA2Solver
44
+
45
+ return solver[name]
46
+
47
+
48
+ def get_selection(name):
49
+ from moospread.utils.mobo_utils.mobo.selection import HVI, Uncertainty, Random, DGEMOSelect, MOEADSelect
50
+
51
+ selection = {
52
+ 'hvi': HVI,
53
+ 'uncertainty': Uncertainty,
54
+ 'random': Random,
55
+ 'dgemo': DGEMOSelect,
56
+ 'moead': MOEADSelect,
57
+ }
58
+
59
+ selection['default'] = HVI
60
+
61
+ return selection[name]
62
+
63
+
64
+ def init_from_config(config, framework_args):
65
+ '''
66
+ Initialize each component of the MOBO framework from config
67
+ '''
68
+ init_func = {
69
+ 'surrogate': get_surrogate_model,
70
+ 'acquisition': get_acquisition,
71
+ 'selection': get_selection,
72
+ 'solver': get_solver,
73
+ }
74
+
75
+ framework = {}
76
+ for key, func in init_func.items():
77
+ kwargs = framework_args[key]
78
+ if config is None:
79
+ # no config specified, initialize from user arguments
80
+ name = kwargs[key]
81
+ else:
82
+ # initialize from config specifications, if certain keys are not provided, use default settings
83
+ name = config[key] if key in config else 'default'
84
+ framework[key] = func(name)(**kwargs)
85
+
86
+ return framework