coco-experiment 2.7.2__tar.gz → 2.7.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.
Files changed (23) hide show
  1. {coco_experiment-2.7.2 → coco_experiment-2.7.4}/PKG-INFO +1 -1
  2. {coco_experiment-2.7.2 → coco_experiment-2.7.4}/meson.build +1 -0
  3. {coco_experiment-2.7.2 → coco_experiment-2.7.4}/src/cocoex/_version.py +1 -1
  4. {coco_experiment-2.7.2 → coco_experiment-2.7.4}/src/cocoex/coco.c +1 -1
  5. coco_experiment-2.7.4/src/cocoex/download_example.py +45 -0
  6. {coco_experiment-2.7.2 → coco_experiment-2.7.4}/src/cocoex/noiser.py +2 -1
  7. {coco_experiment-2.7.2 → coco_experiment-2.7.4}/src/cocoex/utilities.py +37 -17
  8. {coco_experiment-2.7.2 → coco_experiment-2.7.4}/.gitignore +0 -0
  9. {coco_experiment-2.7.2 → coco_experiment-2.7.4}/LICENSE +0 -0
  10. {coco_experiment-2.7.2 → coco_experiment-2.7.4}/README.md +0 -0
  11. {coco_experiment-2.7.2 → coco_experiment-2.7.4}/pyproject.toml +0 -0
  12. {coco_experiment-2.7.2 → coco_experiment-2.7.4}/scripts/run-doctest.py +0 -0
  13. {coco_experiment-2.7.2 → coco_experiment-2.7.4}/src/cocoex/__init__.py +0 -0
  14. {coco_experiment-2.7.2 → coco_experiment-2.7.4}/src/cocoex/bare_problem.pyx +0 -0
  15. {coco_experiment-2.7.2 → coco_experiment-2.7.4}/src/cocoex/coco.h +0 -0
  16. {coco_experiment-2.7.2 → coco_experiment-2.7.4}/src/cocoex/exceptions.py +0 -0
  17. {coco_experiment-2.7.2 → coco_experiment-2.7.4}/src/cocoex/interface.pyx +0 -0
  18. {coco_experiment-2.7.2 → coco_experiment-2.7.4}/src/cocoex/solvers.py +0 -0
  19. {coco_experiment-2.7.2 → coco_experiment-2.7.4}/tests/bbob2009_testcases.txt +0 -0
  20. {coco_experiment-2.7.2 → coco_experiment-2.7.4}/tests/bbob2009_testcases2.txt +0 -0
  21. {coco_experiment-2.7.2 → coco_experiment-2.7.4}/tests/test_bare_problem.py +0 -0
  22. {coco_experiment-2.7.2 → coco_experiment-2.7.4}/tests/test_regression.py +0 -0
  23. {coco_experiment-2.7.2 → coco_experiment-2.7.4}/tests/test_suite.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: coco-experiment
3
- Version: 2.7.2
3
+ Version: 2.7.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/
@@ -64,6 +64,7 @@ dep_numpy = declare_dependency(include_directories: inc_numpy, compile_args: cfl
64
64
  python_sources = [
65
65
  'src/cocoex/__init__.py',
66
66
  'src/cocoex/_version.py',
67
+ 'src/cocoex/download_example.py',
67
68
  'src/cocoex/exceptions.py',
68
69
  'src/cocoex/noiser.py',
69
70
  'src/cocoex/solvers.py',
@@ -1,7 +1,7 @@
1
1
  # file generated by fabricate
2
2
  # Do not change, do not track in version control!
3
3
 
4
- __version__ = "2.7.2"
4
+ __version__ = "2.7.4"
5
5
  version = __version__
6
6
 
7
7
  if __name__ == "__main__":
@@ -31526,7 +31526,7 @@ void coco_archive_free(coco_archive_t *archive) {
31526
31526
  * don't change, don't track in version control!
31527
31527
  */
31528
31528
 
31529
- const char *coco_version = "2.7.2";
31529
+ const char *coco_version = "2.7.4";
31530
31530
  #line 1 "coco_runtime_c.c"
31531
31531
  /**
31532
31532
  * @file coco_runtime_c.c
@@ -0,0 +1,45 @@
1
+ """Download example scripts from GitHub to a local folder, by default `cocoex-example`
2
+ in the current folder.
3
+
4
+ Usage::
5
+
6
+ python -m cocoex.download_example [folder_name]
7
+
8
+ """
9
+ import os
10
+ import sys
11
+
12
+ default_local_folder = 'cocoex-example'
13
+
14
+ remote_folder = 'https://raw.githubusercontent.com/numbbo/coco-experiment/main/build/python/example/'
15
+
16
+ file_names = ['mkl_bugfix.py',
17
+ 'example_experiment_simple.py',
18
+ 'example_experiment_complete.py',
19
+ 'example_experiment_non_anytime.py',
20
+ 'example_experiment_parameter_sweep.py',
21
+ ]
22
+
23
+ def main(folder=None):
24
+ """download example scripts from GitHub into `folder`, by default `./cocoex-example`"""
25
+ try:
26
+ import urllib.request
27
+ except ImportError:
28
+ print('Install urllib (`pip install urllib`) to download example')
29
+ raise
30
+ if folder is None:
31
+ folder = default_local_folder
32
+ if os.path.exists(folder):
33
+ raise ValueError('local target folder {0} already exists. Remove the folder\n'
34
+ 'or pass another folder name as argument to `cocoex.download_example`'
35
+ .format(folder))
36
+ os.mkdir(folder)
37
+ for file_name in file_names:
38
+ with urllib.request.urlopen(remote_folder + file_name) as f:
39
+ d = f.read().decode('utf-8')
40
+ with open(folder + '/' + file_name, 'w') as f:
41
+ f.write(d)
42
+ print(' example scripts have been downloaded to {0}'.format(folder))
43
+
44
+ if __name__ == '__main__':
45
+ main(sys.argv[1] if len(sys.argv) > 1 else None)
@@ -70,7 +70,8 @@ class Noisifier:
70
70
  noise generator and the numbers scaled by pi/2 such that P(number > k)
71
71
  equals about 1/k when k >= 5.
72
72
 
73
- See also https://github.com/numbbo/coco-experiment/blob/main/build/python/example/example_experiment_complete.py
73
+ See also https://github.com/numbbo/coco-experiment/issues/36 and
74
+ https://github.com/numbbo/coco-experiment/blob/main/build/python/example/example_experiment_complete.py
74
75
 
75
76
  """
76
77
  def __init__(self, p_add=0.2, p_subtract=0.0, p_epsilon=0, epsilon=1e-4,
@@ -647,8 +647,9 @@ class ExperimentRepeater:
647
647
  When problem instances are repeated in a single suite, they may be
648
648
  *partially* skipped *after* the first full sweep. That is, the
649
649
  configuration ``1-5,1-5,1-5`` can also lead to four trials of each
650
- instance 1-5, because all instances have been repeated the same number
651
- of times.
650
+ instance 1-5 of some problems when all instances have been repeated the
651
+ same number of times and have enough successes or the budget is
652
+ exhaused.
652
653
 
653
654
  >>> import cocoex # some not very meaningful testing
654
655
  >>> repeater = cocoex.ExperimentRepeater(2)
@@ -658,18 +659,31 @@ class ExperimentRepeater:
658
659
  >>> assert len(repeater.evaluations((1, 2))) == 0
659
660
 
660
661
  """
661
- def __init__(self, budget_multiplier, min_successes=None):
662
- """``min_successes=11`` is default and provokes at least three
663
-
664
- sweeps when the suite has (only) 5 instance and the
665
- `budget_multiplier` is large enough such that the algorithm
666
- terminates the second sweep before the overall budget is exhausted.
667
- This would emulate the 3 x 1-5 instance-setup from BBOB 2009,
668
- however the choice of the initial solution still slightly differs.
662
+ min_successes_default = 11
663
+ max_sweeps_default = 20
664
+ def __init__(self, budget_multiplier, min_successes=None, max_sweeps=None):
665
+ """constructor for `ExperimentRepeater`.
666
+
667
+ The "timeout" budget is computed as ``budget_multiplier`` times
668
+ problem dimension.
669
+
670
+ ``min_successes=11`` is default and provokes at least three sweeps
671
+ when the suite has (only) 5 instance and the `budget_multiplier` is
672
+ large enough such that the algorithm terminates the second sweep
673
+ before the overall budget is exhausted. This would emulate the 3 x
674
+ 1-5 instance-setup from BBOB 2009, however the choice of the
675
+ initial solution still slightly differs.
676
+
677
+ ``max_sweeps`` is the limit number of repititions for each
678
+ instance, by default 20. To have a limit is in particular useful
679
+ when the budget is large but an algorithm terminates very quickly
680
+ and invariably unsuccessfully.
669
681
  """
670
682
  self.params = {k: v for k, v in locals().items() if k != 'self'}
671
- self.min_successes = 11 if min_successes is None else min_successes
672
- self.max_sweeps = 1e4 # should not be necessary
683
+ self.min_successes = ExperimentRepeater.min_successes_default if (
684
+ min_successes is None) else min_successes
685
+ self.max_sweeps = ExperimentRepeater.max_sweeps_default if (
686
+ max_sweeps is None) else max_sweeps # useful on F7
673
687
  self._dimension_offset = 0
674
688
  '''budget = (dimension + offset) * budget_multiplier'''
675
689
  self._data = _collections.OrderedDict()
@@ -728,7 +742,13 @@ class ExperimentRepeater:
728
742
  return sum(self.trials(problem))
729
743
  return sum(self.all(self.n_trials).values())
730
744
  def track(self, problem):
731
- """record problem instance evaluations and success (target hit)"""
745
+ """record problem instance evaluations and success (final target hit).
746
+
747
+ Track data to decide (later) whether more experiments or sweeps are
748
+ needed. `track` requires `problem` to have the attributes
749
+ ``id_function, dimension, id_instance, evaluations`` and
750
+ ``final_target_hit``.
751
+ """
732
752
  fun, dim, iinst = self.problem_to_ids(problem)
733
753
  if (fun, dim) not in self._data:
734
754
  self._data[(fun, dim)] = _collections.defaultdict(list)
@@ -848,7 +868,7 @@ class ExperimentRepeater:
848
868
  it cannot account for problems that have not yet been run once.
849
869
 
850
870
  Calling ``done()`` increments the sweep counter iff it returns
851
- `False`, the default for ``max_sweeps`` is ``1e4``. The attribute
871
+ `False`, the default for ``max_sweeps`` is ``20``. The attribute
852
872
  can be directly reassigned at any time.
853
873
 
854
874
  See also: `remaining_problems`
@@ -861,11 +881,11 @@ class ExperimentRepeater:
861
881
  return True
862
882
  if message: # prints nothing when no data are found
863
883
  print(self.message_sweep(), end='') # indicates "sequence of problems" case
864
- self._sweeps += 1 # the sweep number to come
865
- done = self._sweeps >= self.max_sweeps or (
884
+ self._sweeps += 1 # the sweep number to come, needed in remaining_problems()
885
+ done = self._sweeps > self.max_sweeps or (
866
886
  self._sweeps > 1 and len(self._data) == 0) or (
867
887
  self.n_problem_instances() > 0 and not self.remaining_problems())
868
- self._sweeps -= done # don't increment when done
888
+ self._sweeps -= done # revert increment when done is True
869
889
  return done
870
890
  def remaining_problems(self, suite=None):
871
891
  """return `list` of (probably) remaining problem instances to run.
File without changes