Skip to content

hill

DiminishingHill

Bases: OneToOneInversableDerivableTransformer

Transform series by applying the hill function.

Parameters:

Name Type Description Default
S float

Shape parameter. Strictly positive parameter of the hill diminishing function, influencing the concavity of the response curve (interpreted as the largest absolute value of the slope of the curve).

required
K float

Half saturation parameter. Strictly positive parameter of the hill diminishing function, representing the proportion of the max parameter for which half of the maximal impact of the variable is reached.

required
max float

Symbolic maximum, which represents the value above which the variable is in the area of saturation (default to None and then set to the maximum value of the training serie).

None
Source code in eki_mmo_equations/one_to_one_transformations/diminishing_return/hill.py
class DiminishingHill(OneToOneInversableDerivableTransformer):
    """Transform series by applying the hill function.

    ref links:
        - https://static.googleusercontent.com/media/research.google.com/fr//pubs/archive/45999.pdf
        - https://en.wikipedia.org/wiki/Hill_equation_(biochemistry)

    ```math
          \\frac{1}{1 + (\\frac{K \\times max}{serie})^S}
    ```

    Args:
        S (float): Shape parameter. Strictly positive parameter of the hill diminishing function, influencing the
                   concavity of the response curve (interpreted as the largest absolute value of
                   the slope of the curve).
        K (float): Half saturation parameter. Strictly positive parameter of the hill diminishing function,
                   representing the proportion of the max parameter for which half of the maximal impact of the
                   variable is reached.
        max (float, optional): Symbolic maximum, which represents the value above which the variable is in the area
                               of saturation (default to None and then set to the maximum value of the training serie).
    """

    def __init__(self, K, S, max=None) -> None:
        self.K = K
        self.S = S
        self.max = max

    @property
    def parameters(self) -> Dict[str, float]:
        return self.__dict__

    # ------- METHODS -------

    def fit(self, serie: np.ndarray, y=None):
        if self.max is None:
            if np.any(serie[serie > 0]):
                self.max = serie.max()
            else:
                self.max = serie.min() or 1

        return super().fit(serie, y)

    def transform(self, serie: np.ndarray, copy=False) -> np.ndarray:
        serie = super().transform(serie, copy)

        return self._transformer(serie, self.K, self.S, self.max)

    def inverse_transform(self, serie: np.ndarray, copy=False) -> np.ndarray:
        serie = super().inverse_transform(serie, copy)

        return self._inverse_transformer(serie, self.K, self.S, self.max)

    def derivative_transform(self, serie: np.ndarray, copy=False) -> np.ndarray:
        serie = super().derivative_transform(serie, copy)

        return self._derivative_transformer(serie, self.K, self.S, self.max)

    # ------- TRANSFORMERS -------

    @staticmethod
    def _transformer(serie: np.ndarray, K, S, max) -> np.ndarray:
        def hill_func(x, K, S):
            return 1 / (1 + (K / x) ** S)

        scaled_serie = serie / max
        with np.errstate(divide="ignore"):
            transformed_serie = hill_func(scaled_serie, K=K, S=S)

        return np.nan_to_num(transformed_serie)

    @staticmethod
    def _inverse_transformer(serie: np.ndarray, K, S, max) -> np.ndarray:
        def inverse_hill_func(x, K, S):
            return K * ((-1 + 1 / x) ** (-1 / S))

        with np.errstate(divide="ignore"):
            serie = inverse_hill_func(serie, K=K, S=S)
        unscaled_serie = serie * max

        return np.nan_to_num(unscaled_serie)

    @staticmethod
    def _derivative_transformer(serie: np.ndarray, K, S, max) -> np.ndarray:
        scaled_serie = serie / max

        def derivative_hill_func(x, K, S):
            return ((S / K) * ((x / K) ** (-S - 1))) / ((1 + ((K / x) ** S)) ** 2)

        with np.errstate(divide="ignore"):
            transformed_serie = derivative_hill_func(scaled_serie, K=K, S=S)
        transformed_serie /= max

        return np.nan_to_num(transformed_serie)

    # ------- CHECKERS -------

    def check_params(self, serie: np.ndarray):
        """Check if parameters respect their application scope."""
        if self.K <= 0 or self.K >= 1:
            raise ParameterScopeException(f"Parameter K must be in ]0, 1[, not {self.K}.")

        if self.S <= 0:
            raise ParameterScopeException(f"Parameter S must be strictly positive, not {self.S}.")

        if self.max <= 0:
            raise ParameterScopeException(f"Parameter max must be strictly positive, not {self.max}.")

check_params(serie)

Check if parameters respect their application scope.

Source code in eki_mmo_equations/one_to_one_transformations/diminishing_return/hill.py
def check_params(self, serie: np.ndarray):
    """Check if parameters respect their application scope."""
    if self.K <= 0 or self.K >= 1:
        raise ParameterScopeException(f"Parameter K must be in ]0, 1[, not {self.K}.")

    if self.S <= 0:
        raise ParameterScopeException(f"Parameter S must be strictly positive, not {self.S}.")

    if self.max <= 0:
        raise ParameterScopeException(f"Parameter max must be strictly positive, not {self.max}.")

DiminishingHillUnscale

Bases: DiminishingHill

Transform series by applying the hill function multiply by the max parameter.

Parameters:

Name Type Description Default
S float

Shape parameter. Strictly positive parameter of the hill diminishing function, influencing the concavity of the response curve (interpreted as the largest absolute value of the slope of the curve).

required
K float

Half saturation parameter. Strictly positive parameter of the hill diminishing function, representing the proportion of the max parameter for which half of the maximal impact of the variable is reached.

required
max float

Symbolic maximum, which represents the value above which the variable is in the area of saturation (default to None and then set to the maximum value of the training serie).

required
Source code in eki_mmo_equations/one_to_one_transformations/diminishing_return/hill.py
class DiminishingHillUnscale(DiminishingHill):
    """Transform series by applying the hill function multiply by the max parameter.

    ref links:
        - https://static.googleusercontent.com/media/research.google.com/fr//pubs/archive/45999.pdf
        - https://en.wikipedia.org/wiki/Hill_equation_(biochemistry)

    ```math
         max \\times \\frac{1}{1 + (\\frac{K \\times max}{serie})^S}
    ```

    Args:
        S (float): Shape parameter. Strictly positive parameter of the hill diminishing function, influencing the
                   concavity of the response curve (interpreted as the largest absolute value of
                   the slope of the curve).
        K (float): Half saturation parameter. Strictly positive parameter of the hill diminishing function,
                   representing the proportion of the max parameter for which half of the maximal impact of the
                   variable is reached.
        max (float, optional): Symbolic maximum, which represents the value above which the variable is in the area
                               of saturation (default to None and then set to the maximum value of the training serie).
    """

    @staticmethod
    def _transformer(serie: np.ndarray, K, S, max) -> np.ndarray:
        return max * super(DiminishingHillUnscale, DiminishingHillUnscale)._transformer(serie=serie, K=K, S=S, max=max)

    @staticmethod
    def _inverse_transformer(serie: np.ndarray, K, S, max) -> np.ndarray:
        def inverse_hill_func(x, K, S):
            return K * ((-1 + max / x) ** (-1 / S))

        with np.errstate(divide="ignore"):
            serie = inverse_hill_func(serie, K=K, S=S)
        unscaled_serie = serie * max

        return np.nan_to_num(unscaled_serie)

    @staticmethod
    def _derivative_transformer(serie: np.ndarray, K, S, max) -> np.ndarray:
        return max * super(DiminishingHillUnscale, DiminishingHillUnscale)._derivative_transformer(
            serie=serie, K=K, S=S, max=max
        )

    # ------- CHECKERS -------

    def check_params(self, serie: np.ndarray):
        """Check if parameters respect their application scope."""
        if self.K <= 0 or self.K >= 1:
            raise ParameterScopeException(f"Parameter K must be in ]0, 1[, not {self.K}.")

        if self.S <= 0:
            raise ParameterScopeException(f"Parameter S must be strictly positive, not {self.S}.")

        if self.max <= 0:
            raise ParameterScopeException(f"Parameter max must be strictly positive, not {self.max}.")

check_params(serie)

Check if parameters respect their application scope.

Source code in eki_mmo_equations/one_to_one_transformations/diminishing_return/hill.py
def check_params(self, serie: np.ndarray):
    """Check if parameters respect their application scope."""
    if self.K <= 0 or self.K >= 1:
        raise ParameterScopeException(f"Parameter K must be in ]0, 1[, not {self.K}.")

    if self.S <= 0:
        raise ParameterScopeException(f"Parameter S must be strictly positive, not {self.S}.")

    if self.max <= 0:
        raise ParameterScopeException(f"Parameter max must be strictly positive, not {self.max}.")