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/astro.py
CHANGED
|
@@ -6,38 +6,37 @@
|
|
|
6
6
|
import sys
|
|
7
7
|
import math
|
|
8
8
|
import os
|
|
9
|
-
import numpy as np
|
|
10
9
|
import ctypes as ct
|
|
11
10
|
from scipy.optimize import Bounds
|
|
11
|
+
from fcmaes.decpp import libcmalib
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
13
|
+
if not libcmalib is None:
|
|
14
|
+
|
|
15
|
+
astro_map = {
|
|
16
|
+
"messengerfullC": libcmalib.messengerfullC,
|
|
17
|
+
"messengerC": libcmalib.messengerC,
|
|
18
|
+
"gtoc1C": libcmalib.gtoc1C,
|
|
19
|
+
"cassini1C": libcmalib.cassini1C,
|
|
20
|
+
"cassini1minlpC": libcmalib.cassini1minlpC,
|
|
21
|
+
"cassini2C": libcmalib.cassini2C,
|
|
22
|
+
"rosettaC": libcmalib.rosettaC,
|
|
23
|
+
"sagasC": libcmalib.sagasC,
|
|
24
|
+
"tandemC": libcmalib.tandemC,
|
|
25
|
+
"tandemCu": libcmalib.tandemCu,
|
|
26
|
+
"cassini2minlpC": libcmalib.cassini2minlpC,
|
|
27
|
+
}
|
|
20
28
|
|
|
29
|
+
freemem = libcmalib.free_mem
|
|
30
|
+
freemem.argtypes = [ct.POINTER(ct.c_double)]
|
|
31
|
+
|
|
21
32
|
class Astrofun(object):
|
|
22
33
|
"""Provides access to ESAs GTOP optimization test functions."""
|
|
23
34
|
def __init__(self, name, fun_c, lower, upper):
|
|
24
35
|
self.name = name
|
|
36
|
+
self.fun_c = fun_c
|
|
25
37
|
self.bounds = Bounds(lower, upper)
|
|
26
38
|
self.fun = python_fun(fun_c, self.bounds)
|
|
27
39
|
|
|
28
|
-
# for windows compatibility. Linux can pickle c pointers, windows can not
|
|
29
|
-
astro_map = {
|
|
30
|
-
"messengerfullC": libgtoplib.messengerfullC,
|
|
31
|
-
"messengerC": libgtoplib.messengerC,
|
|
32
|
-
"gtoc1C": libgtoplib.gtoc1C,
|
|
33
|
-
"cassini1C": libgtoplib.cassini1C,
|
|
34
|
-
"cassini2C": libgtoplib.cassini2C,
|
|
35
|
-
"rosettaC": libgtoplib.rosettaC,
|
|
36
|
-
"sagasC": libgtoplib.sagasC,
|
|
37
|
-
"tandemC": libgtoplib.tandemC,
|
|
38
|
-
"tandemCu": libgtoplib.tandemCu
|
|
39
|
-
}
|
|
40
|
-
|
|
41
40
|
for func in astro_map:
|
|
42
41
|
astro_map[func].argtypes = [ct.c_int, ct.POINTER(ct.c_double)]
|
|
43
42
|
astro_map[func].restype = ct.c_double
|
|
@@ -66,7 +65,12 @@ class Gtoc1(object):
|
|
|
66
65
|
Astrofun.__init__(self, 'GTOC1', "gtoc1C",
|
|
67
66
|
[3000.,14.,14.,14.,14.,100.,366.,300.],
|
|
68
67
|
[10000.,2000.,2000.,2000.,2000.,9000.,9000.,9000.]
|
|
69
|
-
|
|
68
|
+
)
|
|
69
|
+
self.gfun = self.fun
|
|
70
|
+
self.fun = self.gtoc1
|
|
71
|
+
|
|
72
|
+
def gtoc1(self, x):
|
|
73
|
+
return self.gfun(x) - 2000000
|
|
70
74
|
|
|
71
75
|
class Cassini1(object):
|
|
72
76
|
""" see https://www.esa.int/gsp/ACT/projects/gtop/cassini1/ """
|
|
@@ -108,7 +112,7 @@ class Tandem(object):
|
|
|
108
112
|
""" see https://www.esa.int/gsp/ACT/projects/gtop/tandem/ """
|
|
109
113
|
def __init__(self, i, constrained=True):
|
|
110
114
|
self.name = ('Tandem ' if constrained else 'Tandem unconstrained ') + str(i+1)
|
|
111
|
-
self.
|
|
115
|
+
self.fun_c = "tandemC" if constrained else "tandemCu"
|
|
112
116
|
self.fun = self.tandem
|
|
113
117
|
self.bounds = Bounds([5475, 2.5, 0, 0, 20, 20, 20, 20, 0.01, 0.01, 0.01, 0.01, 1.05, 1.05, 1.05, -math.pi, -math.pi, -math.pi],
|
|
114
118
|
[9132, 4.9, 1, 1, 2500, 2500, 2500, 2500, 0.99, 0.99, 0.99, 0.99, 10, 10, 10, math.pi, math.pi, math.pi])
|
|
@@ -123,17 +127,128 @@ class Tandem(object):
|
|
|
123
127
|
n = len(x)
|
|
124
128
|
array_type = ct.c_double * n
|
|
125
129
|
ints_type = ct.c_int * 5
|
|
126
|
-
fun_c = astro_map[self.
|
|
130
|
+
fun_c = astro_map[self.fun_c]
|
|
127
131
|
fun_c.argtypes = [ct.c_int, ct.POINTER(ct.c_double), ct.POINTER(ct.c_int)]
|
|
128
132
|
try: # function is only defined inside bounds
|
|
129
|
-
x = np.asarray(x).clip(self.bounds.lb, self.bounds.ub)
|
|
133
|
+
#x = np.asarray(x).clip(self.bounds.lb, self.bounds.ub)
|
|
130
134
|
val = fun_c(n, array_type(*x), ints_type(*self.seq))
|
|
131
135
|
if not math.isfinite(val):
|
|
132
136
|
val = 1E10
|
|
133
137
|
except Exception as ex:
|
|
134
138
|
val = 1E10
|
|
135
139
|
return val
|
|
136
|
-
|
|
140
|
+
|
|
141
|
+
class Tandem_minlp(object):
|
|
142
|
+
""" see https://www.esa.int/gsp/ACT/projects/gtop/tandem/ """
|
|
143
|
+
def __init__(self, constrained=True):
|
|
144
|
+
self.name = ('Tandem minlp ' if constrained else 'Tandem unconstrained minlp ')
|
|
145
|
+
self.fun_c = "tandemC" if constrained else "tandemCu"
|
|
146
|
+
self.fun = self.tandem_minlp
|
|
147
|
+
self.bounds = Bounds([5475, 2.5, 0, 0, 20, 20, 20, 20, 0.01, 0.01, 0.01, 0.01, 1.05, 1.05, 1.05, -math.pi, -math.pi, -math.pi,
|
|
148
|
+
1.51,1.51,1.51],
|
|
149
|
+
[9132, 4.9, 1, 1, 2500, 2500, 2500, 2500, 0.99, 0.99, 0.99, 0.99, 10, 10, 10, math.pi, math.pi, math.pi,
|
|
150
|
+
3.49,4.49,5.49])
|
|
151
|
+
|
|
152
|
+
def tandem_minlp(self, xs):
|
|
153
|
+
n = len(xs) - 3
|
|
154
|
+
x = xs[:-3]
|
|
155
|
+
seq = [3] + [int(round(xi)) for xi in xs[-3:]] + [6]
|
|
156
|
+
array_type = ct.c_double * n
|
|
157
|
+
ints_type = ct.c_int * 5
|
|
158
|
+
fun_c = astro_map[self.fun_c]
|
|
159
|
+
fun_c.argtypes = [ct.c_int, ct.POINTER(ct.c_double), ct.POINTER(ct.c_int)]
|
|
160
|
+
try:
|
|
161
|
+
val = fun_c(n, array_type(*x), ints_type(*seq))
|
|
162
|
+
if not math.isfinite(val):
|
|
163
|
+
val = 1E10
|
|
164
|
+
except Exception as ex:
|
|
165
|
+
val = 1E10
|
|
166
|
+
return val
|
|
167
|
+
|
|
168
|
+
class Cassini1multi(object):
|
|
169
|
+
""" see https://www.esa.int/gsp/ACT/projects/gtop/cassini1/ """
|
|
170
|
+
|
|
171
|
+
def __init__(self, weights = [1,0,0,0], planets = [2,2,3,5]):
|
|
172
|
+
Astrofun.__init__(self, 'Cassini1minlp', "Cassini1minlpC",
|
|
173
|
+
[-1000.,30.,100.,30.,400.,1000.],
|
|
174
|
+
[0.,400.,470.,400.,2000.,6000.]
|
|
175
|
+
)
|
|
176
|
+
self.fun = self.cassini1
|
|
177
|
+
self.weights = weights
|
|
178
|
+
self.planets = planets
|
|
179
|
+
self.mfun = lambda x: cassini1multi(x + [2,2,3,5])
|
|
180
|
+
|
|
181
|
+
def cassini1(self, x):
|
|
182
|
+
r = cassini1multi(x + self.planets)
|
|
183
|
+
return self.weights[0]*r[0] + self.weights[1]*r[1] + self.weights[2]*r[2] + self.weights[3]*r[3]
|
|
184
|
+
|
|
185
|
+
class Cassini1minlp(object):
|
|
186
|
+
""" see https://www.esa.int/gsp/ACT/projects/gtop/cassini1/ """
|
|
187
|
+
|
|
188
|
+
def __init__(self, planets = [2,2,3,5]):
|
|
189
|
+
Astrofun.__init__(self, 'Cassini1', "cassini1C",
|
|
190
|
+
[-1000.,30.,100.,30.,400.,1000.],
|
|
191
|
+
[0.,400.,470.,400.,2000.,6000.]
|
|
192
|
+
)
|
|
193
|
+
self.fun = self.cassini1
|
|
194
|
+
self.planets = planets
|
|
195
|
+
|
|
196
|
+
def cassini1(self, x):
|
|
197
|
+
return cassini1minlp(list(x) + self.planets)
|
|
198
|
+
|
|
199
|
+
def cassini1minlp(x):
|
|
200
|
+
n = len(x)
|
|
201
|
+
array_type = ct.c_double * n
|
|
202
|
+
fun_c = astro_map["cassini1minlpC"]
|
|
203
|
+
fun_c.argtypes = [ct.c_int, ct.POINTER(ct.c_double)]
|
|
204
|
+
fun_c.restype = ct.POINTER(ct.c_double)
|
|
205
|
+
try: # function is only defined inside bounds
|
|
206
|
+
res = fun_c(n, array_type(*x))
|
|
207
|
+
dv = res[0]
|
|
208
|
+
freemem(res)
|
|
209
|
+
if not math.isfinite(dv):
|
|
210
|
+
dv = 1E10
|
|
211
|
+
except Exception as ex:
|
|
212
|
+
print(ex)
|
|
213
|
+
dv = 1E10
|
|
214
|
+
return dv
|
|
215
|
+
|
|
216
|
+
def cassini1multi(x):
|
|
217
|
+
n = len(x)
|
|
218
|
+
array_type = ct.c_double * n
|
|
219
|
+
fun_c = astro_map["cassini1minlpC"]
|
|
220
|
+
fun_c.argtypes = [ct.c_int, ct.POINTER(ct.c_double)]
|
|
221
|
+
fun_c.restype = ct.POINTER(ct.c_double)
|
|
222
|
+
try: # function is only defined inside bounds
|
|
223
|
+
res = fun_c(n, array_type(*x))
|
|
224
|
+
dv = res[0]
|
|
225
|
+
launch_dv = res[1]
|
|
226
|
+
freemem(res)
|
|
227
|
+
if not math.isfinite(dv):
|
|
228
|
+
dv = 1E10
|
|
229
|
+
except Exception as ex:
|
|
230
|
+
print(ex)
|
|
231
|
+
dv = 1E10
|
|
232
|
+
launch_dv = 1E10
|
|
233
|
+
tof = sum(x[1:6])
|
|
234
|
+
launch_time = x[0]
|
|
235
|
+
return [dv, tof, launch_time]
|
|
236
|
+
|
|
237
|
+
def cassini2multi(x):
|
|
238
|
+
n = len(x)
|
|
239
|
+
array_type = ct.c_double * n
|
|
240
|
+
fun_c = astro_map["cassini2minlpC"]
|
|
241
|
+
fun_c.argtypes = [ct.c_int, ct.POINTER(ct.c_double)]
|
|
242
|
+
fun_c.restype = ct.c_double
|
|
243
|
+
try: # function is only defined inside bounds
|
|
244
|
+
dv = fun_c(n, array_type(*x))
|
|
245
|
+
except Exception as ex:
|
|
246
|
+
print(ex)
|
|
247
|
+
dv = 1E99
|
|
248
|
+
tof = sum(x[4:9])
|
|
249
|
+
launch_time = x[0]
|
|
250
|
+
return [dv, tof, launch_time]
|
|
251
|
+
|
|
137
252
|
class python_fun(object):
|
|
138
253
|
|
|
139
254
|
def __init__(self, cfun, bounds):
|
|
@@ -151,4 +266,5 @@ class python_fun(object):
|
|
|
151
266
|
val = 1E10
|
|
152
267
|
except Exception as ex:
|
|
153
268
|
val = 1E10
|
|
154
|
-
return val
|
|
269
|
+
return val
|
|
270
|
+
|
fcmaes/bitecpp.py
ADDED
|
@@ -0,0 +1,107 @@
|
|
|
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
|
+
""" Implements a stochastic non-linear
|
|
7
|
+
bound-constrained derivative-free optimization method.
|
|
8
|
+
Description is available at https://github.com/avaneev/biteopt
|
|
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, mo_call_back_type, callback_so, libcmalib
|
|
19
|
+
|
|
20
|
+
from typing import Optional, Callable
|
|
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
|
+
max_evaluations: Optional[int] = 100000,
|
|
29
|
+
stop_fitness: Optional[float] = -np.inf,
|
|
30
|
+
M: Optional[int] = 1,
|
|
31
|
+
popsize: Optional[int] = 0,
|
|
32
|
+
stall_criterion: Optional[int] = 0,
|
|
33
|
+
rg: Optional[Generator] = Generator(PCG64DXSM()),
|
|
34
|
+
runid: Optional[int] = 0) -> OptimizeResult:
|
|
35
|
+
"""Minimization of a scalar function of one or more variables using a
|
|
36
|
+
C++ SCMA implementation called via ctypes.
|
|
37
|
+
|
|
38
|
+
Parameters
|
|
39
|
+
----------
|
|
40
|
+
fun : callable
|
|
41
|
+
The objective function to be minimized.
|
|
42
|
+
``fun(x) -> float``
|
|
43
|
+
where ``x`` is an 1-D array with shape (dim,)
|
|
44
|
+
bounds : sequence or `Bounds`, optional
|
|
45
|
+
Bounds on variables. There are two ways to specify the bounds:
|
|
46
|
+
1. Instance of the `scipy.Bounds` class.
|
|
47
|
+
2. Sequence of ``(min, max)`` pairs for each element in `x`. None
|
|
48
|
+
is used to specify no bound.
|
|
49
|
+
x0 : ndarray, shape (dim,)
|
|
50
|
+
Initial guess. Array of real elements of size (dim,),
|
|
51
|
+
where 'dim' is the number of independent variables.
|
|
52
|
+
max_evaluations : int, optional
|
|
53
|
+
Forced termination after ``max_evaluations`` function evaluations.
|
|
54
|
+
stop_fitness : float, optional
|
|
55
|
+
Limit for fitness value. If reached minimize terminates.
|
|
56
|
+
M : int, optional
|
|
57
|
+
Depth to use, 1 for plain CBiteOpt algorithm, >1 for CBiteOptDeep. Expected range is [1; 36].
|
|
58
|
+
popsize = int, optional
|
|
59
|
+
initial population size.
|
|
60
|
+
stall_criterion : int, optional
|
|
61
|
+
Terminate if stall_criterion*128*evaluations stalled, Not used if <= 0
|
|
62
|
+
rg = numpy.random.Generator, optional
|
|
63
|
+
Random generator for creating random guesses.
|
|
64
|
+
runid : int, optional
|
|
65
|
+
id used to identify the run for debugging / logging.
|
|
66
|
+
|
|
67
|
+
Returns
|
|
68
|
+
-------
|
|
69
|
+
res : scipy.OptimizeResult
|
|
70
|
+
The optimization result is represented as an ``OptimizeResult`` object.
|
|
71
|
+
Important attributes are: ``x`` the solution array,
|
|
72
|
+
``fun`` the best function value,
|
|
73
|
+
``nfev`` the number of function evaluations,
|
|
74
|
+
``nit`` the number of CMA-ES iterations,
|
|
75
|
+
``status`` the stopping critera and
|
|
76
|
+
``success`` a Boolean flag indicating if the optimizer exited successfully. """
|
|
77
|
+
|
|
78
|
+
lower, upper, guess = _check_bounds(bounds, x0, rg)
|
|
79
|
+
dim = guess.size
|
|
80
|
+
array_type = ct.c_double * dim
|
|
81
|
+
c_callback = mo_call_back_type(callback_so(fun, dim))
|
|
82
|
+
res = np.empty(dim+4)
|
|
83
|
+
res_p = res.ctypes.data_as(ct.POINTER(ct.c_double))
|
|
84
|
+
try:
|
|
85
|
+
optimizeBite_C(runid, c_callback, dim, int(rg.uniform(0, 2**32 - 1)),
|
|
86
|
+
None if x0 is None else array_type(*guess),
|
|
87
|
+
None if lower is None else array_type(*lower),
|
|
88
|
+
None if upper is None else array_type(*upper),
|
|
89
|
+
max_evaluations, stop_fitness, M, popsize, stall_criterion, res_p)
|
|
90
|
+
x = res[:dim]
|
|
91
|
+
val = res[dim]
|
|
92
|
+
evals = int(res[dim+1])
|
|
93
|
+
iterations = int(res[dim+2])
|
|
94
|
+
stop = int(res[dim+3])
|
|
95
|
+
return OptimizeResult(x=x, fun=val, nfev=evals, nit=iterations, status=stop, success=True)
|
|
96
|
+
except Exception as ex:
|
|
97
|
+
return OptimizeResult(x=None, fun=sys.float_info.max, nfev=0, nit=0, status=-1, success=False)
|
|
98
|
+
|
|
99
|
+
if not libcmalib is None:
|
|
100
|
+
|
|
101
|
+
optimizeBite_C = libcmalib.optimizeBite_C
|
|
102
|
+
optimizeBite_C.argtypes = [ct.c_long, mo_call_back_type, ct.c_int, ct.c_int, \
|
|
103
|
+
ct.POINTER(ct.c_double), ct.POINTER(ct.c_double), ct.POINTER(ct.c_double), \
|
|
104
|
+
ct.c_int, ct.c_double, ct.c_int, ct.c_int, ct.c_int, ct.POINTER(ct.c_double)]
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
|