fcmaes 1.1.3__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 +12 -2
- fcmaes/advretry.py +217 -159
- fcmaes/astro.py +143 -27
- fcmaes/bitecpp.py +107 -0
- fcmaes/cmaes.py +204 -173
- fcmaes/cmaescpp.py +253 -87
- fcmaes/crfmnes.py +339 -0
- fcmaes/crfmnescpp.py +273 -0
- fcmaes/dacpp.py +39 -51
- fcmaes/de.py +472 -0
- fcmaes/decpp.py +222 -64
- fcmaes/diversifier.py +357 -0
- fcmaes/evaluator.py +297 -14
- 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/lib/librw_top_trumps.dll +0 -0
- fcmaes/lib/librw_top_trumps.so +0 -0
- fcmaes/mapelites.py +737 -0
- fcmaes/mode.py +719 -0
- fcmaes/modecpp.py +470 -0
- fcmaes/moretry.py +270 -0
- fcmaes/multiretry.py +195 -0
- fcmaes/optimizer.py +883 -112
- fcmaes/pgpecpp.py +340 -0
- fcmaes/pygmoretry.py +10 -19
- fcmaes/retry.py +248 -121
- fcmaes/test_cma.py +207 -30
- fcmaes/testfun.py +38 -1
- {fcmaes-1.1.3.dist-info → fcmaes-1.6.9.dist-info}/METADATA +22 -12
- fcmaes-1.6.9.dist-info/RECORD +36 -0
- {fcmaes-1.1.3.dist-info → fcmaes-1.6.9.dist-info}/WHEEL +1 -1
- fcmaes/hhcpp.py +0 -114
- fcmaes/lib/libgtoplib.dll +0 -0
- fcmaes/lib/libgtoplib.so +0 -0
- fcmaes-1.1.3.dist-info/RECORD +0 -23
- {fcmaes-1.1.3.dist-info → fcmaes-1.6.9.dist-info}/LICENSE +0 -0
- {fcmaes-1.1.3.dist-info → fcmaes-1.6.9.dist-info}/top_level.txt +0 -0
fcmaes/decpp.py
CHANGED
|
@@ -3,34 +3,52 @@
|
|
|
3
3
|
# This source code is licensed under the MIT license found in the
|
|
4
4
|
# LICENSE file in the root directory.
|
|
5
5
|
|
|
6
|
-
"""Eigen based implementation of differential evolution using
|
|
7
|
-
Uses
|
|
6
|
+
"""Eigen based implementation of differential evolution using the DE/best/1 strategy.
|
|
7
|
+
Uses three deviations from the standard DE algorithm:
|
|
8
8
|
a) temporal locality introduced in
|
|
9
9
|
https://www.researchgate.net/publication/309179699_Differential_evolution_for_protein_folding_optimization_based_on_a_three-dimensional_AB_off-lattice_model
|
|
10
|
-
b) reinitialization of individuals based on their age.
|
|
11
|
-
|
|
10
|
+
b) reinitialization of individuals based on their age.
|
|
11
|
+
c) oscillating CR/F parameters.
|
|
12
|
+
|
|
13
|
+
The ints parameter is a boolean array indicating which parameters are discrete integer values. This
|
|
14
|
+
parameter was introduced after observing non optimal results for the ESP2 benchmark problem:
|
|
15
|
+
https://github.com/AlgTUDelft/ExpensiveOptimBenchmark/blob/master/expensiveoptimbenchmark/problems/DockerCFDBenchmark.py
|
|
16
|
+
If defined it causes a "special treatment" for discrete variables: They are rounded to the next integer value and
|
|
17
|
+
there is an additional mutation to avoid getting stuck to local minima."""
|
|
18
|
+
|
|
12
19
|
import sys
|
|
13
20
|
import os
|
|
14
|
-
import math
|
|
15
21
|
import ctypes as ct
|
|
16
22
|
import numpy as np
|
|
17
|
-
from numpy.random import
|
|
18
|
-
from scipy.optimize import OptimizeResult
|
|
19
|
-
from fcmaes.
|
|
23
|
+
from numpy.random import PCG64DXSM, Generator
|
|
24
|
+
from scipy.optimize import OptimizeResult, Bounds
|
|
25
|
+
from fcmaes.evaluator import mo_call_back_type, callback_so, libcmalib
|
|
26
|
+
from fcmaes.de import _check_bounds
|
|
27
|
+
|
|
28
|
+
from typing import Optional, Callable, Tuple, Union
|
|
29
|
+
from numpy.typing import ArrayLike
|
|
20
30
|
|
|
21
31
|
os.environ['MKL_DEBUG_CPU_TYPE'] = '5'
|
|
22
32
|
|
|
23
|
-
def minimize(fun,
|
|
24
|
-
dim,
|
|
25
|
-
bounds = None,
|
|
26
|
-
popsize =
|
|
27
|
-
max_evaluations = 100000,
|
|
28
|
-
|
|
29
|
-
keep = 200
|
|
30
|
-
f = 0.5,
|
|
31
|
-
cr = 0.9,
|
|
32
|
-
rg = Generator(
|
|
33
|
-
|
|
33
|
+
def minimize(fun: Callable[[ArrayLike], float],
|
|
34
|
+
dim: Optional[int] = None,
|
|
35
|
+
bounds: Optional[Bounds] = None,
|
|
36
|
+
popsize: Optional[int] = 31,
|
|
37
|
+
max_evaluations: Optional[int] = 100000,
|
|
38
|
+
stop_fitness: Optional[float] = -np.inf,
|
|
39
|
+
keep: Optional[int] = 200,
|
|
40
|
+
f: Optional[float] = 0.5,
|
|
41
|
+
cr: Optional[float] = 0.9,
|
|
42
|
+
rg: Optional[Generator] = Generator(PCG64DXSM()),
|
|
43
|
+
ints: Optional[ArrayLike] = None,
|
|
44
|
+
min_mutate: Optional[float] = 0.1,
|
|
45
|
+
max_mutate: Optional[float] = 0.5,
|
|
46
|
+
workers: Optional[int] = 1,
|
|
47
|
+
is_terminate: Optional[Callable[[ArrayLike, float], bool]] = None,
|
|
48
|
+
x0: Optional[ArrayLike] = None,
|
|
49
|
+
input_sigma: Optional[Union[float, ArrayLike, Callable]] = None,
|
|
50
|
+
min_sigma: Optional[float] = 0,
|
|
51
|
+
runid: Optional[int] = 0) -> OptimizeResult:
|
|
34
52
|
|
|
35
53
|
"""Minimization of a scalar function of one or more variables using a
|
|
36
54
|
C++ Differential Evolution implementation called via ctypes.
|
|
@@ -39,10 +57,8 @@ def minimize(fun,
|
|
|
39
57
|
----------
|
|
40
58
|
fun : callable
|
|
41
59
|
The objective function to be minimized.
|
|
42
|
-
``fun(x
|
|
43
|
-
where ``x`` is an 1-D array with shape (
|
|
44
|
-
is a tuple of the fixed parameters needed to completely
|
|
45
|
-
specify the function.
|
|
60
|
+
``fun(x) -> float``
|
|
61
|
+
where ``x`` is an 1-D array with shape (dim,)
|
|
46
62
|
dim : int
|
|
47
63
|
dimension of the argument of the objective function
|
|
48
64
|
bounds : sequence or `Bounds`, optional
|
|
@@ -50,9 +66,11 @@ def minimize(fun,
|
|
|
50
66
|
1. Instance of the `scipy.Bounds` class.
|
|
51
67
|
2. Sequence of ``(min, max)`` pairs for each element in `x`. None
|
|
52
68
|
is used to specify no bound.
|
|
69
|
+
popsize : int, optional
|
|
70
|
+
Population size.
|
|
53
71
|
max_evaluations : int, optional
|
|
54
72
|
Forced termination after ``max_evaluations`` function evaluations.
|
|
55
|
-
|
|
73
|
+
stop_fitness : float, optional
|
|
56
74
|
Limit for fitness value. If reached minimize terminates.
|
|
57
75
|
keep = float, optional
|
|
58
76
|
changes the reinitialization probability of individuals based on their age. Higher value
|
|
@@ -65,8 +83,27 @@ def minimize(fun,
|
|
|
65
83
|
In the literature this is also known as the crossover probability.
|
|
66
84
|
rg = numpy.random.Generator, optional
|
|
67
85
|
Random generator for creating random guesses.
|
|
86
|
+
ints = list or array of bool, optional
|
|
87
|
+
indicating which parameters are discrete integer values. If defined these parameters will be
|
|
88
|
+
rounded to the next integer and some additional mutation of discrete parameters are performed.
|
|
89
|
+
min_mutate = float, optional
|
|
90
|
+
Determines the minimal mutation rate for discrete integer parameters.
|
|
91
|
+
max_mutate = float, optional
|
|
92
|
+
Determines the maximal mutation rate for discrete integer parameters.
|
|
93
|
+
workers : int or None, optional
|
|
94
|
+
If not workers is None, function evaluation is performed in parallel for the whole population.
|
|
95
|
+
Useful for costly objective functions but is deactivated for parallel retry.
|
|
96
|
+
is_terminate : callable, optional
|
|
97
|
+
Callback to be used if the caller of minimize wants to decide when to terminate.
|
|
98
|
+
x0 : ndarray, shape (dim,)
|
|
99
|
+
Initial guess. Array of real elements of size (dim,),
|
|
100
|
+
where 'dim' is the number of independent variables.
|
|
101
|
+
input_sigma : ndarray, shape (dim,) or scalar
|
|
102
|
+
Initial sigma for each dimension.
|
|
103
|
+
min_sigma = float, optional
|
|
104
|
+
minimal sigma limit. If 0, uniform random distribution is used (requires bounds).
|
|
68
105
|
runid : int, optional
|
|
69
|
-
id used to identify the
|
|
106
|
+
id used to identify the run for debugging / logging.
|
|
70
107
|
|
|
71
108
|
Returns
|
|
72
109
|
-------
|
|
@@ -77,52 +114,173 @@ def minimize(fun,
|
|
|
77
114
|
``nfev`` the number of function evaluations,
|
|
78
115
|
``nit`` the number of iterations,
|
|
79
116
|
``success`` a Boolean flag indicating if the optimizer exited successfully. """
|
|
80
|
-
|
|
81
|
-
lower =
|
|
82
|
-
upper = np.asarray(bounds.ub)
|
|
83
|
-
n = dim
|
|
117
|
+
|
|
118
|
+
dim, lower, upper = _check_bounds(bounds, dim)
|
|
84
119
|
if popsize is None:
|
|
85
|
-
popsize =
|
|
86
|
-
if
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
120
|
+
popsize = 31
|
|
121
|
+
if not input_sigma is None:
|
|
122
|
+
if callable(input_sigma):
|
|
123
|
+
input_sigma=input_sigma()
|
|
124
|
+
if np.ndim(input_sigma) == 0:
|
|
125
|
+
input_sigma = [input_sigma] * dim
|
|
126
|
+
if workers is None:
|
|
127
|
+
workers = 0
|
|
128
|
+
array_type = ct.c_double * dim
|
|
129
|
+
bool_array_type = ct.c_bool * dim
|
|
130
|
+
c_callback = mo_call_back_type(callback_so(fun, dim, is_terminate))
|
|
93
131
|
seed = int(rg.uniform(0, 2**32 - 1))
|
|
132
|
+
res = np.empty(dim+4)
|
|
133
|
+
res_p = res.ctypes.data_as(ct.POINTER(ct.c_double))
|
|
94
134
|
try:
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
135
|
+
optimizeDE_C(runid, c_callback, dim, seed,
|
|
136
|
+
None if lower is None else array_type(*lower),
|
|
137
|
+
None if upper is None else array_type(*upper),
|
|
138
|
+
None if x0 is None else array_type(*x0),
|
|
139
|
+
None if input_sigma is None else array_type(*input_sigma),
|
|
140
|
+
min_sigma,
|
|
141
|
+
None if ints is None else bool_array_type(*ints),
|
|
142
|
+
max_evaluations, keep, stop_fitness,
|
|
143
|
+
popsize, f, cr, min_mutate, max_mutate, workers, res_p)
|
|
144
|
+
x = res[:dim]
|
|
145
|
+
val = res[dim]
|
|
146
|
+
evals = int(res[dim+1])
|
|
147
|
+
iterations = int(res[dim+2])
|
|
148
|
+
stop = int(res[dim+3])
|
|
105
149
|
return OptimizeResult(x=x, fun=val, nfev=evals, nit=iterations, status=stop, success=True)
|
|
106
150
|
except Exception as ex:
|
|
107
151
|
return OptimizeResult(x=None, fun=sys.float_info.max, nfev=0, nit=0, status=-1, success=False)
|
|
108
152
|
|
|
109
|
-
|
|
153
|
+
class DE_C:
|
|
154
|
+
|
|
155
|
+
def __init__(self,
|
|
156
|
+
dim: Optional[int] = None,
|
|
157
|
+
bounds: Optional[Bounds] = None,
|
|
158
|
+
popsize: Optional[int] = 31,
|
|
159
|
+
keep: Optional[int] = 200,
|
|
160
|
+
f: Optional[float] = 0.5,
|
|
161
|
+
cr: Optional[float] = 0.9,
|
|
162
|
+
rg: Optional[Generator] = Generator(PCG64DXSM()),
|
|
163
|
+
ints: Optional[ArrayLike] = None,
|
|
164
|
+
min_mutate: Optional[float] = 0.1,
|
|
165
|
+
max_mutate: Optional[float] = 0.5,
|
|
166
|
+
x0: Optional[ArrayLike] = None,
|
|
167
|
+
input_sigma: Optional[Union[float, ArrayLike, Callable]] = 0.3,
|
|
168
|
+
min_sigma: Optional[float] = 0,
|
|
169
|
+
):
|
|
170
|
+
dim, lower, upper = _check_bounds(bounds, dim)
|
|
171
|
+
if popsize is None:
|
|
172
|
+
popsize = 31
|
|
173
|
+
if callable(input_sigma):
|
|
174
|
+
input_sigma=input_sigma()
|
|
175
|
+
if np.ndim(input_sigma) == 0:
|
|
176
|
+
input_sigma = [input_sigma] * dim
|
|
177
|
+
if ints is None:
|
|
178
|
+
ints = [False]*dim
|
|
179
|
+
array_type = ct.c_double * dim
|
|
180
|
+
bool_array_type = ct.c_bool * dim
|
|
181
|
+
seed = int(rg.uniform(0, 2**32 - 1))
|
|
182
|
+
try:
|
|
183
|
+
self.ptr = initDE_C(0, dim, seed,
|
|
184
|
+
array_type(*lower), array_type(*upper),
|
|
185
|
+
array_type(*x0), array_type(*input_sigma), min_sigma,
|
|
186
|
+
bool_array_type(*ints),
|
|
187
|
+
keep, popsize, f, cr, min_mutate, max_mutate)
|
|
188
|
+
self.popsize = popsize
|
|
189
|
+
self.dim = dim
|
|
190
|
+
except Exception as ex:
|
|
191
|
+
print (ex)
|
|
192
|
+
pass
|
|
193
|
+
|
|
194
|
+
def __del__(self):
|
|
195
|
+
destroyDE_C(self.ptr)
|
|
196
|
+
|
|
197
|
+
def ask(self) -> np.array:
|
|
198
|
+
try:
|
|
199
|
+
popsize = self.popsize
|
|
200
|
+
n = self.dim
|
|
201
|
+
res = np.empty(popsize*n)
|
|
202
|
+
res_p = res.ctypes.data_as(ct.POINTER(ct.c_double))
|
|
203
|
+
askDE_C(self.ptr, res_p)
|
|
204
|
+
xs = np.empty((popsize, n))
|
|
205
|
+
for p in range(popsize):
|
|
206
|
+
xs[p,:] = res[p*n : (p+1)*n]
|
|
207
|
+
return xs
|
|
208
|
+
except Exception as ex:
|
|
209
|
+
print (ex)
|
|
210
|
+
return None
|
|
211
|
+
|
|
212
|
+
def tell(self, ys: np.ndarray):
|
|
213
|
+
try:
|
|
214
|
+
array_type_ys = ct.c_double * len(ys)
|
|
215
|
+
return tellDE_C(self.ptr, array_type_ys(*ys))
|
|
216
|
+
except Exception as ex:
|
|
217
|
+
print (ex)
|
|
218
|
+
return -1
|
|
219
|
+
|
|
220
|
+
def population(self) -> np.array:
|
|
221
|
+
try:
|
|
222
|
+
popsize = self.popsize
|
|
223
|
+
n = self.dim
|
|
224
|
+
res = np.empty(popsize*n)
|
|
225
|
+
res_p = res.ctypes.data_as(ct.POINTER(ct.c_double))
|
|
226
|
+
populationDE_C(self.ptr, res_p)
|
|
227
|
+
xs = np.array(popsize, n)
|
|
228
|
+
for p in range(popsize):
|
|
229
|
+
xs[p] = res[p*n : (p+1)*n]
|
|
230
|
+
return xs
|
|
231
|
+
except Exception as ex:
|
|
232
|
+
print (ex)
|
|
233
|
+
return None
|
|
110
234
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
235
|
+
def result(self) -> OptimizeResult:
|
|
236
|
+
res = np.empty(self.dim+4)
|
|
237
|
+
res_p = res.ctypes.data_as(ct.POINTER(ct.c_double))
|
|
238
|
+
try:
|
|
239
|
+
resultDE_C(self.ptr, res_p)
|
|
240
|
+
x = res[:self.dim]
|
|
241
|
+
val = res[self.dim]
|
|
242
|
+
evals = int(res[self.dim+1])
|
|
243
|
+
iterations = int(res[self.dim+2])
|
|
244
|
+
stop = int(res[self.dim+3])
|
|
245
|
+
res = OptimizeResult(x=x, fun=val, nfev=evals, nit=iterations, status=stop, success=True)
|
|
246
|
+
except Exception as ex:
|
|
247
|
+
res = OptimizeResult(x=None, fun=sys.float_info.max, nfev=0, nit=0, status=-1, success=False)
|
|
248
|
+
return res
|
|
117
249
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
optimizeDE_C
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
250
|
+
if not libcmalib is None:
|
|
251
|
+
|
|
252
|
+
optimizeDE_C = libcmalib.optimizeDE_C
|
|
253
|
+
optimizeDE_C.argtypes = [ct.c_long, mo_call_back_type, ct.c_int, ct.c_int, \
|
|
254
|
+
ct.POINTER(ct.c_double), ct.POINTER(ct.c_double), \
|
|
255
|
+
ct.POINTER(ct.c_double), ct.POINTER(ct.c_double), ct.c_double, \
|
|
256
|
+
ct.POINTER(ct.c_bool), \
|
|
257
|
+
ct.c_int, ct.c_double, ct.c_double, ct.c_int, \
|
|
258
|
+
ct.c_double, ct.c_double, ct.c_double, ct.c_double,
|
|
259
|
+
ct.c_int, ct.POINTER(ct.c_double)]
|
|
260
|
+
|
|
261
|
+
initDE_C = libcmalib.initDE_C
|
|
262
|
+
initDE_C.argtypes = [ct.c_long, ct.c_int, ct.c_int, \
|
|
263
|
+
ct.POINTER(ct.c_double), ct.POINTER(ct.c_double), \
|
|
264
|
+
ct.POINTER(ct.c_double), ct.POINTER(ct.c_double), ct.c_double, \
|
|
265
|
+
ct.POINTER(ct.c_bool), \
|
|
266
|
+
ct.c_double, ct.c_int, \
|
|
267
|
+
ct.c_double, ct.c_double, ct.c_double, ct.c_double]
|
|
268
|
+
|
|
269
|
+
initDE_C.restype = ct.c_void_p
|
|
270
|
+
|
|
271
|
+
destroyDE_C = libcmalib.destroyDE_C
|
|
272
|
+
destroyDE_C.argtypes = [ct.c_void_p]
|
|
273
|
+
|
|
274
|
+
askDE_C = libcmalib.askDE_C
|
|
275
|
+
askDE_C.argtypes = [ct.c_void_p, ct.POINTER(ct.c_double)]
|
|
276
|
+
|
|
277
|
+
tellDE_C = libcmalib.tellDE_C
|
|
278
|
+
tellDE_C.argtypes = [ct.c_void_p, ct.POINTER(ct.c_double)]
|
|
279
|
+
tellDE_C.restype = ct.c_int
|
|
280
|
+
|
|
281
|
+
populationDE_C = libcmalib.populationDE_C
|
|
282
|
+
populationDE_C.argtypes = [ct.c_void_p, ct.POINTER(ct.c_double)]
|
|
283
|
+
|
|
284
|
+
resultDE_C = libcmalib.resultDE_C
|
|
285
|
+
resultDE_C.argtypes = [ct.c_void_p, ct.POINTER(ct.c_double)]
|
|
124
286
|
|
|
125
|
-
optimizeDE_C.restype = ct.POINTER(ct.c_double)
|
|
126
|
-
freemem = libcmalib.free_mem
|
|
127
|
-
freemem.argtypes = [ct.POINTER(ct.c_double)]
|
|
128
|
-
|