Source code for copul.family.extreme_value.gumbel_hougaard

import sympy as sp

from copul.family.extreme_value.biv_extreme_value_copula import BivExtremeValueCopula
from copul.family.extreme_value.multivariate_gumbel_hougaard import (
    MultivariateGumbelHougaard,
)
from copul.family.other import BivIndependenceCopula


[docs] class GumbelHougaardEV(MultivariateGumbelHougaard, BivExtremeValueCopula): """ Bivariate Gumbel-Hougaard Extreme Value Copula. A specialized version of the multivariate Gumbel-Hougaard copula for the bivariate case. This copula combines features of both the bivariate extreme value copula and the multivariate Gumbel-Hougaard copula. The CDF is given by: C(u,v) = exp(-(((-ln u)^θ + (-ln v)^θ)^(1/θ))) Special cases: - θ = 1: Independence copula - θ → ∞: Comonotonicity copula (perfect positive dependence) Parameters ---------- theta : float, optional Dependence parameter (default is None). Must be greater than or equal to 1. """ # Define parameters theta = sp.symbols("theta", positive=True) params = [theta] intervals = { str(theta): sp.Interval(1, float("inf"), left_open=False, right_open=True) } def __new__(cls, *args, **kwargs): """ Custom instance creation to handle the special case of θ=1. When θ=1, the Gumbel-Hougaard copula reduces to the independence copula. Parameters ---------- *args, **kwargs Additional arguments, potentially including 'theta'. Returns ------- Copula Either a GumbelHougaard or IndependenceCopula instance. """ # Check if theta=1 is passed either as a positional arg or keyword arg theta_is_one = False if len(args) > 0 and args[0] == 1: theta_is_one = True if "theta" in kwargs and kwargs["theta"] == 1: theta_is_one = True if theta_is_one: # Return an IndependenceCopula instance new_kwargs = kwargs.copy() if "theta" in new_kwargs: del new_kwargs["theta"] return BivIndependenceCopula(**new_kwargs) # If theta is not 1, proceed with normal initialization return super().__new__(cls) def __init__(self, theta=None, *args, **kwargs): """ Initialize a Bivariate Gumbel-Hougaard copula. Parameters ---------- theta : float, optional Dependence parameter. Must be greater than or equal to 1. *args, **kwargs Additional parameters. """ # Fix for multiple inheritance: avoid passing dimension twice # Initialize BivExtremeValueCopula first (it will set dimension=2) MultivariateGumbelHougaard.__init__(self, 2, *args, **kwargs) BivExtremeValueCopula.__init__(self, *args, **kwargs) # Set theta parameter if theta is not None: self.theta = theta self._free_symbols = {"theta": self.theta} def __call__(self, *args, **kwargs): """ Return a new instance with updated parameters. Handle the special case where θ=1, which should return an independence copula. Parameters ---------- *args Positional arguments, potentially including theta. **kwargs Keyword arguments, potentially including 'theta'. Returns ------- Copula Either a GumbelHougaard or IndependenceCopula instance. """ if args and len(args) > 0: kwargs["theta"] = args[0] if "theta" in kwargs and kwargs["theta"] == 1: # If theta is 1, return an IndependenceCopula del kwargs["theta"] return BivIndependenceCopula()(**kwargs) # Otherwise, proceed with normal call return super().__call__(*args, **kwargs) @property def is_absolutely_continuous(self) -> bool: """ Check if the copula is absolutely continuous. The Gumbel-Hougaard copula is absolutely continuous. Returns ------- bool True """ return True @property def is_symmetric(self) -> bool: """ Check if the copula is symmetric. The Gumbel-Hougaard copula is symmetric. Returns ------- bool True """ return True @property def _pickands(self): """ Pickands dependence function for the Gumbel-Hougaard copula. A(t) = (t^θ + (1-t)^θ)^(1/θ) Returns ------- sympy.Expr The Pickands dependence function. """ return (self.t**self.theta + (1 - self.t) ** self.theta) ** (1 / self.theta) @property def _cdf_expr(self): return sp.exp( -( (sp.log(1 / self.v) ** self.theta + sp.log(1 / self.u) ** self.theta) ** (1 / self.theta) ) )
[docs] def kendalls_tau(self, *args, **kwargs): """ Compute Kendall's tau for the Gumbel-Hougaard copula. For the Gumbel-Hougaard copula, Kendall's tau has the closed form (θ-1)/θ. Parameters ---------- *args, **kwargs Parameters for the copula. Returns ------- float or sympy.Expr Kendall's tau value or expression. """ self._set_params(args, kwargs) return (self.theta - 1) / self.theta
def _rho(self): """ Compute the expression for Spearman's rho. Returns ------- sympy.Expr Spearman's rho expression. """ t = self.t theta = self.theta integrand = ((t**theta + (1 - t) ** theta) ** (1 / theta) + 1) ** (-2) return 12 * sp.Integral(integrand, (t, 0, 1)) - 3