Skip to content

Domain

categorical

ConstrainedCategoricalObjective (ConstrainedObjective, Objective)

Compute the categorical objective value as:

Po where P is an [n, c] matrix where each row is a probability vector
(P[i, :].sum()=1 for all i) and o is a vector of size [c] of objective values

Attributes:

Name Type Description
w float

float between zero and one for weighting the objective.

desirability list

list of values of size c (c is number of categories) such that the i-th entry is in {True, False}

Source code in bofire/data_models/objectives/categorical.py
class ConstrainedCategoricalObjective(ConstrainedObjective, Objective):
    """Compute the categorical objective value as:

        Po where P is an [n, c] matrix where each row is a probability vector
        (P[i, :].sum()=1 for all i) and o is a vector of size [c] of objective values

    Attributes:
        w (float): float between zero and one for weighting the objective.
        desirability (list): list of values of size c (c is number of categories) such that the i-th entry is in {True, False}
    """

    w: TWeight = 1.0
    categories: CategoryVals
    desirability: List[bool]
    type: Literal["ConstrainedCategoricalObjective"] = "ConstrainedCategoricalObjective"

    @model_validator(mode="after")
    def validate_desireability(self):
        """validates that categories have unique names

        Args:
            categories (List[str]): List or tuple of category names

        Raises:
            ValueError: when categories do not match objective categories

        Returns:
            Tuple[str]: Tuple of the categories
        """
        if len(self.desirability) != len(self.categories):
            raise ValueError(
                "number of categories differs from number of desirabilities"
            )
        return self

    def to_dict(self) -> Dict:
        """Returns the categories and corresponding objective values as dictionary"""
        return dict(zip(self.categories, self.desirability))

    def to_dict_label(self) -> Dict:
        """Returns the catergories and label location of categories"""
        return {c: i for i, c in enumerate(self.categories)}

    def from_dict_label(self) -> Dict:
        """Returns the label location and the categories"""
        d = self.to_dict_label()
        return dict(zip(d.values(), d.keys()))

    def __call__(
        self, x: Union[pd.Series, np.ndarray]
    ) -> Union[pd.Series, np.ndarray, float]:
        """The call function returning a probabilistic reward for x.

        Args:
            x (np.ndarray): A matrix of x values

        Returns:
            np.ndarray: A reward calculated as inner product of probabilities and feasible objectives.
        """
        return np.dot(x, np.array(self.desirability))

__call__(self, x) special

The call function returning a probabilistic reward for x.

Parameters:

Name Type Description Default
x np.ndarray

A matrix of x values

required

Returns:

Type Description
np.ndarray

A reward calculated as inner product of probabilities and feasible objectives.

Source code in bofire/data_models/objectives/categorical.py
def __call__(
    self, x: Union[pd.Series, np.ndarray]
) -> Union[pd.Series, np.ndarray, float]:
    """The call function returning a probabilistic reward for x.

    Args:
        x (np.ndarray): A matrix of x values

    Returns:
        np.ndarray: A reward calculated as inner product of probabilities and feasible objectives.
    """
    return np.dot(x, np.array(self.desirability))

from_dict_label(self)

Returns the label location and the categories

Source code in bofire/data_models/objectives/categorical.py
def from_dict_label(self) -> Dict:
    """Returns the label location and the categories"""
    d = self.to_dict_label()
    return dict(zip(d.values(), d.keys()))

to_dict(self)

Returns the categories and corresponding objective values as dictionary

Source code in bofire/data_models/objectives/categorical.py
def to_dict(self) -> Dict:
    """Returns the categories and corresponding objective values as dictionary"""
    return dict(zip(self.categories, self.desirability))

to_dict_label(self)

Returns the catergories and label location of categories

Source code in bofire/data_models/objectives/categorical.py
def to_dict_label(self) -> Dict:
    """Returns the catergories and label location of categories"""
    return {c: i for i, c in enumerate(self.categories)}

validate_desireability(self)

validates that categories have unique names

Parameters:

Name Type Description Default
categories List[str]

List or tuple of category names

required

Exceptions:

Type Description
ValueError

when categories do not match objective categories

Returns:

Type Description
Tuple[str]

Tuple of the categories

Source code in bofire/data_models/objectives/categorical.py
@model_validator(mode="after")
def validate_desireability(self):
    """validates that categories have unique names

    Args:
        categories (List[str]): List or tuple of category names

    Raises:
        ValueError: when categories do not match objective categories

    Returns:
        Tuple[str]: Tuple of the categories
    """
    if len(self.desirability) != len(self.categories):
        raise ValueError(
            "number of categories differs from number of desirabilities"
        )
    return self

identity

IdentityObjective (Objective)

An objective returning the identity as reward. The return can be scaled, when a lower and upper bound are provided.

Attributes:

Name Type Description
w float

float between zero and one for weighting the objective

bounds Tuple[float]

Bound for normalizing the objective between zero and one. Defaults to (0,1).

Source code in bofire/data_models/objectives/identity.py
class IdentityObjective(Objective):
    """An objective returning the identity as reward.
    The return can be scaled, when a lower and upper bound are provided.

    Attributes:
        w (float): float between zero and one for weighting the objective
        bounds (Tuple[float], optional): Bound for normalizing the objective between zero and one. Defaults to (0,1).
    """

    type: Literal["IdentityObjective"] = "IdentityObjective"
    w: TWeight = 1
    bounds: Tuple[float, float] = (0, 1)

    @property
    def lower_bound(self) -> float:
        return self.bounds[0]

    @property
    def upper_bound(self) -> float:
        return self.bounds[1]

    @field_validator("bounds")
    @classmethod
    def validate_lower_upper(cls, bounds):
        """Validation function to ensure that lower bound is always greater the upper bound

        Args:
            values (Dict): The attributes of the class

        Raises:
            ValueError: when a lower bound higher than the upper bound is passed

        Returns:
            Dict: The attributes of the class
        """
        if bounds[0] > bounds[1]:
            raise ValueError(
                f"lower bound must be <= upper bound, got {bounds[0]} > {bounds[1]}"
            )
        return bounds

    def __call__(self, x: Union[pd.Series, np.ndarray]) -> Union[pd.Series, np.ndarray]:
        """The call function returning a reward for passed x values

        Args:
            x (np.ndarray): An array of x values

        Returns:
            np.ndarray: The identity as reward, might be normalized to the passed lower and upper bounds
        """
        return (x - self.lower_bound) / (self.upper_bound - self.lower_bound)

__call__(self, x) special

The call function returning a reward for passed x values

Parameters:

Name Type Description Default
x np.ndarray

An array of x values

required

Returns:

Type Description
np.ndarray

The identity as reward, might be normalized to the passed lower and upper bounds

Source code in bofire/data_models/objectives/identity.py
def __call__(self, x: Union[pd.Series, np.ndarray]) -> Union[pd.Series, np.ndarray]:
    """The call function returning a reward for passed x values

    Args:
        x (np.ndarray): An array of x values

    Returns:
        np.ndarray: The identity as reward, might be normalized to the passed lower and upper bounds
    """
    return (x - self.lower_bound) / (self.upper_bound - self.lower_bound)

validate_lower_upper(bounds) classmethod

Validation function to ensure that lower bound is always greater the upper bound

Parameters:

Name Type Description Default
values Dict

The attributes of the class

required

Exceptions:

Type Description
ValueError

when a lower bound higher than the upper bound is passed

Returns:

Type Description
Dict

The attributes of the class

Source code in bofire/data_models/objectives/identity.py
@field_validator("bounds")
@classmethod
def validate_lower_upper(cls, bounds):
    """Validation function to ensure that lower bound is always greater the upper bound

    Args:
        values (Dict): The attributes of the class

    Raises:
        ValueError: when a lower bound higher than the upper bound is passed

    Returns:
        Dict: The attributes of the class
    """
    if bounds[0] > bounds[1]:
        raise ValueError(
            f"lower bound must be <= upper bound, got {bounds[0]} > {bounds[1]}"
        )
    return bounds

MaximizeObjective (IdentityObjective)

Child class from the identity function without modifications, since the parent class is already defined as maximization

Attributes:

Name Type Description
w float

float between zero and one for weighting the objective

bounds Tuple[float]

Bound for normalizing the objective between zero and one. Defaults to (0,1).

Source code in bofire/data_models/objectives/identity.py
class MaximizeObjective(IdentityObjective):
    """Child class from the identity function without modifications, since the parent class is already defined as maximization

    Attributes:
        w (float): float between zero and one for weighting the objective
        bounds (Tuple[float], optional): Bound for normalizing the objective between zero and one. Defaults to (0,1).
    """

    type: Literal["MaximizeObjective"] = "MaximizeObjective"

MinimizeObjective (IdentityObjective)

Class returning the negative identity as reward.

Attributes:

Name Type Description
w float

float between zero and one for weighting the objective

bounds Tuple[float]

Bound for normalizing the objective between zero and one. Defaults to (0,1).

Source code in bofire/data_models/objectives/identity.py
class MinimizeObjective(IdentityObjective):
    """Class returning the negative identity as reward.

    Attributes:
        w (float): float between zero and one for weighting the objective
        bounds (Tuple[float], optional): Bound for normalizing the objective between zero and one. Defaults to (0,1).
    """

    type: Literal["MinimizeObjective"] = "MinimizeObjective"

    def __call__(self, x: Union[pd.Series, np.ndarray]) -> Union[pd.Series, np.ndarray]:
        """The call function returning a reward for passed x values

        Args:
            x (np.ndarray): An array of x values

        Returns:
            np.ndarray: The negative identity as reward, might be normalized to the passed lower and upper bounds
        """
        return -1.0 * (x - self.lower_bound) / (self.upper_bound - self.lower_bound)

__call__(self, x) special

The call function returning a reward for passed x values

Parameters:

Name Type Description Default
x np.ndarray

An array of x values

required

Returns:

Type Description
np.ndarray

The negative identity as reward, might be normalized to the passed lower and upper bounds

Source code in bofire/data_models/objectives/identity.py
def __call__(self, x: Union[pd.Series, np.ndarray]) -> Union[pd.Series, np.ndarray]:
    """The call function returning a reward for passed x values

    Args:
        x (np.ndarray): An array of x values

    Returns:
        np.ndarray: The negative identity as reward, might be normalized to the passed lower and upper bounds
    """
    return -1.0 * (x - self.lower_bound) / (self.upper_bound - self.lower_bound)

objective

ConstrainedObjective

This abstract class offers a convenience routine for transforming sigmoid based objectives to botorch output constraints.

Source code in bofire/data_models/objectives/objective.py
class ConstrainedObjective:
    """This abstract class offers a convenience routine for transforming sigmoid based objectives to botorch output constraints."""

Objective (BaseModel)

The base class for all objectives

Source code in bofire/data_models/objectives/objective.py
class Objective(BaseModel):
    """The base class for all objectives"""

    type: str

    @abstractmethod
    def __call__(self, x: Union[pd.Series, np.ndarray]) -> Union[pd.Series, np.ndarray]:
        """Abstract method to define the call function for the class Objective

        Args:
            x (np.ndarray): An array of x values

        Returns:
            np.ndarray: The desirability of the passed x values
        """
        pass

__call__(self, x) special

Abstract method to define the call function for the class Objective

Parameters:

Name Type Description Default
x np.ndarray

An array of x values

required

Returns:

Type Description
np.ndarray

The desirability of the passed x values

Source code in bofire/data_models/objectives/objective.py
@abstractmethod
def __call__(self, x: Union[pd.Series, np.ndarray]) -> Union[pd.Series, np.ndarray]:
    """Abstract method to define the call function for the class Objective

    Args:
        x (np.ndarray): An array of x values

    Returns:
        np.ndarray: The desirability of the passed x values
    """
    pass

sigmoid

MaximizeSigmoidObjective (SigmoidObjective)

Class for a maximizing sigmoid objective

Attributes:

Name Type Description
w float

float between zero and one for weighting the objective.

steepness float

Steepness of the sigmoid function. Has to be greater than zero.

tp float

Turning point of the sigmoid function.

Source code in bofire/data_models/objectives/sigmoid.py
class MaximizeSigmoidObjective(SigmoidObjective):
    """Class for a maximizing sigmoid objective

    Attributes:
        w (float): float between zero and one for weighting the objective.
        steepness (float): Steepness of the sigmoid function. Has to be greater than zero.
        tp (float): Turning point of the sigmoid function.

    """

    type: Literal["MaximizeSigmoidObjective"] = "MaximizeSigmoidObjective"

    def __call__(self, x: Union[pd.Series, np.ndarray]) -> Union[pd.Series, np.ndarray]:
        """The call function returning a sigmoid shaped reward for passed x values.

        Args:
            x (np.ndarray): An array of x values

        Returns:
            np.ndarray: A reward calculated with a sigmoid function. The stepness and the tipping point can be modified via passed arguments.
        """
        return 1 / (1 + np.exp(-1 * self.steepness * (x - self.tp)))

__call__(self, x) special

The call function returning a sigmoid shaped reward for passed x values.

Parameters:

Name Type Description Default
x np.ndarray

An array of x values

required

Returns:

Type Description
np.ndarray

A reward calculated with a sigmoid function. The stepness and the tipping point can be modified via passed arguments.

Source code in bofire/data_models/objectives/sigmoid.py
def __call__(self, x: Union[pd.Series, np.ndarray]) -> Union[pd.Series, np.ndarray]:
    """The call function returning a sigmoid shaped reward for passed x values.

    Args:
        x (np.ndarray): An array of x values

    Returns:
        np.ndarray: A reward calculated with a sigmoid function. The stepness and the tipping point can be modified via passed arguments.
    """
    return 1 / (1 + np.exp(-1 * self.steepness * (x - self.tp)))

MinimizeSigmoidObjective (SigmoidObjective)

Class for a minimizing a sigmoid objective

Attributes:

Name Type Description
w float

float between zero and one for weighting the objective.

steepness float

Steepness of the sigmoid function. Has to be greater than zero.

tp float

Turning point of the sigmoid function.

Source code in bofire/data_models/objectives/sigmoid.py
class MinimizeSigmoidObjective(SigmoidObjective):
    """Class for a minimizing a sigmoid objective

    Attributes:
        w (float): float between zero and one for weighting the objective.
        steepness (float): Steepness of the sigmoid function. Has to be greater than zero.
        tp (float): Turning point of the sigmoid function.
    """

    type: Literal["MinimizeSigmoidObjective"] = "MinimizeSigmoidObjective"

    def __call__(self, x: Union[pd.Series, np.ndarray]) -> Union[pd.Series, np.ndarray]:
        """The call function returning a sigmoid shaped reward for passed x values.

        Args:
            x (np.ndarray): An array of x values

        Returns:
            np.ndarray: A reward calculated with a sigmoid function. The stepness and the tipping point can be modified via passed arguments.
        """
        return 1 - 1 / (1 + np.exp(-1 * self.steepness * (x - self.tp)))

__call__(self, x) special

The call function returning a sigmoid shaped reward for passed x values.

Parameters:

Name Type Description Default
x np.ndarray

An array of x values

required

Returns:

Type Description
np.ndarray

A reward calculated with a sigmoid function. The stepness and the tipping point can be modified via passed arguments.

Source code in bofire/data_models/objectives/sigmoid.py
def __call__(self, x: Union[pd.Series, np.ndarray]) -> Union[pd.Series, np.ndarray]:
    """The call function returning a sigmoid shaped reward for passed x values.

    Args:
        x (np.ndarray): An array of x values

    Returns:
        np.ndarray: A reward calculated with a sigmoid function. The stepness and the tipping point can be modified via passed arguments.
    """
    return 1 - 1 / (1 + np.exp(-1 * self.steepness * (x - self.tp)))

SigmoidObjective (Objective, ConstrainedObjective)

Base class for all sigmoid shaped objectives

Attributes:

Name Type Description
w float

float between zero and one for weighting the objective.

steepness float

Steepness of the sigmoid function. Has to be greater than zero.

tp float

Turning point of the sigmoid function.

Source code in bofire/data_models/objectives/sigmoid.py
class SigmoidObjective(Objective, ConstrainedObjective):
    """Base class for all sigmoid shaped objectives

    Attributes:
        w (float): float between zero and one for weighting the objective.
        steepness (float): Steepness of the sigmoid function. Has to be greater than zero.
        tp (float): Turning point of the sigmoid function.
    """

    steepness: TGt0
    tp: float
    w: TWeight = 1

target

CloseToTargetObjective (Objective)

Optimize towards a target value. It can be used as objective in multiobjective scenarios.

Attributes:

Name Type Description
w float

float between zero and one for weighting the objective.

target_value float

target value that should be reached.

exponent float

the exponent of the expression.

Source code in bofire/data_models/objectives/target.py
class CloseToTargetObjective(Objective):
    """Optimize towards a target value. It can be used as objective
    in multiobjective scenarios.

    Attributes:
        w (float): float between zero and one for weighting the objective.
        target_value (float): target value that should be reached.
        exponent (float): the exponent of the expression.
    """

    type: Literal["CloseToTargetObjective"] = "CloseToTargetObjective"
    w: TWeight = 1
    target_value: float
    exponent: float

    def __call__(self, x: Union[pd.Series, np.ndarray]) -> Union[pd.Series, np.ndarray]:
        return -1 * (np.abs(x - self.target_value) ** self.exponent)

TargetObjective (Objective, ConstrainedObjective)

Class for objectives for optimizing towards a target value

Attributes:

Name Type Description
w float

float between zero and one for weighting the objective.

target_value float

target value that should be reached.

tolerance float

Tolerance for reaching the target. Has to be greater than zero.

steepness float

Steepness of the sigmoid function. Has to be greater than zero.

Source code in bofire/data_models/objectives/target.py
class TargetObjective(Objective, ConstrainedObjective):
    """Class for objectives for optimizing towards a target value

    Attributes:
        w (float): float between zero and one for weighting the objective.
        target_value (float): target value that should be reached.
        tolerance (float): Tolerance for reaching the target. Has to be greater than zero.
        steepness (float): Steepness of the sigmoid function. Has to be greater than zero.

    """

    type: Literal["TargetObjective"] = "TargetObjective"
    w: TWeight = 1
    target_value: float
    tolerance: TGe0
    steepness: TGt0

    def __call__(self, x: Union[pd.Series, np.ndarray]) -> Union[pd.Series, np.ndarray]:
        """The call function returning a reward for passed x values.

        Args:
            x (np.array): An array of x values

        Returns:
            np.array: An array of reward values calculated by the product of two sigmoidal shaped functions resulting in a maximum at the target value.
        """
        return (
            1
            / (
                1
                + np.exp(
                    -1 * self.steepness * (x - (self.target_value - self.tolerance))
                )
            )
            * (
                1
                - 1
                / (
                    1.0
                    + np.exp(
                        -1 * self.steepness * (x - (self.target_value + self.tolerance))
                    )
                )
            )
        )

__call__(self, x) special

The call function returning a reward for passed x values.

Parameters:

Name Type Description Default
x np.array

An array of x values

required

Returns:

Type Description
np.array

An array of reward values calculated by the product of two sigmoidal shaped functions resulting in a maximum at the target value.

Source code in bofire/data_models/objectives/target.py
def __call__(self, x: Union[pd.Series, np.ndarray]) -> Union[pd.Series, np.ndarray]:
    """The call function returning a reward for passed x values.

    Args:
        x (np.array): An array of x values

    Returns:
        np.array: An array of reward values calculated by the product of two sigmoidal shaped functions resulting in a maximum at the target value.
    """
    return (
        1
        / (
            1
            + np.exp(
                -1 * self.steepness * (x - (self.target_value - self.tolerance))
            )
        )
        * (
            1
            - 1
            / (
                1.0
                + np.exp(
                    -1 * self.steepness * (x - (self.target_value + self.tolerance))
                )
            )
        )
    )