Source code for copul.family.other.independence_copula

import numpy as np
import sympy as sp

from copul.family.core.copula import Copula
from copul.family.core.copula_plotting_mixin import CopulaPlottingMixin
from copul.wrapper.cdf_wrapper import CDFWrapper
from copul.wrapper.sympy_wrapper import SymPyFuncWrapper


[docs] class IndependenceCopula(Copula, CopulaPlottingMixin): """ Multivariate Independence Copula implementation. The independence copula represents statistical independence between random variables: C(u₁, u₂, ..., uₙ) = u₁ × u₂ × ... × uₙ This is also a special case of an Archimedean copula with generator φ(t) = -log(t). Parameters ---------- dimension : int, optional Dimension of the copula (number of variables). Default is 2. """ params = [] # No parameters needed for independence copula intervals = {} # No parameter intervals def __init__(self, dimension=2, **kwargs): """ Initialize a multivariate independence copula. Parameters ---------- dimension : int, optional Dimension of the copula (default is 2). **kwargs Additional keyword arguments (ignored). """ super().__init__(dimension=dimension, **kwargs) self._free_symbols = {} def __call__(self, **kwargs): """ Return a new instance with the same dimension. Parameters ---------- **kwargs Additional keyword arguments (ignored). Returns ------- IndependenceCopula A new instance with the same dimension. """ return IndependenceCopula(dimension=self.dim) @property def is_absolutely_continuous(self) -> bool: """ Check if the copula is absolutely continuous. The independence copula is absolutely continuous. Returns ------- bool True """ return True @property def is_symmetric(self) -> bool: """ Check if the copula is symmetric. The independence copula is symmetric in all its arguments. Returns ------- bool True """ return True @property def cdf(self): """ Compute the cumulative distribution function (CDF) of the independence copula. For the independence copula, the CDF is the product of all marginals: C(u₁, u₂, ..., uₙ) = u₁ × u₂ × ... × uₙ Returns ------- CDFWrapper A wrapper around the CDF function. """ # Product of all u symbols product = sp.prod(self.u_symbols) return CDFWrapper(product)
[docs] def cdf_vectorized(self, *args): """ Vectorized implementation of the CDF for the independence copula. Parameters ---------- *args : array_like Arrays of dimension values to evaluate the CDF at. Returns ------- numpy.ndarray Array of CDF values. """ # Convert all inputs to numpy arrays arrays = [np.asarray(arg) for arg in args] # Check dimensions if len(arrays) != self.dim: raise ValueError(f"Expected {self.dim} arrays, got {len(arrays)}") # Compute the product of all arrays # Start with ones array of the right shape result = np.ones(np.broadcast(*arrays).shape) # Multiply by each array for arr in arrays: result = result * arr return result
@property def pdf(self): """ Compute the probability density function (PDF) of the independence copula. For the independence copula, the PDF is constant 1 on the unit cube. Returns ------- SymPyFuncWrapper A wrapper around the PDF function. """ return SymPyFuncWrapper(sp.Integer(1))
[docs] def pdf_vectorized(self, *args): """ Vectorized implementation of the PDF for the independence copula. Parameters ---------- *args : array_like Arrays of dimension values to evaluate the PDF at. Returns ------- numpy.ndarray Array of PDF values (all 1s). """ # Convert all inputs to numpy arrays arrays = [np.asarray(arg) for arg in args] # Check dimensions if len(arrays) != self.dim: raise ValueError(f"Expected {self.dim} arrays, got {len(arrays)}") # Return array of ones with appropriate shape return np.ones(np.broadcast(*arrays).shape)
[docs] def cond_distr(self, i, u=None): """ Compute the conditional distribution of the i-th variable. For the independence copula, the conditional distribution is just the original variable. Parameters ---------- i : int Index of the variable (1-based). u : array_like, optional Values at which to evaluate the conditional distribution. Returns ------- SymPyFuncWrapper or float The conditional distribution function or its value at u. """ if i < 1 or i > self.dim: raise ValueError(f"Index {i} out of bounds for dimension {self.dim}") # For independence, conditional distribution of ui given ui is just u-i product = 1 for j in range(1, self.dim + 1): if j != i: product *= self.u_symbols[j - 1] if u is not None: for j in range(1, self.dim + 1): if j != i: product = product.subs(self.u_symbols[j - 1], u[j - 1]) return SymPyFuncWrapper(product)
[docs] def kendalls_tau(self): """ Compute Kendall's tau for the independence copula. For the independence copula, Kendall's tau is 0 as there is no dependence. Returns ------- float 0 """ return 0
[docs] def spearmans_rho(self): """ Compute Spearman's rho for the independence copula. For the independence copula, Spearman's rho is 0 as there is no dependence. Returns ------- float 0 """ return 0
[docs] def blomqvists_beta(self, *args, **kwargs): return 0
[docs] def gini_gamma(self, *args, **kwargs): return 0
[docs] def spearman_footrule(self, *args, **kwargs): return 0
[docs] def blests_nu(self, *args, **kwargs): return 0
[docs] def schweizer_wolff_sigma(self, *args, **kwargs): return 0
[docs] def hoeffdings_d(self, *args, **kwargs): return 0
[docs] def lp_concordance(self, p: int = 2, *args, **kwargs): return 0
[docs] def mutual_information(self, *args, **kwargs): return 0.0
[docs] def lambda_L(self): """ Compute the lower tail dependence coefficient. For the independence copula, there is no tail dependence. Returns ------- float 0 """ return 0
[docs] def lambda_U(self): """ Compute the upper tail dependence coefficient. For the independence copula, there is no tail dependence. Returns ------- float 0 """ return 0
[docs] def rvs(self, n=1, random_state=None): """ Generate random variates from the independence copula. For the independence copula, this simply generates independent uniform random variables. Parameters ---------- n : int, optional Number of samples to generate (default is 1). random_state : int or None, optional Seed for the random number generator. Returns ------- numpy.ndarray Array of shape (n, dim) containing independent uniform samples. """ # Set random seed if provided if random_state is not None: np.random.seed(random_state) # Generate independent uniform random variables return np.random.uniform(0, 1, size=(n, self.dim))