xopt 3.2.0__tar.gz → 3.2.2__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 (270) hide show
  1. {xopt-3.2.0 → xopt-3.2.2}/PKG-INFO +1 -1
  2. {xopt-3.2.0 → xopt-3.2.2}/environment.yml +2 -0
  3. {xopt-3.2.0 → xopt-3.2.2}/xopt/_version.py +3 -3
  4. {xopt-3.2.0 → xopt-3.2.2}/xopt/base.py +87 -14
  5. {xopt-3.2.0 → xopt-3.2.2}/xopt/generators/bayesian/bax/algorithms.py +15 -14
  6. {xopt-3.2.0 → xopt-3.2.2}/xopt/generators/bayesian/bax_generator.py +71 -23
  7. {xopt-3.2.0 → xopt-3.2.2}/xopt/generators/bayesian/bayesian_generator.py +49 -23
  8. {xopt-3.2.0 → xopt-3.2.2}/xopt/generators/bayesian/turbo.py +4 -3
  9. {xopt-3.2.0 → xopt-3.2.2}/xopt/generators/bayesian/utils.py +7 -8
  10. xopt-3.2.2/xopt/generators/checkpoints.py +123 -0
  11. xopt-3.2.2/xopt/generators/ga/base.py +239 -0
  12. {xopt-3.2.0 → xopt-3.2.2}/xopt/generators/ga/cnsga.py +3 -1
  13. {xopt-3.2.0 → xopt-3.2.2}/xopt/generators/ga/nsga2.py +11 -204
  14. {xopt-3.2.0 → xopt-3.2.2}/xopt/pydantic.py +22 -9
  15. {xopt-3.2.0 → xopt-3.2.2}/xopt/tests/generators/bayesian/test_bax.py +53 -6
  16. {xopt-3.2.0 → xopt-3.2.2}/xopt/tests/generators/bayesian/test_high_level.py +3 -3
  17. {xopt-3.2.0 → xopt-3.2.2}/xopt/tests/generators/bayesian/test_model_constructor.py +43 -15
  18. {xopt-3.2.0 → xopt-3.2.2}/xopt/tests/generators/bayesian/test_turbo.py +25 -1
  19. xopt-3.2.2/xopt/tests/generators/ga/test_base.py +474 -0
  20. {xopt-3.2.0 → xopt-3.2.2}/xopt/tests/generators/ga/test_cnsga.py +2 -2
  21. {xopt-3.2.0 → xopt-3.2.2}/xopt/tests/generators/ga/test_nsga2.py +2 -8
  22. xopt-3.2.2/xopt/tests/generators/test_checkpoints.py +122 -0
  23. {xopt-3.2.0 → xopt-3.2.2}/xopt/tests/test_log.py +1 -0
  24. {xopt-3.2.0 → xopt-3.2.2}/xopt/tests/test_xopt.py +125 -6
  25. {xopt-3.2.0 → xopt-3.2.2}/xopt.egg-info/PKG-INFO +1 -1
  26. {xopt-3.2.0 → xopt-3.2.2}/xopt.egg-info/SOURCES.txt +4 -60
  27. {xopt-3.2.0 → xopt-3.2.2}/xopt.egg-info/scm_file_list.json +171 -227
  28. xopt-3.2.2/xopt.egg-info/scm_version.json +8 -0
  29. xopt-3.2.0/.github/workflows/gh-pages.yml +0 -353
  30. xopt-3.2.0/.github/workflows/lint.yml +0 -64
  31. xopt-3.2.0/.github/workflows/pypi_upload.yml +0 -36
  32. xopt-3.2.0/.github/workflows/test-notebooks.yml +0 -265
  33. xopt-3.2.0/.github/workflows/tests.yml +0 -62
  34. xopt-3.2.0/docs/examples/basic/checkpointing_and_restarts.ipynb +0 -155
  35. xopt-3.2.0/docs/examples/basic/xopt_basic.ipynb +0 -532
  36. xopt-3.2.0/docs/examples/basic/xopt_cli.md +0 -77
  37. xopt-3.2.0/docs/examples/basic/xopt_evaluator.ipynb +0 -448
  38. xopt-3.2.0/docs/examples/basic/xopt_generator.ipynb +0 -222
  39. xopt-3.2.0/docs/examples/basic/xopt_parallel.ipynb +0 -584
  40. xopt-3.2.0/docs/examples/basic/xopt_stopping_condition.ipynb +0 -791
  41. xopt-3.2.0/docs/examples/basic/xopt_vocs.ipynb +0 -506
  42. xopt-3.2.0/docs/examples/bayes_exp/bayesian_exploration.ipynb +0 -261
  43. xopt-3.2.0/docs/examples/bayes_exp/bayesian_exploration_from_yaml.ipynb +0 -169
  44. xopt-3.2.0/docs/examples/bayes_exp/bayesian_exploration_w_interpolation.ipynb +0 -299
  45. xopt-3.2.0/docs/examples/bayes_exp/bayesian_exploration_with_nans.ipynb +0 -191
  46. xopt-3.2.0/docs/examples/developer/benchmarking.md +0 -87
  47. xopt-3.2.0/docs/examples/ga/cnsga_tnk.ipynb +0 -537
  48. xopt-3.2.0/docs/examples/ga/nsga2/assets/benchmarking.pdf +0 -0
  49. xopt-3.2.0/docs/examples/ga/nsga2/assets/zdt3_pf.png +0 -0
  50. xopt-3.2.0/docs/examples/ga/nsga2/genetic_operators.ipynb +0 -165
  51. xopt-3.2.0/docs/examples/ga/nsga2/index.md +0 -40
  52. xopt-3.2.0/docs/examples/ga/nsga2/nsga2_python.ipynb +0 -379
  53. xopt-3.2.0/docs/examples/ga/nsga2/nsga2_to_cnsga.ipynb +0 -276
  54. xopt-3.2.0/docs/examples/ga/nsga2/yaml_interface/assets/yaml_runner_example/eval_fun.py +0 -41
  55. xopt-3.2.0/docs/examples/ga/nsga2/yaml_interface/assets/yaml_runner_example/nsga2_from_checkpoint.yml +0 -71
  56. xopt-3.2.0/docs/examples/ga/nsga2/yaml_interface/assets/yaml_runner_example/nsga2_zdt3.yml +0 -72
  57. xopt-3.2.0/docs/examples/ga/nsga2/yaml_interface/index.md +0 -297
  58. xopt-3.2.0/docs/examples/ga/nsga2/yaml_interface/nsga2_yaml.ipynb +0 -201
  59. xopt-3.2.0/docs/examples/gp_model_creation/approximate.ipynb +0 -186
  60. xopt-3.2.0/docs/examples/gp_model_creation/batched_model.ipynb +0 -264
  61. xopt-3.2.0/docs/examples/gp_model_creation/model_creation.ipynb +0 -243
  62. xopt-3.2.0/docs/examples/multi_objective_bayes_opt/mggpo.ipynb +0 -205
  63. xopt-3.2.0/docs/examples/multi_objective_bayes_opt/mobo.ipynb +0 -220
  64. xopt-3.2.0/docs/examples/multi_objective_bayes_opt/multi_fidelity_mobo.ipynb +0 -335
  65. xopt-3.2.0/docs/examples/scipy/latin_hypercube.ipynb +0 -190
  66. xopt-3.2.0/docs/examples/sequential/extremum_seeking.ipynb +0 -962
  67. xopt-3.2.0/docs/examples/sequential/neldermead.ipynb +0 -653
  68. xopt-3.2.0/docs/examples/sequential/rcds.ipynb +0 -862
  69. xopt-3.2.0/docs/examples/single_objective_bayes_opt/bax_tutorial.ipynb +0 -378
  70. xopt-3.2.0/docs/examples/single_objective_bayes_opt/benchmarking.ipynb +0 -280
  71. xopt-3.2.0/docs/examples/single_objective_bayes_opt/bo_tutorial.ipynb +0 -313
  72. xopt-3.2.0/docs/examples/single_objective_bayes_opt/constrained_bo_tutorial.ipynb +0 -383
  73. xopt-3.2.0/docs/examples/single_objective_bayes_opt/contextual_bo.ipynb +0 -380
  74. xopt-3.2.0/docs/examples/single_objective_bayes_opt/custom_model.ipynb +0 -270
  75. xopt-3.2.0/docs/examples/single_objective_bayes_opt/custom_objective.ipynb +0 -231
  76. xopt-3.2.0/docs/examples/single_objective_bayes_opt/fast_model_eval.ipynb +0 -160
  77. xopt-3.2.0/docs/examples/single_objective_bayes_opt/fixed_features.ipynb +0 -309
  78. xopt-3.2.0/docs/examples/single_objective_bayes_opt/hessian_kernel.ipynb +0 -157
  79. xopt-3.2.0/docs/examples/single_objective_bayes_opt/heteroskedastic_noise_tutorial.ipynb +0 -314
  80. xopt-3.2.0/docs/examples/single_objective_bayes_opt/interpolate_tutorial.ipynb +0 -298
  81. xopt-3.2.0/docs/examples/single_objective_bayes_opt/mixed_discrete.ipynb +0 -274
  82. xopt-3.2.0/docs/examples/single_objective_bayes_opt/multi_fidelity_simple.ipynb +0 -339
  83. xopt-3.2.0/docs/examples/single_objective_bayes_opt/noisy_bo_tutorial.ipynb +0 -312
  84. xopt-3.2.0/docs/examples/single_objective_bayes_opt/time_dependent_bo.ipynb +0 -425
  85. xopt-3.2.0/docs/examples/single_objective_bayes_opt/upper_confidence_bound.ipynb +0 -153
  86. xopt-3.2.0/docs/examples/trust_region_bo/turbo_basics.ipynb +0 -222
  87. xopt-3.2.0/docs/examples/trust_region_bo/turbo_optimize.ipynb +0 -361
  88. xopt-3.2.0/docs/examples/trust_region_bo/turbo_safety.ipynb +0 -368
  89. xopt-3.2.0/xopt.egg-info/scm_version.json +0 -8
  90. {xopt-3.2.0 → xopt-3.2.2}/.pre-commit-config.yaml +0 -0
  91. {xopt-3.2.0 → xopt-3.2.2}/LICENSE +0 -0
  92. {xopt-3.2.0 → xopt-3.2.2}/MANIFEST.in +0 -0
  93. {xopt-3.2.0 → xopt-3.2.2}/README.md +0 -0
  94. {xopt-3.2.0 → xopt-3.2.2}/benchmarks/__init__.py +0 -0
  95. {xopt-3.2.0 → xopt-3.2.2}/benchmarks/test_mo.py +0 -0
  96. {xopt-3.2.0 → xopt-3.2.2}/benchmarks/test_neldermead.py +0 -0
  97. {xopt-3.2.0 → xopt-3.2.2}/benchmarks/test_ucb.py +0 -0
  98. {xopt-3.2.0 → xopt-3.2.2}/codecov.yml +0 -0
  99. {xopt-3.2.0 → xopt-3.2.2}/docs/algorithms.md +0 -0
  100. {xopt-3.2.0 → xopt-3.2.2}/docs/api/evaluator.md +0 -0
  101. {xopt-3.2.0 → xopt-3.2.2}/docs/api/generators/bayesian/bax/acquisition_functions.md +0 -0
  102. {xopt-3.2.0 → xopt-3.2.2}/docs/api/generators/bayesian/bax/algorithms.md +0 -0
  103. {xopt-3.2.0 → xopt-3.2.2}/docs/api/generators/bayesian/bax/bax_generator.md +0 -0
  104. {xopt-3.2.0 → xopt-3.2.2}/docs/api/generators/bayesian/bax/visualize.md +0 -0
  105. {xopt-3.2.0 → xopt-3.2.2}/docs/api/generators/bayesian/bayesian_exploration.md +0 -0
  106. {xopt-3.2.0 → xopt-3.2.2}/docs/api/generators/bayesian/bayesian_generator.md +0 -0
  107. {xopt-3.2.0 → xopt-3.2.2}/docs/api/generators/bayesian/expected_improvement.md +0 -0
  108. {xopt-3.2.0 → xopt-3.2.2}/docs/api/generators/bayesian/mggpo.md +0 -0
  109. {xopt-3.2.0 → xopt-3.2.2}/docs/api/generators/bayesian/mobo.md +0 -0
  110. {xopt-3.2.0 → xopt-3.2.2}/docs/api/generators/bayesian/models/base_model_constructor.md +0 -0
  111. {xopt-3.2.0 → xopt-3.2.2}/docs/api/generators/bayesian/models/standard_model_constructor.md +0 -0
  112. {xopt-3.2.0 → xopt-3.2.2}/docs/api/generators/bayesian/models/time_dependent_model_constructor.md +0 -0
  113. {xopt-3.2.0 → xopt-3.2.2}/docs/api/generators/bayesian/multi_fidelity.md +0 -0
  114. {xopt-3.2.0 → xopt-3.2.2}/docs/api/generators/bayesian/time_dependent.md +0 -0
  115. {xopt-3.2.0 → xopt-3.2.2}/docs/api/generators/bayesian/turbo.md +0 -0
  116. {xopt-3.2.0 → xopt-3.2.2}/docs/api/generators/bayesian/upper_confidence_bound.md +0 -0
  117. {xopt-3.2.0 → xopt-3.2.2}/docs/api/generators/bayesian/utils.md +0 -0
  118. {xopt-3.2.0 → xopt-3.2.2}/docs/api/generators/deduplicated.md +0 -0
  119. {xopt-3.2.0 → xopt-3.2.2}/docs/api/generators/ga/cnsga.md +0 -0
  120. {xopt-3.2.0 → xopt-3.2.2}/docs/api/generators/ga/deap_creator.md +0 -0
  121. {xopt-3.2.0 → xopt-3.2.2}/docs/api/generators/ga/deap_fitness_with_constraints.md +0 -0
  122. {xopt-3.2.0 → xopt-3.2.2}/docs/api/generators/ga/nsga2.md +0 -0
  123. {xopt-3.2.0 → xopt-3.2.2}/docs/api/generators/ga/operators.md +0 -0
  124. {xopt-3.2.0 → xopt-3.2.2}/docs/api/generators/random.md +0 -0
  125. {xopt-3.2.0 → xopt-3.2.2}/docs/api/generators/sequential/extremumseeking.md +0 -0
  126. {xopt-3.2.0 → xopt-3.2.2}/docs/api/generators/sequential/neldermead.md +0 -0
  127. {xopt-3.2.0 → xopt-3.2.2}/docs/api/generators/sequential/rcds.md +0 -0
  128. {xopt-3.2.0 → xopt-3.2.2}/docs/api/generators/sequential/sequential_generator.md +0 -0
  129. {xopt-3.2.0 → xopt-3.2.2}/docs/api/generators/utils.md +0 -0
  130. {xopt-3.2.0 → xopt-3.2.2}/docs/api/generators.md +0 -0
  131. {xopt-3.2.0 → xopt-3.2.2}/docs/api/numerical_optimizer.md +0 -0
  132. {xopt-3.2.0 → xopt-3.2.2}/docs/api/stopping_conditions.md +0 -0
  133. {xopt-3.2.0 → xopt-3.2.2}/docs/api/utils.md +0 -0
  134. {xopt-3.2.0 → xopt-3.2.2}/docs/api/vocs.md +0 -0
  135. {xopt-3.2.0 → xopt-3.2.2}/docs/api/xopt.md +0 -0
  136. {xopt-3.2.0 → xopt-3.2.2}/docs/assets/Xopt-logo.png +0 -0
  137. {xopt-3.2.0 → xopt-3.2.2}/docs/assets/xopt_overview.pdf +0 -0
  138. {xopt-3.2.0 → xopt-3.2.2}/docs/hooks/zip_generator.py +0 -0
  139. {xopt-3.2.0 → xopt-3.2.2}/docs/index.md +0 -0
  140. {xopt-3.2.0 → xopt-3.2.2}/docs/installation.md +0 -0
  141. {xopt-3.2.0 → xopt-3.2.2}/docs/overrides/main.html +0 -0
  142. {xopt-3.2.0 → xopt-3.2.2}/docs/stylesheets/extra.css +0 -0
  143. {xopt-3.2.0 → xopt-3.2.2}/mkdocs.yml +0 -0
  144. {xopt-3.2.0 → xopt-3.2.2}/pyproject.toml +0 -0
  145. {xopt-3.2.0 → xopt-3.2.2}/scripts/execute_notebooks.bash +0 -0
  146. {xopt-3.2.0 → xopt-3.2.2}/scripts/run_benchmarks.py +0 -0
  147. {xopt-3.2.0 → xopt-3.2.2}/scripts/run_examples.py +0 -0
  148. {xopt-3.2.0 → xopt-3.2.2}/scripts/run_tests.py +0 -0
  149. {xopt-3.2.0 → xopt-3.2.2}/setup.cfg +0 -0
  150. {xopt-3.2.0 → xopt-3.2.2}/xopt/__init__.py +0 -0
  151. {xopt-3.2.0 → xopt-3.2.2}/xopt/asynchronous.py +0 -0
  152. {xopt-3.2.0 → xopt-3.2.2}/xopt/entrypoint.py +0 -0
  153. {xopt-3.2.0 → xopt-3.2.2}/xopt/errors.py +0 -0
  154. {xopt-3.2.0 → xopt-3.2.2}/xopt/evaluator.py +0 -0
  155. {xopt-3.2.0 → xopt-3.2.2}/xopt/generator.py +0 -0
  156. {xopt-3.2.0 → xopt-3.2.2}/xopt/generators/__init__.py +0 -0
  157. {xopt-3.2.0 → xopt-3.2.2}/xopt/generators/bayesian/__init__.py +0 -0
  158. {xopt-3.2.0 → xopt-3.2.2}/xopt/generators/bayesian/base_model.py +0 -0
  159. {xopt-3.2.0 → xopt-3.2.2}/xopt/generators/bayesian/bax/__init__.py +0 -0
  160. {xopt-3.2.0 → xopt-3.2.2}/xopt/generators/bayesian/bax/acquisition.py +0 -0
  161. {xopt-3.2.0 → xopt-3.2.2}/xopt/generators/bayesian/bax/visualize.py +0 -0
  162. {xopt-3.2.0 → xopt-3.2.2}/xopt/generators/bayesian/bayesian_exploration.py +0 -0
  163. {xopt-3.2.0 → xopt-3.2.2}/xopt/generators/bayesian/custom_botorch/__init__.py +0 -0
  164. {xopt-3.2.0 → xopt-3.2.2}/xopt/generators/bayesian/custom_botorch/constrained_acquisition.py +0 -0
  165. {xopt-3.2.0 → xopt-3.2.2}/xopt/generators/bayesian/custom_botorch/hessian_kernel.py +0 -0
  166. {xopt-3.2.0 → xopt-3.2.2}/xopt/generators/bayesian/custom_botorch/heteroskedastic.py +0 -0
  167. {xopt-3.2.0 → xopt-3.2.2}/xopt/generators/bayesian/custom_botorch/log_acquisition_function.py +0 -0
  168. {xopt-3.2.0 → xopt-3.2.2}/xopt/generators/bayesian/custom_botorch/multi_fidelity.py +0 -0
  169. {xopt-3.2.0 → xopt-3.2.2}/xopt/generators/bayesian/expected_improvement.py +0 -0
  170. {xopt-3.2.0 → xopt-3.2.2}/xopt/generators/bayesian/mggpo.py +0 -0
  171. {xopt-3.2.0 → xopt-3.2.2}/xopt/generators/bayesian/mobo.py +0 -0
  172. {xopt-3.2.0 → xopt-3.2.2}/xopt/generators/bayesian/models/__init__.py +0 -0
  173. {xopt-3.2.0 → xopt-3.2.2}/xopt/generators/bayesian/models/approximate.py +0 -0
  174. {xopt-3.2.0 → xopt-3.2.2}/xopt/generators/bayesian/models/prior_mean.py +0 -0
  175. {xopt-3.2.0 → xopt-3.2.2}/xopt/generators/bayesian/models/standard.py +0 -0
  176. {xopt-3.2.0 → xopt-3.2.2}/xopt/generators/bayesian/models/time_dependent.py +0 -0
  177. {xopt-3.2.0 → xopt-3.2.2}/xopt/generators/bayesian/multi_fidelity.py +0 -0
  178. {xopt-3.2.0 → xopt-3.2.2}/xopt/generators/bayesian/objectives.py +0 -0
  179. {xopt-3.2.0 → xopt-3.2.2}/xopt/generators/bayesian/time_dependent.py +0 -0
  180. {xopt-3.2.0 → xopt-3.2.2}/xopt/generators/bayesian/upper_confidence_bound.py +0 -0
  181. {xopt-3.2.0 → xopt-3.2.2}/xopt/generators/bayesian/visualize.py +0 -0
  182. {xopt-3.2.0 → xopt-3.2.2}/xopt/generators/deduplicated.py +0 -0
  183. {xopt-3.2.0 → xopt-3.2.2}/xopt/generators/ga/__init__.py +0 -0
  184. {xopt-3.2.0 → xopt-3.2.2}/xopt/generators/ga/deap_creator.py +0 -0
  185. {xopt-3.2.0 → xopt-3.2.2}/xopt/generators/ga/deap_fitness_with_constraints.py +0 -0
  186. {xopt-3.2.0 → xopt-3.2.2}/xopt/generators/ga/operators.py +0 -0
  187. {xopt-3.2.0 → xopt-3.2.2}/xopt/generators/random.py +0 -0
  188. {xopt-3.2.0 → xopt-3.2.2}/xopt/generators/scipy/__init__.py +0 -0
  189. {xopt-3.2.0 → xopt-3.2.2}/xopt/generators/scipy/latin_hypercube.py +0 -0
  190. {xopt-3.2.0 → xopt-3.2.2}/xopt/generators/sequential/__init__.py +0 -0
  191. {xopt-3.2.0 → xopt-3.2.2}/xopt/generators/sequential/extremumseeking.py +0 -0
  192. {xopt-3.2.0 → xopt-3.2.2}/xopt/generators/sequential/neldermead.py +0 -0
  193. {xopt-3.2.0 → xopt-3.2.2}/xopt/generators/sequential/rcds.py +0 -0
  194. {xopt-3.2.0 → xopt-3.2.2}/xopt/generators/sequential/sequential_generator.py +0 -0
  195. {xopt-3.2.0 → xopt-3.2.2}/xopt/generators/utils.py +0 -0
  196. {xopt-3.2.0 → xopt-3.2.2}/xopt/log.py +0 -0
  197. {xopt-3.2.0 → xopt-3.2.2}/xopt/mpi/__init__.py +0 -0
  198. {xopt-3.2.0 → xopt-3.2.2}/xopt/mpi/run.py +0 -0
  199. {xopt-3.2.0 → xopt-3.2.2}/xopt/numerical_optimizer.py +0 -0
  200. {xopt-3.2.0 → xopt-3.2.2}/xopt/resources/__init__.py +0 -0
  201. {xopt-3.2.0 → xopt-3.2.2}/xopt/resources/bench_framework.py +0 -0
  202. {xopt-3.2.0 → xopt-3.2.2}/xopt/resources/bench_functions/__init__.py +0 -0
  203. {xopt-3.2.0 → xopt-3.2.2}/xopt/resources/bench_functions/generators.py +0 -0
  204. {xopt-3.2.0 → xopt-3.2.2}/xopt/resources/bench_functions/models.py +0 -0
  205. {xopt-3.2.0 → xopt-3.2.2}/xopt/resources/bench_profiler.py +0 -0
  206. {xopt-3.2.0 → xopt-3.2.2}/xopt/resources/bench_runner.py +0 -0
  207. {xopt-3.2.0 → xopt-3.2.2}/xopt/resources/test_functions/__init__.py +0 -0
  208. {xopt-3.2.0 → xopt-3.2.2}/xopt/resources/test_functions/ackley_20.py +0 -0
  209. {xopt-3.2.0 → xopt-3.2.2}/xopt/resources/test_functions/haverly_pooling.py +0 -0
  210. {xopt-3.2.0 → xopt-3.2.2}/xopt/resources/test_functions/modified_tnk.py +0 -0
  211. {xopt-3.2.0 → xopt-3.2.2}/xopt/resources/test_functions/multi_objective.py +0 -0
  212. {xopt-3.2.0 → xopt-3.2.2}/xopt/resources/test_functions/problem.py +0 -0
  213. {xopt-3.2.0 → xopt-3.2.2}/xopt/resources/test_functions/rosenbrock.py +0 -0
  214. {xopt-3.2.0 → xopt-3.2.2}/xopt/resources/test_functions/sinusoid_1d.py +0 -0
  215. {xopt-3.2.0 → xopt-3.2.2}/xopt/resources/test_functions/tnk.py +0 -0
  216. {xopt-3.2.0 → xopt-3.2.2}/xopt/resources/test_functions/zdt.py +0 -0
  217. {xopt-3.2.0 → xopt-3.2.2}/xopt/resources/testing.py +0 -0
  218. {xopt-3.2.0 → xopt-3.2.2}/xopt/stopping_conditions.py +0 -0
  219. {xopt-3.2.0 → xopt-3.2.2}/xopt/tests/__init__.py +0 -0
  220. {xopt-3.2.0 → xopt-3.2.2}/xopt/tests/generators/__init__.py +0 -0
  221. {xopt-3.2.0 → xopt-3.2.2}/xopt/tests/generators/bayesian/__init__.py +0 -0
  222. {xopt-3.2.0 → xopt-3.2.2}/xopt/tests/generators/bayesian/conftest.py +0 -0
  223. {xopt-3.2.0 → xopt-3.2.2}/xopt/tests/generators/bayesian/test_bax_visualize.py +0 -0
  224. {xopt-3.2.0 → xopt-3.2.2}/xopt/tests/generators/bayesian/test_bayesian_exploration.py +0 -0
  225. {xopt-3.2.0 → xopt-3.2.2}/xopt/tests/generators/bayesian/test_bayesian_generator.py +0 -0
  226. {xopt-3.2.0 → xopt-3.2.2}/xopt/tests/generators/bayesian/test_constraints.py +0 -0
  227. {xopt-3.2.0 → xopt-3.2.2}/xopt/tests/generators/bayesian/test_contextual_bo.py +0 -0
  228. {xopt-3.2.0 → xopt-3.2.2}/xopt/tests/generators/bayesian/test_custom_model.py +0 -0
  229. {xopt-3.2.0 → xopt-3.2.2}/xopt/tests/generators/bayesian/test_discrete_integration.py +0 -0
  230. {xopt-3.2.0 → xopt-3.2.2}/xopt/tests/generators/bayesian/test_expected_improvement.py +0 -0
  231. {xopt-3.2.0 → xopt-3.2.2}/xopt/tests/generators/bayesian/test_hessian_kernel.py +0 -0
  232. {xopt-3.2.0 → xopt-3.2.2}/xopt/tests/generators/bayesian/test_mggpo.py +0 -0
  233. {xopt-3.2.0 → xopt-3.2.2}/xopt/tests/generators/bayesian/test_mobo.py +0 -0
  234. {xopt-3.2.0 → xopt-3.2.2}/xopt/tests/generators/bayesian/test_multi_fidelity.py +0 -0
  235. {xopt-3.2.0 → xopt-3.2.2}/xopt/tests/generators/bayesian/test_objectives.py +0 -0
  236. {xopt-3.2.0 → xopt-3.2.2}/xopt/tests/generators/bayesian/test_time_dependent_bo.py +0 -0
  237. {xopt-3.2.0 → xopt-3.2.2}/xopt/tests/generators/bayesian/test_upper_confidence_bound.py +0 -0
  238. {xopt-3.2.0 → xopt-3.2.2}/xopt/tests/generators/bayesian/test_utils.py +0 -0
  239. {xopt-3.2.0 → xopt-3.2.2}/xopt/tests/generators/bayesian/test_visualize.py +0 -0
  240. {xopt-3.2.0 → xopt-3.2.2}/xopt/tests/generators/external/test_aposmm.py +0 -0
  241. {xopt-3.2.0 → xopt-3.2.2}/xopt/tests/generators/ga/test_deap_creator.py +0 -0
  242. {xopt-3.2.0 → xopt-3.2.2}/xopt/tests/generators/sequential/test_extremum_seeking.py +0 -0
  243. {xopt-3.2.0 → xopt-3.2.2}/xopt/tests/generators/sequential/test_neldermead.py +0 -0
  244. {xopt-3.2.0 → xopt-3.2.2}/xopt/tests/generators/sequential/test_rcds.py +0 -0
  245. {xopt-3.2.0 → xopt-3.2.2}/xopt/tests/generators/sequential/test_sequential.py +0 -0
  246. {xopt-3.2.0 → xopt-3.2.2}/xopt/tests/generators/sequential/test_serialization.py +0 -0
  247. {xopt-3.2.0 → xopt-3.2.2}/xopt/tests/generators/test_deduplicated.py +0 -0
  248. {xopt-3.2.0 → xopt-3.2.2}/xopt/tests/generators/test_latin_hypercube.py +0 -0
  249. {xopt-3.2.0 → xopt-3.2.2}/xopt/tests/generators/test_operators.py +0 -0
  250. {xopt-3.2.0 → xopt-3.2.2}/xopt/tests/generators/test_random.py +0 -0
  251. {xopt-3.2.0 → xopt-3.2.2}/xopt/tests/generators/test_utils.py +0 -0
  252. {xopt-3.2.0 → xopt-3.2.2}/xopt/tests/test_asynch_xopt.py +0 -0
  253. {xopt-3.2.0 → xopt-3.2.2}/xopt/tests/test_entrypoint.py +0 -0
  254. {xopt-3.2.0 → xopt-3.2.2}/xopt/tests/test_evaluator.py +0 -0
  255. {xopt-3.2.0 → xopt-3.2.2}/xopt/tests/test_generator.py +0 -0
  256. {xopt-3.2.0 → xopt-3.2.2}/xopt/tests/test_io.py +0 -0
  257. {xopt-3.2.0 → xopt-3.2.2}/xopt/tests/test_mpi.py +0 -0
  258. {xopt-3.2.0 → xopt-3.2.2}/xopt/tests/test_numerical_optimizer.py +0 -0
  259. {xopt-3.2.0 → xopt-3.2.2}/xopt/tests/test_perf.py +0 -0
  260. {xopt-3.2.0 → xopt-3.2.2}/xopt/tests/test_pydantic.py +0 -0
  261. {xopt-3.2.0 → xopt-3.2.2}/xopt/tests/test_resources.py +0 -0
  262. {xopt-3.2.0 → xopt-3.2.2}/xopt/tests/test_stopping_condition.py +0 -0
  263. {xopt-3.2.0 → xopt-3.2.2}/xopt/tests/test_utils.py +0 -0
  264. {xopt-3.2.0 → xopt-3.2.2}/xopt/tests/test_vocs.py +0 -0
  265. {xopt-3.2.0 → xopt-3.2.2}/xopt/utils.py +0 -0
  266. {xopt-3.2.0 → xopt-3.2.2}/xopt/vocs.py +0 -0
  267. {xopt-3.2.0 → xopt-3.2.2}/xopt.egg-info/dependency_links.txt +0 -0
  268. {xopt-3.2.0 → xopt-3.2.2}/xopt.egg-info/entry_points.txt +0 -0
  269. {xopt-3.2.0 → xopt-3.2.2}/xopt.egg-info/requires.txt +0 -0
  270. {xopt-3.2.0 → xopt-3.2.2}/xopt.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: xopt
3
- Version: 3.2.0
3
+ Version: 3.2.2
4
4
  Summary: Flexible optimization of arbitrary problems in Python.
5
5
  Author: Christopher Mayes, Ryan Roussel, Nikita Kuklev, Christopher Pierce, Sara Miskovich
6
6
  License: Apache License
@@ -15,6 +15,7 @@ dependencies:
15
15
  - tqdm
16
16
  - orjson
17
17
  - matplotlib
18
+ - gest-api>=0.2
18
19
  # parallel
19
20
  - mpi4py
20
21
  - dask
@@ -33,3 +34,4 @@ dependencies:
33
34
  - mkdocstrings-python
34
35
  - ruff
35
36
  - typing-extensions
37
+ - gest-api
@@ -18,7 +18,7 @@ version_tuple: tuple[int | str, ...]
18
18
  commit_id: str | None
19
19
  __commit_id__: str | None
20
20
 
21
- __version__ = version = '3.2.0'
22
- __version_tuple__ = version_tuple = (3, 2, 0)
21
+ __version__ = version = '3.2.2'
22
+ __version_tuple__ = version_tuple = (3, 2, 2)
23
23
 
24
- __commit_id__ = commit_id = 'g0812fd68a'
24
+ __commit_id__ = commit_id = 'gd4c488f75'
@@ -1,5 +1,6 @@
1
1
  import json
2
2
  import logging
3
+ import os
3
4
  from copy import deepcopy
4
5
  from typing import Any, Optional, Union
5
6
 
@@ -40,6 +41,11 @@ from .errors import DataError
40
41
 
41
42
  logger = logging.getLogger(__name__)
42
43
 
44
+ DUMP_FILE_RENAME_MESSAGE = (
45
+ "The attribute `dump_file` in `Xopt` has been renamed to `xopt_dump_file`. "
46
+ "Support for the old name will be removed in later versions of the Xopt library."
47
+ )
48
+
43
49
 
44
50
  class Xopt(XoptBaseModel):
45
51
  """
@@ -59,9 +65,13 @@ class Xopt(XoptBaseModel):
59
65
  strict : bool, optional
60
66
  A flag indicating whether exceptions raised during evaluation should stop the
61
67
  optimization process.
62
- dump_file : str, optional
68
+ xopt_dump_file : str, optional
63
69
  An optional file path for dumping attributes of the xopt object and the
64
- results of evaluations.
70
+ results of evaluations. Environment variables and `~` are expanded when
71
+ dumping.
72
+ data_dump_file : str, optional
73
+ An optional file path for dumping the evaluation data as a CSV file.
74
+ Environment variables and `~` are expanded when dumping.
65
75
  data : DataFrame, optional
66
76
  An optional DataFrame object for storing internal data related to the optimization
67
77
  process.
@@ -98,6 +108,8 @@ class Xopt(XoptBaseModel):
98
108
  Serializes the Xopt configuration to a YAML string.
99
109
  dump(file: str = None, **kwargs)
100
110
  Dumps the Xopt configuration to a specified file.
111
+ dump_data()
112
+ Dumps the evaluation data to the file given by `data_dump_file`.
101
113
  dict(**kwargs) -> dict
102
114
  Provides a custom dictionary representation of the Xopt configuration.
103
115
  json(**kwargs) -> str
@@ -115,8 +127,11 @@ class Xopt(XoptBaseModel):
115
127
  description="flag to indicate if exceptions raised during evaluation "
116
128
  "should stop Xopt",
117
129
  )
118
- dump_file: Optional[str] = Field(
119
- None, description="file to dump the results of the evaluations"
130
+ xopt_dump_file: Optional[str] = Field(
131
+ None, description="file to dump the serialized Xopt object to"
132
+ )
133
+ data_dump_file: Optional[str] = Field(
134
+ None, description="file to dump the evaluation data to as CSV"
120
135
  )
121
136
  data: Optional[DataFrame] = Field(None, description="internal DataFrame object")
122
137
  serialize_torch: bool = Field(
@@ -243,6 +258,35 @@ class Xopt(XoptBaseModel):
243
258
  )
244
259
  return data
245
260
 
261
+ @model_validator(mode="before")
262
+ @classmethod
263
+ def dump_file_legacy(cls, data: Any):
264
+ """
265
+ Handle backward compatibility: convert the old dump_file parameter to
266
+ xopt_dump_file.
267
+ """
268
+ if isinstance(data, dict) and "dump_file" in data:
269
+ warnings.warn(DUMP_FILE_RENAME_MESSAGE, DeprecationWarning, stacklevel=2)
270
+ dump_file = data.pop("dump_file")
271
+ if dump_file is not None:
272
+ if data.get("xopt_dump_file") is not None:
273
+ raise ValueError(
274
+ "Cannot specify both 'dump_file' and 'xopt_dump_file'. "
275
+ "Use 'xopt_dump_file' instead."
276
+ )
277
+ data["xopt_dump_file"] = dump_file
278
+ return data
279
+
280
+ @property
281
+ def dump_file(self) -> Optional[str]:
282
+ warnings.warn(DUMP_FILE_RENAME_MESSAGE, DeprecationWarning, stacklevel=2)
283
+ return self.xopt_dump_file
284
+
285
+ @dump_file.setter
286
+ def dump_file(self, value: Optional[str]):
287
+ warnings.warn(DUMP_FILE_RENAME_MESSAGE, DeprecationWarning, stacklevel=2)
288
+ self.xopt_dump_file = value
289
+
246
290
  @property
247
291
  def n_data(self) -> int:
248
292
  if self.data is None:
@@ -440,9 +484,11 @@ class Xopt(XoptBaseModel):
440
484
 
441
485
  self.add_data(output_data)
442
486
 
443
- # dump data to file if specified
444
- if self.dump_file is not None:
487
+ # dump to file(s) if specified
488
+ if self.xopt_dump_file is not None:
445
489
  self.dump()
490
+ if self.data_dump_file is not None:
491
+ self.dump_data()
446
492
 
447
493
  return output_data
448
494
 
@@ -624,31 +670,58 @@ class Xopt(XoptBaseModel):
624
670
 
625
671
  def dump(self, file: str = None, **kwargs):
626
672
  """
627
- Dump data to a file.
673
+ Dump the Xopt configuration and data to a YAML file.
674
+
675
+ Environment variables and `~` in the path are expanded.
628
676
 
629
677
  Parameters
630
678
  ----------
631
679
  file : str, optional
632
680
  The path to the file where the Xopt configuration will be dumped.
681
+ Defaults to the `xopt_dump_file` attribute.
633
682
  **kwargs
634
683
  Additional keyword arguments for customizing the dump.
635
684
 
636
685
  Raises
637
686
  ------
638
687
  ValueError
639
- If no dump file is specified via argument or in the `dump_file` attribute.
688
+ If no dump file is specified via argument or in the `xopt_dump_file`
689
+ attribute.
640
690
 
641
691
  """
642
- fname = file if file is not None else self.dump_file
692
+ fname = file if file is not None else self.xopt_dump_file
643
693
 
644
694
  if fname is None:
645
695
  raise ValueError(
646
- "no dump file specified via argument or in `dump_file` attribute"
696
+ "no dump file specified via argument or in `xopt_dump_file` attribute"
647
697
  )
648
- else:
649
- with open(fname, "w") as f:
650
- f.write(self.yaml(**kwargs))
651
- logger.debug(f"Dumped state to YAML file: {fname}")
698
+
699
+ fname = os.path.expanduser(os.path.expandvars(fname))
700
+ with open(fname, "w") as f:
701
+ f.write(self.yaml(**kwargs))
702
+ logger.debug(f"Dumped state to YAML file: {fname}")
703
+
704
+ def dump_data(self):
705
+ """
706
+ Dump the evaluation data to the CSV file given by `data_dump_file`.
707
+
708
+ Environment variables and `~` in the path are expanded.
709
+
710
+ Raises
711
+ ------
712
+ ValueError
713
+ If no data dump file is specified in the `data_dump_file` attribute.
714
+
715
+ """
716
+ if self.data_dump_file is None:
717
+ raise ValueError(
718
+ "no data dump file specified in `data_dump_file` attribute"
719
+ )
720
+
721
+ fname = os.path.expanduser(os.path.expandvars(self.data_dump_file))
722
+ data = self.data if self.data is not None else pd.DataFrame()
723
+ data.to_csv(fname, index_label="xopt_index")
724
+ logger.debug(f"Dumped data to CSV file: {fname}")
652
725
 
653
726
  def dict(self, **kwargs) -> dict:
654
727
  """
@@ -1,11 +1,10 @@
1
1
  from abc import ABC, abstractmethod
2
- from typing import ClassVar, List
2
+ from typing import Any
3
3
 
4
4
  import torch
5
5
  from botorch.models.model import Model, ModelList
6
6
  from pydantic import BaseModel, ConfigDict, Field, PositiveInt, computed_field
7
7
  from torch import Tensor
8
-
9
8
  from xopt.pydantic import XoptBaseModel
10
9
 
11
10
 
@@ -56,7 +55,7 @@ class Algorithm(XoptBaseModel, ABC):
56
55
 
57
56
  Attributes
58
57
  ----------
59
- name : ClassVar[str]
58
+ name : str
60
59
  The name of the algorithm.
61
60
  n_samples : PositiveInt
62
61
  Number of execution paths to generate.
@@ -69,12 +68,12 @@ class Algorithm(XoptBaseModel, ABC):
69
68
  Perform the virtual measurement and calculate objective values at the given inputs.
70
69
  """
71
70
 
72
- name: ClassVar[str] = "base_algorithm"
71
+ name: str = Field(default="base_algorithm", frozen=True)
73
72
  n_samples: PositiveInt = Field(
74
73
  default=20, description="number of execution paths to generate"
75
74
  )
76
75
 
77
- @computed_field
76
+ @computed_field # type: ignore[prop-decorator]
78
77
  @property
79
78
  def class_path(self) -> str:
80
79
  return f"{self.__class__.__module__}.{self.__class__.__name__}"
@@ -105,7 +104,7 @@ class Algorithm(XoptBaseModel, ABC):
105
104
  x: Tensor,
106
105
  bounds: Tensor,
107
106
  n_samples: int,
108
- tkwargs: dict = None,
107
+ tkwargs: dict[str, Any] | None = None,
109
108
  ) -> VirtualMeasurementResult:
110
109
  """
111
110
  Evaluate the virtual objective at the given inputs.
@@ -120,7 +119,7 @@ class Algorithm(XoptBaseModel, ABC):
120
119
  The bounds for the optimization.
121
120
  n_samples : int
122
121
  The number of samples to generate.
123
- tkwargs : dict, optional
122
+ tkwargs : dict[str, Any] | None, optional
124
123
  Additional keyword arguments for the evaluation.
125
124
 
126
125
  Returns
@@ -148,7 +147,7 @@ class GridScanAlgorithm(Algorithm, ABC):
148
147
  Create a mesh for evaluating posteriors on.
149
148
  """
150
149
 
151
- name = "grid_scan_algorithm"
150
+ name: str = Field(default="grid_scan", frozen=True)
152
151
  n_mesh_points: PositiveInt = Field(
153
152
  default=10, description="number of mesh points along each axis"
154
153
  )
@@ -200,13 +199,14 @@ class GridOptimize(GridScanAlgorithm):
200
199
 
201
200
  Methods
202
201
  -------
203
- get_execution_paths(self, model: Model, bounds: Tensor) -> Tuple[Tensor, Tensor, Dict]
204
- Get execution paths that minimize the objective function.
202
+ execute(self, model: Model, bounds: Tensor) -> GridOptimizeResult
203
+ Draw samples from the model, compute the sample virtual objective at grid points, and return sample optima.
205
204
  perform_virtual_measurement(self, model: Model, x: Tensor, bounds: Tensor, n_samples: int, tkwargs: dict = None) -> VirtualMeasurementResult
206
205
  Evaluate the virtual measurement and calculate objective values (samples).
207
206
  """
208
207
 
209
- observable_names_ordered: List[str] = Field(
208
+ name: str = Field(default="grid_optimize", frozen=True)
209
+ observable_names_ordered: list[str] = Field(
210
210
  description="names of observable/objective models used in this algorithm",
211
211
  )
212
212
  minimize: bool = True
@@ -228,7 +228,7 @@ class GridOptimize(GridScanAlgorithm):
228
228
  Contains best_inputs, best_objective, input_execution_paths, output_execution_paths, and additional results.
229
229
  """
230
230
  # build evaluation mesh
231
- test_points = self.create_mesh(bounds)
231
+ test_points: Tensor = self.create_mesh(bounds)
232
232
  if isinstance(model, ModelList):
233
233
  test_points = test_points.to(model.models[0].train_targets)
234
234
  else:
@@ -273,7 +273,7 @@ class GridOptimize(GridScanAlgorithm):
273
273
  x: Tensor,
274
274
  bounds: Tensor,
275
275
  n_samples: int,
276
- tkwargs: dict = None,
276
+ tkwargs: dict[str, Any] | None = None,
277
277
  ) -> VirtualMeasurementResult:
278
278
  """
279
279
  Perform the virtual measurement (samples).
@@ -318,6 +318,7 @@ class CurvatureGridOptimize(GridOptimize):
318
318
  Perform the virtual measurement (samples) with curvature.
319
319
  """
320
320
 
321
+ name: str = Field(default="curvature_grid_optimize", frozen=True)
321
322
  use_mean: bool = False
322
323
 
323
324
  def perform_virtual_measurement(
@@ -326,7 +327,7 @@ class CurvatureGridOptimize(GridOptimize):
326
327
  x: Tensor,
327
328
  bounds: Tensor,
328
329
  n_samples: int,
329
- tkwargs: dict = None,
330
+ tkwargs: dict[str, Any] | None = None,
330
331
  ) -> VirtualMeasurementResult:
331
332
  """
332
333
  Evaluate the virtual objective (samples) with curvature.
@@ -1,10 +1,11 @@
1
- from copy import deepcopy
2
1
  import importlib
3
2
  import logging
4
3
  import pickle
5
- from typing import Dict, List, Optional
4
+ from copy import deepcopy
5
+ from typing import Any, Hashable, Optional, cast
6
6
 
7
7
  from botorch.models import ModelListGP, SingleTaskGP
8
+ from gpytorch import Module
8
9
  from pydantic import (
9
10
  Field,
10
11
  SerializeAsAny,
@@ -12,12 +13,18 @@ from pydantic import (
12
13
  field_validator,
13
14
  model_validator,
14
15
  )
15
-
16
+ from pydantic.fields import ModelPrivateAttr, PrivateAttr
17
+ from xopt.errors import VOCSError
16
18
  from xopt.generators.bayesian.bax.acquisition import ModelListExpectedInformationGain
17
19
  from xopt.generators.bayesian.bax.algorithms import Algorithm, GridOptimize
18
20
  from xopt.generators.bayesian.bayesian_generator import BayesianGenerator
19
- from xopt.generators.bayesian.turbo import EntropyTurboController, SafetyTurboController
21
+ from xopt.generators.bayesian.turbo import (
22
+ EntropyTurboController,
23
+ SafetyTurboController,
24
+ TurboController,
25
+ )
20
26
  from xopt.generators.bayesian.utils import validate_turbo_controller_center
27
+ from xopt.vocs import VOCS
21
28
 
22
29
  logger = logging.getLogger()
23
30
 
@@ -56,48 +63,89 @@ class BaxGenerator(BayesianGenerator):
56
63
  supports_no_objective: bool = True
57
64
  supports_discrete_variables: bool = False
58
65
  algorithm: SerializeAsAny[Algorithm] = Field(
59
- description="algorithm evaluated in the BAX process"
66
+ default=GridOptimize(observable_names_ordered=[]),
67
+ description="algorithm evaluated in the BAX process",
60
68
  )
61
- algorithm_results: Optional[Dict] = Field(
69
+ algorithm_results: Optional[dict] = Field(
62
70
  None, description="dictionary results from algorithm", exclude=True
63
71
  )
64
72
  algorithm_results_file: Optional[str] = Field(
65
73
  None, description="file name to save algorithm results at every step"
66
74
  )
67
75
  _n_calls: int = 0
68
- _compatible_turbo_controllers = [EntropyTurboController, SafetyTurboController]
76
+ _compatible_turbo_controllers: list[type[TurboController]] = PrivateAttr(
77
+ default=[EntropyTurboController, SafetyTurboController]
78
+ )
69
79
 
70
80
  # NOTE: this is meant for use in Badger, TODO: add it to Xopt
71
- _compatible_algorithms = [GridOptimize]
81
+ _compatible_algorithms: list[type[Algorithm]] = PrivateAttr(default=[GridOptimize])
72
82
 
73
83
  @model_validator(mode="after")
74
- def validate_model_after(self):
84
+ def validate_model_after(self) -> "BaxGenerator":
75
85
  # validate turbo controller center if it exists
76
86
  validate_turbo_controller_center(self)
77
87
 
78
88
  return self
79
89
 
90
+ @field_validator("vocs", mode="after")
91
+ @classmethod
92
+ def validate_vocs(cls, v: VOCS, info: ValidationInfo) -> VOCS:
93
+ # Preserve inherited Bayesian VOCS validation behavior.
94
+ v = super().validate_vocs(v, info)
95
+
96
+ # assert that the generator had no objectives
97
+ if not v.n_objectives == 0:
98
+ raise VOCSError("BAX generator only supports problems with no objectives")
99
+
100
+ return v
101
+
80
102
  @field_validator("algorithm", mode="before")
81
- def validate_algorithm(cls, v, info: ValidationInfo):
103
+ @classmethod
104
+ def validate_algorithm(cls, v: Any, info: ValidationInfo) -> Any:
82
105
  if isinstance(v, dict):
83
- try:
106
+ if "class_path" in v:
84
107
  class_path = v.pop("class_path")
85
108
  module_name, class_name = class_path.rsplit(".", 1)
86
- except KeyError:
87
- raise ValueError("Algorithm dictionary must contain 'class_path' key")
88
-
89
- try:
90
- algorithm_class = getattr(
91
- importlib.import_module(module_name), class_name
109
+ try:
110
+ algorithm_class = getattr(
111
+ importlib.import_module(module_name), class_name
112
+ )
113
+ except ModuleNotFoundError:
114
+ raise ValueError(f"Cannot import '{module_name}.{class_name}'")
115
+ elif "name" in v:
116
+ name = v["name"]
117
+ algorithm_class = next(
118
+ (
119
+ c
120
+ for c in cls._compatible_algorithms.default
121
+ if c.model_fields["name"].default == name
122
+ ),
123
+ None,
124
+ )
125
+ if algorithm_class is None:
126
+ raise ValueError(
127
+ f"Unknown algorithm name '{name}'. "
128
+ f"Provide one of {[c.model_fields['name'].default for c in cls._compatible_algorithms.default]} "
129
+ f"or supply 'class_path'."
130
+ )
131
+ else:
132
+ raise ValueError(
133
+ "Algorithm dictionary must contain 'class_path' or 'name' key"
92
134
  )
93
- except ModuleNotFoundError:
94
- raise ValueError(f"Cannot import '{module_name}.{class_name}'")
95
135
 
96
136
  v = algorithm_class.model_validate(v)
97
137
 
98
138
  return v
99
139
 
100
- def generate(self, n_candidates: int) -> List[Dict]:
140
+ @classmethod
141
+ def get_compatible_algorithms(cls) -> list[type[Algorithm]]:
142
+ compatible = cls._compatible_algorithms
143
+ compatible_list: list[type[Algorithm]] = []
144
+ if isinstance(compatible, ModelPrivateAttr):
145
+ compatible_list = cast(list[type[Algorithm]], compatible.get_default())
146
+ return compatible_list
147
+
148
+ def generate(self, n_candidates: int) -> list[dict[Hashable, Any]]:
101
149
  """
102
150
  Generate a specified number of candidate samples.
103
151
 
@@ -108,19 +156,19 @@ class BaxGenerator(BayesianGenerator):
108
156
 
109
157
  Returns
110
158
  -------
111
- List[Dict]
159
+ list[dict[Hashable, Any]]
112
160
  A list of dictionaries containing the generated samples.
113
161
  """
114
162
  self._n_calls += 1
115
163
  return super().generate(n_candidates)
116
164
 
117
- def _get_acquisition(self, model) -> ModelListExpectedInformationGain:
165
+ def _get_acquisition(self, model: Module) -> ModelListExpectedInformationGain:
118
166
  """
119
167
  Get the acquisition function.
120
168
 
121
169
  Parameters
122
170
  ----------
123
- model : Model
171
+ model : Module
124
172
  The model to use for the acquisition function.
125
173
 
126
174
  Returns
@@ -1,39 +1,37 @@
1
1
  import logging
2
- from math import prod
3
2
  import os
4
3
  import time
5
4
  import warnings
6
- from copy import deepcopy
7
5
  from abc import ABC, abstractmethod
6
+ from copy import deepcopy
8
7
  from itertools import islice, product
9
- from typing import Any, Dict, List, Optional, Union, cast
8
+ from math import prod
9
+ from typing import Any, Dict, Hashable, List, Optional, Union, cast
10
10
 
11
11
  import numpy as np
12
12
  import pandas as pd
13
13
  import torch
14
14
  from botorch.acquisition import (
15
- FixedFeatureAcquisitionFunction,
16
- qUpperConfidenceBound,
17
15
  AcquisitionFunction,
16
+ FixedFeatureAcquisitionFunction,
18
17
  MCAcquisitionObjective,
18
+ qUpperConfidenceBound,
19
19
  )
20
20
  from botorch.models.model import Model
21
21
  from botorch.sampling.get_sampler import get_sampler
22
+ from gest_api.vocs import VOCS, DiscreteVariable, MaximizeObjective, MinimizeObjective
22
23
  from gpytorch import Module
23
24
  from pydantic import (
24
25
  Field,
25
- field_validator,
26
26
  PositiveInt,
27
27
  SerializeAsAny,
28
+ field_validator,
28
29
  model_validator,
29
30
  )
30
- from pydantic.fields import PrivateAttr, ModelPrivateAttr
31
+ from pydantic.fields import ModelPrivateAttr, PrivateAttr
31
32
  from pydantic_core.core_schema import ValidationInfo
32
33
  from torch import Tensor
33
-
34
- from gest_api.vocs import DiscreteVariable, MinimizeObjective, MaximizeObjective
35
-
36
- from xopt.errors import VOCSError, XoptError, FeasibilityError
34
+ from xopt.errors import FeasibilityError, VOCSError, XoptError
37
35
  from xopt.generator import Generator
38
36
  from xopt.generators.bayesian.base_model import ModelConstructor
39
37
  from xopt.generators.bayesian.custom_botorch.constrained_acquisition import (
@@ -49,19 +47,19 @@ from xopt.generators.bayesian.models.standard import (
49
47
  )
50
48
  from xopt.generators.bayesian.models.time_dependent import TimeDependentModelConstructor
51
49
  from xopt.generators.bayesian.objectives import (
50
+ CustomXoptObjective,
52
51
  create_constraint_callables,
53
52
  create_mc_objective,
54
- CustomXoptObjective,
55
53
  )
56
54
  from xopt.generators.bayesian.turbo import (
57
55
  TurboController,
58
56
  )
59
57
  from xopt.generators.bayesian.utils import (
58
+ compute_hypervolume_and_pf,
60
59
  interpolate_points,
61
60
  rectilinear_domain_union,
62
61
  set_botorch_weights,
63
62
  validate_turbo_controller_base,
64
- compute_hypervolume_and_pf,
65
63
  validate_turbo_controller_center,
66
64
  )
67
65
  from xopt.generators.bayesian.visualize import visualize_generator_model
@@ -76,7 +74,6 @@ from xopt.vocs import (
76
74
  has_discrete_variables,
77
75
  )
78
76
 
79
-
80
77
  logger = logging.getLogger()
81
78
 
82
79
  # It seems pydantic v2 does not auto-register models anymore
@@ -203,6 +200,35 @@ class BayesianGenerator(Generator, ABC):
203
200
  default=[LBFGSOptimizer, GridOptimizer]
204
201
  )
205
202
 
203
+ @field_validator("vocs", mode="after")
204
+ @classmethod
205
+ def validate_vocs(cls, v: VOCS, info: ValidationInfo) -> VOCS:
206
+ if v.n_constraints > 0 and not info.data["supports_constraints"]:
207
+ raise VOCSError("this generator does not support constraints")
208
+
209
+ if has_discrete_variables(v) and not info.data["supports_discrete_variables"]:
210
+ raise VOCSError("this generator does not support discrete variables")
211
+
212
+ if (
213
+ cls._has_contextual_variables(v)
214
+ and not info.data["supports_contextual_variables"]
215
+ ):
216
+ raise VOCSError("this generator does not support contextual variables")
217
+
218
+ # assertion that at least one objective exists is done in model_validator below
219
+
220
+ if v.n_objectives == 1:
221
+ if not info.data["supports_single_objective"]:
222
+ raise VOCSError(
223
+ "this generator does not support single objective optimization"
224
+ )
225
+ elif v.n_objectives > 1 and not info.data["supports_multi_objective"]:
226
+ raise VOCSError(
227
+ "this generator does not support multi-objective optimization"
228
+ )
229
+
230
+ return v
231
+
206
232
  @classmethod
207
233
  def get_compatible_turbo_controllers(cls) -> list[type[TurboController] | None]:
208
234
  compatible = cls._compatible_turbo_controllers
@@ -226,7 +252,7 @@ class BayesianGenerator(Generator, ABC):
226
252
 
227
253
  @field_validator("model", mode="before")
228
254
  @classmethod
229
- def validate_torch_modules(cls, value: Any):
255
+ def validate_torch_modules(cls, value: Any) -> Any:
230
256
  if isinstance(value, str):
231
257
  if value.startswith("base64:"):
232
258
  value = decode_torch_module(value)
@@ -238,7 +264,7 @@ class BayesianGenerator(Generator, ABC):
238
264
 
239
265
  @field_validator("gp_constructor", mode="before")
240
266
  @classmethod
241
- def validate_gp_constructor(cls, value: Any):
267
+ def validate_gp_constructor(cls, value: Any) -> Any:
242
268
  constructor_dict = {
243
269
  "standard": StandardModelConstructor,
244
270
  "batched": BatchedModelConstructor,
@@ -266,7 +292,7 @@ class BayesianGenerator(Generator, ABC):
266
292
 
267
293
  @field_validator("numerical_optimizer", mode="before")
268
294
  @classmethod
269
- def validate_numerical_optimizer(cls, value: Any):
295
+ def validate_numerical_optimizer(cls, value: Any) -> Any:
270
296
  optimizer_dict: dict[str, type[NumericalOptimizer]] = {
271
297
  "grid": GridOptimizer,
272
298
  "LBFGS": LBFGSOptimizer,
@@ -293,7 +319,7 @@ class BayesianGenerator(Generator, ABC):
293
319
 
294
320
  @field_validator("turbo_controller", mode="before")
295
321
  @classmethod
296
- def validate_turbo_controller(cls, value: Any, info: ValidationInfo):
322
+ def validate_turbo_controller(cls, value: Any, info: ValidationInfo) -> Any:
297
323
  """note default behavior is no use of turbo"""
298
324
  if value is None:
299
325
  return value
@@ -313,7 +339,7 @@ class BayesianGenerator(Generator, ABC):
313
339
 
314
340
  @field_validator("computation_time", mode="before")
315
341
  @classmethod
316
- def validate_computation_time(cls, value: Any):
342
+ def validate_computation_time(cls, value: Any) -> Any:
317
343
  if value is None:
318
344
  return value
319
345
  elif isinstance(value, pd.DataFrame):
@@ -328,7 +354,7 @@ class BayesianGenerator(Generator, ABC):
328
354
  return value
329
355
 
330
356
  @model_validator(mode="after")
331
- def validate_model_after(self):
357
+ def validate_model_after(self) -> "BayesianGenerator":
332
358
  # validate turbo controller center if it exists
333
359
  validate_turbo_controller_center(self)
334
360
 
@@ -346,7 +372,7 @@ class BayesianGenerator(Generator, ABC):
346
372
 
347
373
  return self
348
374
 
349
- def add_data(self, new_data: pd.DataFrame):
375
+ def add_data(self, new_data: pd.DataFrame) -> None:
350
376
  """
351
377
  Add new data to the generator for Bayesian Optimization.
352
378
 
@@ -361,7 +387,7 @@ class BayesianGenerator(Generator, ABC):
361
387
  """
362
388
  self.data = pd.concat([self.data, new_data], axis=0, ignore_index=True)
363
389
 
364
- def generate(self, n_candidates: int):
390
+ def generate(self, n_candidates: int) -> list[dict[Hashable, Any]]:
365
391
  """
366
392
  Generate candidates using Bayesian Optimization.
367
393
 
@@ -372,7 +398,7 @@ class BayesianGenerator(Generator, ABC):
372
398
 
373
399
  Returns
374
400
  -------
375
- List[Dict]
401
+ list[dict[Hashable, Any]]
376
402
  A list of dictionaries containing the generated candidates.
377
403
 
378
404
  Raises