Source code for scalarization.Scalarizer

import numpy as np

from typing import Callable, Dict


[docs]class Scalarizer: """Implements a class for scalarizing vector valued functions with a given scalarization function. """ def __init__( self, evaluator: Callable, scalarizer: Callable, evaluator_args: Dict = None, scalarizer_args: Dict = None ): """ Args: evaluator (Callable): A Callable object returning a numpy array. scalarizer (Callable): A function which should accepts as its arguments the output of evaluator and return a single value. evaluator_args (Any, optional): Optional arguments to be passed to evaluator. Defaults to None. scalarizer_args (Any, optional): Optional arguments to be passed to scalarizer. Defaults to None. """ self._evaluator = evaluator self._scalarizer = scalarizer self._evaluator_args = evaluator_args self._scalarizer_args = scalarizer_args
[docs] def evaluate(self, xs: np.ndarray) -> np.ndarray: """Evaluates the scalarized function with the given arguments and returns a scalar value for each vector of variables given in a numpy array. Args: xs (np.ndarray): A 2D numpy array containing vectors of variables on each of its rows. Returns: np.ndarray: A 1D numpy array with the values returned by the scalarizer for each row in xs. """ if self._evaluator_args is not None: res_eval = self._evaluator(xs, **self._evaluator_args) else: res_eval = self._evaluator(xs) if self._scalarizer_args is not None: res_scal = self._scalarizer(res_eval, **self._scalarizer_args) else: res_scal = self._scalarizer(res_eval) return res_scal
[docs] def __call__(self, xs: np.ndarray) -> np.ndarray: """Wrapper to the evaluate method. """ return self.evaluate(xs)
[docs]class DiscreteScalarizer: """Implements a class to scalarize discrete vectors given a scalarizing function. """ def __init__(self, scalarizer: Callable, scalarizer_args: Dict = None): self._scalarizer = scalarizer self._scalarizer_args = scalarizer_args
[docs] def evaluate(self, vectors: np.ndarray) -> np.ndarray: # guarantee two dimensions, makes sure works with single vectors as well. vectors = np.atleast_2d(vectors) if self._scalarizer_args is not None: res_scal = self._scalarizer(vectors, **self._scalarizer_args) else: res_scal = self._scalarizer(vectors) return res_scal
[docs] def __call__(self, vectors: np.ndarray): return self.evaluate(vectors)
if __name__ == "__main__":
[docs] vectors = np.array([[1, 1, 1], [2, 2, 2], [4, 5, 6.0]])
vector = np.array([1, 2, 3]) dscalarizer = DiscreteScalarizer(lambda x, a=1: a * np.sum(x, axis=1), scalarizer_args={"a": 2}) res = dscalarizer(vectors) res_1d = dscalarizer(vector) print(res) print(res_1d)