Source code for optilab.metamodels.iepolation_surrogate

"""
Inter-extra-polation surrogate metamodel.
It uses different surrogate functions for interpolation and extrapolation.
"""

# pylint: disable=no-name-in-module

from scipy.spatial import ConvexHull
from shapely.geometry import Point as ShapelyPoint
from shapely.geometry import Polygon

from ..data_classes import Point, PointList
from ..functions.surrogate.surrogate_objective_function import (
    SurrogateObjectiveFunction,
)


[docs] class IEPolationSurrogate(SurrogateObjectiveFunction): """ Inter-extra-polation surrogate metamodel. It uses different surrogate functions for interpolation and extrapolation. """
[docs] def __init__( self, interpolation_surrogate: SurrogateObjectiveFunction, extrapolation_surrogate: SurrogateObjectiveFunction, train_set: PointList | None = None, ) -> None: """ Class constructor. Args: interpolation_surrogate: Surrogate used for interpolation. extrapolation_surrogate: Surrogate used for extrapolation. train_set: Initial training set for the surrogates. """ super().__init__("iepolation", train_set) self.interpolation_surrogate = interpolation_surrogate self.extrapolation_surrogate = extrapolation_surrogate self.convex_hull = None if train_set: self.build_convex_hull(train_set)
[docs] def build_convex_hull(self, train_set: PointList) -> None: """ Builds a convex hull from the train set. This convex hull is then used to determine wheather the point value should be interpolated or extrapolated. Args: train_set: Training set. """ hull = ConvexHull(train_set.x()) hull_points = hull.points[hull.vertices] self.convex_hull = Polygon(hull_points)
[docs] def train(self, train_set: PointList) -> None: """ Train both surrogate functions with provided data. Args: train_set: Training data for the model. """ super().train(train_set) self.interpolation_surrogate.train(self.train_set) self.extrapolation_surrogate.train(self.train_set) self.build_convex_hull(self.train_set)
[docs] def is_in_convex_hull(self, point: Point) -> bool: """ Check if the given point lies inside of the convex hull of training points. Args: point: The point to be checked. Returns: True if the given point lies inside the convex hull, False otherwise. """ return self.convex_hull.contains(ShapelyPoint(point.x))
[docs] def __call__(self, point: Point) -> Point: """ Estimate the value of a single point with the surrogate function. Args: x: Point to estimate. Raises: ValueError: If dimensionality of x doesn't match self.dim. Return: Point: Estimated point. """ super().__call__(point) if self.is_in_convex_hull(point): return self.interpolation_surrogate(point) return self.extrapolation_surrogate(point)