copul documentation

copul is a package designed for mathematical computation and visualization of bivariate copula families. It accompanies the Dependence properties of bivariate copula families article released in the Dependence Modeling journal and in particular covers implementations of 35+ copula families, see Copula families, properties and methods for an overview.


Import the package

>>> import copul as cp

List callable copula families

>>> cp.families
['Clayton', 'Nelsen2', 'AliMikhailHaq', 'GumbelHougaard', 'Frank', 'Joe', 'Nelsen7', 'Nelsen8', 'GumbelBarnett', 'Nelsen10', 'Nelsen11', 'Nelsen12', 'Nelsen13', 'Nelsen14', 'GenestGhoudi', 'Nelsen16', 'Nelsen17', 'Nelsen18', 'Nelsen19', 'Nelsen20', 'Nelsen21', 'Nelsen22', 'JoeEV', 'BB5', 'CuadrasAuge', 'Galambos', 'GumbelHougaard', 'HueslerReiss', 'Tawn', 'tEV', 'MarshallOlkin', 'Gaussian', 'StudentT', 'Laplace', 'B11', 'CheckerboardCopula', 'FarlieGumbelMorgenstern', 'Frechet', 'IndependenceCopula', 'LowerFrechet', 'Mardia', 'Plackett', 'Raftery', 'UpperFrechet']

Call a copula family and view its parameters

>>> clayton = cp.Clayton()
>>> cp.Clayton().parameters
{'theta': Interval(-1, oo)}
>>> cp.MarshallOlkin().parameters
{'alpha_1': Interval(0, 1), 'alpha_2': Interval(0, 1)}

Simulate data points from a copula

>>> cp.Clayton(0.5).rvs(n=3)
array([[0.33620426, 0.34329421],
       [0.34242024, 0.21372513],
       [0.5785887 , 0.94612088]])

Generate scatter plots of a copula

cp.GenestGhoudi(4).scatter_plot()
cp.GenestGhoudi(8).scatter_plot()
alternate text alternate text


Cumlative distribution functions

>>> cp.Clayton().cdf  # cumulative distribution function
Max(0, -1 + v**(-theta) + u**(-theta))**(-1/theta)
>>> cp.Clayton(theta=0.5).cdf  # specify a parameter
Max(0, u**(-0.5) + v**(-0.5) - 1)**(-2.0)
>>> cp.Clayton(0.5).cdf  # the parameter can be passed as a positional argument
Max(0, u**(-0.5) + v**(-0.5) - 1)**(-2.0)
>>> cp.Clayton(0.5).cdf(0.3, 1)
0.
cp.UpperFrechet().plot_cdf()
cp.LowerFrechet().plot_cdf()
alternate text alternate text

Visualize conditional distributions of copulas

>>> cp.Plackett().cond_distr_1()
(theta - (-2*theta*v*(theta - 1) + (2*theta - 2)*((theta - 1)*(u + v) + 1)/2)/sqrt(-4*theta*u*v*(theta - 1) + ((theta - 1)*(u + v) + 1)**2) - 1)/(2*theta - 2)
>>> plackett = cp.Plackett(0.1)
>>> plackett.plot(plackett.cond_distr_1, plackett.cond_distr_2)
alternate text alternate text

Visualize probability density functions of copulas

>>> cp.HueslerReiss(0.3).pdf
(u*v)**(-(log(v)/log(u*v) - 1)*(erf(sqrt(2)*(0.15*log(-(log(v)/log(u*v) - 1)*log(u*v)/log(v)) + 3.33333333333333)/2)/2 + 1/2) + (erf(sqrt(2)*(0.15*log(-log(v)/((log(v)/log(u*v) - 1)*log(u*v))) + 3.33333333333333)/2)/2 + 1/2)*log(v)/log(u*v))*((-((log(v)/log(u*v) - 1)*(erf(sqrt(2)*(0.15*log(-(log(v)/log(u*v) - 1)*log(u*v)/log(v)) + 3.33333333333333)/2)/2 + 1/2) - (erf(sqrt(2)*(0.15*log(-log(v)/((log(v)/log(u*v) - 1)*log(u*v))) + 3.33333333333333)/2)/2 + 1/2)*log(v)/log(u*v))*log(u*v) - (log(v) - log(u*v))*(-0.075*sqrt(2)*(log(v)/log(u*v) - 1)*(-1/(log(v)/log(u*v) - 1) + log(v)/((log(v)/log(u*v) - 1)**2*log(u*v)))*exp(-5.55555555555556*(0.045*log(-log(v)/((log(v)/log(u*v) - 1)*log(u*v))) + 1)**2)/sqrt(pi) + 0.075*sqrt(2)*((log(v)/log(u*v) - 1)*log(u*v)**2/log(v)**2 - log(u*v)/log(v))*exp(-5.55555555555556*(0.045*log(-(log(v)/log(u*v) - 1)*log(u*v)/log(v)) + 1)**2)*log(v)/(sqrt(pi)*log(u*v)) + erf(sqrt(2)*(0.15*log(-log(v)/((log(v)/log(u*v) - 1)*log(u*v))) + 3.33333333333333)/2)/2 - erf(sqrt(2)*(0.15*log(-(log(v)/log(u*v) - 1)*log(u*v)/log(v)) + 3.33333333333333)/2)/2))*(-((log(v)/log(u*v) - 1)*(erf(sqrt(2)*(0.15*log(-(log(v)/log(u*v) - 1)*log(u*v)/log(v)) + 3.33333333333333)/2)/2 + 1/2) - (erf(sqrt(2)*(0.15*log(-log(v)/((log(v)/log(u*v) - 1)*log(u*v))) + 3.33333333333333)/2)/2 + 1/2)*log(v)/log(u*v))*log(u*v) - (-0.075*sqrt(2)*(log(v)/log(u*v) - 1)*(-1/(log(v)/log(u*v) - 1) + log(v)/((log(v)/log(u*v) - 1)**2*log(u*v)))*exp(-5.55555555555556*(0.045*log(-log(v)/((log(v)/log(u*v) - 1)*log(u*v))) + 1)**2)/sqrt(pi) + 0.075*sqrt(2)*((log(v)/log(u*v) - 1)*log(u*v)**2/log(v)**2 - log(u*v)/log(v))*exp(-5.55555555555556*(0.045*log(-(log(v)/log(u*v) - 1)*log(u*v)/log(v)) + 1)**2)*log(v)/(sqrt(pi)*log(u*v)) + erf(sqrt(2)*(0.15*log(-log(v)/((log(v)/log(u*v) - 1)*log(u*v))) + 3.33333333333333)/2)/2 - erf(sqrt(2)*(0.15*log(-(log(v)/log(u*v) - 1)*log(u*v)/log(v)) + 3.33333333333333)/2)/2)*log(v))*log(u*v) + sqrt(2)*(log(v) - log(u*v))*(-0.0375*(-1 + log(v)/((log(v)/log(u*v) - 1)*log(u*v)))**2*(0.045*log(-log(v)/((log(v)/log(u*v) - 1)*log(u*v))) + 1)*exp(-5.55555555555556*(0.045*log(-log(v)/((log(v)/log(u*v) - 1)*log(u*v))) + 1)**2)*log(u*v)/log(v) + (-0.15 + 0.15*log(v)/((log(v)/log(u*v) - 1)*log(u*v)))*exp(-5.55555555555556*(0.045*log(-log(v)/((log(v)/log(u*v) - 1)*log(u*v))) + 1)**2)/(log(v)/log(u*v) - 1) - (-0.075 + 0.075*log(v)/((log(v)/log(u*v) - 1)*log(u*v)))*exp(-5.55555555555556*(0.045*log(-log(v)/((log(v)/log(u*v) - 1)*log(u*v))) + 1)**2)*log(u*v)/log(v) - (-0.075 + 0.075*log(v)/((log(v)/log(u*v) - 1)*log(u*v)))*exp(-5.55555555555556*(0.045*log(-log(v)/((log(v)/log(u*v) - 1)*log(u*v))) + 1)**2)/(log(v)/log(u*v) - 1) + (-0.15*(log(v)/log(u*v) - 1)*log(u*v)/log(v) + 0.15)*exp(-5.55555555555556*(0.045*log(-(log(v)/log(u*v) - 1)*log(u*v)/log(v)) + 1)**2)*log(u*v)/log(v) - (-0.075*(log(v)/log(u*v) - 1)*log(u*v)/log(v) + 0.075)*exp(-5.55555555555556*(0.045*log(-(log(v)/log(u*v) - 1)*log(u*v)/log(v)) + 1)**2)*log(u*v)/log(v) + 0.0375*(-(log(v)/log(u*v) - 1)*log(u*v)/log(v) + 1)**2*(0.045*log(-(log(v)/log(u*v) - 1)*log(u*v)/log(v)) + 1)*exp(-5.55555555555556*(0.045*log(-(log(v)/log(u*v) - 1)*log(u*v)/log(v)) + 1)**2)/(log(v)/log(u*v) - 1) - (-0.075*(log(v)/log(u*v) - 1)*log(u*v)/log(v) + 0.075)*exp(-5.55555555555556*(0.045*log(-(log(v)/log(u*v) - 1)*log(u*v)/log(v)) + 1)**2)/(log(v)/log(u*v) - 1))*log(v)/sqrt(pi))/(u*v*log(u*v)**3)
>>> cp.HueslerReiss(0.3).plot_pdf()
alternate text

Use matrices for Checkerboard copulas

Checkerboard copulas are copulas that have probability density functions, which are constant on rectangles and can be represented by matrices.

>>> matr = [[0, 9, 1], [1, 0, 9], [9, 1, 0]]
        >>> ccop = cp.BivCheckPi(matr)
        >>> ccop.cdf(0.2, 1)
        0.2
        >>> ccop.pdf(0.2, 1)
        0.03333333333333333
        >>> ccop.scatter_plot()
    >>> ccop = cp.CheckerboardCopula(matr)
    >>> ccop.cdf(0.2, 1)
    0.2
    >>> ccop.pdf(0.2, 1)
    0.03333333333333333
    >>> ccop.scatter_plot()
    >>> ccop = cp.CheckPi(matr)
    >>> ccop.cdf(0.2, 1)
    0.2
    >>> ccop.pdf(0.2, 1)
    0.03333333333333333
    >>> ccop.scatter_plot()
>>> ccop = cp.CheckerboardCopula(matr)
>>> ccop.cdf(0.2, 1)
0.2
>>> ccop.pdf(0.2, 1)
0.03333333333333333
>>> ccop.scatter_plot()
alternate text
>>> ccop.plot_pdf()
alternate text

Spearman’s rho, Kendall’s tau and Chatterjee’s xi

>>> cp.CuadrasAuge().spearmans_rho()
-3*delta/(delta - 4)
>>> cp.CuadrasAuge(0.5).spearmans_rho()
0.428571428571427
>>> cp.FarlieGumbelMorgenstern().kendalls_tau()
2*theta/9
>>> cp.AliMikhailHaq().chatterjees_xi()
-theta/6 - 0.666666666666667 + 3/theta - 2/theta**2 - 2*(1 - theta)**2*log(1 - theta)/theta**3
>>> cp.Gaussian().plot_rank_correlations(1_000_000, 50)
alternate text

Archimedean copulas: Generator and inverse generator functions

Archimedean copulas are characterized by a generator function, which is available in the package.

>>> nelsen7 = cp.Nelsen7()
>>> nelsen7.generator
-log(t*theta - theta + 1)
>>> nelsen7.inv_generator
(theta*exp(y) - exp(y) + 1)*exp(-y)*Heaviside(-y - log(1 - theta))/theta
>>> cp.Nelsen7(0.5).plot_generator()
alternate text

Extreme-value copulas: Pickands dependence functions

Extreme-value copulas are characterized by a pickands dependence function, which is also available in the package.

>>> galambos = cp.Galambos()
>>> galambos.pickands
1 - 1/((1 - t)**(-delta) + t**(-delta))**(1/delta)
>>> galambos.plot_pickands(delta=[0.5, 1, 2])
alternate text

Indices and tables