Source code for sorbetto.tile.correlation_tile

import math

import numpy as np

from sorbetto.flavor.correlation_flavor import CorrelationFlavor
from sorbetto.parameterization.abstract_parameterization import AbstractParameterization
from sorbetto.tile.numeric_tile import NumericTile


[docs] class CorrelationTile(NumericTile): def __init__( self, parameterization: AbstractParameterization, flavor: CorrelationFlavor, name: str = "Correlation Tile", resolution: int = 1001, disable_colorbar: bool = False, ): super().__init__( parameterization=parameterization, flavor=flavor, name=name, resolution=resolution, disable_colorbar=disable_colorbar, ) self._score = self.flavor.score self._correlation_coefficient = self.flavor.correlation_coefficient self._performance = self.flavor.performances @property def flavor(self) -> CorrelationFlavor: return super().flavor # type: ignore
[docs] def minimize(self, precision: float = 1e-8): """ Tries to minimize the value. There is no guarantee to find the minimum with the implemented algorithm. As described in Section A.7.2 of the supplementary material for :cite:t:`Pierard2025Foundations`, this method implements a custom coarse-to-fine grid-based direct search :cite:t:`Conn2009Introduction`: we compute the value on a coarse grid over the Tile, locate the minimum on the grid, center a smaller region of interrest and a finer grid around that point, and iterate until the region of interrest is small enough. Args: precision (float, optional): the desired precision for the coordinates of the point on the Tile. Defaults to 1e-8. Returns: float: the first coordinate of the point on the Tile where the smallest value has been found. float: the second coordinate of the point on the Tile where the smallest value has been found. float: the smallest value that has been found. """ parameterization = self.parameterization flavor = self.flavor assert flavor is not None min_x, max_x = parameterization.getBoundsParameter1() min_y, max_y = parameterization.getBoundsParameter2() center_x = 0.5 * (min_x + max_x) center_y = 0.5 * (min_y + max_y) best_x_y_min = [center_x, center_y] # initial point for the optimization best_val_min = math.inf scale_x = max_x - min_x scale_y = max_y - min_y for _ in range(64): if precision > scale_x and precision > scale_y: break scale_x = scale_x * 0.5 scale_y = scale_y * 0.5 best_x, best_y = best_x_y_min for x in np.linspace(best_x - scale_x, best_x + scale_x, 16): if x < min_x or x > max_x: continue for y in np.linspace(best_y - scale_y, best_y + scale_y, 16): if y < min_y or y > max_y: continue importance = parameterization.getCanonicalImportance(x, y) val = flavor(importance) if val < best_val_min: best_x_y_min = x, y best_val_min = val return best_x_y_min[0], best_x_y_min[1], best_val_min
[docs] def maximize(self, precision: float = 1e-8): """ Tries to maximize the value. There is no guarantee to find the maximum with the implemented algorithm. As described in Section A.7.2 of the supplementary material for :cite:t:`Pierard2025Foundations`, this method implements a custom coarse-to-fine grid-based direct search :cite:t:`Conn2009Introduction`: we compute the value on a coarse grid over the Tile, locate the maximum on the grid, center a smaller region of interrest and a finer grid around that point, and iterate until the region of interrest is small enough. Args: precision (float, optional): the desired precision for the coordinates of the point on the Tile. Defaults to 1e-8. Returns: float: the first coordinate of the point on the Tile where the largest value has been found. float: the second coordinate of the point on the Tile where the largest value has been found. float: the largest value that has been found. """ parameterization = self.parameterization flavor = self.flavor assert flavor is not None min_x, max_x = parameterization.getBoundsParameter1() min_y, max_y = parameterization.getBoundsParameter2() center_x = 0.5 * (min_x + max_x) center_y = 0.5 * (min_y + max_y) best_x_y_min = [center_x, center_y] # initial point for the optimization best_val_min = -math.inf scale_x = max_x - min_x scale_y = max_y - min_y for _ in range(64): if precision > scale_x and precision > scale_y: break scale_x = scale_x * 0.5 scale_y = scale_y * 0.5 best_x, best_y = best_x_y_min for x in np.linspace(best_x - scale_x, best_x + scale_x, 16): if x < min_x or x > max_x: continue for y in np.linspace(best_y - scale_y, best_y + scale_y, 16): if y < min_y or y > max_y: continue importance = parameterization.getCanonicalImportance(x, y) val = flavor(importance) if val > best_val_min: best_x_y_min = x, y best_val_min = val return best_x_y_min[0], best_x_y_min[1], best_val_min
[docs] def getExplanation(self) -> str: return "Not implemented for CorrelationTile yet."