164 lines
4.8 KiB
Python
164 lines
4.8 KiB
Python
""" Extreme Value Copulas
|
||
Created on Fri Jan 29 19:19:45 2021
|
||
|
||
Author: Josef Perktold
|
||
License: BSD-3
|
||
|
||
"""
|
||
|
||
import numpy as np
|
||
from .copulas import Copula
|
||
|
||
|
||
def copula_bv_ev(u, transform, args=()):
|
||
'''generic bivariate extreme value copula
|
||
'''
|
||
u, v = u
|
||
return np.exp(np.log(u * v) * (transform(np.log(u)/np.log(u*v), *args)))
|
||
|
||
|
||
class ExtremeValueCopula(Copula):
|
||
"""Extreme value copula constructed from Pickand's dependence function.
|
||
|
||
Currently only bivariate copulas are available.
|
||
|
||
Parameters
|
||
----------
|
||
transform: instance of transformation class
|
||
Pickand's dependence function with required methods including first
|
||
and second derivatives
|
||
args : tuple
|
||
Optional copula parameters. Copula parameters can be either provided
|
||
when creating the instance or as arguments when calling methods.
|
||
k_dim : int
|
||
Currently only bivariate extreme value copulas are supported.
|
||
|
||
Notes
|
||
-----
|
||
currently the following dependence function and copulas are available
|
||
|
||
- AsymLogistic
|
||
- AsymNegLogistic
|
||
- AsymMixed
|
||
- HR
|
||
|
||
TEV and AsymBiLogistic currently do not have required derivatives for pdf.
|
||
|
||
See Also
|
||
--------
|
||
dep_func_ev
|
||
|
||
"""
|
||
|
||
def __init__(self, transform, args=(), k_dim=2):
|
||
super().__init__(k_dim=k_dim)
|
||
self.transform = transform
|
||
self.k_args = transform.k_args
|
||
self.args = args
|
||
if k_dim != 2:
|
||
raise ValueError("Only bivariate EV copulas are available.")
|
||
|
||
def _handle_args(self, args):
|
||
# TODO: how to we handle non-tuple args? two we allow single values?
|
||
# Model fit might give an args that can be empty
|
||
if isinstance(args, np.ndarray):
|
||
args = tuple(args) # handles empty arrays, unpacks otherwise
|
||
if args == () or args is None:
|
||
args = self.args
|
||
if not isinstance(args, tuple):
|
||
args = (args,)
|
||
|
||
return args
|
||
|
||
def cdf(self, u, args=()):
|
||
"""Evaluate cdf of bivariate extreme value copula.
|
||
|
||
Parameters
|
||
----------
|
||
u : array_like
|
||
Values of random bivariate random variable, each defined on [0, 1],
|
||
for which cdf is computed.
|
||
Can be two dimensional with multivariate components in columns and
|
||
observation in rows.
|
||
args : tuple
|
||
Required parameters for the copula. The meaning and number of
|
||
parameters in the tuple depends on the specific copula.
|
||
|
||
Returns
|
||
-------
|
||
CDF values at evaluation points.
|
||
"""
|
||
# currently only Bivariate
|
||
u, v = np.asarray(u).T
|
||
args = self._handle_args(args)
|
||
cdfv = np.exp(np.log(u * v) *
|
||
self.transform(np.log(u)/np.log(u*v), *args))
|
||
return cdfv
|
||
|
||
def pdf(self, u, args=()):
|
||
"""Evaluate pdf of bivariate extreme value copula.
|
||
|
||
Parameters
|
||
----------
|
||
u : array_like
|
||
Values of random bivariate random variable, each defined on [0, 1],
|
||
for which cdf is computed.
|
||
Can be two dimensional with multivariate components in columns and
|
||
observation in rows.
|
||
args : tuple
|
||
Required parameters for the copula. The meaning and number of
|
||
parameters in the tuple depends on the specific copula.
|
||
|
||
Returns
|
||
-------
|
||
PDF values at evaluation points.
|
||
"""
|
||
tr = self.transform
|
||
u1, u2 = np.asarray(u).T
|
||
args = self._handle_args(args)
|
||
|
||
log_u12 = np.log(u1 * u2)
|
||
t = np.log(u1) / log_u12
|
||
cdf = self.cdf(u, args)
|
||
dep = tr(t, *args)
|
||
d1 = tr.deriv(t, *args)
|
||
d2 = tr.deriv2(t, *args)
|
||
pdf_ = cdf / (u1 * u2) * ((dep + (1 - t) * d1) * (dep - t * d1) -
|
||
d2 * (1 - t) * t / log_u12)
|
||
|
||
return pdf_
|
||
|
||
def logpdf(self, u, args=()):
|
||
"""Evaluate log-pdf of bivariate extreme value copula.
|
||
|
||
Parameters
|
||
----------
|
||
u : array_like
|
||
Values of random bivariate random variable, each defined on [0, 1],
|
||
for which cdf is computed.
|
||
Can be two dimensional with multivariate components in columns and
|
||
observation in rows.
|
||
args : tuple
|
||
Required parameters for the copula. The meaning and number of
|
||
parameters in the tuple depends on the specific copula.
|
||
|
||
Returns
|
||
-------
|
||
Log-pdf values at evaluation points.
|
||
"""
|
||
return np.log(self.pdf(u, args=args))
|
||
|
||
def conditional_2g1(self, u, args=()):
|
||
"""conditional distribution
|
||
|
||
not yet implemented
|
||
|
||
C2|1(u2|u1) := ∂C(u1, u2) / ∂u1 = C(u1, u2) / u1 * (A(t) − t A'(t))
|
||
|
||
where t = np.log(v)/np.log(u*v)
|
||
"""
|
||
raise NotImplementedError
|
||
|
||
def fit_corr_param(self, data):
|
||
raise NotImplementedError
|