coco-experiment 2.8.2__tar.gz → 2.8.4__tar.gz
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.
- {coco_experiment-2.8.2 → coco_experiment-2.8.4}/.gitignore +2 -0
- {coco_experiment-2.8.2 → coco_experiment-2.8.4}/PKG-INFO +7 -8
- {coco_experiment-2.8.2 → coco_experiment-2.8.4}/pyproject.toml +7 -8
- {coco_experiment-2.8.2 → coco_experiment-2.8.4}/src/cocoex/__init__.py +1 -0
- {coco_experiment-2.8.2 → coco_experiment-2.8.4}/src/cocoex/_version.py +1 -1
- {coco_experiment-2.8.2 → coco_experiment-2.8.4}/src/cocoex/coco.c +22 -13
- {coco_experiment-2.8.2 → coco_experiment-2.8.4}/src/cocoex/interface.pyx +9 -2
- {coco_experiment-2.8.2 → coco_experiment-2.8.4}/src/cocoex/noiser.py +68 -24
- {coco_experiment-2.8.2 → coco_experiment-2.8.4}/src/cocoex/utilities.py +15 -6
- {coco_experiment-2.8.2 → coco_experiment-2.8.4}/LICENSE +0 -0
- {coco_experiment-2.8.2 → coco_experiment-2.8.4}/README.md +0 -0
- {coco_experiment-2.8.2 → coco_experiment-2.8.4}/meson.build +0 -0
- {coco_experiment-2.8.2 → coco_experiment-2.8.4}/scripts/run-doctest.py +0 -0
- {coco_experiment-2.8.2 → coco_experiment-2.8.4}/src/cocoex/bare_problem.pyx +0 -0
- {coco_experiment-2.8.2 → coco_experiment-2.8.4}/src/cocoex/coco.h +0 -0
- {coco_experiment-2.8.2 → coco_experiment-2.8.4}/src/cocoex/download_example.py +0 -0
- {coco_experiment-2.8.2 → coco_experiment-2.8.4}/src/cocoex/exceptions.py +0 -0
- {coco_experiment-2.8.2 → coco_experiment-2.8.4}/src/cocoex/solvers.py +0 -0
- {coco_experiment-2.8.2 → coco_experiment-2.8.4}/tests/bbob2009_testcases.txt +0 -0
- {coco_experiment-2.8.2 → coco_experiment-2.8.4}/tests/bbob2009_testcases2.txt +0 -0
- {coco_experiment-2.8.2 → coco_experiment-2.8.4}/tests/test_bare_problem.py +0 -0
- {coco_experiment-2.8.2 → coco_experiment-2.8.4}/tests/test_regression.py +0 -0
- {coco_experiment-2.8.2 → coco_experiment-2.8.4}/tests/test_suite.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
2
|
Name: coco-experiment
|
|
3
|
-
Version: 2.8.
|
|
3
|
+
Version: 2.8.4
|
|
4
4
|
Summary: Benchmarking framework for all types of black-box optimization algorithms.
|
|
5
5
|
Project-URL: Homepage, https://github.com/numbbo/coco-experiment
|
|
6
6
|
Project-URL: Documentation, https://numbbo.github.io/coco-doc/apidocs/cocoex/
|
|
@@ -11,14 +11,13 @@ License-File: LICENSE
|
|
|
11
11
|
Classifier: Development Status :: 4 - Beta
|
|
12
12
|
Classifier: License :: OSI Approved :: BSD License
|
|
13
13
|
Classifier: Programming Language :: Python
|
|
14
|
-
Classifier: Programming Language :: Python :: 3.8
|
|
15
|
-
Classifier: Programming Language :: Python :: 3.9
|
|
16
|
-
Classifier: Programming Language :: Python :: 3.10
|
|
17
|
-
Classifier: Programming Language :: Python :: 3.11
|
|
18
14
|
Classifier: Programming Language :: Python :: 3.12
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.15
|
|
19
18
|
Classifier: Programming Language :: Python :: Implementation :: CPython
|
|
20
|
-
Requires-Python: >=3.
|
|
21
|
-
Requires-Dist: numpy>=1.
|
|
19
|
+
Requires-Python: >=3.12
|
|
20
|
+
Requires-Dist: numpy>=1.26.0
|
|
22
21
|
Description-Content-Type: text/markdown
|
|
23
22
|
|
|
24
23
|
<h1 align="center">
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
[build-system]
|
|
2
|
-
requires = ["meson-python", "Cython >= 3.
|
|
2
|
+
requires = ["meson-python >= 0.22", "Cython >= 3.3", "wheel", "numpy >= 2.5"]
|
|
3
3
|
build-backend = 'mesonpy'
|
|
4
4
|
|
|
5
5
|
[project]
|
|
@@ -22,21 +22,20 @@ authors = [
|
|
|
22
22
|
]
|
|
23
23
|
description = 'Benchmarking framework for all types of black-box optimization algorithms.'
|
|
24
24
|
readme = "README.md"
|
|
25
|
-
requires-python = ">=3.
|
|
25
|
+
requires-python = ">=3.12"
|
|
26
26
|
license = { text = "BSD-3-Clause" }
|
|
27
27
|
classifiers = [
|
|
28
28
|
"Development Status :: 4 - Beta",
|
|
29
29
|
"License :: OSI Approved :: BSD License",
|
|
30
30
|
"Programming Language :: Python",
|
|
31
|
-
"Programming Language :: Python :: 3.8",
|
|
32
|
-
"Programming Language :: Python :: 3.9",
|
|
33
|
-
"Programming Language :: Python :: 3.10",
|
|
34
|
-
"Programming Language :: Python :: 3.11",
|
|
35
31
|
"Programming Language :: Python :: 3.12",
|
|
32
|
+
"Programming Language :: Python :: 3.13",
|
|
33
|
+
"Programming Language :: Python :: 3.14",
|
|
34
|
+
"Programming Language :: Python :: 3.15",
|
|
36
35
|
"Programming Language :: Python :: Implementation :: CPython",
|
|
37
36
|
]
|
|
38
37
|
dependencies = [
|
|
39
|
-
"numpy >= 1.
|
|
38
|
+
"numpy >= 1.26.0",
|
|
40
39
|
]
|
|
41
40
|
dynamic = ["version"]
|
|
42
41
|
|
|
@@ -76,5 +75,5 @@ path = "src/cocoex/_version.py"
|
|
|
76
75
|
|
|
77
76
|
[dependency-groups]
|
|
78
77
|
dev = [
|
|
79
|
-
"build>=1.
|
|
78
|
+
"build>=1.6",
|
|
80
79
|
]
|
|
@@ -19,6 +19,7 @@ from . import noiser # noqa: F401
|
|
|
19
19
|
from . import solvers # noqa: F401
|
|
20
20
|
from . import utilities # noqa: F401
|
|
21
21
|
from . import exceptions # noqa: F401
|
|
22
|
+
# from . import test # noqa: F401 # gives a circular import, why???
|
|
22
23
|
from .interface import Observer as _Observer
|
|
23
24
|
from .interface import Problem as _Problem
|
|
24
25
|
from .interface import Suite as _Suite
|
|
@@ -26241,14 +26241,16 @@ static void coco_observer_targets_free(coco_observer_targets_t *targets) {
|
|
|
26241
26241
|
* dim*1, dim*2, dim*5, 10*dim*1, 10*dim*2, 10*dim*5, 100*dim*1, 100*dim*2,
|
|
26242
26242
|
* 100*dim*5, ...
|
|
26243
26243
|
*/
|
|
26244
|
-
static coco_observer_evaluations_t *coco_observer_evaluations(const
|
|
26244
|
+
static coco_observer_evaluations_t *coco_observer_evaluations(const size_t number_evaluation_triggers,
|
|
26245
|
+
const char *base_evaluations,
|
|
26246
|
+
const size_t dimension) {
|
|
26245
26247
|
|
|
26246
26248
|
coco_observer_evaluations_t *evaluations = (coco_observer_evaluations_t *)coco_allocate_memory(sizeof(*evaluations));
|
|
26247
26249
|
|
|
26248
26250
|
/* First trigger */
|
|
26249
26251
|
evaluations->value1 = 1;
|
|
26250
26252
|
evaluations->exponent1 = 0;
|
|
26251
|
-
evaluations->number_of_triggers =
|
|
26253
|
+
evaluations->number_of_triggers = number_evaluation_triggers;
|
|
26252
26254
|
|
|
26253
26255
|
/* Second trigger */
|
|
26254
26256
|
evaluations->base_evaluations =
|
|
@@ -26381,6 +26383,12 @@ static coco_observer_t *coco_observer_allocate(
|
|
|
26381
26383
|
observer->logger_free_function = NULL;
|
|
26382
26384
|
observer->restart_function = NULL;
|
|
26383
26385
|
observer->is_active = 1;
|
|
26386
|
+
coco_debug("Function coco_observer_allocate() called with values: result_folder: %s, observer_name: %s, algorithm_name: %s, "
|
|
26387
|
+
"algorithm_info: %s, settings: %s, number_target_triggers: %lu, log_target_precision: %e, lin_target_precision: %e, "
|
|
26388
|
+
"number_evaluation_triggers: %lu, base_evaluation_triggers: %s, precision_x: %d, precision_f: %d, precision_g: %d, "
|
|
26389
|
+
"log_discrete_as_int: %d", result_folder, observer_name, algorithm_name, algorithm_info, settings, (unsigned long)number_target_triggers,
|
|
26390
|
+
log_target_precision, lin_target_precision, (unsigned long)number_evaluation_triggers, base_evaluation_triggers, precision_x, precision_f,
|
|
26391
|
+
precision_g, log_discrete_as_int);
|
|
26384
26392
|
return observer;
|
|
26385
26393
|
}
|
|
26386
26394
|
|
|
@@ -27252,8 +27260,8 @@ static coco_problem_t *logger_bbob(coco_observer_t *observer, coco_problem_t *in
|
|
|
27252
27260
|
/* Initialize triggers performance and evaluation triggers depending on the observer option */
|
|
27253
27261
|
logger_data->targets = coco_observer_targets(suite->known_optima, observer->lin_target_precision,
|
|
27254
27262
|
observer->number_target_triggers, observer->log_target_precision);
|
|
27255
|
-
logger_data->evaluations =
|
|
27256
|
-
|
|
27263
|
+
logger_data->evaluations = coco_observer_evaluations(
|
|
27264
|
+
observer->number_evaluation_triggers, observer->base_evaluation_triggers, inner_problem->number_of_variables);
|
|
27257
27265
|
logger_data->mdat_targets = coco_observer_targets(suite->known_optima, observer->lin_target_precision,
|
|
27258
27266
|
observer->number_target_triggers, observer->log_target_precision);
|
|
27259
27267
|
|
|
@@ -27266,7 +27274,7 @@ static coco_problem_t *logger_bbob(coco_observer_t *observer, coco_problem_t *in
|
|
|
27266
27274
|
observer_data->observed_problem = problem;
|
|
27267
27275
|
return problem;
|
|
27268
27276
|
}
|
|
27269
|
-
#line
|
|
27277
|
+
#line 518 "coco_observer.c"
|
|
27270
27278
|
#line 1 "logger_bbob_old.c"
|
|
27271
27279
|
/**
|
|
27272
27280
|
* @file logger_bbob_old.c
|
|
@@ -27919,8 +27927,8 @@ static coco_problem_t *logger_bbob_old(coco_observer_t *observer, coco_problem_t
|
|
|
27919
27927
|
|
|
27920
27928
|
/* Initialize triggers based on target values and number of evaluations */
|
|
27921
27929
|
logger_data->targets = coco_observer_log_targets(observer->number_target_triggers, observer->log_target_precision);
|
|
27922
|
-
logger_data->evaluations =
|
|
27923
|
-
|
|
27930
|
+
logger_data->evaluations = coco_observer_evaluations(
|
|
27931
|
+
observer->number_evaluation_triggers, observer->base_evaluation_triggers, inner_problem->number_of_variables);
|
|
27924
27932
|
|
|
27925
27933
|
problem =
|
|
27926
27934
|
coco_problem_transformed_allocate(inner_problem, logger_data, logger_bbob_old_free, observer->observer_name);
|
|
@@ -27929,7 +27937,7 @@ static coco_problem_t *logger_bbob_old(coco_observer_t *observer, coco_problem_t
|
|
|
27929
27937
|
bbob_old_logger_is_open = 1;
|
|
27930
27938
|
return problem;
|
|
27931
27939
|
}
|
|
27932
|
-
#line
|
|
27940
|
+
#line 519 "coco_observer.c"
|
|
27933
27941
|
#line 1 "logger_biobj.c"
|
|
27934
27942
|
/**
|
|
27935
27943
|
* @file logger_biobj.c
|
|
@@ -29616,7 +29624,8 @@ static logger_biobj_indicator_t *logger_biobj_indicator(const logger_biobj_data_
|
|
|
29616
29624
|
|
|
29617
29625
|
indicator->targets = coco_observer_targets(suite->known_optima, observer->lin_target_precision,
|
|
29618
29626
|
observer->number_target_triggers, observer->log_target_precision);
|
|
29619
|
-
indicator->evaluations = coco_observer_evaluations(observer->base_evaluation_triggers,
|
|
29627
|
+
indicator->evaluations = coco_observer_evaluations(observer->number_evaluation_triggers, observer->base_evaluation_triggers,
|
|
29628
|
+
problem->number_of_variables);
|
|
29620
29629
|
|
|
29621
29630
|
/* Prepare the info file */
|
|
29622
29631
|
path_name = coco_allocate_string(COCO_PATH_MAX + 1);
|
|
@@ -30253,7 +30262,7 @@ static coco_problem_t *logger_biobj(coco_observer_t *observer, coco_problem_t *i
|
|
|
30253
30262
|
observer_data->observed_problem = problem;
|
|
30254
30263
|
return problem;
|
|
30255
30264
|
}
|
|
30256
|
-
#line
|
|
30265
|
+
#line 520 "coco_observer.c"
|
|
30257
30266
|
#line 1 "logger_rw.c"
|
|
30258
30267
|
/**
|
|
30259
30268
|
* @file logger_rw.c
|
|
@@ -30589,7 +30598,7 @@ static coco_problem_t *logger_rw(coco_observer_t *observer, coco_problem_t *inne
|
|
|
30589
30598
|
|
|
30590
30599
|
return problem;
|
|
30591
30600
|
}
|
|
30592
|
-
#line
|
|
30601
|
+
#line 521 "coco_observer.c"
|
|
30593
30602
|
#line 1 "logger_toy.c"
|
|
30594
30603
|
/**
|
|
30595
30604
|
* @file logger_toy.c
|
|
@@ -30778,7 +30787,7 @@ static coco_problem_t *logger_toy(coco_observer_t *observer, coco_problem_t *inn
|
|
|
30778
30787
|
|
|
30779
30788
|
return problem;
|
|
30780
30789
|
}
|
|
30781
|
-
#line
|
|
30790
|
+
#line 522 "coco_observer.c"
|
|
30782
30791
|
|
|
30783
30792
|
/**
|
|
30784
30793
|
* Currently, four observers are supported:
|
|
@@ -31544,7 +31553,7 @@ void coco_archive_free(coco_archive_t *archive) {
|
|
|
31544
31553
|
* don't change, don't track in version control!
|
|
31545
31554
|
*/
|
|
31546
31555
|
|
|
31547
|
-
const char *coco_version = "2.8.
|
|
31556
|
+
const char *coco_version = "2.8.4";
|
|
31548
31557
|
#line 1 "coco_runtime_c.c"
|
|
31549
31558
|
/**
|
|
31550
31559
|
* @file coco_runtime_c.c
|
|
@@ -83,6 +83,7 @@ cdef extern from "coco.h":
|
|
|
83
83
|
void bbob_problem_best_parameter_print(const coco_problem_t *problem)
|
|
84
84
|
void bbob_biobj_problem_best_parameter_print(const coco_problem_t *problem)
|
|
85
85
|
|
|
86
|
+
cdef extern double coco_problem_get_best_value(coco_problem_t *p) # copied from bare_problem.pyx
|
|
86
87
|
|
|
87
88
|
cdef bytes _bstring(s):
|
|
88
89
|
if type(s) is bytes:
|
|
@@ -424,7 +425,7 @@ cdef class Suite:
|
|
|
424
425
|
% (self.name, self.instance, self.options,
|
|
425
426
|
len(self), '' if len(self) == 1 else 's',
|
|
426
427
|
'' if len(self.dimensions) == 1 else 's',
|
|
427
|
-
'%d
|
|
428
|
+
'%d-%d' % (min(self.dimensions), max(self.dimensions)))
|
|
428
429
|
def __len__(self):
|
|
429
430
|
return len(self._indices)
|
|
430
431
|
|
|
@@ -556,7 +557,7 @@ cdef class Problem:
|
|
|
556
557
|
raise RuntimeError("Problem already initialized")
|
|
557
558
|
if problem == NULL:
|
|
558
559
|
raise ValueError("in Problem._initialize(problem,...): problem is NULL")
|
|
559
|
-
self.problem = problem
|
|
560
|
+
self.problem = problem # should probably be private ._problem?
|
|
560
561
|
self._problem_index = coco_problem_get_suite_dep_index(self.problem)
|
|
561
562
|
self._do_free = free
|
|
562
563
|
self._list_of_observers = []
|
|
@@ -783,6 +784,12 @@ cdef class Problem:
|
|
|
783
784
|
"""
|
|
784
785
|
assert(self.problem)
|
|
785
786
|
return bool(coco_problem_final_target_hit(self.problem))
|
|
787
|
+
@property
|
|
788
|
+
def _best_value(self):
|
|
789
|
+
"""return best f-value
|
|
790
|
+
"""
|
|
791
|
+
assert(self.problem)
|
|
792
|
+
return coco_problem_get_best_value(self.problem)
|
|
786
793
|
#@property
|
|
787
794
|
#def final_target_fvalue1(self):
|
|
788
795
|
# assert(self.problem)
|
|
@@ -8,8 +8,12 @@ import json
|
|
|
8
8
|
import numpy as np # for checking finite values
|
|
9
9
|
|
|
10
10
|
_frozen_noise = True
|
|
11
|
-
math_floor = int
|
|
12
11
|
parameters_file = 'noiser_parameters.json'
|
|
12
|
+
'''default file name where to save current parameters of `Noisifier`'''
|
|
13
|
+
save_parameters = False
|
|
14
|
+
'''flag whether `Noisifier.__init__` saves noise parameters in file'''
|
|
15
|
+
|
|
16
|
+
math_floor = int
|
|
13
17
|
|
|
14
18
|
def rand(x, i=0):
|
|
15
19
|
"""return a uniform random value seeded with ``x[:2]`` and `i`"""
|
|
@@ -20,7 +24,7 @@ def randn(x, i=0):
|
|
|
20
24
|
def randc(x, i=0):
|
|
21
25
|
"""return a Cauchy random value seeded with ``x[:2]`` and `i`.
|
|
22
26
|
|
|
23
|
-
We observe that median
|
|
27
|
+
We observe that ``median(|Z|) == 1`` and ``p(pi x Z / 2 > a) == 1/a``.
|
|
24
28
|
"""
|
|
25
29
|
return _cauchy(1, _seed(x, i))[0]
|
|
26
30
|
|
|
@@ -52,11 +56,12 @@ class Noisifier:
|
|
|
52
56
|
### prepare
|
|
53
57
|
suite = cocoex.Suite(suite_name, "", "")
|
|
54
58
|
observer = cocoex.Observer(suite_name, "")
|
|
59
|
+
noisifier = cocoex.noiser.Noisifier() # wrapper without internal state
|
|
55
60
|
|
|
56
61
|
### go
|
|
57
62
|
for problem in suite: # this loop may take several minutes or more
|
|
58
63
|
problem.observe_with(observer) # generates the data for cocopp
|
|
59
|
-
problem =
|
|
64
|
+
problem = noisifier.noisify(problem) # wrap problem as noisy
|
|
60
65
|
fmin(problem, problem.initial_solution, disp=False)
|
|
61
66
|
|
|
62
67
|
The `problem` is now a `Noisifier` but it still abides by the interface
|
|
@@ -70,13 +75,35 @@ class Noisifier:
|
|
|
70
75
|
noise generator and the numbers scaled by pi/2 such that P(number > k)
|
|
71
76
|
equals about 1/k when k >= 5.
|
|
72
77
|
|
|
78
|
+
Parameter settings are by default saved to the file indicated by the module
|
|
79
|
+
global variable `cocoex.noiser.parameters_file` if
|
|
80
|
+
``bool(cocoex.noiser.save_parameters) is True``.
|
|
81
|
+
|
|
82
|
+
A minimal regression test:
|
|
83
|
+
|
|
84
|
+
>>> import cocoex
|
|
85
|
+
>>> def eq(x, y):
|
|
86
|
+
... return [cocoex.utilities.about_equal(xi, yi)
|
|
87
|
+
... for xi, yi in zip(x, y)]
|
|
88
|
+
>>> def fun(x):
|
|
89
|
+
... return 2 * x[0], 3 * x[1]
|
|
90
|
+
|
|
91
|
+
>>> n = cocoex.noiser.Noisifier(p_add=.5)
|
|
92
|
+
>>> f = n.noisify(fun)
|
|
93
|
+
>>> assert all(eq(f([1, 2]), [2, 41.39010606165791])
|
|
94
|
+
... ), f([1, 2])
|
|
95
|
+
>>> assert all(eq(f([2, 3, 4]), [11.518074565992698, 9.705537168513859])
|
|
96
|
+
... ), f([2, 3, 4]) # x[2:] have no influence here
|
|
97
|
+
>>> assert all(eq(f([-1, 2]), [-2, 6])
|
|
98
|
+
... ), f([-1, 2])
|
|
99
|
+
|
|
73
100
|
See also https://github.com/numbbo/coco-experiment/issues/36 and
|
|
74
101
|
https://github.com/numbbo/coco-experiment/blob/main/build/python/example/example_experiment_complete.py
|
|
75
102
|
|
|
76
103
|
"""
|
|
77
104
|
p_add_single_default = 0.2
|
|
78
105
|
def __init__(self, p_add=None, p_subtract=0.0, p_epsilon=0.0, epsilon=1e-4,
|
|
79
|
-
rands=(rand, randn, randc)):
|
|
106
|
+
rands=(rand, randn, randc), filename=None):
|
|
80
107
|
"""constructor with 4 optional parameters for the noise model,
|
|
81
108
|
|
|
82
109
|
`p_add`: probability for adding a positive heavy tail random value
|
|
@@ -89,6 +116,11 @@ class Noisifier:
|
|
|
89
116
|
`p_epsilon`: probability for adding a Gaussian random value
|
|
90
117
|
|
|
91
118
|
`epsilon`: standard deviation of the Gaussian random value
|
|
119
|
+
|
|
120
|
+
`filename`: for saving parameter setting, if not given use module global
|
|
121
|
+
variable `cocoex.noiser.parameters_file`, saving depends on the module
|
|
122
|
+
variable `save_parameters`.
|
|
123
|
+
|
|
92
124
|
"""
|
|
93
125
|
if p_add is None:
|
|
94
126
|
if p_subtract == p_epsilon == 0:
|
|
@@ -97,15 +129,17 @@ class Noisifier:
|
|
|
97
129
|
p_add = 0.0
|
|
98
130
|
self._params = {k: v for k, v in locals().items() if k != 'self'}
|
|
99
131
|
if sum(self._params[p] for p in ('p_subtract', 'p_add')) > 1:
|
|
100
|
-
warnings.warn("p_subtract={0} + p_add={1} > 1, hence p_add
|
|
101
|
-
" as ``1-p_subtract``"
|
|
132
|
+
warnings.warn("p_subtract={0} + p_add={1} > 1, hence p_add" # noqa: UP030
|
|
133
|
+
" is interpreted as ``1-p_subtract``"
|
|
102
134
|
.format(self._params['p_subtract'], self._params['p_add']))
|
|
103
135
|
if p_add < 0 or p_subtract < 0 or p_epsilon < 0 or epsilon < 0:
|
|
104
|
-
raise ValueError("parameters cannot be negative
|
|
105
|
-
.format(self._params))
|
|
136
|
+
raise ValueError("parameters cannot be negative" # noqa: UP030, UP032
|
|
137
|
+
" but were {0}".format(self._params))
|
|
106
138
|
if p_epsilon > 0 and epsilon == 0:
|
|
107
|
-
warnings.warn("p_epsilon = {0} > 0 is not effective
|
|
108
|
-
.format(p_epsilon))
|
|
139
|
+
warnings.warn("p_epsilon = {0} > 0 is not effective" # noqa: UP030, UP032
|
|
140
|
+
" because epsilon = 0".format(p_epsilon))
|
|
141
|
+
if save_parameters:
|
|
142
|
+
self.save_parameters()
|
|
109
143
|
|
|
110
144
|
def noisify(self, problem):
|
|
111
145
|
"""wrap `problem` with frozen noise"""
|
|
@@ -116,23 +150,19 @@ class Noisifier:
|
|
|
116
150
|
def parameters(self):
|
|
117
151
|
return {k: v for (k, v) in self._params.items() if k.startswith(('p_', 'eps'))}
|
|
118
152
|
|
|
119
|
-
def
|
|
120
|
-
|
|
153
|
+
def save_parameters(self, filename=None):
|
|
154
|
+
"""save parameter `dict` to a `json` file"""
|
|
155
|
+
with open(filename or self._params.get('filename')
|
|
156
|
+
or parameters_file, 'wt') as fp:
|
|
121
157
|
json.dump(self.parameters, fp)
|
|
122
158
|
|
|
123
|
-
def
|
|
124
|
-
|
|
125
|
-
with open(parameters_file, 'rt') as fp:
|
|
126
|
-
return json.load(fp)
|
|
127
|
-
except warn_errors as e:
|
|
128
|
-
warnings.warn('NoisifyProblem._load_params raised the exception "{0}"'.format(e))
|
|
129
|
-
except ignore_errors:
|
|
130
|
-
pass
|
|
131
|
-
return {}
|
|
159
|
+
def _set_params(self, filename=None, **kwargs):
|
|
160
|
+
"""set parameters from file `filename` or filename passed at
|
|
132
161
|
|
|
133
|
-
|
|
134
|
-
"""
|
|
135
|
-
self._params.update(self.
|
|
162
|
+
instantiation or `cocoex.noiser.parameters_file`.
|
|
163
|
+
"""
|
|
164
|
+
self._params.update(_read_params(filename or self._params.get('filename')
|
|
165
|
+
or parameters_file), **kwargs)
|
|
136
166
|
|
|
137
167
|
def __getattr__(self, name):
|
|
138
168
|
"""pretend to be a COCO `problem` as passed in `noisify`"""
|
|
@@ -192,6 +222,20 @@ class Noisifier:
|
|
|
192
222
|
assert np.isfinite(n)
|
|
193
223
|
return n
|
|
194
224
|
|
|
225
|
+
|
|
226
|
+
def _read_params(filename=None,
|
|
227
|
+
warn_errors=(FileNotFoundError,), ignore_errors=()):
|
|
228
|
+
"""read parameters from a json file and return a parameters `dict`"""
|
|
229
|
+
try:
|
|
230
|
+
with open(filename or parameters_file, 'rt') as fp:
|
|
231
|
+
return json.load(fp)
|
|
232
|
+
except warn_errors as e:
|
|
233
|
+
warnings.warn('noiser._read_params raised the exception: ' + str(e))
|
|
234
|
+
except ignore_errors:
|
|
235
|
+
pass
|
|
236
|
+
return {}
|
|
237
|
+
|
|
238
|
+
|
|
195
239
|
_seed_weights = [1.23468, 2.34579] # otherwise, coordinate search would be noisefree
|
|
196
240
|
_seeds = collections.deque(maxlen=99) # for the record only
|
|
197
241
|
def _seed(x, i=0):
|
|
@@ -269,7 +269,7 @@ class ProblemNonAnytime:
|
|
|
269
269
|
``p_unobserved.evaluations >= p_observed.evaluations``.
|
|
270
270
|
|
|
271
271
|
"""
|
|
272
|
-
inherited_constant_attributes = [
|
|
272
|
+
inherited_constant_attributes = [ # easier and better solved by defining __getattr__!?
|
|
273
273
|
'dimension',
|
|
274
274
|
'id',
|
|
275
275
|
'index',
|
|
@@ -377,7 +377,7 @@ class SameFunction:
|
|
|
377
377
|
>>> from cocoex.utilities import SameFunction
|
|
378
378
|
>>>
|
|
379
379
|
>>> suite = cocoex.Suite('bbob', '', '')
|
|
380
|
-
>>> already_seen = SameFunction()
|
|
380
|
+
>>> already_seen = seen = SameFunction()
|
|
381
381
|
>>> processed = 0
|
|
382
382
|
>>> for problem in suite:
|
|
383
383
|
... if already_seen(problem.id) > 5:
|
|
@@ -600,6 +600,9 @@ class ExperimentRepeater:
|
|
|
600
600
|
sweeps until some given budget is exhaused, namely, ``budget_multiplier
|
|
601
601
|
* dimension``.
|
|
602
602
|
|
|
603
|
+
CAVEAT: this works as desired only when all instances of the same problem
|
|
604
|
+
are run in the same batch, as it is the case with `BatchScheduler`.
|
|
605
|
+
|
|
603
606
|
Example code snippet::
|
|
604
607
|
|
|
605
608
|
[...]
|
|
@@ -934,6 +937,9 @@ class ExperimentRepeater:
|
|
|
934
937
|
class BatchScheduler:
|
|
935
938
|
"""Facilitate to run a benchmarking experiment in independent batches.
|
|
936
939
|
|
|
940
|
+
All instances of the same ``(function, dimension)`` belong to the same
|
|
941
|
+
batch, in order to allow for uniform instance repetitions.
|
|
942
|
+
|
|
937
943
|
The batch scheduler crucially assumes that in each batch the same
|
|
938
944
|
problems are given *in the same order* when calling `is_in_batch`.
|
|
939
945
|
|
|
@@ -953,10 +959,13 @@ class BatchScheduler:
|
|
|
953
959
|
``batch_to_execute in (0,1,2,3)`` to generate the full experimental
|
|
954
960
|
data.
|
|
955
961
|
|
|
956
|
-
Details:
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
962
|
+
Details: while making the number of functions not divisible by the number of
|
|
963
|
+
batches may sometimes achieve a more even time distribution over all
|
|
964
|
+
batches, in practice, it is advisable to keep each function in a single or a
|
|
965
|
+
few batches as it is enforced by the `BatchScheduler`. Hence, for the 24
|
|
966
|
+
functions of the `'bbob'` testbed, having 48 or 24 or 12 or 8 or 6 or 4
|
|
967
|
+
batches is advisable. Additionally, it can be useful to run the largest
|
|
968
|
+
dimension in a separate launch (with at most 24 batches in this case).
|
|
960
969
|
"""
|
|
961
970
|
def __init__(self, number_of_batches, batch_to_execute):
|
|
962
971
|
"""distribute over `number_of_batches` batches and execute
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|