Skip to content

Objectives

CloseToTarget

Bases: Objective

Source code in opti/objective.py
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
class CloseToTarget(Objective):
    def __init__(
        self,
        name: str,
        target: float = 0,
        exponent: float = 1,
        tolerance: float = 0,
    ):
        """Objective for getting as close as possible to a given value.

        s(y) = |y - target| ** exponent - tolerance ** exponent

        Args:
            name: output to optimize
            target: target value
            exponent: exponent of the difference
            tolerance: only when used as output constraint. distance to target below which no further improvement is required
        """
        super().__init__(name)
        self.target = target
        self.exponent = exponent
        self.tolerance = tolerance

    def __call__(self, y: pd.Series) -> pd.Series:
        return (
            y - self.target
        ).abs() ** self.exponent - self.tolerance**self.exponent

    def __repr__(self):
        return f"CloseToTarget('{self.name}', target={self.target})"

    def to_config(self) -> Dict:
        config = dict(name=self.name, type="close-to-target", target=self.target)
        if self.exponent != 1:
            config["exponent"] = self.exponent
        if self.tolerance != 0:
            config["tolerance"] = self.tolerance
        return config

__init__(name, target=0, exponent=1, tolerance=0)

Objective for getting as close as possible to a given value.

s(y) = |y - target| ** exponent - tolerance ** exponent

Parameters:

Name Type Description Default
name str

output to optimize

required
target float

target value

0
exponent float

exponent of the difference

1
tolerance float

only when used as output constraint. distance to target below which no further improvement is required

0
Source code in opti/objective.py
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
def __init__(
    self,
    name: str,
    target: float = 0,
    exponent: float = 1,
    tolerance: float = 0,
):
    """Objective for getting as close as possible to a given value.

    s(y) = |y - target| ** exponent - tolerance ** exponent

    Args:
        name: output to optimize
        target: target value
        exponent: exponent of the difference
        tolerance: only when used as output constraint. distance to target below which no further improvement is required
    """
    super().__init__(name)
    self.target = target
    self.exponent = exponent
    self.tolerance = tolerance

Maximize

Bases: Objective

Source code in opti/objective.py
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
class Maximize(Objective):
    def __init__(self, name: str, target: float = 0):
        """Maximization objective

        s(y) = target - y

        Args:
            name: output to maximize
            target: only when used as output constraint. value above which no further improvement is required
        """
        super().__init__(name)
        self.target = target

    def __call__(self, y: pd.Series) -> pd.Series:
        return self.target - y

    def untransform(self, y: pd.Series) -> pd.Series:
        """Undo the transformation from output to objective value"""
        return self.target - y

    def __repr__(self):
        return f"Maximize('{self.name}')"

    def to_config(self) -> Dict:
        config = dict(name=self.name, type="maximize")
        if self.target != 0:
            config["target"] = str(self.target)
        return config

__init__(name, target=0)

Maximization objective

s(y) = target - y

Parameters:

Name Type Description Default
name str

output to maximize

required
target float

only when used as output constraint. value above which no further improvement is required

0
Source code in opti/objective.py
54
55
56
57
58
59
60
61
62
63
64
def __init__(self, name: str, target: float = 0):
    """Maximization objective

    s(y) = target - y

    Args:
        name: output to maximize
        target: only when used as output constraint. value above which no further improvement is required
    """
    super().__init__(name)
    self.target = target

untransform(y)

Undo the transformation from output to objective value

Source code in opti/objective.py
69
70
71
def untransform(self, y: pd.Series) -> pd.Series:
    """Undo the transformation from output to objective value"""
    return self.target - y

Minimize

Bases: Objective

Source code in opti/objective.py
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
class Minimize(Objective):
    def __init__(self, name: str, target: float = 0):
        """Minimization objective

        s(y) = y - target

        Args:
            name: output to minimize
            target: only when used as output constraint. value below which no further improvement is required
        """
        super().__init__(name)
        self.target = target

    def __call__(self, y: pd.Series) -> pd.Series:
        return y - self.target

    def untransform(self, y: pd.Series) -> pd.Series:
        """Undo the transformation from output to objective value"""
        return y + self.target

    def __repr__(self):
        return f"Minimize('{self.name}')"

    def to_config(self) -> Dict:
        config = dict(name=self.name, type="minimize")
        if self.target != 0:
            config["target"] = str(self.target)
        return config

__init__(name, target=0)

Minimization objective

s(y) = y - target

Parameters:

Name Type Description Default
name str

output to minimize

required
target float

only when used as output constraint. value below which no further improvement is required

0
Source code in opti/objective.py
24
25
26
27
28
29
30
31
32
33
34
def __init__(self, name: str, target: float = 0):
    """Minimization objective

    s(y) = y - target

    Args:
        name: output to minimize
        target: only when used as output constraint. value below which no further improvement is required
    """
    super().__init__(name)
    self.target = target

untransform(y)

Undo the transformation from output to objective value

Source code in opti/objective.py
39
40
41
def untransform(self, y: pd.Series) -> pd.Series:
    """Undo the transformation from output to objective value"""
    return y + self.target

Objective

Source code in opti/objective.py
 9
10
11
12
13
14
15
16
17
18
19
20
class Objective:
    def __init__(self, name: str):
        """Base class for optimzation objectives."""
        self.name = name

    def __call__(self, df: pd.DataFrame) -> pd.Series:
        """Evaluate the objective values for given output values."""
        raise NotImplementedError

    def to_config(self) -> Dict:
        """Return a json-serializable dictionary of the objective."""
        raise NotImplementedError

__call__(df)

Evaluate the objective values for given output values.

Source code in opti/objective.py
14
15
16
def __call__(self, df: pd.DataFrame) -> pd.Series:
    """Evaluate the objective values for given output values."""
    raise NotImplementedError

__init__(name)

Base class for optimzation objectives.

Source code in opti/objective.py
10
11
12
def __init__(self, name: str):
    """Base class for optimzation objectives."""
    self.name = name

to_config()

Return a json-serializable dictionary of the objective.

Source code in opti/objective.py
18
19
20
def to_config(self) -> Dict:
    """Return a json-serializable dictionary of the objective."""
    raise NotImplementedError

Objectives

Container for optimization objectives.

Objectives can be either used to quantify the optimility or as a constraint on the viability of output values (chance / feasibility constraint)

Source code in opti/objective.py
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
class Objectives:
    """Container for optimization objectives.

    Objectives can be either used to quantify the optimility or as a constraint on the
    viability of output values (chance / feasibility constraint)
    """

    def __init__(self, objectives: Union[List[Objective], List[Dict]]):
        _objectives = []
        for m in objectives:
            if isinstance(m, Objective):
                _objectives.append(m)
            else:
                _objectives.append(make_objective(**m))
        self.objectives = _objectives

    def __call__(self, df: pd.DataFrame) -> pd.DataFrame:
        return pd.concat([obj(df[obj.name]) for obj in self.objectives], axis=1)

    def __repr__(self):
        return "Objectives(\n" + pprint.pformat(self.objectives) + "\n)"

    def __iter__(self):
        return iter(self.objectives)

    def __len__(self):
        return len(self.objectives)

    def __getitem__(self, i: int) -> Objective:
        return self.objectives[i]

    @property
    def names(self):
        return [obj.name for obj in self]

    def bounds(self, outputs: Parameters) -> pd.DataFrame:
        """Compute the bounds in objective space based on the output space bounds.

        The bounds can be interpreted as the ideal and nadir points.

        Examples for continuous parameters:
            min y for y in [0, 10] -> ideal = 0, nadir = 10
            max y for y in [0, 10] -> ideal = -10, nadir = 0
            min (y - 7)**2 for y in [0, 10] -> ideal = 0, nadir = 7**2

        Args:
            outputs: Output parameters.
        """
        Z = self(outputs.bounds)
        bounds = pd.DataFrame(columns=self.names, dtype=float)
        bounds.loc["min"] = Z.min(axis=0)
        bounds.loc["max"] = Z.max(axis=0)

        for name, obj in zip(self.names, self):
            if isinstance(obj, CloseToTarget):
                bounds.loc["min", name] = 0

        return bounds

    def to_config(self) -> List[Dict]:
        return [obj.to_config() for obj in self.objectives]

    def get(self, types) -> "Objectives":
        """Get all parameters of the given type(s)."""
        return Objectives([o for o in self if isinstance(o, types)])

bounds(outputs)

Compute the bounds in objective space based on the output space bounds.

The bounds can be interpreted as the ideal and nadir points.

Examples for continuous parameters

min y for y in [0, 10] -> ideal = 0, nadir = 10 max y for y in [0, 10] -> ideal = -10, nadir = 0 min (y - 7)2 for y in [0, 10] -> ideal = 0, nadir = 72

Parameters:

Name Type Description Default
outputs Parameters

Output parameters.

required
Source code in opti/objective.py
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
def bounds(self, outputs: Parameters) -> pd.DataFrame:
    """Compute the bounds in objective space based on the output space bounds.

    The bounds can be interpreted as the ideal and nadir points.

    Examples for continuous parameters:
        min y for y in [0, 10] -> ideal = 0, nadir = 10
        max y for y in [0, 10] -> ideal = -10, nadir = 0
        min (y - 7)**2 for y in [0, 10] -> ideal = 0, nadir = 7**2

    Args:
        outputs: Output parameters.
    """
    Z = self(outputs.bounds)
    bounds = pd.DataFrame(columns=self.names, dtype=float)
    bounds.loc["min"] = Z.min(axis=0)
    bounds.loc["max"] = Z.max(axis=0)

    for name, obj in zip(self.names, self):
        if isinstance(obj, CloseToTarget):
            bounds.loc["min", name] = 0

    return bounds

get(types)

Get all parameters of the given type(s).

Source code in opti/objective.py
185
186
187
def get(self, types) -> "Objectives":
    """Get all parameters of the given type(s)."""
    return Objectives([o for o in self if isinstance(o, types)])

make_objective(type, name, **kwargs)

Make an objective from a configuration.

obj = make_objective(**config)

Parameters:

Name Type Description Default
type str

objective type

required
name str

output to optimize

required
Source code in opti/objective.py
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
def make_objective(type: str, name: str, **kwargs) -> Objective:
    """Make an objective from a configuration.

    ```
    obj = make_objective(**config)
    ```

    Args:
        type: objective type
        name: output to optimize
    """
    objective = {
        "minimize": Minimize,
        "maximize": Maximize,
        "close-to-target": CloseToTarget,
    }[type.lower()]
    return objective(name, **kwargs)