Skip to content

Commit

Permalink
separate into actual and meta strategy (experimental-design#363)
Browse files Browse the repository at this point in the history
* separate into actual and meta strategy

* fix circular condition import

* remove duplications also for mapper
  • Loading branch information
bertiqwerty authored Mar 10, 2024
1 parent faddc23 commit 4f8eacb
Show file tree
Hide file tree
Showing 8 changed files with 113 additions and 129 deletions.
33 changes: 33 additions & 0 deletions bofire/data_models/strategies/actual_strategy_type.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
from typing import Union

from bofire.data_models.strategies.doe import DoEStrategy
from bofire.data_models.strategies.factorial import FactorialStrategy
from bofire.data_models.strategies.predictives.mobo import MoboStrategy
from bofire.data_models.strategies.predictives.qehvi import QehviStrategy
from bofire.data_models.strategies.predictives.qnehvi import QnehviStrategy
from bofire.data_models.strategies.predictives.qparego import QparegoStrategy
from bofire.data_models.strategies.predictives.sobo import (
AdditiveSoboStrategy,
CustomSoboStrategy,
MultiplicativeSoboStrategy,
SoboStrategy,
)
from bofire.data_models.strategies.random import RandomStrategy
from bofire.data_models.strategies.shortest_path import ShortestPathStrategy
from bofire.data_models.strategies.space_filling import SpaceFillingStrategy

ActualStrategy = Union[
SoboStrategy,
AdditiveSoboStrategy,
MultiplicativeSoboStrategy,
CustomSoboStrategy,
QehviStrategy,
QnehviStrategy,
QparegoStrategy,
SpaceFillingStrategy,
RandomStrategy,
DoEStrategy,
FactorialStrategy,
MoboStrategy,
ShortestPathStrategy,
]
19 changes: 3 additions & 16 deletions bofire/data_models/strategies/api.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
from typing import Union

from bofire.data_models.strategies.actual_strategy_type import ActualStrategy
from bofire.data_models.strategies.doe import DoEStrategy
from bofire.data_models.strategies.factorial import FactorialStrategy
from bofire.data_models.strategies.meta_strategy_type import MetaStrategy
from bofire.data_models.strategies.predictives.botorch import LSRBO, BotorchStrategy
from bofire.data_models.strategies.predictives.mobo import MoboStrategy
from bofire.data_models.strategies.predictives.multiobjective import (
Expand Down Expand Up @@ -43,22 +45,7 @@
MultiobjectiveStrategy,
]

AnyStrategy = Union[
SoboStrategy,
AdditiveSoboStrategy,
MultiplicativeSoboStrategy,
CustomSoboStrategy,
QehviStrategy,
QnehviStrategy,
QparegoStrategy,
SpaceFillingStrategy,
RandomStrategy,
DoEStrategy,
StepwiseStrategy,
FactorialStrategy,
MoboStrategy,
ShortestPathStrategy,
]
AnyStrategy = Union[ActualStrategy, MetaStrategy]

AnyPredictive = Union[
SoboStrategy,
Expand Down
5 changes: 5 additions & 0 deletions bofire/data_models/strategies/meta_strategy_type.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
from bofire.data_models.strategies.stepwise.stepwise import StepwiseStrategy

# Meta strategies compositions of other strategies.
# currently, we only have the Stepwise strategy as meta strategy.
MetaStrategy = StepwiseStrategy
40 changes: 6 additions & 34 deletions bofire/data_models/strategies/stepwise/stepwise.py
Original file line number Diff line number Diff line change
@@ -1,51 +1,23 @@
from typing import List, Literal, Optional, Type, Union
from typing import List, Literal, Optional, Type

from pydantic import Field, field_validator
from typing_extensions import Annotated

from bofire.data_models.base import BaseModel
from bofire.data_models.constraints.api import Constraint
from bofire.data_models.features.api import Feature
from bofire.data_models.strategies.api import AnyCondition
from bofire.data_models.strategies.doe import DoEStrategy
from bofire.data_models.strategies.factorial import FactorialStrategy
from bofire.data_models.strategies.predictives.mobo import MoboStrategy
from bofire.data_models.strategies.predictives.qehvi import QehviStrategy
from bofire.data_models.strategies.predictives.qnehvi import QnehviStrategy
from bofire.data_models.strategies.predictives.qparego import QparegoStrategy
from bofire.data_models.strategies.predictives.sobo import (
AdditiveSoboStrategy,
CustomSoboStrategy,
MultiplicativeSoboStrategy,
SoboStrategy,
from bofire.data_models.strategies.actual_strategy_type import ActualStrategy
from bofire.data_models.strategies.stepwise.conditions import (
AlwaysTrueCondition,
AnyCondition,
)
from bofire.data_models.strategies.random import RandomStrategy
from bofire.data_models.strategies.shortest_path import ShortestPathStrategy
from bofire.data_models.strategies.space_filling import SpaceFillingStrategy
from bofire.data_models.strategies.stepwise.conditions import AlwaysTrueCondition
from bofire.data_models.strategies.strategy import Strategy
from bofire.data_models.transforms.api import AnyTransform

AnyStrategy = Union[
SoboStrategy,
AdditiveSoboStrategy,
MultiplicativeSoboStrategy,
CustomSoboStrategy,
QehviStrategy,
QnehviStrategy,
QparegoStrategy,
SpaceFillingStrategy,
RandomStrategy,
DoEStrategy,
FactorialStrategy,
MoboStrategy,
ShortestPathStrategy,
]


class Step(BaseModel):
type: Literal["Step"] = "Step"
strategy_data: AnyStrategy
strategy_data: ActualStrategy
condition: AnyCondition
transform: Optional[AnyTransform] = None

Expand Down
46 changes: 8 additions & 38 deletions bofire/strategies/mapper.py
Original file line number Diff line number Diff line change
@@ -1,44 +1,14 @@
from typing import Dict, Type

import bofire.data_models.strategies.api as data_models
from bofire.strategies.doe_strategy import DoEStrategy
from bofire.strategies.factorial import FactorialStrategy
from bofire.strategies.predictives.botorch import BotorchStrategy
from bofire.strategies.predictives.mobo import MoboStrategy
from bofire.strategies.predictives.predictive import PredictiveStrategy
from bofire.strategies.predictives.qehvi import QehviStrategy
from bofire.strategies.predictives.qnehvi import QnehviStrategy
from bofire.strategies.predictives.qparego import QparegoStrategy
from bofire.strategies.predictives.sobo import (
AdditiveSoboStrategy,
CustomSoboStrategy,
MultiplicativeSoboStrategy,
SoboStrategy,
)
from bofire.strategies.random import RandomStrategy
from bofire.strategies.shortest_path import ShortestPathStrategy
from bofire.strategies.space_filling import SpaceFillingStrategy
from bofire.strategies.stepwise.stepwise import StepwiseStrategy
from bofire.strategies.mapper_actual import STRATEGY_MAP as ACTUAL_MAP
from bofire.strategies.mapper_meta import STRATEGY_MAP as META_MAP
from bofire.strategies.strategy import Strategy

STRATEGY_MAP: Dict[Type[data_models.Strategy], Type[Strategy]] = {
data_models.RandomStrategy: RandomStrategy,
data_models.SoboStrategy: SoboStrategy,
data_models.AdditiveSoboStrategy: AdditiveSoboStrategy,
data_models.MultiplicativeSoboStrategy: MultiplicativeSoboStrategy,
data_models.CustomSoboStrategy: CustomSoboStrategy,
data_models.QehviStrategy: QehviStrategy,
data_models.QnehviStrategy: QnehviStrategy,
data_models.QparegoStrategy: QparegoStrategy,
data_models.SpaceFillingStrategy: SpaceFillingStrategy,
data_models.DoEStrategy: DoEStrategy,
data_models.StepwiseStrategy: StepwiseStrategy,
data_models.FactorialStrategy: FactorialStrategy,
data_models.MoboStrategy: MoboStrategy,
data_models.ShortestPathStrategy: ShortestPathStrategy,
}


def map(data_model: data_models.Strategy) -> Strategy:
cls = STRATEGY_MAP[data_model.__class__]
data_cls = data_model.__class__
if data_cls in META_MAP:
cls = META_MAP[data_cls]
else:
cls = ACTUAL_MAP[data_cls]

return cls.from_spec(data_model=data_model)
40 changes: 40 additions & 0 deletions bofire/strategies/mapper_actual.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
from typing import Dict, Type

import bofire.data_models.strategies.api as data_models
from bofire.strategies.doe_strategy import DoEStrategy
from bofire.strategies.factorial import FactorialStrategy
from bofire.strategies.predictives.mobo import MoboStrategy
from bofire.strategies.predictives.qehvi import QehviStrategy
from bofire.strategies.predictives.qnehvi import QnehviStrategy
from bofire.strategies.predictives.qparego import QparegoStrategy
from bofire.strategies.predictives.sobo import (
AdditiveSoboStrategy,
CustomSoboStrategy,
MultiplicativeSoboStrategy,
SoboStrategy,
)
from bofire.strategies.random import RandomStrategy
from bofire.strategies.shortest_path import ShortestPathStrategy
from bofire.strategies.space_filling import SpaceFillingStrategy
from bofire.strategies.strategy import Strategy

STRATEGY_MAP: Dict[Type[data_models.Strategy], Type[Strategy]] = {
data_models.RandomStrategy: RandomStrategy,
data_models.SoboStrategy: SoboStrategy,
data_models.AdditiveSoboStrategy: AdditiveSoboStrategy,
data_models.MultiplicativeSoboStrategy: MultiplicativeSoboStrategy,
data_models.CustomSoboStrategy: CustomSoboStrategy,
data_models.QehviStrategy: QehviStrategy,
data_models.QnehviStrategy: QnehviStrategy,
data_models.QparegoStrategy: QparegoStrategy,
data_models.SpaceFillingStrategy: SpaceFillingStrategy,
data_models.DoEStrategy: DoEStrategy,
data_models.FactorialStrategy: FactorialStrategy,
data_models.MoboStrategy: MoboStrategy,
data_models.ShortestPathStrategy: ShortestPathStrategy,
}


def map(data_model: data_models.Strategy) -> Strategy:
cls = STRATEGY_MAP[data_model.__class__]
return cls.from_spec(data_model=data_model)
15 changes: 15 additions & 0 deletions bofire/strategies/mapper_meta.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
from typing import Dict, Type

import bofire.data_models.strategies.api as data_models
from bofire.strategies.stepwise.stepwise import StepwiseStrategy
from bofire.strategies.strategy import Strategy

# Meta strategies compositions of other strategies.
STRATEGY_MAP: Dict[Type[data_models.Strategy], Type[Strategy]] = {
data_models.StepwiseStrategy: StepwiseStrategy,
}


def map(data_model: data_models.Strategy) -> Strategy:
cls = STRATEGY_MAP[data_model.__class__]
return cls.from_spec(data_model=data_model)
44 changes: 3 additions & 41 deletions bofire/strategies/stepwise/stepwise.py
Original file line number Diff line number Diff line change
@@ -1,53 +1,15 @@
from typing import Dict, Literal, Optional, Tuple, Type, TypeVar, Union
from typing import Literal, Optional, Tuple, TypeVar, Union

import pandas as pd
from pydantic import PositiveInt

import bofire.data_models.strategies.api as data_models
import bofire.transforms.api as transforms
from bofire.data_models.domain.api import Domain
from bofire.data_models.strategies.api import StepwiseStrategy as data_model
from bofire.strategies.doe_strategy import DoEStrategy
from bofire.strategies.factorial import FactorialStrategy
from bofire.strategies.predictives.mobo import MoboStrategy
from bofire.strategies.predictives.qehvi import QehviStrategy
from bofire.strategies.predictives.qnehvi import QnehviStrategy
from bofire.strategies.predictives.qparego import QparegoStrategy
from bofire.strategies.predictives.sobo import (
AdditiveSoboStrategy,
CustomSoboStrategy,
MultiplicativeSoboStrategy,
SoboStrategy,
)
from bofire.strategies.random import RandomStrategy
from bofire.strategies.shortest_path import ShortestPathStrategy
from bofire.strategies.space_filling import SpaceFillingStrategy
from bofire.strategies.mapper_actual import map as map_actual
from bofire.strategies.strategy import Strategy
from bofire.transforms.transform import Transform

# we have to duplicate the map functionality due to prevent circular imports
STRATEGY_MAP: Dict[Type[data_models.Strategy], Type[Strategy]] = {
data_models.RandomStrategy: RandomStrategy,
data_models.SoboStrategy: SoboStrategy,
data_models.AdditiveSoboStrategy: AdditiveSoboStrategy,
data_models.MultiplicativeSoboStrategy: MultiplicativeSoboStrategy,
data_models.CustomSoboStrategy: CustomSoboStrategy,
data_models.QehviStrategy: QehviStrategy,
data_models.QnehviStrategy: QnehviStrategy,
data_models.QparegoStrategy: QparegoStrategy,
data_models.SpaceFillingStrategy: SpaceFillingStrategy,
data_models.DoEStrategy: DoEStrategy,
data_models.FactorialStrategy: FactorialStrategy,
data_models.MoboStrategy: MoboStrategy,
data_models.ShortestPathStrategy: ShortestPathStrategy,
}


def _map(data_model: data_models.Strategy) -> Strategy:
cls = STRATEGY_MAP[data_model.__class__]
return cls.from_spec(data_model=data_model)


T = TypeVar("T", pd.DataFrame, Domain)


Expand All @@ -66,7 +28,7 @@ def _apply_tf(
class StepwiseStrategy(Strategy):
def __init__(self, data_model: data_model, **kwargs):
super().__init__(data_model, **kwargs)
self.strategies = [_map(s.strategy_data) for s in data_model.steps]
self.strategies = [map_actual(s.strategy_data) for s in data_model.steps]
self.conditions = [s.condition for s in data_model.steps]
self.transforms = [
s.transform and transforms.map(s.transform) for s in data_model.steps
Expand Down

0 comments on commit 4f8eacb

Please sign in to comment.