import numpy as np
from ._base_distributions import BaseDistribution
[docs]
class GPDPoiss(BaseDistribution):
def __init__(self) -> None:
"""
Initialize the GPD-Poisson mode
"""
super().__init__()
@property
def name() -> str:
return "GPD-Poisson model"
@property
def nparams() -> int:
"""
Number of parameters of GPD-Poisson model
"""
return int(4)
@property
def param_names() -> list[str]:
"""
Name of parameters of GPD-Poisson
"""
return ["threshold", "scale", "shape", "poisson"]
[docs]
@staticmethod
def pdf(
x: np.ndarray,
threshold: float = 0.0,
scale: float = 1.0,
shape: float = 0.0,
poisson: float = 1.0,
) -> np.ndarray:
"""
Probability density function
Parameters
----------
x : np.ndarray
Values to compute the probability density value
threshold : float, default=0.0
Threshold parameter
scale : float, default = 1.0
Scale parameter.
Must be greater than 0.
shape : float, default = 0.0
Shape parameter.
poisson : float, default = 1.0
Returns
----------
pdf : np.ndarray
Probability density function values
Raises
------
ValueError
If scale is not greater than 0.
ValueError
If poisson is not greater than 0.
"""
if scale <= 0:
raise ValueError("Scale parameter must be > 0")
if poisson <= 0:
raise ValueError("Poisson parameter must be > 0")
y = np.maximum(x - threshold, 0) / scale
# # Gumbel case (shape = 0)
# if shape == 0.0:
# pdf = (1 / scale) * (np.exp(-y) * np.exp(-np.exp(-y)))
# # General case (Weibull and Frechet, shape != 0)
# else:
# pdf = np.full_like(x, 0, dtype=float) # 0
# yy = 1 + shape * y
# yymask = yy > 0
# pdf[yymask] = (1 / scale) * (
# yy[yymask] ** (-1 - (1 / shape)) * np.exp(-(yy[yymask] ** (-1 / shape)))
# )
# return pdf
[docs]
@staticmethod
def qf(
p: np.ndarray,
threshold: float = 0.0,
scale: float = 1.0,
shape: float = 0.0,
poisson: float = 1.0,
) -> np.ndarray:
"""
Quantile function (Inverse of Cumulative Distribution Function)
Parameters
----------
p : np.ndarray
Probabilities to compute their quantile
loc : float, default=0.0
Location parameter
scale : float, default = 1.0
Scale parameter.
Must be greater than 0.
shape : float, default = 0.0
Shape parameter.
Returns
----------
q : np.ndarray
Quantile value
Raises
------
ValueError
If probabilities are not in the range (0, 1).
ValueError
If scale is not greater than 0.
"""
if np.min(p) <= 0 or np.max(p) >= 1:
raise ValueError("Probabilities must be in the range (0, 1)")
if scale <= 0:
raise ValueError("Scale parameter must be > 0")
if poisson <= 0:
raise ValueError("Poisson parameter must be > 0")
# Gumbel case (shape = 0)
if shape == 0.0:
q = threshold - scale * np.log(-np.log(p) / poisson)
# General case (Weibull and Frechet, shape != 0)
else:
q = threshold - (1 - (-np.log(p) / poisson) ** (-shape)) * scale / shape
return q
[docs]
def cdf(
x: np.ndarray,
threshold: float = 0.0,
scale: float = 1.0,
shape: float = 0.0,
poisson: float = 1.0,
) -> np.ndarray:
if shape == 0.0:
expr = (np.maximum(x - threshold, 0)) / scale
return np.exp(-poisson * np.exp(-expr))
else:
expr = 1 + shape * (np.maximum(x - threshold, 0) / scale)
return np.exp(-poisson * expr ** (-1 / shape))