Skip to content

Commit

Permalink
Merge branch 'main' into i_optimality
Browse files Browse the repository at this point in the history
  • Loading branch information
Osburg authored Jan 23, 2025
2 parents fc8fb6f + 4d6d6c6 commit 755b081
Show file tree
Hide file tree
Showing 74 changed files with 2,639 additions and 336 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/lint.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ jobs:
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.9"
python-version: "3.10"

- name: Set up uv
uses: astral-sh/setup-uv@v2
Expand Down
8 changes: 4 additions & 4 deletions .github/workflows/test.yaml
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' ]
python-version: ['3.10', '3.11', '3.12', '3.13']
steps:
- name: Check out repo
uses: actions/checkout@v4
Expand All @@ -42,7 +42,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: [ '3.9', '3.11' ]
python-version: [ '3.10', '3.12' ]
steps:
- name: Check out repo
uses: actions/checkout@v4
Expand Down Expand Up @@ -72,7 +72,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: [ '3.10' ]
python-version: [ '3.12' ]
steps:
- name: Check out repo
uses: actions/checkout@v4
Expand Down Expand Up @@ -106,7 +106,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: [ '3.10' ]
python-version: [ '3.12' ]
steps:
- name: Check out repo
uses: actions/checkout@v4
Expand Down
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,9 @@ venv.bak/
.vscode/
.devcontainer

# pycharm project settings
.idea/

# Rope project settings
.ropeproject

Expand Down
10 changes: 5 additions & 5 deletions bofire/benchmarks/detergent.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,11 +57,11 @@ def __init__(self):

self._domain = Domain.from_lists(
inputs=[
ContinuousInput(key="x1", bounds=(0.0, 0.2)),
ContinuousInput(key="x2", bounds=(0.0, 0.3)),
ContinuousInput(key="x3", bounds=(0.02, 0.2)),
ContinuousInput(key="x4", bounds=(0.0, 0.06)),
ContinuousInput(key="x5", bounds=(0.0, 0.04)),
ContinuousInput(key="x1", bounds=[0.0, 0.2]),
ContinuousInput(key="x2", bounds=[0.0, 0.3]),
ContinuousInput(key="x3", bounds=[0.02, 0.2]),
ContinuousInput(key="x4", bounds=[0.0, 0.06]),
ContinuousInput(key="x5", bounds=[0.0, 0.04]),
],
outputs=[ContinuousOutput(key=f"y{i+1}") for i in range(5)],
constraints=[
Expand Down
9 changes: 8 additions & 1 deletion bofire/benchmarks/hyperopt.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from typing import Optional

import pandas as pd
from tqdm import tqdm

import bofire.surrogates.api as surrogates
from bofire.benchmarks.benchmark import Benchmark
Expand All @@ -15,6 +16,7 @@ def __init__(
training_data: pd.DataFrame,
folds: int,
random_state: Optional[int] = None,
show_progress_bar: bool = False,
) -> None:
super().__init__()
if surrogate_data.hyperconfig is None:
Expand All @@ -24,6 +26,7 @@ def __init__(
self.folds = folds
self.results = None
self.random_state = random_state
self.show_progress_bar = show_progress_bar

@property
def domain(self) -> Domain:
Expand All @@ -34,7 +37,11 @@ def target_metric(self):
return self.surrogate_data.hyperconfig.target_metric # type: ignore

def _f(self, candidates: pd.DataFrame) -> pd.DataFrame:
for i, candidate in candidates.iterrows():
for i, candidate in tqdm(
candidates.iterrows(),
total=candidates.shape[0],
disable=self.show_progress_bar is False,
):
self.surrogate_data.update_hyperparameters(candidate)
surrogate = surrogates.map(self.surrogate_data)
_, cv_test, _ = surrogate.cross_validate( # type: ignore
Expand Down
30 changes: 15 additions & 15 deletions bofire/benchmarks/multi.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ def __init__(self, dim: PositiveInt, num_objectives: PositiveInt = 2, **kwargs):

inputs = []
for i in range(self.dim):
inputs.append(ContinuousInput(key="x_%i" % (i), bounds=(0, 1)))
inputs.append(ContinuousInput(key="x_%i" % (i), bounds=[0, 1]))
outputs = []
self.k = self.dim - self.num_objectives + 1
for i in range(self.num_objectives):
Expand Down Expand Up @@ -140,8 +140,8 @@ def __init__(self, constraints: bool = True, **kwargs):
self._domain = Domain(
inputs=Inputs(
features=[
ContinuousInput(key="x1", bounds=(0, 5)),
ContinuousInput(key="x2", bounds=(0, 3)),
ContinuousInput(key="x1", bounds=[0, 5]),
ContinuousInput(key="x2", bounds=[0, 3]),
],
),
outputs=Outputs(
Expand Down Expand Up @@ -187,8 +187,8 @@ def __init__(self, **kwargs):
self._domain = Domain(
inputs=Inputs(
features=[
ContinuousInput(key="x1", bounds=(0, math.pi)),
ContinuousInput(key="x2", bounds=(0, math.pi)),
ContinuousInput(key="x1", bounds=[0, math.pi]),
ContinuousInput(key="x2", bounds=[0, math.pi]),
],
),
outputs=Outputs(
Expand Down Expand Up @@ -293,13 +293,13 @@ def __init__(self, C_i: Optional[np.ndarray] = None, **kwargs):
# Decision variables
# "residence time in minutes"
inputs = [
ContinuousInput(key="tau", bounds=(0.5, 2)),
ContinuousInput(key="tau", bounds=[0.5, 2]),
# "equivalents of pyrrolidine"
ContinuousInput(key="equiv_pldn", bounds=(1, 5)),
ContinuousInput(key="equiv_pldn", bounds=[1, 5]),
# "concentration of 2,4 dinitrofluorobenenze at reactor inlet (after mixing) in M"
ContinuousInput(key="conc_dfnb", bounds=(0.1, 0.5)),
ContinuousInput(key="conc_dfnb", bounds=[0.1, 0.5]),
# "Reactor temperature in degrees celsius"
ContinuousInput(key="temperature", bounds=(30, 120)),
ContinuousInput(key="temperature", bounds=[30, 120]),
]
# Objectives
# "space time yield (kg/m^3/h)"
Expand Down Expand Up @@ -442,7 +442,7 @@ def __init__(self, n_inputs=30, **kwargs):
super().__init__(**kwargs)
self.n_inputs = n_inputs
inputs = [
ContinuousInput(key=f"x{i+1}", bounds=(0, 1)) for i in range(n_inputs)
ContinuousInput(key=f"x{i+1}", bounds=[0, 1]) for i in range(n_inputs)
]
inputs = Inputs(features=inputs)
outputs = [
Expand Down Expand Up @@ -550,11 +550,11 @@ def __init__(
],
),
# "base equivalents"
ContinuousInput(key="base_eq", bounds=(1, 2.5)),
ContinuousInput(key="base_eq", bounds=[1, 2.5]),
# "Reactor temperature in degrees celsius"
ContinuousInput(key="temperature", bounds=(30, 100)),
ContinuousInput(key="temperature", bounds=[30, 100]),
# "residence time in seconds (s)"
ContinuousInput(key="t_res", bounds=(60, 1800)),
ContinuousInput(key="t_res", bounds=[60, 1800]),
]

input_preprocessing_specs = {
Expand All @@ -566,11 +566,11 @@ def __init__(
outputs = [
ContinuousOutput(
key="yield",
objective=MaximizeObjective(w=1.0, bounds=(0.0, 1.0)),
objective=MaximizeObjective(w=1.0, bounds=[0.0, 1.0]),
),
ContinuousOutput(
key="cost",
objective=MinimizeObjective(w=1.0, bounds=(0.0, 1.0)),
objective=MinimizeObjective(w=1.0, bounds=[0.0, 1.0]),
),
]
self.ref_point = {"yield": 0.0, "cost": 1.0}
Expand Down
50 changes: 23 additions & 27 deletions bofire/benchmarks/single.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ def __init__(
# continuous input features
for d in range(self.dim):
input_feature_list.append(
ContinuousInput(key=f"x_{d+1}", bounds=(self.lower, self.upper)),
ContinuousInput(key=f"x_{d+1}", bounds=[self.lower, self.upper]),
)

# Objective
Expand Down Expand Up @@ -179,7 +179,7 @@ def __init__(self, dim: int = 6, allowed_k: Optional[int] = None, **kwargs) -> N
self._domain = Domain(
inputs=Inputs(
features=[
ContinuousInput(key=f"x_{i}", bounds=(0, 1)) for i in range(dim)
ContinuousInput(key=f"x_{i}", bounds=[0, 1]) for i in range(dim)
],
),
outputs=Outputs(
Expand Down Expand Up @@ -235,7 +235,7 @@ def __init__(self, dim: int = 6, allowed_k: Optional[int] = None, **kwargs) -> N
self._domain = Domain(
inputs=Inputs(
features=[
ContinuousInput(key=f"x_{i}", bounds=(0, 1)) for i in range(dim)
ContinuousInput(key=f"x_{i}", bounds=[0, 1]) for i in range(dim)
]
),
outputs=Outputs(
Expand Down Expand Up @@ -291,27 +291,23 @@ def __init__(self, locality_factor: Optional[float] = None, **kwargs) -> None:
features=[
ContinuousInput(
key="x_1",
bounds=(-5.0, 10),
local_relative_bounds=(
(
0.5 * locality_factor,
0.5 * locality_factor,
)
if locality_factor is not None
else None
),
bounds=[-5.0, 10],
local_relative_bounds=[
0.5 * locality_factor,
0.5 * locality_factor,
]
if locality_factor is not None
else None,
),
ContinuousInput(
key="x_2",
bounds=(0.0, 15.0),
local_relative_bounds=(
(
1.5 * locality_factor,
1.5 * locality_factor,
)
if locality_factor is not None
else None
),
bounds=[0.0, 15.0],
local_relative_bounds=[
1.5 * locality_factor,
1.5 * locality_factor,
]
if locality_factor is not None
else None,
),
],
),
Expand Down Expand Up @@ -355,7 +351,7 @@ def __init__(self, **kwargs) -> None:
self._domain = Domain(
inputs=Inputs(
features=[
ContinuousInput(key=f"x_{i+1:02d}", bounds=(0, 1))
ContinuousInput(key=f"x_{i+1:02d}", bounds=[0, 1])
for i in range(30)
],
),
Expand Down Expand Up @@ -398,8 +394,8 @@ def __init__(self, use_constraints: bool = False, **kwargs):
self.use_constraints = use_constraints
inputs = []

inputs.append(ContinuousInput(key="x_1", bounds=(-6, 6)))
inputs.append(ContinuousInput(key="x_2", bounds=(-6, 6)))
inputs.append(ContinuousInput(key="x_1", bounds=[-6, 6]))
inputs.append(ContinuousInput(key="x_2", bounds=[-6, 6]))

objective = MinimizeObjective(w=1.0)
output_feature = ContinuousOutput(key="y", objective=objective)
Expand Down Expand Up @@ -472,8 +468,8 @@ def __init__(self, use_constraints: bool = False, **kwargs):
inputs = []

inputs.append(TaskInput(key="task_id", categories=["task_1", "task_2"]))
inputs.append(ContinuousInput(key="x_1", bounds=(-6, 6)))
inputs.append(ContinuousInput(key="x_2", bounds=(-6, 6)))
inputs.append(ContinuousInput(key="x_1", bounds=[-6, 6]))
inputs.append(ContinuousInput(key="x_2", bounds=[-6, 6]))

objective = MinimizeObjective(w=1.0)
output_feature = ContinuousOutput(key="y", objective=objective)
Expand Down Expand Up @@ -645,7 +641,7 @@ def __init__(
self._domain = Domain(
inputs=Inputs(
features=[
ContinuousInput(key=f"x_{i}", bounds=(0, 1))
ContinuousInput(key=f"x_{i}", bounds=[0, 1])
for i in range(self.dim)
],
),
Expand Down
1 change: 1 addition & 0 deletions bofire/data_models/domain/features.py
Original file line number Diff line number Diff line change
Expand Up @@ -622,6 +622,7 @@ def _validate_transform_specs(
raise ValueError(
f"Forbidden transform type for feature with key {key}",
)

return specs

def get_bounds(
Expand Down
2 changes: 1 addition & 1 deletion bofire/data_models/features/continuous.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ class ContinuousInput(NumericalInput):

bounds: Bounds
local_relative_bounds: Optional[
Tuple[Annotated[float, Field(gt=0)], Annotated[float, Field(gt=0)]]
Annotated[List[Annotated[float, Field(gt=0)]], Field(min_items=2, max_items=2)] # type: ignore
] = None
stepsize: Optional[float] = None

Expand Down
8 changes: 4 additions & 4 deletions bofire/data_models/kernels/aggregation.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@

from bofire.data_models.kernels.categorical import HammingDistanceKernel
from bofire.data_models.kernels.continuous import LinearKernel, MaternKernel, RBFKernel
from bofire.data_models.kernels.kernel import Kernel
from bofire.data_models.kernels.kernel import AggregationKernel
from bofire.data_models.kernels.molecular import TanimotoKernel
from bofire.data_models.kernels.shape import WassersteinKernel
from bofire.data_models.priors.api import AnyGeneralPrior


class AdditiveKernel(Kernel):
class AdditiveKernel(AggregationKernel):
type: Literal["AdditiveKernel"] = "AdditiveKernel"
kernels: Sequence[
Union[
Expand All @@ -26,7 +26,7 @@ class AdditiveKernel(Kernel):
type: Literal["AdditiveKernel"] = "AdditiveKernel"


class MultiplicativeKernel(Kernel):
class MultiplicativeKernel(AggregationKernel):
type: Literal["MultiplicativeKernel"] = "MultiplicativeKernel"
kernels: Sequence[
Union[
Expand All @@ -42,7 +42,7 @@ class MultiplicativeKernel(Kernel):
]


class ScaleKernel(Kernel):
class ScaleKernel(AggregationKernel):
type: Literal["ScaleKernel"] = "ScaleKernel"
base_kernel: Union[
RBFKernel,
Expand Down
15 changes: 13 additions & 2 deletions bofire/data_models/kernels/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,23 @@
PolynomialKernel,
RBFKernel,
)
from bofire.data_models.kernels.kernel import Kernel
from bofire.data_models.kernels.kernel import (
AggregationKernel,
FeatureSpecificKernel,
Kernel,
)
from bofire.data_models.kernels.molecular import MolecularKernel, TanimotoKernel
from bofire.data_models.kernels.shape import WassersteinKernel


AbstractKernel = Union[Kernel, CategoricalKernel, ContinuousKernel, MolecularKernel]
AbstractKernel = Union[
Kernel,
CategoricalKernel,
ContinuousKernel,
MolecularKernel,
FeatureSpecificKernel,
AggregationKernel,
]

AnyContinuousKernel = Union[
MaternKernel,
Expand Down
4 changes: 2 additions & 2 deletions bofire/data_models/kernels/categorical.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
from typing import Literal

from bofire.data_models.kernels.kernel import Kernel
from bofire.data_models.kernels.kernel import FeatureSpecificKernel


class CategoricalKernel(Kernel):
class CategoricalKernel(FeatureSpecificKernel):
pass


Expand Down
Loading

0 comments on commit 755b081

Please sign in to comment.