Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 3 additions & 6 deletions .github/ISSUE_TEMPLATE/bug_report.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,11 @@ Ex:
```python
from bayes_opt import BayesianOptimization

black_box_function = lambda x, y: -x ** 2 - (y - 1) ** 2 + 1
black_box_function = lambda x, y: -(x**2) - (y - 1) ** 2 + 1

pbounds = {'x': (2, 4), 'y': (-3, 3)}
pbounds = {"x": (2, 4), "y": (-3, 3)}

optimizer = BayesianOptimization(
f=black_box_function,
pbounds=pbounds
)
optimizer = BayesianOptimization(f=black_box_function, pbounds=pbounds)
optimizer.maximize()
```

Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/build_docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ jobs:
- name: Install uv
uses: astral-sh/setup-uv@v6
with:
python-version: "3.10"
python-version: "3.11"
- name: Get tag
uses: olegtarasov/get-tag@v2.1
- name: Install pandoc
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/format_and_lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ jobs:
- name: Install uv
uses: astral-sh/setup-uv@v6
with:
python-version: "3.9"
python-version: "3.11"
- name: Install dependencies
run: uv sync --extra dev
- name: Run pre-commit
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/run_tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["3.9", "3.10", "3.11", "3.12", "3.13", "3.14", "3.14t"]
python-version: ["3.11", "3.12", "3.13", "3.14", "3.14t"]
numpy-major: ["1", "2"]
exclude:
- python-version: "3.13" # numpy<2 is not supported on 3.13+
Expand Down
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,4 @@ repos:
name: ruff-format
args: [--check]
repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.12.3
rev: v0.17.1
15 changes: 4 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ def black_box_function(x, y):
purposes think of the internals of this function, i.e.: the process
which generates its output values, as unknown.
"""
return -x ** 2 - (y - 1) ** 2 + 1
return -(x**2) - (y - 1) ** 2 + 1
```

### 2. Getting Started
Expand All @@ -82,13 +82,9 @@ All we need to get started is to instantiate a `BayesianOptimization` object spe
from bayes_opt import BayesianOptimization

# Bounded region of parameter space
pbounds = {'x': (2, 4), 'y': (-3, 3)}
pbounds = {"x": (2, 4), "y": (-3, 3)}

optimizer = BayesianOptimization(
f=black_box_function,
pbounds=pbounds,
random_state=1,
)
optimizer = BayesianOptimization(f=black_box_function, pbounds=pbounds, random_state=1)
```

The BayesianOptimization object will work out of the box without much tuning needed. The main method you should be aware of is `maximize`, which does exactly what you think it does.
Expand All @@ -99,10 +95,7 @@ There are many parameters you can pass to maximize, nonetheless, the most import


```python
optimizer.maximize(
init_points=2,
n_iter=3,
)
optimizer.maximize(init_points=2, n_iter=3)
```

| iter | target | x | y |
Expand Down
4 changes: 2 additions & 2 deletions bayes_opt/acquisition.py
Original file line number Diff line number Diff line change
Expand Up @@ -1024,7 +1024,7 @@ def _copy_target_space(self, target_space: TargetSpace) -> TargetSpace:
A copy of the target space.
"""
keys = target_space.keys
pbounds = {key: bound for key, bound in zip(keys, target_space.bounds)}
pbounds = {key: bound for key, bound in zip(keys, target_space.bounds, strict=False)}
target_space_copy = TargetSpace(
None, pbounds=pbounds, allow_duplicate_points=target_space._allow_duplicate_points
)
Expand Down Expand Up @@ -1351,7 +1351,7 @@ def set_acquisition_params(self, params: dict[str, Any]) -> None:
params : dict
Dictionary containing the acquisition function parameters.
"""
for acq, acq_params in zip(self.base_acquisitions, params["base_acquisitions_params"]):
for acq, acq_params in zip(self.base_acquisitions, params["base_acquisitions_params"], strict=False):
acq.set_acquisition_params(acq_params)

self.gains = np.array(params["gains"])
Expand Down
4 changes: 2 additions & 2 deletions bayes_opt/bayesian_optimization.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@

from bayes_opt.acquisition import AcquisitionFunction
from bayes_opt.constraint import ConstraintModel
from bayes_opt.domain_reduction import DomainTransformer
from bayes_opt.parameter import BoundsMapping, ParamsType

Float = np.floating[Any]
Expand Down Expand Up @@ -476,7 +475,8 @@ def _load_state_dict(self, state: dict[str, Any]) -> None:

if state.get("transformed_bounds") and self._bounds_transformer:
new_bounds = {
key: bounds for key, bounds in zip(self._space.keys, np.array(state["transformed_bounds"]))
key: bounds
for key, bounds in zip(self._space.keys, np.array(state["transformed_bounds"]), strict=False)
}
self._space.set_bounds(new_bounds)
self._bounds_transformer.initialize(self._space)
Expand Down
9 changes: 3 additions & 6 deletions bayes_opt/domain_reduction.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ def initialize(self, target_space: TargetSpace) -> None:
else:
self.minimum_window_value = self.minimum_window_value

any_not_float = any([not isinstance(p, FloatParameter) for p in target_space._params_config.values()])
any_not_float = any(not isinstance(p, FloatParameter) for p in target_space._params_config.values())
if any_not_float:
msg = "Domain reduction is only supported for all-FloatParameter optimization."
raise ValueError(msg)
Expand Down Expand Up @@ -180,11 +180,8 @@ def _trim(self, new_bounds: NDArray[Float], global_bounds: NDArray[Float]) -> ND
for i, pbounds in enumerate(new_bounds):
# If the one of the bounds is outside the global bounds, reset the bound to the global bound
# This is expected to happen when the window is near the global bounds, no warning is issued
if pbounds[0] < global_bounds[i, 0]:
pbounds[0] = global_bounds[i, 0]

if pbounds[1] > global_bounds[i, 1]:
pbounds[1] = global_bounds[i, 1]
pbounds[0] = max(pbounds[0], global_bounds[i, 0])
pbounds[1] = min(pbounds[1], global_bounds[i, 1])

# If a lower bound is greater than the associated global upper bound,
# reset it to the global lower bound
Expand Down
16 changes: 8 additions & 8 deletions bayes_opt/parameter.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@
from __future__ import annotations

import abc
from collections.abc import Sequence
from collections.abc import Callable, Sequence
from inspect import signature
from numbers import Number
from typing import TYPE_CHECKING, Any, Callable, Union
from typing import TYPE_CHECKING, Any

import numpy as np
from sklearn.gaussian_process import kernels
Expand All @@ -23,15 +23,15 @@

FloatBoundsWithoutType = tuple[float, float]
FloatBoundsWithType = tuple[float, float, type[float]]
FloatBounds = Union[FloatBoundsWithoutType, FloatBoundsWithType]
IntBounds = tuple[Union[int, float], Union[int, float], type[int]]
FloatBounds = FloatBoundsWithoutType | FloatBoundsWithType
IntBounds = tuple[int | float, int | float, type[int]]
CategoricalBounds = Sequence[Any]
Bounds = Union[FloatBounds, IntBounds, CategoricalBounds]
Bounds = FloatBounds | IntBounds | CategoricalBounds
BoundsMapping = Mapping[str, Bounds]

# FIXME: categorical parameters can be of any type.
# This will make static type checking for parameters difficult.
ParamsType = Union[Mapping[str, Any], Sequence[Any], NDArray[Float]]
ParamsType = Mapping[str, Any] | Sequence[Any] | NDArray[Float]


def is_numeric(value: Any) -> bool:
Expand Down Expand Up @@ -280,7 +280,7 @@ def random_sample(
random_state = ensure_rng(random_state)
return random_state.randint(self.bounds[0], self.bounds[1] + 1, n_samples).astype(float)

def to_float(self, value: int | float) -> float:
def to_float(self, value: float) -> float:
"""Convert a parameter value to a float.

Parameters
Expand All @@ -290,7 +290,7 @@ def to_float(self, value: int | float) -> float:
"""
return float(value)

def to_param(self, value: int | float | NDArray[Int] | NDArray[Float]) -> int:
def to_param(self, value: float | NDArray[Int] | NDArray[Float]) -> int:
"""Convert a float value to a parameter.

Parameters
Expand Down
6 changes: 5 additions & 1 deletion bayes_opt/target_space.py
Original file line number Diff line number Diff line change
Expand Up @@ -670,7 +670,10 @@ def res(self) -> list[dict[str, Any]]:
if self._constraint is None:
params = [self.array_to_params(p) for p in self.params]

return [{"target": target, "params": param} for target, param in zip(self.target, params)]
return [
{"target": target, "params": param}
for target, param in zip(self.target, params, strict=False)
]

params = [self.array_to_params(p) for p in self.params]

Expand All @@ -681,6 +684,7 @@ def res(self) -> list[dict[str, Any]]:
self._constraint_values,
params,
self._constraint.allowed(self._constraint_values),
strict=False,
)
]

Expand Down
12 changes: 4 additions & 8 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,11 @@ description = "Bayesian Optimization package"
authors = [{ name = "Fernando Nogueira", email = "fmfnogueira@gmail.com" }]
license = { file = "LICENSE" }
readme = "README.md"
requires-python = ">=3.9"
requires-python = ">=3.11"
classifiers = [
"License :: OSI Approved :: MIT License",
"Programming Language :: Python",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
Expand Down Expand Up @@ -43,12 +41,10 @@ dev = [
"pre-commit>=3.7.1",
"pytest>=8.0.0",
"pytest-cov>=4.1.0",
"ruff>=0.15.6",
"ruff==0.17.1",
"sphinx-immaterial>=0.12.0",
"sphinx>=7.0.0; python_version<'3.10'",
"sphinx>=8.0.0; python_version>='3.10'",
"sphinx-autodoc-typehints>=2.3.0; python_version<'3.10'",
"sphinx-autodoc-typehints>=2.4.0; python_version>='3.10'",
"sphinx>=8.0.0",
"sphinx-autodoc-typehints>=2.4.0",
]
[project.urls]
Repository = "https://github.com/bayesian-optimization/BayesianOptimization"
Expand Down
2 changes: 1 addition & 1 deletion ruff.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
line-length = 110
unsafe-fixes = false
target-version = "py39"
target-version = "py311"
extend = "./pyproject.toml"
exclude = [
# docs
Expand Down
9 changes: 2 additions & 7 deletions tests/test_bayesian_optimization.py
Original file line number Diff line number Diff line change
Expand Up @@ -329,13 +329,8 @@ def test_duplicate_points():
# register once (should work)
optimizer.register(params=next_point_to_probe, target=target)
# register twice (should throw error)
try:
with pytest.raises(NotUniqueError):
optimizer.register(params=next_point_to_probe, target=target)
duplicate_point_error = None # should be overwritten below
except Exception as e:
duplicate_point_error = e

assert isinstance(duplicate_point_error, NotUniqueError)

# OK, now let's test that it DOESNT fail when allow_duplicate_points=True
optimizer = BayesianOptimization(
Expand Down Expand Up @@ -384,7 +379,7 @@ def test_load_state_rejects_incompatible_keys(tmp_path, saved_points, existing_p
restored.probe(dict.fromkeys(pbounds, 0), lazy=False)
before = restored.res

with pytest.raises(ValueError, match="parameter keys.*same order"):
with pytest.raises(ValueError, match=r"parameter keys.*same order"):
restored.load_state(state_path)

assert restored.res == before
Expand Down
2 changes: 1 addition & 1 deletion tests/test_notebooks_run.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
@pytest.mark.parametrize("notebook", sorted(this_file_loc.with_name("examples").glob("*.ipynb")))
def test_all_notebooks_run(notebook: Path):
as_string = str(notebook)
if any([nb in as_string for nb in _NOTEBOOKS_NOT_TO_RUN]):
if any(nb in as_string for nb in _NOTEBOOKS_NOT_TO_RUN):
pytest.skip(f"skipping [{notebook!s}]")

print(f"running: {notebook}...")
Expand Down
Loading