Source code for paref.pareto_reflections.priority_search

from typing import Callable

import numpy as np
import scipy as sp

from paref.pareto_reflections.find_edge_points import FindEdgePoints
from paref.pareto_reflections.minimize_g import MinGParetoReflection


[docs] class PrioritySearch(MinGParetoReflection): """Find Pareto points which reflect your priorities When to use ----------- This Pareto reflection should be used if you wish to obtain Pareto points where different weights are assigned to the different dimensions of the target space. .. warning:: This Pareto reflection assumes that an edge point corresponding to each component was already (approximately) found. Use the ``FindEdgePointsSequence`` sequence of Pareto reflections first. """ def __init__(self, blackbox_function, priority: np.ndarray): super().__init__(blackbox_function=blackbox_function) if len(priority) != blackbox_function.dimension_target_space: raise ValueError(f'Priority vector has dimension {len(priority)} but must have dimension' f'{blackbox_function.dimension_target_space}!') priority = -(priority - np.sum(priority)) priority = np.array(priority) / np.sum(priority) self._minima_components_pp = [] # TODO: it might happen that the edge points collapse i.e. that two edge points agree. than this algo fails for i in range(len(priority)): self._minima_components_pp.append( FindEdgePoints(dimension=i, blackbox_function=blackbox_function).best_fits( blackbox_function.y)[0]) self._center = np.sum( [priority[i] * self._minima_components_pp[i] for i in range(blackbox_function.dimension_target_space)], axis=0) # calculate orthogonal basis span = self._minima_components_pp - self._center self.orthogonal_basis = sp.linalg.orth(span.T).T @property def g(self) -> Callable: return lambda x: np.linalg.norm(np.sum(np.array([np.dot(x - self._center, basis_vector) * basis_vector for basis_vector in self.orthogonal_basis]), axis=0))