fcmaes 2.0.2__tar.gz → 2.0.3__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 (96) hide show
  1. {fcmaes-2.0.2 → fcmaes-2.0.3}/PKG-INFO +9 -4
  2. {fcmaes-2.0.2 → fcmaes-2.0.3}/README.adoc +27 -2
  3. fcmaes-2.0.3/README.md +13 -0
  4. fcmaes-2.0.3/ai-context.md +711 -0
  5. {fcmaes-2.0.2 → fcmaes-2.0.3}/pyproject.toml +3 -1
  6. fcmaes-2.0.2/README.md +0 -10
  7. {fcmaes-2.0.2 → fcmaes-2.0.3}/.gitignore +0 -0
  8. {fcmaes-2.0.2 → fcmaes-2.0.3}/CMakeLists.txt +0 -0
  9. {fcmaes-2.0.2 → fcmaes-2.0.3}/LICENSE +0 -0
  10. {fcmaes-2.0.2 → fcmaes-2.0.3}/_fcmaescpp/CMakeLists.txt +0 -0
  11. {fcmaes-2.0.2 → fcmaes-2.0.3}/_fcmaescpp/acmaesoptimizer.cpp +0 -0
  12. {fcmaes-2.0.2 → fcmaes-2.0.3}/_fcmaescpp/bindings/acma_bindings.cpp +0 -0
  13. {fcmaes-2.0.2 → fcmaes-2.0.3}/_fcmaescpp/bindings/acma_bindings.hpp +0 -0
  14. {fcmaes-2.0.2 → fcmaes-2.0.3}/_fcmaescpp/bindings/bite_bindings.cpp +0 -0
  15. {fcmaes-2.0.2 → fcmaes-2.0.3}/_fcmaescpp/bindings/bite_bindings.hpp +0 -0
  16. {fcmaes-2.0.2 → fcmaes-2.0.3}/_fcmaescpp/bindings/common.hpp +0 -0
  17. {fcmaes-2.0.2 → fcmaes-2.0.3}/_fcmaescpp/bindings/crfmnes_bindings.cpp +0 -0
  18. {fcmaes-2.0.2 → fcmaes-2.0.3}/_fcmaescpp/bindings/crfmnes_bindings.hpp +0 -0
  19. {fcmaes-2.0.2 → fcmaes-2.0.3}/_fcmaescpp/bindings/da_bindings.cpp +0 -0
  20. {fcmaes-2.0.2 → fcmaes-2.0.3}/_fcmaescpp/bindings/da_bindings.hpp +0 -0
  21. {fcmaes-2.0.2 → fcmaes-2.0.3}/_fcmaescpp/bindings/de_bindings.cpp +0 -0
  22. {fcmaes-2.0.2 → fcmaes-2.0.3}/_fcmaescpp/bindings/de_bindings.hpp +0 -0
  23. {fcmaes-2.0.2 → fcmaes-2.0.3}/_fcmaescpp/bindings/gil_utils.hpp +0 -0
  24. {fcmaes-2.0.2 → fcmaes-2.0.3}/_fcmaescpp/bindings/gtop_bindings.cpp +0 -0
  25. {fcmaes-2.0.2 → fcmaes-2.0.3}/_fcmaescpp/bindings/gtop_bindings.hpp +0 -0
  26. {fcmaes-2.0.2 → fcmaes-2.0.3}/_fcmaescpp/bindings/mode_bindings.cpp +0 -0
  27. {fcmaes-2.0.2 → fcmaes-2.0.3}/_fcmaescpp/bindings/mode_bindings.hpp +0 -0
  28. {fcmaes-2.0.2 → fcmaes-2.0.3}/_fcmaescpp/bindings/module.cpp +0 -0
  29. {fcmaes-2.0.2 → fcmaes-2.0.3}/_fcmaescpp/bindings/ndarray_utils.hpp +0 -0
  30. {fcmaes-2.0.2 → fcmaes-2.0.3}/_fcmaescpp/bindings/pgpe_bindings.cpp +0 -0
  31. {fcmaes-2.0.2 → fcmaes-2.0.3}/_fcmaescpp/bindings/pgpe_bindings.hpp +0 -0
  32. {fcmaes-2.0.2 → fcmaes-2.0.3}/_fcmaescpp/biteoptimizer.cpp +0 -0
  33. {fcmaes-2.0.2 → fcmaes-2.0.3}/_fcmaescpp/crfmnes.cpp +0 -0
  34. {fcmaes-2.0.2 → fcmaes-2.0.3}/_fcmaescpp/daoptimizer.cpp +0 -0
  35. {fcmaes-2.0.2 → fcmaes-2.0.3}/_fcmaescpp/deoptimizer.cpp +0 -0
  36. {fcmaes-2.0.2 → fcmaes-2.0.3}/_fcmaescpp/gtop.cpp +0 -0
  37. {fcmaes-2.0.2 → fcmaes-2.0.3}/_fcmaescpp/include/LBFGS.h +0 -0
  38. {fcmaes-2.0.2 → fcmaes-2.0.3}/_fcmaescpp/include/LBFGSB.h +0 -0
  39. {fcmaes-2.0.2 → fcmaes-2.0.3}/_fcmaescpp/include/LBFGSpp/BFGSMat.h +0 -0
  40. {fcmaes-2.0.2 → fcmaes-2.0.3}/_fcmaescpp/include/LBFGSpp/BKLDLT.h +0 -0
  41. {fcmaes-2.0.2 → fcmaes-2.0.3}/_fcmaescpp/include/LBFGSpp/Cauchy.h +0 -0
  42. {fcmaes-2.0.2 → fcmaes-2.0.3}/_fcmaescpp/include/LBFGSpp/LineSearchBacktracking.h +0 -0
  43. {fcmaes-2.0.2 → fcmaes-2.0.3}/_fcmaescpp/include/LBFGSpp/LineSearchBracketing.h +0 -0
  44. {fcmaes-2.0.2 → fcmaes-2.0.3}/_fcmaescpp/include/LBFGSpp/LineSearchMoreThuente.h +0 -0
  45. {fcmaes-2.0.2 → fcmaes-2.0.3}/_fcmaescpp/include/LBFGSpp/LineSearchNocedalWright.h +0 -0
  46. {fcmaes-2.0.2 → fcmaes-2.0.3}/_fcmaescpp/include/LBFGSpp/Param.h +0 -0
  47. {fcmaes-2.0.2 → fcmaes-2.0.3}/_fcmaescpp/include/LBFGSpp/SubspaceMin.h +0 -0
  48. {fcmaes-2.0.2 → fcmaes-2.0.3}/_fcmaescpp/include/acmaesoptimizer.hpp +0 -0
  49. {fcmaes-2.0.2 → fcmaes-2.0.3}/_fcmaescpp/include/biteaux.h +0 -0
  50. {fcmaes-2.0.2 → fcmaes-2.0.3}/_fcmaescpp/include/biteopt.h +0 -0
  51. {fcmaes-2.0.2 → fcmaes-2.0.3}/_fcmaescpp/include/biteopt_asktell.h +0 -0
  52. {fcmaes-2.0.2 → fcmaes-2.0.3}/_fcmaescpp/include/biteoptimizer.hpp +0 -0
  53. {fcmaes-2.0.2 → fcmaes-2.0.3}/_fcmaescpp/include/biteort.h +0 -0
  54. {fcmaes-2.0.2 → fcmaes-2.0.3}/_fcmaescpp/include/crfmnesoptimizer.hpp +0 -0
  55. {fcmaes-2.0.2 → fcmaes-2.0.3}/_fcmaescpp/include/daoptimizer.hpp +0 -0
  56. {fcmaes-2.0.2 → fcmaes-2.0.3}/_fcmaescpp/include/deopt.h +0 -0
  57. {fcmaes-2.0.2 → fcmaes-2.0.3}/_fcmaescpp/include/deoptimizer.hpp +0 -0
  58. {fcmaes-2.0.2 → fcmaes-2.0.3}/_fcmaescpp/include/evaluator.h +0 -0
  59. {fcmaes-2.0.2 → fcmaes-2.0.3}/_fcmaescpp/include/gtop.hpp +0 -0
  60. {fcmaes-2.0.2 → fcmaes-2.0.3}/_fcmaescpp/include/modeoptimizer.hpp +0 -0
  61. {fcmaes-2.0.2 → fcmaes-2.0.3}/_fcmaescpp/include/nmsopt.h +0 -0
  62. {fcmaes-2.0.2 → fcmaes-2.0.3}/_fcmaescpp/include/pcg_extras.hpp +0 -0
  63. {fcmaes-2.0.2 → fcmaes-2.0.3}/_fcmaescpp/include/pcg_random.hpp +0 -0
  64. {fcmaes-2.0.2 → fcmaes-2.0.3}/_fcmaescpp/include/pcg_uint128.hpp +0 -0
  65. {fcmaes-2.0.2 → fcmaes-2.0.3}/_fcmaescpp/include/pgpeoptimizer.hpp +0 -0
  66. {fcmaes-2.0.2 → fcmaes-2.0.3}/_fcmaescpp/include/smaesopt.h +0 -0
  67. {fcmaes-2.0.2 → fcmaes-2.0.3}/_fcmaescpp/include/spheropt.h +0 -0
  68. {fcmaes-2.0.2 → fcmaes-2.0.3}/_fcmaescpp/modeoptimizer.cpp +0 -0
  69. {fcmaes-2.0.2 → fcmaes-2.0.3}/_fcmaescpp/pgpe.cpp +0 -0
  70. {fcmaes-2.0.2 → fcmaes-2.0.3}/fcmaes/__init__.py +0 -0
  71. {fcmaes-2.0.2 → fcmaes-2.0.3}/fcmaes/_fcmaes_ext.pyi +0 -0
  72. {fcmaes-2.0.2 → fcmaes-2.0.3}/fcmaes/_native.py +0 -0
  73. {fcmaes-2.0.2 → fcmaes-2.0.3}/fcmaes/advretry.py +0 -0
  74. {fcmaes-2.0.2 → fcmaes-2.0.3}/fcmaes/astro.py +0 -0
  75. {fcmaes-2.0.2 → fcmaes-2.0.3}/fcmaes/bitecpp.py +0 -0
  76. {fcmaes-2.0.2 → fcmaes-2.0.3}/fcmaes/cmaes.py +0 -0
  77. {fcmaes-2.0.2 → fcmaes-2.0.3}/fcmaes/cmaescpp.py +0 -0
  78. {fcmaes-2.0.2 → fcmaes-2.0.3}/fcmaes/crfmnes.py +0 -0
  79. {fcmaes-2.0.2 → fcmaes-2.0.3}/fcmaes/crfmnescpp.py +0 -0
  80. {fcmaes-2.0.2 → fcmaes-2.0.3}/fcmaes/dacpp.py +0 -0
  81. {fcmaes-2.0.2 → fcmaes-2.0.3}/fcmaes/de.py +0 -0
  82. {fcmaes-2.0.2 → fcmaes-2.0.3}/fcmaes/decpp.py +0 -0
  83. {fcmaes-2.0.2 → fcmaes-2.0.3}/fcmaes/diversifier.py +0 -0
  84. {fcmaes-2.0.2 → fcmaes-2.0.3}/fcmaes/evaluator.py +0 -0
  85. {fcmaes-2.0.2 → fcmaes-2.0.3}/fcmaes/journal.py +0 -0
  86. {fcmaes-2.0.2 → fcmaes-2.0.3}/fcmaes/mapelites.py +0 -0
  87. {fcmaes-2.0.2 → fcmaes-2.0.3}/fcmaes/mode.py +0 -0
  88. {fcmaes-2.0.2 → fcmaes-2.0.3}/fcmaes/modecpp.py +0 -0
  89. {fcmaes-2.0.2 → fcmaes-2.0.3}/fcmaes/moretry.py +0 -0
  90. {fcmaes-2.0.2 → fcmaes-2.0.3}/fcmaes/multiretry.py +0 -0
  91. {fcmaes-2.0.2 → fcmaes-2.0.3}/fcmaes/optimizer.py +0 -0
  92. {fcmaes-2.0.2 → fcmaes-2.0.3}/fcmaes/pgpecpp.py +0 -0
  93. {fcmaes-2.0.2 → fcmaes-2.0.3}/fcmaes/pygmoretry.py +0 -0
  94. {fcmaes-2.0.2 → fcmaes-2.0.3}/fcmaes/retry.py +0 -0
  95. {fcmaes-2.0.2 → fcmaes-2.0.3}/fcmaes/test_cma.py +0 -0
  96. {fcmaes-2.0.2 → fcmaes-2.0.3}/fcmaes/testfun.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: fcmaes
3
- Version: 2.0.2
3
+ Version: 2.0.3
4
4
  Summary: A Python 3 gradient-free optimization library.
5
5
  Keywords: optimization,multi-objective,parallel
6
6
  Author-Email: Dietmar Wolz <drdietmarwolz@yahoo.de>
@@ -24,6 +24,8 @@ Classifier: Topic :: Scientific/Engineering :: Information Analysis
24
24
  Classifier: Topic :: Scientific/Engineering :: Mathematics
25
25
  Project-URL: Homepage, https://github.com/dietmarwo/fast-cma-es
26
26
  Project-URL: Repository, https://github.com/dietmarwo/fast-cma-es
27
+ Project-URL: Documentation, https://dietmarwo.github.io/fast-cma-es/
28
+ Project-URL: Tutorials, https://dietmarwo.github.io/fast-cma-es/tutorials/
27
29
  Requires-Python: >=3.10
28
30
  Requires-Dist: numpy
29
31
  Requires-Dist: scipy
@@ -37,9 +39,12 @@ Description-Content-Type: text/markdown
37
39
  # fcmaes
38
40
  A Python 3 gradient-free optimization library.
39
41
 
40
- - [README](https://github.com/dietmarwo/fast-cma-es/blob/master/README.adoc)
41
- - [Tutorials](https://github.com/dietmarwo/fast-cma-es/blob/master/tutorials/Tutorials.adoc)
42
-
42
+ - [Documentation book](https://dietmarwo.github.io/fast-cma-es/)
43
+ - [Full README](https://github.com/dietmarwo/fast-cma-es/blob/master/README.adoc)
44
+ - [Tutorials](https://dietmarwo.github.io/fast-cma-es/tutorials/)
45
+ - [Python API](https://dietmarwo.github.io/fast-cma-es/fcmaes_documentation.html)
46
+ - [C++ API](https://dietmarwo.github.io/fast-cma-es/cpp_documentation.html)
47
+ - [Examples API](https://dietmarwo.github.io/fast-cma-es/examples_documentation.html)
43
48
 
44
49
 
45
50
 
@@ -14,9 +14,9 @@ It supports multi-threaded use of several gradient-free
14
14
  https://dietmarwo.github.io/fast-cma-es/fcmaes_documentation.html[algorithms] partly implemented in https://dietmarwo.github.io/fast-cma-es/cpp_documentation.html[{cpp}].
15
15
  It is designed for real-world problems, including multi-objective and constrained optimization. The main algorithms are available in both Python and C++. They support parallel fitness evaluation as well as parallel retry strategies.
16
16
 
17
- There are many practical https://github.com/dietmarwo/fast-cma-es/blob/master/tutorials/README.adoc[tutorials] and https://dietmarwo.github.io/fast-cma-es/examples_documentation.html[examples] that show how to use fcmaes in detail.
17
+ The https://dietmarwo.github.io/fast-cma-es/[documentation book] combines the API references with many practical https://dietmarwo.github.io/fast-cma-es/tutorials/[tutorials] and https://dietmarwo.github.io/fast-cma-es/examples_documentation.html[examples] that show how to use fcmaes in detail.
18
18
 
19
- Detailed benchmark results are available in https://github.com/dietmarwo/fast-cma-es/blob/master/tutorials/Performance.adoc[performance].
19
+ Detailed benchmark results are available in the book's https://dietmarwo.github.io/fast-cma-es/tutorials/Performance.html[performance chapter].
20
20
 
21
21
  === Features
22
22
 
@@ -29,6 +29,9 @@ Detailed benchmark results are available in https://github.com/dietmarwo/fast-cm
29
29
  - Offers a selection of efficient single-objective optimizers.
30
30
  - Provides an ask-tell interface for CMA-ES, CR-FM-NES, DE, MODE, and PGPE.
31
31
 
32
+ === Update: Native Rust implementation of fcmaes
33
+ See https://github.com/dietmarwo/fcmaes-rust[fcmaes-rust]. This repo is an alternative both for Rust and Python users as it provides a PyO3 API. See https://github.com/dietmarwo/fcmaes-rust/blob/main/examples/python/test_cma.py[python example].
34
+
32
35
  === Update (2.0.2): Ask Tell interface for BiteOpt
33
36
 
34
37
  The native BiteOpt backend now also provides an ask/tell interface through `bitecpp.Bite_C`.
@@ -245,6 +248,28 @@ Example dependencies:
245
248
 
246
249
  - pykep: https://esa.github.io/pykep/[pykep]. Install with 'pip install pykep'.
247
250
 
251
+ === Documentation
252
+
253
+ The GitHub Pages workflow builds this README, all AsciiDoc tutorials, and the
254
+ three maintained HTML API references as one navigable site:
255
+
256
+ - https://dietmarwo.github.io/fast-cma-es/[Documentation home]
257
+ - https://dietmarwo.github.io/fast-cma-es/fcmaes_documentation.html[Python API]
258
+ - https://dietmarwo.github.io/fast-cma-es/cpp_documentation.html[{cpp} API]
259
+ - https://dietmarwo.github.io/fast-cma-es/examples_documentation.html[Examples API]
260
+ - https://dietmarwo.github.io/fast-cma-es/tutorials/[Tutorial index]
261
+
262
+ Build and validate the same site locally with Asciidoctor 2.0.23 or newer:
263
+
264
+ [source,bash]
265
+ ----
266
+ gem install asciidoctor --version 2.0.23 --no-document
267
+ python scripts/build_docs.py
268
+ ----
269
+
270
+ The generated site is written to `target/site`. AsciiDoc remains the canonical
271
+ source; no Markdown conversion is required.
272
+
248
273
  === Packaging and release
249
274
 
250
275
  - Pull requests and branch pushes build wheels on Linux, Windows, and macOS.
fcmaes-2.0.3/README.md ADDED
@@ -0,0 +1,13 @@
1
+ # fcmaes
2
+ A Python 3 gradient-free optimization library.
3
+
4
+ - [Documentation book](https://dietmarwo.github.io/fast-cma-es/)
5
+ - [Full README](https://github.com/dietmarwo/fast-cma-es/blob/master/README.adoc)
6
+ - [Tutorials](https://dietmarwo.github.io/fast-cma-es/tutorials/)
7
+ - [Python API](https://dietmarwo.github.io/fast-cma-es/fcmaes_documentation.html)
8
+ - [C++ API](https://dietmarwo.github.io/fast-cma-es/cpp_documentation.html)
9
+ - [Examples API](https://dietmarwo.github.io/fast-cma-es/examples_documentation.html)
10
+
11
+
12
+
13
+
@@ -0,0 +1,711 @@
1
+ # AI context for solving user optimization problems with fcmaes
2
+
3
+ This file is operational context for an AI that must design and implement an
4
+ optimization solution with this repository. It is not a claim that one
5
+ optimizer is universally best. Use the problem structure, evaluation cost, and
6
+ the user's desired output to choose a small set of defensible candidates, then
7
+ compare them under the same evaluation and worker budget.
8
+
9
+ The repository provides the `fcmaes` Python package. It combines Python
10
+ optimizer and orchestration code with a C++17 backend exposed through nanobind.
11
+ The modules whose names end in `cpp` use that native backend; modules such as
12
+ `de.py`, `cmaes.py`, and `mode.py` contain Python implementations. All
13
+ optimizers minimize.
14
+
15
+ The public distribution and import name are the same:
16
+
17
+ ```text
18
+ python -m pip install fcmaes
19
+ python -c "import fcmaes"
20
+ ```
21
+
22
+ The published package requires Python 3.10 or newer. Release wheels target
23
+ CPython 3.10 through 3.13 on Linux x86-64, Windows AMD64, and current Intel and
24
+ Apple Silicon macOS runners. Installing a matching wheel needs no compiler.
25
+ A source build needs a C++17 compiler, CMake, nanobind, and Eigen 3.4.
26
+ Repository `examples`, `tutorials`, documentation sources, scripts, and tests
27
+ are intentionally excluded from the source distribution.
28
+
29
+ Use public Python wrappers such as `fcmaes.decpp.minimize` rather than calling
30
+ private extension symbols directly. Return values from scalar minimizers are
31
+ normally `scipy.optimize.OptimizeResult` objects with `x`, `fun`, `nfev`,
32
+ `nit`, `status`, and `success` fields. Multi-objective and quality-diversity
33
+ entry points return arrays or archives as documented by their modules.
34
+
35
+ ## Required workflow for the AI
36
+
37
+ Before selecting an algorithm, create a problem card containing these facts.
38
+ Inspect the user's code and data where possible. Ask only for facts that cannot
39
+ be inferred and would materially change the solution.
40
+
41
+ | Question | Why it matters |
42
+ |---|---|
43
+ | What is the decision dimension? | Population size, covariance cost, and useful budgets depend strongly on dimension. |
44
+ | What is each variable's lower and upper bound? | Most global algorithms need a finite, meaningful search box. |
45
+ | Which variables are continuous, integer, ordinal, categorical, or structured? | DE and MODE have integer support, but categorical and structured variables still need decoding or repair. |
46
+ | Is there one objective, several objectives, or a quality-diversity archive? | This selects scalar optimization, MODE/weighted retry, or MAP-Elites. |
47
+ | Which directions are optimized? | Convert maximization to minimization by negating the value. |
48
+ | What are the constraints and feasibility convention? | MODE and `moretry` require constraints after objectives and treat `g(x) <= 0` as feasible. |
49
+ | Is a good initial point known? | CMA-ES, CR-FM-NES, PGPE, and local refinement benefit from it. |
50
+ | Is the objective smooth, discontinuous, noisy, stochastic, or multimodal? | Distribution search, restart strategy, and stopping tolerances differ. |
51
+ | For a stochastic objective, can simulations accept explicit seeds? | Common random numbers make comparisons fair; disjoint seeds are needed for validation. |
52
+ | How long does one evaluation take, and is it safe to run in another process? | This determines inner population evaluation versus outer retry parallelism. |
53
+ | What is the evaluation, wall-time, memory, and core budget? | Evaluation counts are the fairest first comparison unit. |
54
+ | Is a target value known? | Set `stop_fitness`; do not confuse it with the store filter `value_limit`. |
55
+ | Does the user need one solution, a Pareto front, or diverse behavior niches? | The requested output is part of the algorithm choice. |
56
+
57
+ Do not proceed with arbitrary placeholder bounds. If bounds are genuinely
58
+ unknown, derive physically meaningful limits or transform the variables. An
59
+ unnecessarily wide search box can cost orders of magnitude more evaluations.
60
+
61
+ For every completed solution, report the problem card, algorithm and rejected
62
+ alternatives, objective and constraint convention, every non-default
63
+ parameter, evaluation and process budgets, random seeds, validation method,
64
+ and quality statistics. Code without this configuration record is not a
65
+ reproducible optimization solution.
66
+
67
+ ## First decide whether fcmaes is appropriate
68
+
69
+ Do not choose a gradient-free optimizer merely because the model is a
70
+ simulation. Prefer a gradient-based optimizer when all variables are
71
+ continuous, the complete objective is differentiable, reliable analytical,
72
+ automatic-differentiation, adjoint, or sensitivity gradients are available,
73
+ and the user needs one optimum or a smooth trade-off. Those gradients usually
74
+ carry much more information per evaluation.
75
+
76
+ fcmaes is a strong candidate when one or more of these conditions holds:
77
+
78
+ - gradients are unavailable, unreliable, or dominated by simulation noise;
79
+ - events, contact, clipping, repair, routing, integer choices, or categorical
80
+ decoding make the complete objective nonsmooth;
81
+ - the landscape is multimodal and needs global exploration or many restarts;
82
+ - objectives are cheap enough that optimizer overhead and parallel retries
83
+ matter;
84
+ - the result must cover behaviorally different niches instead of returning
85
+ only one optimum; or
86
+ - robust maxima, quantiles, failures, or other outer logic make an otherwise
87
+ smooth model nonsmooth.
88
+
89
+ Route evaluation-scarce problems to Bayesian or surrogate optimization when
90
+ only tens or hundreds of evaluations are affordable and a useful surrogate
91
+ can be fitted. Route exact linear, mixed-integer linear, routing, and
92
+ scheduling formulations to dedicated mathematical-programming solvers when
93
+ their structure can be expressed faithfully. Use fcmaes for structured
94
+ problems only when a defensible continuous encoding and deterministic repair
95
+ are part of the formulation.
96
+
97
+ ## Fast algorithm-selection decision tree
98
+
99
+ 1. If valid and economical gradients exist for the complete map from decisions
100
+ to objectives, start with a gradient-based method.
101
+ 2. If the user wants the best solution in many behavior niches, use
102
+ `mapelites.optimize_map_elites`. Add `diversifier.minimize` when local
103
+ improvement emitters are useful.
104
+ 3. If there are two or more competing objectives:
105
+ - Use `modecpp.minimize` for one coordinated Pareto population, especially
106
+ with explicit constraints or integer-decoded variables.
107
+ - Use `moretry.minimize` when many independent weighted scalar runs are
108
+ desirable or a DE/CMA/BiteOpt scalar pipeline is already effective.
109
+ 4. For one scalar objective:
110
+ - Start with native BiteOpt for a difficult bounded, nonsmooth,
111
+ multimodal, or poorly characterized black box.
112
+ - Start with native DE for robust bounded exploration, integer-decoded
113
+ variables, and DE-to-CMA sequences.
114
+ - Use active CMA-ES when a useful guess exists, variables are continuous,
115
+ and correlations or ill-conditioning matter.
116
+ - Use CR-FM-NES for higher-dimensional continuous distribution search.
117
+ - Use PGPE for very high-dimensional mirrored sampling, noisy policy
118
+ search, or high-throughput batch objectives.
119
+ - Use Dual Annealing for low-to-moderate-dimensional global exploration,
120
+ optionally followed by its local search.
121
+ 5. If local optima are likely, use independent `retry`. Compare
122
+ `advretry` only when retained elites, crossover boxes, and increasing
123
+ per-run budgets are plausible advantages.
124
+ 6. Benchmark at least two plausible choices with identical bounds, objective,
125
+ total evaluations, random protocol, and worker resources. A useful general
126
+ comparison is BiteOpt retry versus DE followed by CMA-ES.
127
+
128
+ ## Choose the integration surface
129
+
130
+ For normal Python use, prefer these native wrappers:
131
+
132
+ - `fcmaes.bitecpp.minimize`
133
+ - `fcmaes.decpp.minimize`
134
+ - `fcmaes.cmaescpp.minimize`
135
+ - `fcmaes.crfmnescpp.minimize`
136
+ - `fcmaes.pgpecpp.minimize`
137
+ - `fcmaes.dacpp.minimize`
138
+ - `fcmaes.modecpp.minimize`
139
+
140
+ The corresponding stateful `Bite_C`, `DE_C`, `ACMA_C`, `CRFMNES_C`,
141
+ `PGPE_C`, and `MODE_C` classes provide ask/tell integration. Use ask/tell when
142
+ the application owns batching, remote execution, accelerators, or a simulator
143
+ pool. Preserve candidate order between `ask()` and `tell()`.
144
+
145
+ The Python `de`, `cmaes`, `crfmnes`, and `mode` modules remain useful for
146
+ experimentation, inspection, custom modifiers, and comparisons. Do not mix
147
+ Python and C++ APIs just because class names look similar; verify the exact
148
+ signature in the current module or generated API documentation.
149
+
150
+ Use `fcmaes.optimizer` adapters with `retry` and `advretry`. `Sequence`
151
+ passes the best point from one optimizer to the next. `Choice` selects one
152
+ configured optimizer per run. Maintained constructors include `de_cma`,
153
+ `de_cma_py`, `da_cma`, `de_crfmnes`, `crfmnes_bite`, `bite_cma`, and
154
+ `cma_bite`.
155
+
156
+ The objective callback boundary is important:
157
+
158
+ - Cheap scalar Python callbacks do not become fast merely because the search
159
+ loop is C++; each callback still crosses into Python and needs the GIL.
160
+ - `retry`, `advretry`, `moretry`, and the evaluator helpers use Python
161
+ processes, bypassing the GIL but requiring serializable inputs and incurring
162
+ inter-process communication.
163
+ - NumPy, SciPy, native extensions, external programs, and simulations may
164
+ release the GIL or own their own thread pools. Measure the complete topology.
165
+ - Ask/tell is the safest integration for a user-owned vectorized, distributed,
166
+ or asynchronous evaluator.
167
+
168
+ ## Algorithm comparison
169
+
170
+ | Algorithm | Best fit | Main limitation | Practical initial configuration |
171
+ |---|---|---|---|
172
+ | Native DE (`decpp`) | Bounded global search, discontinuities, integer decoding, restarts | Smooth local convergence can be slower than CMA-ES | Population 31, `F=0.5`, `CR=0.9`; compare a DE-to-CMA sequence |
173
+ | Active CMA-ES (`cmaescpp`) | Continuous correlated or ill-conditioned variables, refinement from a guess | Full covariance work becomes costly in high dimension | Population 31, normalized coordinates, sigma based on uncertainty |
174
+ | CR-FM-NES (`crfmnescpp`) | Medium/high-dimensional continuous search and complete batch evaluation | Needs a meaningful center and scalar sigma; not a discrete optimizer | Even population 32; parallelize expensive batches |
175
+ | PGPE (`pgpecpp`) | Very high-dimensional mirrored sampling, noisy objectives, policy search | Diagonal distribution does not learn a full covariance matrix | Even population 32; ranking enabled for one-shot `minimize` |
176
+ | Dual Annealing (`dacpp`) | Low/moderate-dimensional global exploration with optional refinement | No population ask/tell interface | Keep local search for deterministic smooth-enough objectives |
177
+ | BiteOpt (`bitecpp`) | Hard bounded black boxes, nonsmoothness, multimodality, little tuning | Constraints need penalties or repair; batched ask/tell changes feedback timing | Automatic population and `M=1` first |
178
+ | MODE (`modecpp`) | Constrained multi-objective Pareto search | Objective rows and constraint conventions must be exact | Population 64–256, NSGA-II update, evaluate complete populations |
179
+ | Weighted MO retry (`moretry`) | Independent scalarizations with any scalar optimizer | Sensitive to objective scaling and weight ranges | Tens or hundreds of retries; normalize objectives |
180
+ | CVT MAP-Elites (`mapelites`) | Quality-diversity over meaningful descriptors | Requires fixed descriptor bounds and enough evaluations for coverage | Pilot with hundreds of niches before increasing capacity |
181
+ | Diversifier (`diversifier`) | CMA-ME-style local improvement of an archive | More expensive and parameter-rich than basic MAP-Elites | Seed an archive first; use a small solver set |
182
+
183
+ These are starting hypotheses. The objective landscape dominates generic
184
+ rules.
185
+
186
+ ## Scalar optimizer parameters
187
+
188
+ All scalar objectives are minimized. Return a finite `float`. The wrappers
189
+ generally replace exceptions and non-finite values with a very large finite
190
+ value, but explicit, scaled rejection values are easier to diagnose.
191
+
192
+ Use `numpy.random.Generator(PCG64DXSM(seed))` for controlled runs. Avoid the
193
+ module signatures' already-constructed default generators in reproducibility-
194
+ critical code; supply a fresh generator explicitly.
195
+
196
+ ### Native Differential Evolution
197
+
198
+ `decpp.minimize` defaults:
199
+
200
+ | Parameter | Default | Guidance |
201
+ |---|---:|---|
202
+ | `popsize` | 31 | Increase for broad multimodal exploration only if many generations still fit. |
203
+ | `max_evaluations` | 100,000 | Set from the real budget. |
204
+ | `keep` | 200 | Usually leave unchanged; controls temporal/history behavior. |
205
+ | `stop_fitness` | negative infinity | Set only for a genuine known target. |
206
+ | `f` / `cr` | 0.5 / 0.9 | Tune after population and budget. |
207
+ | `min_mutate` / `max_mutate` | 0.1 / 0.5 | Additional mutation range for integer-marked coordinates. |
208
+ | `min_sigma` | 0 | Usually leave at zero. |
209
+ | `workers` | 1 | More workers call Python objectives concurrently from the native path; benchmark carefully. |
210
+
211
+ Pass a Boolean `ints` mask for integer coordinates, but still round, clamp,
212
+ lookup, and repair authoritatively in the objective. Integer mutation does not
213
+ turn unrelated categorical indices into a meaningful metric space.
214
+
215
+ Without `x0`, DE initializes from the bounds. With `x0`, provide a compatible
216
+ `input_sigma` if local initialization is intended. `DE_C` exposes
217
+ `ask()`, `tell(ys)`, `population()`, and `result()`.
218
+
219
+ ### Native active CMA-ES
220
+
221
+ `cmaescpp.minimize` defaults to population 31, 100,000 evaluations,
222
+ `input_sigma=0.3`, normalized coordinates, delayed update enabled,
223
+ `accuracy=1`, no finite target, and automatic history/update settings.
224
+
225
+ With `normalize=True`, the search coordinates are scaled relative to the
226
+ bounds. Choose sigma in that normalized optimizer space. A sigma around
227
+ 0.05–0.3 is a useful first range only when it matches the real uncertainty in
228
+ the guess. With normalization disabled, sigma is in physical units.
229
+
230
+ Use `workers > 1` only after measuring. With `delayed_update=False`, the wrapper
231
+ uses a multiprocessing batch evaluator; with delayed update enabled, native
232
+ parallel callback behavior applies. Do not combine a full process pool with a
233
+ simulator or BLAS library already using all cores.
234
+
235
+ ### CR-FM-NES
236
+
237
+ `crfmnescpp.minimize` defaults to an even population of 32, 100,000
238
+ evaluations, `input_sigma=0.3`, no finite target, bound-violation handling
239
+ enabled, `penalty_coef=1e5`, and `normalize=False`.
240
+
241
+ The `use_constraint_violation` option concerns box-bound handling, not
242
+ arbitrary user constraints. General constraints still require a penalty,
243
+ repair, MODE, or another constrained formulation. Supply a guess and use a
244
+ batch objective for expensive populations. Compare against CMA-ES around
245
+ dimension 100 rather than treating a dimension threshold as absolute.
246
+
247
+ ### PGPE
248
+
249
+ `pgpecpp.minimize` defaults:
250
+
251
+ | Parameter | Default |
252
+ |---|---:|
253
+ | `popsize` | 32, expected to be even |
254
+ | `input_sigma` | 0.1 |
255
+ | `max_evaluations` | 100,000 |
256
+ | `lr_decay_steps` | 1,000 |
257
+ | `use_ranking` | true |
258
+ | `center_learning_rate` | 0.15 |
259
+ | `stdev_learning_rate` | 0.1 |
260
+ | `stdev_max_change` | 0.2 |
261
+ | `b1` / `b2` / `eps` | 0.9 / 0.999 / 1e-8 |
262
+ | `decay_coef` | 1.0 |
263
+ | `normalize` | true |
264
+
265
+ Keep ranking enabled for a robust first experiment. Increase the even
266
+ population for noisy objectives or more parallel work. Change learning rates
267
+ one at a time and validate across multiple seeds. Note that the low-level
268
+ `PGPE_C` constructor defaults `use_ranking=False`; set it explicitly when
269
+ reproducing the one-shot wrapper's behavior.
270
+
271
+ ### Dual Annealing
272
+
273
+ `dacpp.minimize` defaults to 100,000 evaluations and local search enabled.
274
+ Use finite bounds. Local finite-difference refinement is inappropriate for
275
+ very noisy or sharply discontinuous objectives; disable `use_local_search` in
276
+ that case.
277
+
278
+ ### BiteOpt
279
+
280
+ `bitecpp.minimize` defaults to automatic population (`popsize=0`), 100,000
281
+ evaluations, `M=1`, automatic stall criterion, and no finite target.
282
+
283
+ Start with `M=1`. Test a small deeper value only when multimodality and budget
284
+ justify multiple internal populations. `Bite_C` provides batched ask/tell with
285
+ configurable `batch_size`; compare it against ordinary one-at-a-time BiteOpt
286
+ because delayed selector feedback can change convergence.
287
+
288
+ ## Recommended scalar recipes
289
+
290
+ ### Unknown bounded black box
291
+
292
+ Run two fair baselines:
293
+
294
+ 1. `Bite_cpp` with automatic population and `M=1`.
295
+ 2. A fixed-budget `Sequence([De_cpp(...), Cma_cpp(...)])`.
296
+
297
+ Set the DE and CMA evaluation allocations explicitly for a controlled
298
+ comparison. `optimizer.de_cma` randomly assigns between 10% and 50% of the
299
+ total budget to DE when explicit stage budgets are omitted, so it is
300
+ convenient for retry diversity but not a fixed-protocol benchmark.
301
+
302
+ ### Known good continuous guess
303
+
304
+ Use normalized active CMA-ES first. Compare CR-FM-NES at larger dimensions and
305
+ PGPE when diagonal mirrored search matches the problem. Derive per-coordinate
306
+ uncertainty from the model rather than copying one sigma blindly.
307
+
308
+ ### Expensive objective
309
+
310
+ Prefer one population with parallel or vectorized evaluation when every
311
+ generation is expensive and useful. Choose a population at least as large as
312
+ the worker count. If independent global restarts matter more, use outer retry
313
+ processes and keep inner workers at one.
314
+
315
+ If the simulator owns a process or thread pool, compare two explicit
316
+ topologies: many serial simulator evaluations under fcmaes versus fewer
317
+ fcmaes evaluations using the simulator's internal parallelism. Keep the total
318
+ core allowance equal.
319
+
320
+ ### Noisy objective
321
+
322
+ Use PGPE ranking, larger populations, or repeated evaluations. Do not use a
323
+ tight `stop_fitness` based on one noisy observation. If each objective call
324
+ averages replications, report both optimizer calls and the true simulation
325
+ count.
326
+
327
+ Use the same fixed training seed set for every candidate. Re-evaluate
328
+ finalists, Pareto points, and archive elites on a disjoint holdout seed set.
329
+ For noisy QD, validate both quality and descriptor location because an elite
330
+ can move to another niche.
331
+
332
+ ## Constraints and variable encoding
333
+
334
+ Use these conventions consistently:
335
+
336
+ - All objectives are minimized. Negate quantities that must be maximized.
337
+ - MODE and `moretry` rows are `[objective_0, ..., objective_m,
338
+ constraint_0, ..., constraint_k]`.
339
+ - A constraint is feasible when `constraint <= 0`.
340
+ - Convert `h(x) = 0` to `abs(h(x)) - tolerance <= 0` when a tolerance is
341
+ meaningful.
342
+ - For scalar optimizers, use decoding or repair for hard structure and a
343
+ scaled penalty for remaining violations. A useful starting form is
344
+ `objective + rho * sum(max(0, g_i(x))**2)` after normalizing terms.
345
+ - Return a large finite rejection value for invalid simulations.
346
+ - Encode a bounded integer as a real coordinate, round it, and clamp it in the
347
+ objective; optionally also set DE or MODE's integer mask.
348
+ - Encode a category as an index into a fixed list. Do not interpret distances
349
+ between unrelated categories physically.
350
+ - Decode random keys or repair permutations, schedules, subsets, and mutually
351
+ exclusive choices deterministically.
352
+
353
+ The `JobShop`, `Scheduling`, `Routing`, `Subset`, `UAV`, `FluidDynamics`, and
354
+ `MINLP` tutorials are repository-specific encoding references. Test every
355
+ decoder independently before optimization.
356
+
357
+ If a scalar penalty dominates everywhere, normalize the base objective and
358
+ constraint residuals before tuning `rho`. Too small lets infeasible points
359
+ win; too large creates a nearly flat rejection landscape.
360
+
361
+ ## Multi-objective optimization
362
+
363
+ ### MODE
364
+
365
+ Use `modecpp.minimize` for a coordinated Pareto population. The objective must
366
+ return exactly `nobj + ncon` finite values, with constraints trailing the
367
+ objectives. The defaults are population 64, `F=0.5`, `CR=0.9`, NSGA-II update,
368
+ `pro_c=0.5`, `dis_c=15`, `pro_m=0.9`, `dis_m=20`, and integer mutation range
369
+ 0.1–0.5.
370
+
371
+ Guidance:
372
+
373
+ - Start with NSGA-II update.
374
+ - Use at least population 64; try 128–512 for difficult fronts, cheap
375
+ objectives, or more objectives while preserving many generations.
376
+ - Scale objective magnitudes before judging front quality.
377
+ - Use `workers > 1` for expensive objective populations, not for tiny Python
378
+ callbacks.
379
+ - Use `MODE_C.ask()` and `tell(ys)` when the application owns evaluation.
380
+ - Filter feasible rows before calculating or reporting a Pareto front.
381
+ - `modecpp.retry` runs independent MODE processes and can consume
382
+ approximately `num_retries * max_evaluations`; set both explicitly.
383
+
384
+ ### Weighted multi-objective retry
385
+
386
+ `moretry.minimize` samples weights inside `weight_bounds`, scalarizes the
387
+ objective prefix, adds penalties for positive trailing constraints, runs a
388
+ scalar optimizer, and then re-evaluates retained points using the original
389
+ multi-objective function.
390
+
391
+ Use it when independent scalar runs are effective and easy to parallelize.
392
+ Set `ncon` exactly. Normalize or shift objective values to comparable,
393
+ preferably nonnegative scales before choosing weight bounds. With non-integer
394
+ `value_exp`, negative weighted values can be mathematically invalid. Report
395
+ the retained unscalarized objective vectors, not the scalar retry score.
396
+
397
+ ## Quality diversity
398
+
399
+ Use MAP-Elites only when behavior descriptors express diversity the user
400
+ actually values. A descriptor is not another minimized objective.
401
+
402
+ The QD fitness contract is:
403
+
404
+ ```python
405
+ fitness, descriptor = qd_fitness(x)
406
+ ```
407
+
408
+ The descriptor must match `qd_bounds`. A typical workflow is:
409
+
410
+ 1. Define decision and descriptor bounds.
411
+ 2. Create or let `optimize_map_elites` create an archive.
412
+ 3. Seed the archive with evaluated candidates.
413
+ 4. Run MAP-Elites variation and optional CMA emitters.
414
+ 5. Optionally pass the archive to `diversifier.minimize`.
415
+ 6. Report occupied niches, coverage, best fitness, descriptor ranges, and
416
+ representative elites.
417
+
418
+ `mapelites.optimize_map_elites` defaults to 4,000 niches, 20 CVT samples per
419
+ niche, all CPU processes, and 100 iterations. Those defaults can be expensive:
420
+ pilot with fewer niches and a measured evaluation budget. In two descriptor
421
+ dimensions, inspect whether grid indexing or CVT centers fit the intended
422
+ geometry. Capacity controls both resolution and memory.
423
+
424
+ `diversifier.minimize` accepts one solver configuration or a sequence through
425
+ `opt_params`. Supported maintained solver names include `CMA`, `CMA_CPP`,
426
+ `CRMFNES`, `CRMFNES_CPP`, `DE`, `DE_CPP`, `PGPE`, `BITE_CPP`, and `elites`.
427
+ Start with a small, explicit configuration rather than relying on a large
428
+ mixed default. Keep archive updates and stochastic validation reproducible.
429
+
430
+ ## Retry selection and parameters
431
+
432
+ ### Basic retry
433
+
434
+ `retry.minimize` defaults to 1,024 retries, one process per CPU, a retained
435
+ capacity of 500, 50,000 evaluations per run, no value filter, and no finite
436
+ stop target. Its default optimizer is a DE-to-CMA sequence.
437
+
438
+ Set these explicitly in production:
439
+
440
+ - `num_retries`: number of independent runs;
441
+ - `workers`: number of outer processes;
442
+ - the optimizer's per-run `max_evaluations`;
443
+ - `capacity`: number of retained distinct results;
444
+ - `value_limit`: strict upper filter for stored results;
445
+ - `stop_fitness`: target that stops new work;
446
+ - a reproducible random protocol; and
447
+ - `statistic_num` if improvement history is required.
448
+
449
+ Configured work is roughly `num_retries * evaluations_per_run`, reduced by
450
+ early termination. `popsize` and `max_evaluations` on `retry.minimize` are
451
+ ignored when a custom `optimizer` object supplies its own settings.
452
+
453
+ ### Advanced retry
454
+
455
+ `advretry.minimize` coordinates restarts through a shared result store,
456
+ crossover boxes, and a budget that increases with retry progress. Defaults are
457
+ 5,000 retries, 1,500 initial evaluations, check interval 100, retained
458
+ capacity 500, and an automatically capped final budget factor up to 50.
459
+
460
+ Use it only after a basic retry baseline. `value_limit` matters more here:
461
+ retaining many poor parents can make crossover regions unhelpful. Optimizer
462
+ adapters receive the store-derived local bounds, guess, standard deviations,
463
+ and evaluation budget through their normal `minimize` interface. A custom
464
+ adapter that ignores those values defeats advanced retry.
465
+
466
+ `datafile` can persist and reload advanced-retry state. Treat it as mutable
467
+ run state, not source data, and record the code version and problem definition
468
+ with it.
469
+
470
+ ## Parallelism rules
471
+
472
+ There are three possible levels:
473
+
474
+ 1. Outer process parallelism: `retry`, `advretry`, `moretry`,
475
+ `modecpp.retry`, MAP-Elites, and Diversifier.
476
+ 2. Inner population evaluation: `workers` on supported scalar/MODE wrappers,
477
+ `evaluator.parallel`, `parallel_mo`, or application-owned ask/tell batches.
478
+ 3. Parallelism inside NumPy, BLAS, a simulator, an external program, or a
479
+ machine-learning framework.
480
+
481
+ Do not enable every level at the full core count. For 16 cores, compare:
482
+
483
+ - 16 retry processes and one inner worker;
484
+ - one optimizer with a 16-worker expensive population;
485
+ - four retry processes with four inner workers only if both levels have
486
+ enough work; or
487
+ - one fcmaes worker when the simulator already owns 16 threads.
488
+
489
+ Process objectives and their captured data must be serializable under the
490
+ platform's multiprocessing start method. Put process-launching code behind
491
+ `if __name__ == "__main__":`, especially on Windows and macOS. Do not rely on
492
+ fork-only global state.
493
+
494
+ The evaluator uses persistent processes and must be stopped. Use `try/finally`
495
+ or a wrapper that stops it. fcmaes limits BLAS threads in several retry worker
496
+ paths, but the application is still responsible for avoiding nested pools in
497
+ other libraries.
498
+
499
+ Multi-process scheduling can change result arrival order. Treat stochastic
500
+ parallel retry as statistically reproducible unless the exact scheduling and
501
+ seed-to-run assignment are explicitly controlled. Ask/tell with ordered,
502
+ deterministic batch results is the strongest reproducibility path.
503
+
504
+ ## Budget and parameter-setting procedure
505
+
506
+ Tune in this order:
507
+
508
+ 1. Validate objective values, signs, constraints, decoding, and bounds.
509
+ 2. Transform variables with extreme scale differences. Use log coordinates
510
+ for positive variables spanning orders of magnitude.
511
+ 3. Choose the algorithm family from the requested result and problem
512
+ structure.
513
+ 4. Set the total evaluation and worker budget.
514
+ 5. Set population size so several generations fit and workers receive work.
515
+ 6. Set initialization and sigma from real uncertainty.
516
+ 7. Only then tune mutation, crossover, or learning rates.
517
+
518
+ Use a staged budget:
519
+
520
+ - Smoke test: a few populations to exercise decoding, invalid paths, and
521
+ reporting.
522
+ - Pilot: several seeds for two or three candidate algorithms.
523
+ - Production: use the measured wall-time/evaluation budget for the most robust
524
+ configuration and retain disjoint validation seeds.
525
+
526
+ Population algorithms may check limits at generation boundaries, so actual
527
+ evaluations can exceed the requested limit by part of a population. Compare
528
+ the returned `nfev`, not only configured limits.
529
+
530
+ ## Minimal implementation patterns
531
+
532
+ ### Bounded scalar native DE
533
+
534
+ ```python
535
+ import numpy as np
536
+ from numpy.random import Generator, PCG64DXSM
537
+ from scipy.optimize import Bounds
538
+ from fcmaes import decpp
539
+
540
+ bounds = Bounds([-5.0] * 8, [5.0] * 8)
541
+
542
+ def objective(x):
543
+ return float(np.dot(x, x))
544
+
545
+ result = decpp.minimize(
546
+ objective,
547
+ bounds=bounds,
548
+ popsize=31,
549
+ max_evaluations=50_000,
550
+ rg=Generator(PCG64DXSM(1)),
551
+ )
552
+ assert result.success and np.isfinite(result.fun)
553
+ ```
554
+
555
+ ### Reproducible ask/tell population
556
+
557
+ ```python
558
+ import numpy as np
559
+ from numpy.random import Generator, PCG64DXSM
560
+ from scipy.optimize import Bounds
561
+ from fcmaes.decpp import DE_C
562
+
563
+ bounds = Bounds([-5.0] * 4, [5.0] * 4)
564
+ solver = DE_C(
565
+ dim=4,
566
+ bounds=bounds,
567
+ popsize=32,
568
+ rg=Generator(PCG64DXSM(2)),
569
+ )
570
+
571
+ for _ in range(100):
572
+ xs = solver.ask()
573
+ ys = np.asarray([np.dot(x, x) for x in xs], dtype=np.float64)
574
+ if solver.tell(ys) != 0:
575
+ break
576
+
577
+ result = solver.result()
578
+ ```
579
+
580
+ ### Parallel retry
581
+
582
+ ```python
583
+ import multiprocessing as mp
584
+ import numpy as np
585
+ from scipy.optimize import Bounds
586
+ from fcmaes import retry
587
+ from fcmaes.optimizer import Bite_cpp
588
+
589
+ def objective(x):
590
+ return float(np.dot(x, x))
591
+
592
+ if __name__ == "__main__":
593
+ result = retry.minimize(
594
+ objective,
595
+ Bounds([-5.0] * 6, [5.0] * 6),
596
+ optimizer=Bite_cpp(max_evaluations=20_000),
597
+ num_retries=32,
598
+ workers=min(8, mp.cpu_count()),
599
+ capacity=32,
600
+ )
601
+ print(result.fun, result.x, result.nfev)
602
+ ```
603
+
604
+ ### Constrained native MODE
605
+
606
+ ```python
607
+ import numpy as np
608
+ from numpy.random import Generator, PCG64DXSM
609
+ from scipy.optimize import Bounds
610
+ from fcmaes import modecpp
611
+
612
+ def objectives_and_constraint(x):
613
+ return np.asarray([
614
+ np.dot(x, x),
615
+ np.dot(x - 1.0, x - 1.0),
616
+ x.sum() - 2.5, # feasible when <= 0
617
+ ])
618
+
619
+ xs, ys = modecpp.minimize(
620
+ objectives_and_constraint,
621
+ nobj=2,
622
+ ncon=1,
623
+ bounds=Bounds([0.0] * 4, [1.0] * 4),
624
+ popsize=128,
625
+ max_evaluations=50_000,
626
+ workers=1,
627
+ rg=Generator(PCG64DXSM(3)),
628
+ )
629
+ feasible = ys[:, -1] <= 0
630
+ ```
631
+
632
+ For optimizer sequences and advanced retry, copy the maintained adapters from
633
+ `fcmaes/optimizer.py` instead of recreating store and budget handling ad hoc.
634
+
635
+ ## Validation and reporting checklist
636
+
637
+ Before declaring success:
638
+
639
+ - Unit-test decoding, objective signs, constraint signs, bounds, and known
640
+ reference points.
641
+ - Confirm every final point is decoded and re-evaluated independently.
642
+ - Run the deterministic wheel smoke suite with the selected interpreter:
643
+ `python -m pytest -q tests/test_wheel_smoke.py`.
644
+ - Run relevant module and example tests; the historical `fcmaes/test_cma.py`
645
+ suite is stochastic and comparatively expensive, so report retries or
646
+ failures honestly.
647
+ - Record algorithm, every non-default parameter, bounds, generator seed,
648
+ workers, configured budget, actual evaluations, and wall time.
649
+ - Compare algorithms using the same objective calls and core allowance.
650
+ - Use multiple seeds and report best, median or mean, dispersion, and
651
+ success/feasibility rate.
652
+ - For multi-objective runs, report feasible Pareto points and an appropriate
653
+ front-quality measure, not only one selected point.
654
+ - For QD runs, report capacity, occupied niches, coverage, best fitness,
655
+ descriptor ranges, and holdout niche migration for noisy problems.
656
+ - Test scaling with workers 1 and N before claiming parallel speedup.
657
+ - Preserve a small deterministic smoke configuration.
658
+
659
+ ## Failure diagnosis
660
+
661
+ | Symptom | Likely cause | First action |
662
+ |---|---|---|
663
+ | No improvement from initialization | Wrong sign, invalid decoding, flat penalty, or bounds too broad | Print and test decoded points and every objective term. |
664
+ | All results are infeasible | Constraint sign error or badly scaled violation | Verify feasible means `<= 0` and test a known feasible point. |
665
+ | CMA-ES immediately hits bounds | Guess or sigma uses the wrong coordinate scale | Check `normalize` and rescale sigma. |
666
+ | DE explores but does not refine | Population is too large for the budget or local smooth convergence is needed | Reduce population or hand the best point to CMA-ES. |
667
+ | Parallel execution is slower | Objective is cheap, IPC dominates, or pools are nested | Use one worker level and benchmark a larger batch. |
668
+ | Multiprocessing hangs or recursively starts | Missing main guard or unpicklable objective state | Add `if __name__ == "__main__":` and isolate process-safe data. |
669
+ | Front covers one extreme | Poor objective scaling, population, or weight bounds | Normalize objectives and increase MODE population or scalarization diversity. |
670
+ | MAP-Elites coverage stays low | Wrong descriptor bounds, too many niches, or invalid descriptors | Inspect descriptor distributions and reduce pilot capacity. |
671
+ | Noisy runs stop inconsistently | Target or tolerance is tighter than the noise | Increase replication/population and validate on disjoint seeds. |
672
+ | Native wrapper returns `success=False` with a huge value | Input shape/type error or an exception hidden by the defensive wrapper | Reproduce with a tiny call, validate contiguous numeric arrays, and inspect the underlying exception path. |
673
+
674
+ ## Repository references
675
+
676
+ - `README.adoc`: installation, algorithm overview, release behavior, and
677
+ documentation entry points.
678
+ - `fcmaes/optimizer.py`: retry adapters, sequences, choices, and maintained
679
+ scalar recipes.
680
+ - `fcmaes/retry.py`: independent parallel retry and result storage.
681
+ - `fcmaes/advretry.py`: coordinated retry, crossover, adaptive budgets, and
682
+ persisted state.
683
+ - `fcmaes/moretry.py`: weighted multi-objective retry and Pareto filtering.
684
+ - `fcmaes/modecpp.py`: native constrained MODE wrapper and ask/tell state.
685
+ - `fcmaes/mode.py`: Python MODE implementation, modifiers, feasibility, and
686
+ Pareto utilities.
687
+ - `fcmaes/mapelites.py`: CVT MAP-Elites archive and emitters.
688
+ - `fcmaes/diversifier.py`: archive improvement with scalar solvers.
689
+ - `fcmaes/evaluator.py`: persistent multiprocessing evaluators and callback
690
+ safety behavior.
691
+ - `fcmaes/_fcmaes_ext.pyi`: native extension signatures.
692
+ - `tests/test_wheel_smoke.py`: deterministic installed-wheel smoke coverage.
693
+ - `tutorials/README.adoc`: tutorial index and retry output explanation.
694
+ - `tutorials/Introduction.adoc`: practical optimizer selection and trajectory
695
+ examples.
696
+ - `tutorials/Performance.adoc`: performance comparisons.
697
+ - `tutorials/Constraints.adoc`, `tutorials/MODE.adoc`, and
698
+ `tutorials/MultiObjective.adoc`: constraint and Pareto formulations.
699
+ - `tutorials/MapElites.adoc` and `tutorials/Diversity.adoc`: quality-diversity
700
+ workflows.
701
+ - `tutorials/FluidDynamics.adoc`, `tutorials/MINLP.adoc`,
702
+ `tutorials/JobShop.adoc`, `tutorials/Scheduling.adoc`,
703
+ `tutorials/Routing.adoc`, `tutorials/Subset.adoc`, and
704
+ `tutorials/UAV.adoc`: mixed and structured encodings.
705
+ - Generated API documentation:
706
+ `https://dietmarwo.github.io/fast-cma-es/fcmaes_documentation.html`.
707
+ - Local documentation build: `python scripts/build_docs.py`.
708
+
709
+ When this guide and the implementation disagree, treat the current public
710
+ Python API, native type stub, and tests as authoritative. Update this file with
711
+ the implementation and record why the behavior changed.
@@ -7,7 +7,7 @@ build-backend = "scikit_build_core.build"
7
7
 
8
8
  [project]
9
9
  name = "fcmaes"
10
- version = "2.0.2"
10
+ version = "2.0.3"
11
11
  description = "A Python 3 gradient-free optimization library."
12
12
  readme = { file = "README.md", content-type = "text/markdown" }
13
13
  requires-python = ">=3.10"
@@ -51,6 +51,8 @@ jit = [
51
51
  [project.urls]
52
52
  Homepage = "https://github.com/dietmarwo/fast-cma-es"
53
53
  Repository = "https://github.com/dietmarwo/fast-cma-es"
54
+ Documentation = "https://dietmarwo.github.io/fast-cma-es/"
55
+ Tutorials = "https://dietmarwo.github.io/fast-cma-es/tutorials/"
54
56
 
55
57
  [tool.scikit-build]
56
58
  minimum-version = "build-system.requires"
fcmaes-2.0.2/README.md DELETED
@@ -1,10 +0,0 @@
1
- # fcmaes
2
- A Python 3 gradient-free optimization library.
3
-
4
- - [README](https://github.com/dietmarwo/fast-cma-es/blob/master/README.adoc)
5
- - [Tutorials](https://github.com/dietmarwo/fast-cma-es/blob/master/tutorials/Tutorials.adoc)
6
-
7
-
8
-
9
-
10
-
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
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
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes