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/crfmnescpp.py
ADDED
|
@@ -0,0 +1,273 @@
|
|
|
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
|
+
""" Eigen based implementation of Fast Moving Natural Evolution Strategy
|
|
7
|
+
for High-Dimensional Problems (CR-FM-NES), see https://arxiv.org/abs/2201.11422 .
|
|
8
|
+
Derived from https://github.com/nomuramasahir0/crfmnes .
|
|
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 = 0.3,
|
|
29
|
+
popsize = 32,
|
|
30
|
+
max_evaluations = 100000,
|
|
31
|
+
workers = None,
|
|
32
|
+
stop_fitness = -np.inf,
|
|
33
|
+
rg = Generator(PCG64DXSM()),
|
|
34
|
+
runid=0,
|
|
35
|
+
normalize = False,
|
|
36
|
+
use_constraint_violation = True,
|
|
37
|
+
penalty_coef = 1E5
|
|
38
|
+
) -> OptimizeResult:
|
|
39
|
+
|
|
40
|
+
"""Minimization of a scalar function of one or more variables using a
|
|
41
|
+
C++ CR-FM-NES implementation called via ctypes.
|
|
42
|
+
|
|
43
|
+
Parameters
|
|
44
|
+
----------
|
|
45
|
+
fun : callable
|
|
46
|
+
The objective function to be minimized.
|
|
47
|
+
``fun(x) -> float``
|
|
48
|
+
where ``x`` is an 1-D array with shape (dim,)
|
|
49
|
+
bounds : sequence or `Bounds`, optional
|
|
50
|
+
Bounds on variables. There are two ways to specify the bounds:
|
|
51
|
+
1. Instance of the `scipy.Bounds` class.
|
|
52
|
+
2. Sequence of ``(min, max)`` pairs for each element in `x`. None
|
|
53
|
+
is used to specify no bound.
|
|
54
|
+
x0 : ndarray, shape (dim,)
|
|
55
|
+
Initial guess. Array of real elements of size (dim,),
|
|
56
|
+
where 'dim' is the number of independent variables.
|
|
57
|
+
input_sigma : float, optional
|
|
58
|
+
Initial step size.
|
|
59
|
+
popsize = int, optional
|
|
60
|
+
CMA-ES population size.
|
|
61
|
+
max_evaluations : int, optional
|
|
62
|
+
Forced termination after ``max_evaluations`` function evaluations.
|
|
63
|
+
workers : int or None, optional
|
|
64
|
+
If workers > 1, function evaluation is performed in parallel for the whole population.
|
|
65
|
+
Useful for costly objective functions but is deactivated for parallel retry.
|
|
66
|
+
stop_fitness : float, optional
|
|
67
|
+
Limit for fitness value. If reached minimize terminates.
|
|
68
|
+
rg = numpy.random.Generator, optional
|
|
69
|
+
Random generator for creating random guesses.
|
|
70
|
+
runid : int, optional
|
|
71
|
+
id used by the is_terminate callback to identify the CMA-ES run.
|
|
72
|
+
normalize : boolean, optional
|
|
73
|
+
if true pheno -> geno transformation maps arguments to interval [-1,1]
|
|
74
|
+
|
|
75
|
+
Returns
|
|
76
|
+
-------
|
|
77
|
+
res : scipy.OptimizeResult
|
|
78
|
+
The optimization result is represented as an ``OptimizeResult`` object.
|
|
79
|
+
Important attributes are: ``x`` the solution array,
|
|
80
|
+
``fun`` the best function value,
|
|
81
|
+
``nfev`` the number of function evaluations,
|
|
82
|
+
``nit`` the number of CMA-ES iterations,
|
|
83
|
+
``status`` the stopping critera and
|
|
84
|
+
``success`` a Boolean flag indicating if the optimizer exited successfully. """
|
|
85
|
+
|
|
86
|
+
lower, upper, guess = _check_bounds(bounds, x0, rg)
|
|
87
|
+
dim = guess.size
|
|
88
|
+
if popsize is None:
|
|
89
|
+
popsize = 32
|
|
90
|
+
if popsize % 2 == 1: # requires even popsize
|
|
91
|
+
popsize += 1
|
|
92
|
+
if callable(input_sigma):
|
|
93
|
+
input_sigma=input_sigma()
|
|
94
|
+
if np.ndim(input_sigma) > 0:
|
|
95
|
+
input_sigma = np.mean(input_sigma)
|
|
96
|
+
array_type = ct.c_double * dim
|
|
97
|
+
parfun = None if (workers is None or workers <= 1) else parallel(fun, workers)
|
|
98
|
+
c_callback_par = call_back_par(callback_par(fun, parfun))
|
|
99
|
+
res = np.empty(dim+4)
|
|
100
|
+
res_p = res.ctypes.data_as(ct.POINTER(ct.c_double))
|
|
101
|
+
try:
|
|
102
|
+
optimizeCRFMNES_C(runid, c_callback_par, dim, array_type(*guess),
|
|
103
|
+
None if lower is None else array_type(*lower),
|
|
104
|
+
None if upper is None else array_type(*upper),
|
|
105
|
+
input_sigma, max_evaluations, stop_fitness,
|
|
106
|
+
popsize, int(rg.uniform(0, 2**32 - 1)), penalty_coef,
|
|
107
|
+
use_constraint_violation, normalize, res_p)
|
|
108
|
+
x = res[:dim]
|
|
109
|
+
val = res[dim]
|
|
110
|
+
evals = int(res[dim+1])
|
|
111
|
+
iterations = int(res[dim+2])
|
|
112
|
+
stop = int(res[dim+3])
|
|
113
|
+
res = OptimizeResult(x=x, fun=val, nfev=evals, nit=iterations, status=stop, success=True)
|
|
114
|
+
except Exception as ex:
|
|
115
|
+
res = OptimizeResult(x=None, fun=sys.float_info.max, nfev=0, nit=0, status=-1, success=False)
|
|
116
|
+
if not parfun is None:
|
|
117
|
+
parfun.stop()
|
|
118
|
+
return res
|
|
119
|
+
|
|
120
|
+
class CRFMNES_C:
|
|
121
|
+
|
|
122
|
+
def __init__(self,
|
|
123
|
+
dim: int,
|
|
124
|
+
bounds: Optional[Bounds] = None,
|
|
125
|
+
x0: Optional[ArrayLike] = None,
|
|
126
|
+
input_sigma: Optional[Union[float, ArrayLike, Callable]] = 0.3,
|
|
127
|
+
popsize: Optional[int] = 32,
|
|
128
|
+
rg: Optional[Generator] = Generator(PCG64DXSM()),
|
|
129
|
+
runid: Optional[int] = 0,
|
|
130
|
+
normalize: Optional[bool] = False,
|
|
131
|
+
use_constraint_violation: Optional[bool] = True,
|
|
132
|
+
penalty_coef: Optional[float] = 1E5
|
|
133
|
+
):
|
|
134
|
+
|
|
135
|
+
"""Minimization of a scalar function of one or more variables using a
|
|
136
|
+
C++ CR-FM-NES implementation called via ctypes.
|
|
137
|
+
|
|
138
|
+
Parameters
|
|
139
|
+
----------
|
|
140
|
+
dim : int
|
|
141
|
+
dimension of the argument of the objective function
|
|
142
|
+
bounds : sequence or `Bounds`, optional
|
|
143
|
+
Bounds on variables. There are two ways to specify the bounds:
|
|
144
|
+
1. Instance of the `scipy.Bounds` class.
|
|
145
|
+
2. Sequence of ``(min, max)`` pairs for each element in `x`. None
|
|
146
|
+
is used to specify no bound.
|
|
147
|
+
x0 : ndarray, shape (dim,)
|
|
148
|
+
Initial guess. Array of real elements of size (dim,),
|
|
149
|
+
where 'dim' is the number of independent variables.
|
|
150
|
+
input_sigma : float, optional
|
|
151
|
+
Initial step size.
|
|
152
|
+
popsize = int, optional
|
|
153
|
+
CMA-ES population size.
|
|
154
|
+
rg = numpy.random.Generator, optional
|
|
155
|
+
Random generator for creating random guesses.
|
|
156
|
+
runid : int, optional
|
|
157
|
+
id used by the is_terminate callback to identify the CMA-ES run.
|
|
158
|
+
normalize : boolean, optional
|
|
159
|
+
if true pheno -> geno transformation maps arguments to interval [-1,1]"""
|
|
160
|
+
|
|
161
|
+
lower, upper, guess = _get_bounds(dim, bounds, x0, rg)
|
|
162
|
+
if popsize is None:
|
|
163
|
+
popsize = 32
|
|
164
|
+
if popsize % 2 == 1: # requires even popsize
|
|
165
|
+
popsize += 1
|
|
166
|
+
if lower is None:
|
|
167
|
+
lower = [0]*dim
|
|
168
|
+
upper = [0]*dim
|
|
169
|
+
if callable(input_sigma):
|
|
170
|
+
input_sigma=input_sigma()
|
|
171
|
+
if np.ndim(input_sigma) > 0:
|
|
172
|
+
input_sigma = np.mean(input_sigma)
|
|
173
|
+
array_type = ct.c_double * dim
|
|
174
|
+
try:
|
|
175
|
+
self.ptr = initCRFMNES_C(runid, dim, array_type(*guess),
|
|
176
|
+
array_type(*lower), array_type(*upper),
|
|
177
|
+
input_sigma, popsize, int(rg.uniform(0, 2**32 - 1)), penalty_coef,
|
|
178
|
+
use_constraint_violation, normalize)
|
|
179
|
+
self.popsize = popsize
|
|
180
|
+
self.dim = dim
|
|
181
|
+
except Exception as ex:
|
|
182
|
+
print (ex)
|
|
183
|
+
pass
|
|
184
|
+
|
|
185
|
+
def __del__(self):
|
|
186
|
+
destroyCRFMNES_C(self.ptr)
|
|
187
|
+
|
|
188
|
+
def ask(self) -> np.ndarray:
|
|
189
|
+
try:
|
|
190
|
+
lamb = self.popsize
|
|
191
|
+
n = self.dim
|
|
192
|
+
res = np.empty(lamb*n)
|
|
193
|
+
res_p = res.ctypes.data_as(ct.POINTER(ct.c_double))
|
|
194
|
+
askCRFMNES_C(self.ptr, res_p)
|
|
195
|
+
xs = np.empty((lamb, n))
|
|
196
|
+
for p in range(lamb):
|
|
197
|
+
xs[p,:] = res[p*n : (p+1)*n]
|
|
198
|
+
return xs
|
|
199
|
+
except Exception as ex:
|
|
200
|
+
print (ex)
|
|
201
|
+
return None
|
|
202
|
+
|
|
203
|
+
def tell(self, ys: np.ndarray):
|
|
204
|
+
try:
|
|
205
|
+
array_type_ys = ct.c_double * len(ys)
|
|
206
|
+
return tellCRFMNES_C(self.ptr, array_type_ys(*ys))
|
|
207
|
+
except Exception as ex:
|
|
208
|
+
print (ex)
|
|
209
|
+
return -1
|
|
210
|
+
|
|
211
|
+
def population(self) -> np.ndarray:
|
|
212
|
+
try:
|
|
213
|
+
lamb = self.popsize
|
|
214
|
+
n = self.dim
|
|
215
|
+
res = np.empty(lamb*n)
|
|
216
|
+
res_p = res.ctypes.data_as(ct.POINTER(ct.c_double))
|
|
217
|
+
populationCRFMNES_C(self.ptr, res_p)
|
|
218
|
+
xs = np.array(lamb, n)
|
|
219
|
+
for p in range(lamb):
|
|
220
|
+
xs[p] = res[p*n : (p+1)*n]
|
|
221
|
+
return xs
|
|
222
|
+
except Exception as ex:
|
|
223
|
+
print (ex)
|
|
224
|
+
return None
|
|
225
|
+
|
|
226
|
+
def result(self) -> OptimizeResult:
|
|
227
|
+
res = np.empty(self.dim+4)
|
|
228
|
+
res_p = res.ctypes.data_as(ct.POINTER(ct.c_double))
|
|
229
|
+
try:
|
|
230
|
+
resultCRFMNES_C(self.ptr, res_p)
|
|
231
|
+
x = res[:self.dim]
|
|
232
|
+
val = res[self.dim]
|
|
233
|
+
evals = int(res[self.dim+1])
|
|
234
|
+
iterations = int(res[self.dim+2])
|
|
235
|
+
stop = int(res[self.dim+3])
|
|
236
|
+
res = OptimizeResult(x=x, fun=val, nfev=evals, nit=iterations, status=stop, success=True)
|
|
237
|
+
except Exception as ex:
|
|
238
|
+
res = OptimizeResult(x=None, fun=sys.float_info.max, nfev=0, nit=0, status=-1, success=False)
|
|
239
|
+
return res
|
|
240
|
+
|
|
241
|
+
if not libcmalib is None:
|
|
242
|
+
|
|
243
|
+
optimizeCRFMNES_C = libcmalib.optimizeCRFMNES_C
|
|
244
|
+
optimizeCRFMNES_C.argtypes = [ct.c_long, call_back_par, ct.c_int, \
|
|
245
|
+
ct.POINTER(ct.c_double), ct.POINTER(ct.c_double), ct.POINTER(ct.c_double), \
|
|
246
|
+
ct.c_double, ct.c_int, ct.c_double, ct.c_int,
|
|
247
|
+
ct.c_long, ct.c_double,
|
|
248
|
+
ct.c_bool, ct.c_bool, ct.POINTER(ct.c_double)]
|
|
249
|
+
|
|
250
|
+
initCRFMNES_C = libcmalib.initCRFMNES_C
|
|
251
|
+
initCRFMNES_C.argtypes = [ct.c_long, ct.c_int, \
|
|
252
|
+
ct.POINTER(ct.c_double), ct.POINTER(ct.c_double), ct.POINTER(ct.c_double), \
|
|
253
|
+
ct.c_double, ct.c_int,
|
|
254
|
+
ct.c_long, ct.c_double,
|
|
255
|
+
ct.c_bool, ct.c_bool]
|
|
256
|
+
|
|
257
|
+
initCRFMNES_C.restype = ct.c_void_p
|
|
258
|
+
|
|
259
|
+
destroyCRFMNES_C = libcmalib.destroyCRFMNES_C
|
|
260
|
+
destroyCRFMNES_C.argtypes = [ct.c_void_p]
|
|
261
|
+
|
|
262
|
+
askCRFMNES_C = libcmalib.askCRFMNES_C
|
|
263
|
+
askCRFMNES_C.argtypes = [ct.c_void_p, ct.POINTER(ct.c_double)]
|
|
264
|
+
|
|
265
|
+
tellCRFMNES_C = libcmalib.tellCRFMNES_C
|
|
266
|
+
tellCRFMNES_C.argtypes = [ct.c_void_p, ct.POINTER(ct.c_double)]
|
|
267
|
+
tellCRFMNES_C.restype = ct.c_int
|
|
268
|
+
|
|
269
|
+
populationCRFMNES_C = libcmalib.populationCRFMNES_C
|
|
270
|
+
populationCRFMNES_C.argtypes = [ct.c_void_p, ct.POINTER(ct.c_double)]
|
|
271
|
+
|
|
272
|
+
resultCRFMNES_C = libcmalib.resultCRFMNES_C
|
|
273
|
+
resultCRFMNES_C.argtypes = [ct.c_void_p, ct.POINTER(ct.c_double)]
|
fcmaes/dacpp.py
CHANGED
|
@@ -12,21 +12,22 @@ import sys
|
|
|
12
12
|
import os
|
|
13
13
|
import ctypes as ct
|
|
14
14
|
import numpy as np
|
|
15
|
-
from numpy.random import
|
|
16
|
-
from scipy.optimize import OptimizeResult
|
|
17
|
-
from fcmaes.
|
|
18
|
-
|
|
19
|
-
from
|
|
15
|
+
from numpy.random import PCG64DXSM, Generator
|
|
16
|
+
from scipy.optimize import OptimizeResult, Bounds
|
|
17
|
+
from fcmaes.evaluator import _check_bounds, call_back_type, callback, libcmalib
|
|
18
|
+
|
|
19
|
+
from typing import Optional, Callable, Union
|
|
20
|
+
from numpy.typing import ArrayLike
|
|
20
21
|
|
|
21
22
|
os.environ['MKL_DEBUG_CPU_TYPE'] = '5'
|
|
22
23
|
|
|
23
|
-
def minimize(fun,
|
|
24
|
-
bounds=None,
|
|
25
|
-
x0=None,
|
|
26
|
-
max_evaluations = 100000,
|
|
27
|
-
use_local_search = True,
|
|
28
|
-
rg = Generator(
|
|
29
|
-
runid=0):
|
|
24
|
+
def minimize(fun: Callable[[ArrayLike], float],
|
|
25
|
+
bounds: Optional[Bounds] = None,
|
|
26
|
+
x0: Optional[ArrayLike] = None,
|
|
27
|
+
max_evaluations: Optional[int] = 100000,
|
|
28
|
+
use_local_search: Optional[bool] = True,
|
|
29
|
+
rg: Optional[Generator] = Generator(PCG64DXSM()),
|
|
30
|
+
runid: Optional[int] = 0) -> OptimizeResult:
|
|
30
31
|
|
|
31
32
|
"""Minimization of a scalar function of one or more variables using a
|
|
32
33
|
C++ Dual Annealing implementation called via ctypes.
|
|
@@ -35,10 +36,8 @@ def minimize(fun,
|
|
|
35
36
|
----------
|
|
36
37
|
fun : callable
|
|
37
38
|
The objective function to be minimized.
|
|
38
|
-
``fun(x
|
|
39
|
-
where ``x`` is an 1-D array with shape (dim,)
|
|
40
|
-
is a tuple of the fixed parameters needed to completely
|
|
41
|
-
specify the function.
|
|
39
|
+
``fun(x) -> float``
|
|
40
|
+
where ``x`` is an 1-D array with shape (dim,)
|
|
42
41
|
bounds : sequence or `Bounds`, optional
|
|
43
42
|
Bounds on variables. There are two ways to specify the bounds:
|
|
44
43
|
1. Instance of the `scipy.Bounds` class.
|
|
@@ -67,10 +66,7 @@ def minimize(fun,
|
|
|
67
66
|
``success`` a Boolean flag indicating if the optimizer exited successfully. """
|
|
68
67
|
|
|
69
68
|
lower, upper, guess = _check_bounds(bounds, x0, rg)
|
|
70
|
-
dim = guess.size
|
|
71
|
-
if lower is None:
|
|
72
|
-
lower = [0]*dim
|
|
73
|
-
upper = [0]*dim
|
|
69
|
+
dim = guess.size
|
|
74
70
|
array_type = ct.c_double * dim
|
|
75
71
|
c_callback = call_back_type(callback(fun))
|
|
76
72
|
seed = int(rg.uniform(0, 2**32 - 1))
|
|
@@ -78,7 +74,9 @@ def minimize(fun,
|
|
|
78
74
|
res_p = res.ctypes.data_as(ct.POINTER(ct.c_double))
|
|
79
75
|
try:
|
|
80
76
|
optimizeDA_C(runid, c_callback, dim, seed,
|
|
81
|
-
array_type(*guess),
|
|
77
|
+
array_type(*guess),
|
|
78
|
+
None if lower is None else array_type(*lower),
|
|
79
|
+
None if upper is None else array_type(*upper),
|
|
82
80
|
max_evaluations, use_local_search, res_p)
|
|
83
81
|
x = res[:dim]
|
|
84
82
|
val = res[dim]
|
|
@@ -88,10 +86,11 @@ def minimize(fun,
|
|
|
88
86
|
return OptimizeResult(x=x, fun=val, nfev=evals, nit=iterations, status=stop, success=True)
|
|
89
87
|
except Exception as ex:
|
|
90
88
|
return OptimizeResult(x=None, fun=sys.float_info.max, nfev=0, nit=0, status=-1, success=False)
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
optimizeDA_C
|
|
95
|
-
|
|
96
|
-
|
|
89
|
+
|
|
90
|
+
if not libcmalib is None:
|
|
91
|
+
|
|
92
|
+
optimizeDA_C = libcmalib.optimizeDA_C
|
|
93
|
+
optimizeDA_C.argtypes = [ct.c_long, call_back_type, ct.c_int, ct.c_int, \
|
|
94
|
+
ct.POINTER(ct.c_double), ct.POINTER(ct.c_double), ct.POINTER(ct.c_double), \
|
|
95
|
+
ct.c_int, ct.c_bool, ct.POINTER(ct.c_double)]
|
|
97
96
|
|