# Copulas.jl: A fully Distributions.jl-compliant copula package

Oskar Laverny  0000-0002-7508-999X Santiago Jimenez  Federal University of
Pernambuco  0000-0002-8198-3656

(16 November 2023)

## Summary

Copulas are functions that describe dependence structures of random vectors,
without describing their univariate marginals. In statistics, the separation
is sometimes useful, the quality and/or quantity of available information on
these two objects might differ. This separation can be formally stated through
Sklar’s theorem:

Theorem: existance and uniqueness of the copula (Sklar, 1959): For a given
$d$-variate absolutely continuous random vector $\mathbf{X}$ with marginals
$X_{1},...X_{d}$, there exists a unique function $C$, the copula, such that

$F(\mathbf{x})=C(F_{1}(x_{1}),...,F_{d}(x_{d})),$

where $F,F_{1},...F_{d}$ are respectively the distributions functions of
$\mathbf{X},X_{1},...X_{d}$.

Copulas are standard tools in probability and statistics, with a wide range of
applications from biostatistics, finance or medicine, to fuzzy logic, global
sensitivity and broader analysis. A few standard theoretical references on the
matter are (Joe, 1997), (Nelsen, 2006), (Joe, 2014), and (Durante & Sempi,
2015).

The Julia package Copulas.jl brings most standard copula-related features into
native Julia: random number generation, density and distribution function
evaluations, fitting, construction of multivariate models through Sklar’s
theorem, and many more related functionalities. Copulas being fundamentally
distributions of random vectors, we fully comply with the Distributions.jl API
(Besançon et al., 2021; Lin et al., 2019), the Julian standard for
implementation of random variables and random vectors. This complience allows
interoperability with other packages based on this API such as, e.g.,
Turing.jl (Ge et al., 2018) and several others.

## Statement of need

The R package copula (Hofert et al., 2020; Ivan Kojadinovic & Jun Yan, 2010;
Jun Yan, 2007; Marius Hofert & Martin Mächler, 2011) is the gold standard when
it comes to sampling, estimating, or simply working around dependence
structures. However, in other languages, the available tools are not as
developped and/or not as recognised. We bridge the gap in the Julian ecosystem
with this Julia-native implementation. Due to the very flexible type system in
Julia, our code expressiveness and tidyness will increase its usability and
maintenability in the long-run. Type-stability allows sampling in arbitrary
precision without requiering more code, and Julia’s multiple dispatch yields
most of the below-described applications.

There are competing packages in Julia, such as BivariateCopulas.jl which only
deals with a few models in bivariate settings but has very nice graphs, or
DatagenCopulaBased.jl, which only provides sampling and does not have exactly
the same models as Copulas.jl. While not fully covering out both of these
package’s functionality (mostly because the three projects chose different
copulas to implement), Copulas.jl is clearly the must fully featured, and
brings, as a key feature, the complience with the broader ecosystem.

## Examples

###  SklarDist: sampling and fitting examples

The Distributions.jl’s API provides a fit function. You may use it to simply
fit a compound model to some dataset as follows:

using Copulas, Distributions, Random# Define the marginals and the copula,
then use Sklar's theorem:X1 = Gamma(2,3)X2 = Pareto(0.5)X3 = Binomial(10,0.8)C
= ClaytonCopula(3,0.7)X = SklarDist(C,(X1,X2,X3))# Sample from the model: x =
rand(D,1000)# You may estimate the model as follows: Dhat =
fit(SklarDist{FrankCopula,Tuple{Gamma,Normal,Binomial}}, x)# Although you'll
probbaly get a bad fit !

The API does not fix the fitting procedure, and only loosely specify it, thus
the implemented default might vary on the copula. If you want more control,
you may turn to bayesian estimation using Turing.jl (Ge et al., 2018):

using Turing@model function model(dataset) # Priors theta ~
TruncatedNormal(1.0, 1.0, theta, Inf) gamma ~ TruncatedNormal(1.0, 1.0, 0.25,
Inf) eta ~ Beta(1,1) delta ~ Exponential(1) # Define the model through Sklar's
theorem:  X1 = Gamma(2,theta) X2 = Pareto(gamma) X3 = Binomial(10,eta) C =
ClaytonCopula(3,delta) X = SklarDist(C,(X1,X2,X3)) # Add the loglikelyhood to
the model :  Turing.Turing.@addlogprob! loglikelihood(D, dataset)end

### The Archimedean API

Archimedean copulas are a huge family of copulas that has seen a lot of
theoretical work. Among others, you may take a look at (McNeil & Nešlehová,
2009). We use WilliamsonTransformations.jl’s implementation of the Williamson
$d$-transfrom to sample from any archimedean copula, including for example the
ClaytonCopula with negative dependence parameter in any dimension, which is a
first to our knowledge.

The API is consisting of the folloiwng functions:

phi(C::MyArchimedean, t) # Generatorwilliamson_dist(C::MyArchimedean) #
Williamson d-transform

So that implementing your own archimedean copula only requires to subset the
ArchimedeanCopula type and provide your generator as follows:

struct MyUnknownArchimedean{d,T} <: ArchimedeanCopula{d}
theta::Tendphi(C::MyUnknownArchimedean,t) = exp(-t*C.theta)

The obtained model can be used as follows:

C = MyUnknownCopula{2,Float64}(3.0)spl = rand(C,1000) # samplingcdf(C,spl) #
cdfpdf(C,spl) # pdfloglikelihood(C,spl) # llh

The following functions have defaults but can be overridden for performance:

phi_inv(C::MyArchimedean, t) # Inverse of phiphi_1(C::MyArchimedean, t) #
first defrivative of phiphi_d(C::MyArchimedean,t) # dth defrivative of
phitau(C::MyArchimedean) # Kendall tautau_inv(::Type{MyArchimedean},tau) = #
Inverse kendall taufit(::Type{MyArchimedean},data) # fitting.

### Broader ecosystem

The package is starting to get used in several other places of the ecosystem.
Among others, we noted:

  * •

The package GlobalSensitivity.jl exploit Copulas.jl to provide Shapley effects
implementation, see this documentation.

  * •

EconomicScenarioGenerators.jl uses depndence structures between financial
assets.

## Acknowledgments

## References

reBesançon, M., Papamarkou, T., Anthoff, D., Arslan, A., Byrne, S., Lin, D., &
Pearson, J. (2021). Distributions.jl: Definition and modeling of probability
distributions in the JuliaStats ecosystem. _Journal of Statistical Software_ ,
_98_(16), 1–30. https://doi.org/10.18637/jss.v098.i16

preDurante, F., & Sempi, C. (2015). _Principles of copula theory_. Chapman and
Hall/CRC. https://doi.org/10.1201/b18674

preGe, H., Xu, K., & Ghahramani, Z. (2018). Turing: A language for flexible
probabilistic inference. _International Conference on Artificial Intelligence
and Statistics, AISTATS 2018, 9-11 April 2018, Playa Blanca, Lanzarote, Canary
Islands, Spain_ , 1682–1690. http://proceedings.mlr.press/v84/ge18b.html

preHofert, M., Kojadinovic, I., Maechler, M., & Yan, J. (2020). _Copula:
Multivariate dependence with copulas_.
https://CRAN.R-project.org/package=copula

preIvan Kojadinovic, & Jun Yan. (2010). Modeling multivariate distributions
with continuous margins using the copula R package. _Journal of Statistical
Software_ , _34_(9), 1–20. https://doi.org/10.18637/jss.v034.i09

preJoe, H. (1997). _Multivariate models and multivariate dependence concepts_.
CRC press. https://doi.org/10.1201/9780367803896

preJoe, H. (2014). _Dependence modeling with copulas_. CRC press.

preJun Yan. (2007). Enjoy the joy of copulas: With a package copula. _Journal
of Statistical Software_ , _21_(4), 1–21.
https://doi.org/10.18637/jss.v021.i04

preLin, D., White, J. M., Byrne, S., Bates, D., Noack, A., Pearson, J.,
Arslan, A., Squire, K., Anthoff, D., Papamarkou, T., Besançon, M.,
Drugowitsch, J., Schauer, M., & contributors, other. (2019).
_JuliaStats/Distributions.jl: a Julia package for probability distributions
and associated functions_. https://doi.org/10.5281/zenodo.2647458

preMarius Hofert, & Martin Mächler. (2011). Nested archimedean copulas meet R:
The nacopula package. _Journal of Statistical Software_ , _39_(9), 1–20.
https://doi.org/10.18637/jss.v039.i09

preMcNeil, A. J., & Nešlehová, J. (2009). Multivariate Archimedean copulas, d
-monotone functions and L1 -norm symmetric distributions. _The Annals of
Statistics_ , _37_(5B), 3059–3097. https://doi.org/10.1214/07-AOS556

preNelsen, R. B. (2006). _An introduction to copulas_ (2nd ed). Springer.
ISBN: 978-0-387-28659-4

preSklar, A. (1959). Fonction de répartition dont les marges sont données.
_Inst. Stat. Univ. Paris_ , _8_ , 229–231.

p