fcmaes 1.3.17__py3-none-any.whl → 1.6.9__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.
- fcmaes/__init__.py +5 -4
- fcmaes/advretry.py +135 -141
- fcmaes/astro.py +64 -40
- fcmaes/bitecpp.py +33 -32
- fcmaes/cmaes.py +69 -142
- fcmaes/cmaescpp.py +231 -39
- fcmaes/crfmnes.py +339 -0
- fcmaes/crfmnescpp.py +273 -0
- fcmaes/dacpp.py +26 -27
- fcmaes/de.py +163 -56
- fcmaes/decpp.py +188 -179
- fcmaes/diversifier.py +357 -0
- fcmaes/evaluator.py +279 -6
- fcmaes/lib/libacmalib.dll +0 -0
- fcmaes/lib/libacmalib.dylib +0 -0
- fcmaes/lib/libacmalib.so +0 -0
- fcmaes/lib/libhbv.so +0 -0
- fcmaes/lib/liblrgv.so +0 -0
- fcmaes/mapelites.py +737 -0
- fcmaes/mode.py +399 -256
- fcmaes/modecpp.py +326 -149
- fcmaes/moretry.py +107 -77
- fcmaes/multiretry.py +37 -30
- fcmaes/optimizer.py +695 -271
- fcmaes/pgpecpp.py +340 -0
- fcmaes/pygmoretry.py +8 -17
- fcmaes/retry.py +161 -139
- fcmaes/test_cma.py +45 -25
- fcmaes-1.6.9.dist-info/METADATA +47 -0
- fcmaes-1.6.9.dist-info/RECORD +36 -0
- {fcmaes-1.3.17.dist-info → fcmaes-1.6.9.dist-info}/WHEEL +1 -1
- fcmaes/csmacpp.py +0 -108
- fcmaes/gcldecpp.py +0 -148
- fcmaes/lcldecpp.py +0 -138
- fcmaes/ldecpp.py +0 -172
- fcmaes/lib/libgcc_s_seh-1.dll +0 -0
- fcmaes/lib/libgtoplib.dll +0 -0
- fcmaes/lib/libgtoplib.so +0 -0
- fcmaes/lib/libstdc++-6.dll +0 -0
- fcmaes/lib/libwinpthread-1.dll +0 -0
- fcmaes-1.3.17.dist-info/METADATA +0 -55
- fcmaes-1.3.17.dist-info/RECORD +0 -37
- {fcmaes-1.3.17.dist-info → fcmaes-1.6.9.dist-info}/LICENSE +0 -0
- {fcmaes-1.3.17.dist-info → fcmaes-1.6.9.dist-info}/top_level.txt +0 -0
fcmaes/pgpecpp.py
ADDED
|
@@ -0,0 +1,340 @@
|
|
|
1
|
+
# Copyright (c) Dietmar Wolz.
|
|
2
|
+
#
|
|
3
|
+
# This source code is licensed under the MIT license found in the
|
|
4
|
+
# LICENSE file in the root directory.
|
|
5
|
+
|
|
6
|
+
"""
|
|
7
|
+
Eigen based implementation of PGPE see http://mediatum.ub.tum.de/doc/1099128/631352.pdf .
|
|
8
|
+
Derived from https://github.com/google/evojax/blob/main/evojax/algo/pgpe.py .
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
import sys
|
|
12
|
+
import os
|
|
13
|
+
import math
|
|
14
|
+
import ctypes as ct
|
|
15
|
+
import numpy as np
|
|
16
|
+
from numpy.random import PCG64DXSM, Generator
|
|
17
|
+
from scipy.optimize import OptimizeResult, Bounds
|
|
18
|
+
from fcmaes.evaluator import _check_bounds, _get_bounds, callback_par, parallel, call_back_par, libcmalib
|
|
19
|
+
|
|
20
|
+
from typing import Optional, Callable, Union
|
|
21
|
+
from numpy.typing import ArrayLike
|
|
22
|
+
|
|
23
|
+
os.environ['MKL_DEBUG_CPU_TYPE'] = '5'
|
|
24
|
+
|
|
25
|
+
def minimize(fun: Callable[[ArrayLike], float],
|
|
26
|
+
bounds: Optional[Bounds] = None,
|
|
27
|
+
x0: Optional[ArrayLike] = None,
|
|
28
|
+
input_sigma: Optional[Union[float, ArrayLike, Callable]] = 0.1,
|
|
29
|
+
popsize: Optional[int] = 32,
|
|
30
|
+
max_evaluations: Optional[int] = 100000,
|
|
31
|
+
workers: Optional[int] = None,
|
|
32
|
+
stop_fitness: Optional[float] = -np.inf,
|
|
33
|
+
rg: Optional[Generator] = Generator(PCG64DXSM()),
|
|
34
|
+
runid: Optional[int] = 0,
|
|
35
|
+
normalize: Optional[bool] = True,
|
|
36
|
+
lr_decay_steps: Optional[int] = 1000,
|
|
37
|
+
use_ranking: Optional[bool] = True,
|
|
38
|
+
center_learning_rate: Optional[float] = 0.15,
|
|
39
|
+
stdev_learning_rate: Optional[float] = 0.1,
|
|
40
|
+
stdev_max_change: Optional[float] = 0.2,
|
|
41
|
+
b1: Optional[float] = 0.9,
|
|
42
|
+
b2: Optional[float] = 0.999,
|
|
43
|
+
eps: Optional[float] = 1e-8,
|
|
44
|
+
decay_coef: Optional[float] = 1.0,
|
|
45
|
+
) -> OptimizeResult:
|
|
46
|
+
|
|
47
|
+
"""Minimization of a scalar function of one or more variables using a
|
|
48
|
+
C++ PGPE implementation called via ctypes.
|
|
49
|
+
|
|
50
|
+
Parameters
|
|
51
|
+
----------
|
|
52
|
+
fun : callable
|
|
53
|
+
The objective function to be minimized.
|
|
54
|
+
``fun(x) -> float``
|
|
55
|
+
where ``x`` is an 1-D array with shape (dim,)
|
|
56
|
+
bounds : sequence or `Bounds`, optional
|
|
57
|
+
Bounds on variables. There are two ways to specify the bounds:
|
|
58
|
+
1. Instance of the `scipy.Bounds` class.
|
|
59
|
+
2. Sequence of ``(min, max)`` pairs for each element in `x`. None
|
|
60
|
+
is used to specify no bound.
|
|
61
|
+
x0 : ndarray, shape (dim,)
|
|
62
|
+
Initial guess. Array of real elements of size (dim,),
|
|
63
|
+
where 'dim' is the number of independent variables.
|
|
64
|
+
input_sigma : float or np.array, optional
|
|
65
|
+
Initial step size.
|
|
66
|
+
popsize = int, optional
|
|
67
|
+
CMA-ES population size.
|
|
68
|
+
max_evaluations : int, optional
|
|
69
|
+
Forced termination after ``max_evaluations`` function evaluations.
|
|
70
|
+
workers : int or None, optional
|
|
71
|
+
If workers > 1, function evaluation is performed in parallel for the whole population.
|
|
72
|
+
Useful for costly objective functions but is deactivated for parallel retry.
|
|
73
|
+
stop_fitness : float, optional
|
|
74
|
+
Limit for fitness value. If reached minimize terminates.
|
|
75
|
+
rg = numpy.random.Generator, optional
|
|
76
|
+
Random generator for creating random guesses.
|
|
77
|
+
runid : int, optional
|
|
78
|
+
id used by the is_terminate callback to identify the CMA-ES run.
|
|
79
|
+
normalize : boolean, optional
|
|
80
|
+
if true pheno -> geno transformation maps arguments to interval [-1,1]
|
|
81
|
+
lr_decay_steps int, optional - ADAM optimizer configuration
|
|
82
|
+
use_ranking : boolean, optional - Should we treat the fitness as rankings or not.
|
|
83
|
+
center_learning_rate : float, optional - Learning rate for the Gaussian mean.
|
|
84
|
+
stdev_learning_rate : float, optional - Learning rate for the Gaussian stdev.
|
|
85
|
+
init_stdev : float, optional - Initial stdev for the Gaussian distribution.
|
|
86
|
+
stdev_max_change : float, optional - Maximum allowed change for stdev in abs values.
|
|
87
|
+
b1 : float, optional - ADAM optimizer configuration
|
|
88
|
+
b2 : float, optional - ADAM optimizer configuration
|
|
89
|
+
eps : float, optional - ADAM optimizer configuration
|
|
90
|
+
decay_coef : float, optional - ADAM optimizer configuration
|
|
91
|
+
|
|
92
|
+
Returns
|
|
93
|
+
-------
|
|
94
|
+
res : scipy.OptimizeResult
|
|
95
|
+
The optimization result is represented as an ``OptimizeResult`` object.
|
|
96
|
+
Important attributes are: ``x`` the solution array,
|
|
97
|
+
``fun`` the best function value,
|
|
98
|
+
``nfev`` the number of function evaluations,
|
|
99
|
+
``nit`` the number of CMA-ES iterations,
|
|
100
|
+
``status`` the stopping critera and
|
|
101
|
+
``success`` a Boolean flag indicating if the optimizer exited successfully. """
|
|
102
|
+
|
|
103
|
+
lower, upper, guess = _check_bounds(bounds, x0, rg)
|
|
104
|
+
dim = guess.size
|
|
105
|
+
if popsize is None:
|
|
106
|
+
popsize = 32
|
|
107
|
+
if popsize % 2 == 1: # requires even popsize
|
|
108
|
+
popsize += 1
|
|
109
|
+
if lower is None:
|
|
110
|
+
lower = [0]*dim
|
|
111
|
+
upper = [0]*dim
|
|
112
|
+
if callable(input_sigma):
|
|
113
|
+
input_sigma=input_sigma()
|
|
114
|
+
if np.ndim(input_sigma) == 0:
|
|
115
|
+
input_sigma = [input_sigma] * dim
|
|
116
|
+
parfun = None if (workers is None or workers <= 1) else parallel(fun, workers)
|
|
117
|
+
array_type = ct.c_double * dim
|
|
118
|
+
c_callback_par = call_back_par(callback_par(fun, parfun))
|
|
119
|
+
res = np.empty(dim+4)
|
|
120
|
+
res_p = res.ctypes.data_as(ct.POINTER(ct.c_double))
|
|
121
|
+
try:
|
|
122
|
+
optimizePGPE_C(runid, c_callback_par, dim, array_type(*guess),
|
|
123
|
+
array_type(*lower), array_type(*upper),
|
|
124
|
+
array_type(*input_sigma), max_evaluations, stop_fitness,
|
|
125
|
+
popsize, int(rg.uniform(0, 2**32 - 1)),
|
|
126
|
+
lr_decay_steps, use_ranking, center_learning_rate,
|
|
127
|
+
stdev_learning_rate, stdev_max_change, b1, b2, eps, decay_coef,
|
|
128
|
+
normalize, res_p)
|
|
129
|
+
x = res[:dim]
|
|
130
|
+
val = res[dim]
|
|
131
|
+
evals = int(res[dim+1])
|
|
132
|
+
iterations = int(res[dim+2])
|
|
133
|
+
stop = int(res[dim+3])
|
|
134
|
+
res = OptimizeResult(x=x, fun=val, nfev=evals, nit=iterations, status=stop, success=True)
|
|
135
|
+
except Exception as ex:
|
|
136
|
+
res = OptimizeResult(x=None, fun=sys.float_info.max, nfev=0, nit=0, status=-1, success=False)
|
|
137
|
+
if not parfun is None:
|
|
138
|
+
parfun.stop()
|
|
139
|
+
return res
|
|
140
|
+
|
|
141
|
+
class PGPE_C:
|
|
142
|
+
|
|
143
|
+
def __init__(self,
|
|
144
|
+
dim: int,
|
|
145
|
+
bounds: Optional[Bounds] = None,
|
|
146
|
+
x0: Optional[ArrayLike] = None,
|
|
147
|
+
input_sigma: Optional[Union[float, ArrayLike, Callable]] = 0.1,
|
|
148
|
+
popsize: Optional[int] = 32,
|
|
149
|
+
rg: Optional[Generator] = Generator(PCG64DXSM()),
|
|
150
|
+
runid: Optional[int] = 0,
|
|
151
|
+
normalize: Optional[bool] = True,
|
|
152
|
+
lr_decay_steps: Optional[int] = 1000,
|
|
153
|
+
use_ranking: Optional[bool] = False,
|
|
154
|
+
center_learning_rate: Optional[float] = 0.15,
|
|
155
|
+
stdev_learning_rate: Optional[float] = 0.1,
|
|
156
|
+
stdev_max_change: Optional[float] = 0.2,
|
|
157
|
+
b1: Optional[float] = 0.9,
|
|
158
|
+
b2: Optional[float] = 0.999,
|
|
159
|
+
eps: Optional[float] = 1e-8,
|
|
160
|
+
decay_coef: Optional[float] = 1.0,
|
|
161
|
+
):
|
|
162
|
+
|
|
163
|
+
"""Minimization of a scalar function of one or more variables using a
|
|
164
|
+
C++ CR-FM-NES implementation called via ctypes.
|
|
165
|
+
|
|
166
|
+
Parameters
|
|
167
|
+
----------
|
|
168
|
+
dim : int
|
|
169
|
+
dimension of the argument of the objective function
|
|
170
|
+
bounds : sequence or `Bounds`, optional
|
|
171
|
+
Bounds on variables. There are two ways to specify the bounds:
|
|
172
|
+
1. Instance of the `scipy.Bounds` class.
|
|
173
|
+
2. Sequence of ``(min, max)`` pairs for each element in `x`. None
|
|
174
|
+
is used to specify no bound.
|
|
175
|
+
x0 : ndarray, shape (dim,)
|
|
176
|
+
Initial guess. Array of real elements of size (dim,),
|
|
177
|
+
where 'dim' is the number of independent variables.
|
|
178
|
+
input_sigma : float, optional
|
|
179
|
+
Initial step size.
|
|
180
|
+
popsize = int, optional
|
|
181
|
+
CMA-ES population size.
|
|
182
|
+
max_evaluations : int, optional
|
|
183
|
+
Forced termination after ``max_evaluations`` function evaluations.
|
|
184
|
+
workers : int or None, optional
|
|
185
|
+
If workers > 1, function evaluation is performed in parallel for the whole population.
|
|
186
|
+
Useful for costly objective functions but is deactivated for parallel retry.
|
|
187
|
+
stop_fitness : float, optional
|
|
188
|
+
Limit for fitness value. If reached minimize terminates.
|
|
189
|
+
rg = numpy.random.Generator, optional
|
|
190
|
+
Random generator for creating random guesses.
|
|
191
|
+
runid : int, optional
|
|
192
|
+
id used by the is_terminate callback to identify the CMA-ES run.
|
|
193
|
+
normalize : boolean, optional
|
|
194
|
+
if true pheno -> geno transformation maps arguments to interval [-1,1]
|
|
195
|
+
lr_decay_steps int, optional - ADAM optimizer configuration
|
|
196
|
+
use_ranking : boolean, optional - Should we treat the fitness as rankings or not.
|
|
197
|
+
center_learning_rate : float, optional - Learning rate for the Gaussian mean.
|
|
198
|
+
stdev_learning_rate : float, optional - Learning rate for the Gaussian stdev.
|
|
199
|
+
init_stdev : float, optional - Initial stdev for the Gaussian distribution.
|
|
200
|
+
stdev_max_change : float, optional - Maximum allowed change for stdev in abs values.
|
|
201
|
+
b1 : float, optional - ADAM optimizer configuration
|
|
202
|
+
b2 : float, optional - ADAM optimizer configuration
|
|
203
|
+
eps : float, optional - ADAM optimizer configuration
|
|
204
|
+
decay_coef : float, optional - ADAM optimizer configuration"""
|
|
205
|
+
|
|
206
|
+
lower, upper, guess = _get_bounds(dim, bounds, x0, rg)
|
|
207
|
+
if popsize is None:
|
|
208
|
+
popsize = 32
|
|
209
|
+
if popsize % 2 == 1: # requires even popsize
|
|
210
|
+
popsize += 1
|
|
211
|
+
if lower is None:
|
|
212
|
+
lower = [0]*dim
|
|
213
|
+
upper = [0]*dim
|
|
214
|
+
if callable(input_sigma):
|
|
215
|
+
input_sigma=input_sigma()
|
|
216
|
+
if np.ndim(input_sigma) == 0:
|
|
217
|
+
input_sigma = [input_sigma] * dim
|
|
218
|
+
array_type = ct.c_double * dim
|
|
219
|
+
try:
|
|
220
|
+
self.ptr = initPGPE_C(runid, dim, array_type(*guess),
|
|
221
|
+
array_type(*lower), array_type(*upper),
|
|
222
|
+
array_type(*input_sigma), popsize, int(rg.uniform(0, 2**32 - 1)),
|
|
223
|
+
lr_decay_steps, use_ranking, center_learning_rate,
|
|
224
|
+
stdev_learning_rate, stdev_max_change, b1, b2, eps, decay_coef,
|
|
225
|
+
normalize)
|
|
226
|
+
self.popsize = popsize
|
|
227
|
+
self.dim = dim
|
|
228
|
+
except Exception as ex:
|
|
229
|
+
print (ex)
|
|
230
|
+
pass
|
|
231
|
+
|
|
232
|
+
def __del__(self):
|
|
233
|
+
destroyPGPE_C(self.ptr)
|
|
234
|
+
|
|
235
|
+
def ask(self) -> np.array:
|
|
236
|
+
"""ask for popsize new argument vectors.
|
|
237
|
+
|
|
238
|
+
Returns
|
|
239
|
+
-------
|
|
240
|
+
xs : popsize sized list of dim sized argument lists."""
|
|
241
|
+
|
|
242
|
+
try:
|
|
243
|
+
lamb = self.popsize
|
|
244
|
+
n = self.dim
|
|
245
|
+
res = np.empty(lamb*n)
|
|
246
|
+
res_p = res.ctypes.data_as(ct.POINTER(ct.c_double))
|
|
247
|
+
askPGPE_C(self.ptr, res_p)
|
|
248
|
+
xs = np.empty((lamb, n))
|
|
249
|
+
for p in range(lamb):
|
|
250
|
+
xs[p,:] = res[p*n : (p+1)*n]
|
|
251
|
+
return xs
|
|
252
|
+
except Exception as ex:
|
|
253
|
+
print (ex)
|
|
254
|
+
return None
|
|
255
|
+
|
|
256
|
+
def tell(self,
|
|
257
|
+
ys: np.ndarray) -> int:
|
|
258
|
+
"""tell function values for the argument lists retrieved by ask().
|
|
259
|
+
|
|
260
|
+
Parameters
|
|
261
|
+
----------
|
|
262
|
+
ys : popsize sized list of function values
|
|
263
|
+
|
|
264
|
+
Returns
|
|
265
|
+
-------
|
|
266
|
+
stop : int termination criteria, if != 0 loop should stop."""
|
|
267
|
+
|
|
268
|
+
try:
|
|
269
|
+
array_type_ys = ct.c_double * len(ys)
|
|
270
|
+
return tellPGPE_C(self.ptr, array_type_ys(*ys))
|
|
271
|
+
except Exception as ex:
|
|
272
|
+
print (ex)
|
|
273
|
+
return -1
|
|
274
|
+
|
|
275
|
+
def population(self) -> np.array:
|
|
276
|
+
try:
|
|
277
|
+
lamb = self.popsize
|
|
278
|
+
n = self.dim
|
|
279
|
+
res = np.empty(lamb*n)
|
|
280
|
+
res_p = res.ctypes.data_as(ct.POINTER(ct.c_double))
|
|
281
|
+
populationPGPE_C(self.ptr, res_p)
|
|
282
|
+
xs = np.array(lamb, n)
|
|
283
|
+
for p in range(lamb):
|
|
284
|
+
xs[p] = res[p*n : (p+1)*n]
|
|
285
|
+
return xs
|
|
286
|
+
except Exception as ex:
|
|
287
|
+
print (ex)
|
|
288
|
+
return None
|
|
289
|
+
|
|
290
|
+
def result(self) -> OptimizeResult:
|
|
291
|
+
res = np.empty(self.dim+4)
|
|
292
|
+
res_p = res.ctypes.data_as(ct.POINTER(ct.c_double))
|
|
293
|
+
try:
|
|
294
|
+
resultPGPE_C(self.ptr, res_p)
|
|
295
|
+
x = res[:self.dim]
|
|
296
|
+
val = res[self.dim]
|
|
297
|
+
evals = int(res[self.dim+1])
|
|
298
|
+
iterations = int(res[self.dim+2])
|
|
299
|
+
stop = int(res[self.dim+3])
|
|
300
|
+
res = OptimizeResult(x=x, fun=val, nfev=evals, nit=iterations, status=stop, success=True)
|
|
301
|
+
except Exception as ex:
|
|
302
|
+
res = OptimizeResult(x=None, fun=sys.float_info.max, nfev=0, nit=0, status=-1, success=False)
|
|
303
|
+
return res
|
|
304
|
+
|
|
305
|
+
if not libcmalib is None:
|
|
306
|
+
|
|
307
|
+
optimizePGPE_C = libcmalib.optimizePGPE_C
|
|
308
|
+
optimizePGPE_C.argtypes = [ct.c_long, call_back_par, ct.c_int, \
|
|
309
|
+
ct.POINTER(ct.c_double), ct.POINTER(ct.c_double), ct.POINTER(ct.c_double), \
|
|
310
|
+
ct.POINTER(ct.c_double), ct.c_int, ct.c_double, ct.c_int,
|
|
311
|
+
ct.c_long, ct.c_int,
|
|
312
|
+
ct.c_bool, ct.c_double, ct.c_double, ct.c_double,
|
|
313
|
+
ct.c_double, ct.c_double, ct.c_double, ct.c_double,
|
|
314
|
+
ct.c_bool, ct.POINTER(ct.c_double)]
|
|
315
|
+
|
|
316
|
+
initPGPE_C = libcmalib.initPGPE_C
|
|
317
|
+
initPGPE_C.argtypes = [ct.c_long, ct.c_int, ct.POINTER(ct.c_double),
|
|
318
|
+
ct.POINTER(ct.c_double), ct.POINTER(ct.c_double), ct.POINTER(ct.c_double),
|
|
319
|
+
ct.c_int, ct.c_long, ct.c_int,
|
|
320
|
+
ct.c_bool, ct.c_double, ct.c_double, ct.c_double,
|
|
321
|
+
ct.c_double, ct.c_double, ct.c_double, ct.c_double,
|
|
322
|
+
ct.c_bool]
|
|
323
|
+
|
|
324
|
+
initPGPE_C.restype = ct.c_void_p
|
|
325
|
+
|
|
326
|
+
destroyPGPE_C = libcmalib.destroyPGPE_C
|
|
327
|
+
destroyPGPE_C.argtypes = [ct.c_void_p]
|
|
328
|
+
|
|
329
|
+
askPGPE_C = libcmalib.askPGPE_C
|
|
330
|
+
askPGPE_C.argtypes = [ct.c_void_p, ct.POINTER(ct.c_double)]
|
|
331
|
+
|
|
332
|
+
tellPGPE_C = libcmalib.tellPGPE_C
|
|
333
|
+
tellPGPE_C.argtypes = [ct.c_void_p, ct.POINTER(ct.c_double)]
|
|
334
|
+
tellPGPE_C.restype = ct.c_int
|
|
335
|
+
|
|
336
|
+
populationPGPE_C = libcmalib.populationPGPE_C
|
|
337
|
+
populationPGPE_C.argtypes = [ct.c_void_p, ct.POINTER(ct.c_double)]
|
|
338
|
+
|
|
339
|
+
resultPGPE_C = libcmalib.resultPGPE_C
|
|
340
|
+
resultPGPE_C.argtypes = [ct.c_void_p, ct.POINTER(ct.c_double)]
|
fcmaes/pygmoretry.py
CHANGED
|
@@ -6,12 +6,12 @@
|
|
|
6
6
|
import math
|
|
7
7
|
import os
|
|
8
8
|
import sys
|
|
9
|
-
|
|
9
|
+
import numpy as np
|
|
10
|
+
from numpy.random import Generator, PCG64DXSM, SeedSequence
|
|
10
11
|
from scipy.optimize import OptimizeResult, Bounds
|
|
11
12
|
import multiprocessing as mp
|
|
12
13
|
from multiprocessing import Process
|
|
13
14
|
from fcmaes.retry import Store
|
|
14
|
-
from fcmaes.optimizer import logger
|
|
15
15
|
|
|
16
16
|
os.environ['MKL_DEBUG_CPU_TYPE'] = '5'
|
|
17
17
|
os.environ['MKL_NUM_THREADS'] = '1'
|
|
@@ -19,12 +19,11 @@ os.environ['OPENBLAS_NUM_THREADS'] = '1'
|
|
|
19
19
|
|
|
20
20
|
def minimize(prob,
|
|
21
21
|
algo,
|
|
22
|
-
value_limit =
|
|
22
|
+
value_limit = np.inf,
|
|
23
23
|
num_retries = 100*mp.cpu_count(),
|
|
24
|
-
logger = None,
|
|
25
24
|
workers = mp.cpu_count(),
|
|
26
25
|
popsize = 1,
|
|
27
|
-
):
|
|
26
|
+
) -> OptimizeResult:
|
|
28
27
|
"""Minimization of a scalar function of one or more variables using parallel retry.
|
|
29
28
|
Similar to fcmaes.retry but works with pygmo / pagmo problems + algorithms.
|
|
30
29
|
For problems with equality/inequality contraints or multiple objectives fcmaes.retry cannot
|
|
@@ -44,10 +43,6 @@ def minimize(prob,
|
|
|
44
43
|
Upper limit for optimized function values to be stored.
|
|
45
44
|
num_retries : int, optional
|
|
46
45
|
Number of optimization retries.
|
|
47
|
-
logger : logger, optional
|
|
48
|
-
logger for log output of the retry mechanism. If None, logging
|
|
49
|
-
is switched off. Default is a logger which logs both to stdout and
|
|
50
|
-
appends to a file ``optimizer.log``.
|
|
51
46
|
workers : int, optional
|
|
52
47
|
number of parallel processes used. Default is mp.cpu_count()
|
|
53
48
|
popsize = int, optional
|
|
@@ -63,30 +58,26 @@ def minimize(prob,
|
|
|
63
58
|
|
|
64
59
|
lb, ub = prob.get_bounds()
|
|
65
60
|
bounds = Bounds(lb, ub)
|
|
66
|
-
store = Store(bounds
|
|
61
|
+
store = Store(bounds)
|
|
67
62
|
return retry(store, prob, algo, num_retries, value_limit, popsize, workers)
|
|
68
63
|
|
|
69
|
-
def retry(store, prob, algo, num_retries, value_limit =
|
|
64
|
+
def retry(store, prob, algo, num_retries, value_limit = np.inf, popsize=1, workers=mp.cpu_count()):
|
|
70
65
|
try:
|
|
71
66
|
import pygmo as pg
|
|
72
67
|
except ImportError as e:
|
|
73
68
|
raise ImportError("Please install PYGMO (pip install pygmo) to use PAGMO optimizers") from e
|
|
74
69
|
sg = SeedSequence()
|
|
75
|
-
rgs = [Generator(
|
|
70
|
+
rgs = [Generator(PCG64DXSM(s)) for s in sg.spawn(workers)]
|
|
76
71
|
proc=[Process(target=_retry_loop,
|
|
77
72
|
args=(pid, rgs, store, prob, algo, num_retries, value_limit, popsize, pg)) for pid in range(workers)]
|
|
78
73
|
[p.start() for p in proc]
|
|
79
74
|
[p.join() for p in proc]
|
|
80
|
-
store.sort()
|
|
75
|
+
store.sort(store.get_xs())
|
|
81
76
|
store.dump()
|
|
82
77
|
return OptimizeResult(x=store.get_x_best(), fun=store.get_y_best(),
|
|
83
78
|
nfev=store.get_count_evals(), success=True)
|
|
84
79
|
|
|
85
80
|
def _retry_loop(pid, rgs, store, prob, algo, num_retries, value_limit, popsize, pg):
|
|
86
|
-
|
|
87
|
-
#reinitialize logging config for windows - multi threading fix
|
|
88
|
-
if 'win' in sys.platform and not store.logger is None:
|
|
89
|
-
store.logger = logger()
|
|
90
81
|
|
|
91
82
|
while store.get_runs_compare_incr(num_retries):
|
|
92
83
|
try:
|