From 54655fd76811217b91a455540e0a526c9c863aed Mon Sep 17 00:00:00 2001 From: szcf-weiya Date: Thu, 14 Dec 2023 11:32:51 -0500 Subject: [PATCH 1/5] fix typo in docstring (#101) --- src/EllipticalCopulas/GaussianCopula.jl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/EllipticalCopulas/GaussianCopula.jl b/src/EllipticalCopulas/GaussianCopula.jl index 0ff555d4..21c1d65b 100644 --- a/src/EllipticalCopulas/GaussianCopula.jl +++ b/src/EllipticalCopulas/GaussianCopula.jl @@ -9,12 +9,12 @@ Constructor GaussianCopula(Σ) The [Gaussian Copula](https://en.wikipedia.org/wiki/Copula_(probability_theory)#Gaussian_copula) is the -copula of a [Multivariate normal distribution](http://en.wikipedia.org/wiki/Multivariate_normal_distribution). It is constructed as : +copula of a [Multivariate normal distribution](http://en.wikipedia.org/wiki/Multivariate_normal_distribution). It is constructed as: ```math C(\\mathbf{x}; \\boldsymbol{\\Sigma}) = F_{\\Sigma}(F_{\\Sigma,i}^{-1}(x_i),i\\in 1,...d) ``` -where ``F_{\\Sigma}`` is a cdf of a gaussina random vector and `F_{\\Sigma,i}` is the ith marignal cdf, while ```\\Sigma`` is the covariance matrix. +where ``F_{\\Sigma}`` is a cdf of a gaussian random vector and `F_{\\Sigma,i}` is the ith marginal cdf, while ``\\Sigma`` is the covariance matrix. It can be constructed in Julia via: ```julia @@ -59,4 +59,4 @@ function _cdf(C::CT,u) where {CT<:GaussianCopula} μ = zeros(T,d) lb = repeat([T(-Inf)],d) return MvNormalCDF.mvnormcdf(μ, C.Σ, lb, x)[1] -end \ No newline at end of file +end From 8c802056daea4aab007245a60d9e0662623fe018 Mon Sep 17 00:00:00 2001 From: szcf-weiya Date: Thu, 14 Dec 2023 15:56:41 -0500 Subject: [PATCH 2/5] fix typo in formula (#102) --- docs/src/archimedean/generalities.md | 6 +++--- src/EllipticalCopula.jl | 12 ++++++------ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/docs/src/archimedean/generalities.md b/docs/src/archimedean/generalities.md index 999e1b21..249a3200 100644 --- a/docs/src/archimedean/generalities.md +++ b/docs/src/archimedean/generalities.md @@ -87,10 +87,10 @@ This transformation is implemented through one method in the Generator interface To put it in a nutshell, for ``\phi`` a ``d``-monotone archimedean generator, the inverse Williamson-d-transform of ``\\phi`` is the cumulative distribution function ``F`` of a non-negative random variable ``R``, defined by : ```math -F(x) = 𝒲_{d}^{-1}(\\phi)(x) = 1 - \\frac{(-x)^{d-1} \\phi_+^{(d-1)}(x)}{k!} - \\sum_{k=0}^{d-2} \\frac{(-x)^k \\phi^{(k)}(x)}{k!} +F(x) = 𝒲_{d}^{-1}(\phi)(x) = 1 - \frac{(-x)^{d-1} \phi_+^{(d-1)}(x)}{k!} - \sum_{k=0}^{d-2} \frac{(-x)^k \phi^{(k)}(x)}{k!} ``` -The [WilliamsonTransforms.jl](https://github.com/lrnv/WilliamsonTransforms.jl) package implements this transfromation (and its inverse, the Williamson d-transfrom) in all generality. It returns this cumulative distribution function in the form of the corresponding random variable `<:Distributions.ContinuousUnivariateDistribution` from `Distributions.jl`. You may then compute : +The [WilliamsonTransforms.jl](https://github.com/lrnv/WilliamsonTransforms.jl) package implements this transformation (and its inverse, the Williamson d-transfrom) in all generality. It returns this cumulative distribution function in the form of the corresponding random variable `<:Distributions.ContinuousUnivariateDistribution` from `Distributions.jl`. You may then compute : * The cdf via `Distributions.cdf` * The pdf via `Distributions.pdf` and the logpdf via `Distributions.logpdf` * Samples from the distribution via `rand(X,n)` @@ -139,4 +139,4 @@ ArchimedeanCopula ```@bibliography Pages = ["generalities.md"] Canonical = false -``` \ No newline at end of file +``` diff --git a/src/EllipticalCopula.jl b/src/EllipticalCopula.jl index 35265617..2a0444fa 100644 --- a/src/EllipticalCopula.jl +++ b/src/EllipticalCopula.jl @@ -4,15 +4,15 @@ This is an abstract type. It implements an interface for all Elliptical copulas. We construct internally elliptical copulas using the sklar's theorem, by considering the copula ``C`` to be defined as : ```math -C = F `\\circ (F_1^{-1},...,F_d^{-1}), +C = F \\circ (F_1^{-1},...,F_d^{-1}), ``` -where ``F`` and ``F_1,...,F_d`` are respectively the multivariate distribution function of some elliptical random vector and the univaraite distribution function of its marginals. For a type `MyCop <: EllipitcalCopula`, it is necessary to implement the following methods: +where ``F`` and ``F_1,...,F_d`` are respectively the multivariate distribution function of some elliptical random vector and the univariate distribution function of its marginals. For a type `MyCop <: EllipitcalCopula`, it is necessary to implement the following methods: -- `N(::Type{MyCOp})`, returning the constructor of the elliptical random vector from its corelation matrix. For example, `N(GaussianCopula)` simply returns `MvNormal` from `Distributions.jl`. -- `U(::Type{MyCOp})`, returning the constructor for the univariate marginal, usually in standardized form. For exemple, `U(GaussianCopula)` returns `Normal` from `Distributions.jl`. +- `N(::Type{MyCOp})`, returning the constructor of the elliptical random vector from its correlation matrix. For example, `N(GaussianCopula)` simply returns `MvNormal` from `Distributions.jl`. +- `U(::Type{MyCOp})`, returning the constructor for the univariate marginal, usually in standardized form. For example, `U(GaussianCopula)` returns `Normal` from `Distributions.jl`. -From these two functions, the abstract type provide a fully functional copula. +From these two functions, the abstract type provides a fully functional copula. # Details @@ -60,4 +60,4 @@ function make_cor!(Σ) Σ[i,j] *= σ[i] .* σ[j] end end -end \ No newline at end of file +end From 71c92be2cfb644be6d0f5782fd73c5112d1bedd1 Mon Sep 17 00:00:00 2001 From: Oskar Laverny Date: Fri, 15 Dec 2023 10:15:08 +0100 Subject: [PATCH 3/5] Update README.md --- README.md | 66 +++++++------------------------------------------------ 1 file changed, 8 insertions(+), 58 deletions(-) diff --git a/README.md b/README.md index 05464a2c..e2cf15f0 100644 --- a/README.md +++ b/README.md @@ -4,18 +4,16 @@

Stable Dev + + DOI
Project Status: Active – The project has reached a stable, usable state and is being actively developed. Build Status -
Aqua QA
- License: MIT - DOI -
ColPrac: Contributor's Guide on Collaborative Practices for Community Packages Code Style: Blue

@@ -38,14 +36,14 @@ The package revolves around two main types: **Warning: This is fairly experimental work and our API might change without notice.** -## Instalation +## Getting started + +The package is registered in Julia's General registry so you may simply install the package by running : ```julia ] add Copulas ``` -## Usage - The API contains random number generation, cdf and pdf evaluation, and the `fit` function from `Distributions.jl`. A typical use case might look like this: ```julia @@ -64,61 +62,13 @@ D̂ = fit(SklarDist{FrankCopula,Tuple{Gamma,Normal,LogNormal}}, simu) # Increase the number of observations to get a beter fit (or not?) ``` -Available copula families are: -- `EllipticalCopulas`: `GaussianCopula` and `TCopula` -- `ArchimedeanCopula`: `WilliamsonCopula` (for any generator), but also `ClaytonCopula`,`FrankCopula`, `AMHCopula`, `JoeCopula`, `GumbelCopula`, supporting the full ranges in every dimensions (e.g. ClaytonCopula can be sampled with negative dependence in any dimension, not just d=2). -- `WCopula`, `IndependentCopula` and `MCopula`, which are [Fréchet-Hoeffding bounds](https://en.wikipedia.org/wiki/Copula_(probability_theory)#Fr%C3%A9chet%E2%80%93Hoeffding_copula_bounds), -- `PlackettCopula`, see ref? -- `EmpiricalCopula` to follow closely a given dataset. - -The next ones to be implemented will probably be: -- Extreme values copulas. -- Nested archimedeans (for any generators, with automatic nesting conditions checking). -- Bernstein copula and more general Beta copula as smoothing of the Empirical copula. -- `CheckerboardCopula` (and more generally `PatchworkCopula`) - -Adding a new `ArchimedeanCopula` is very easy. The `Clayton` implementation is as short as: - -```julia -struct ClaytonCopula{d,T} <: Copulas.ArchimedeanCopula{d} - θ::T -end -ClaytonCopula(d,θ) = ClaytonCopula{d,typeof(θ)}(θ) # Constructor -ϕ(C::ClaytonCopula, t) = (1+sign(C.θ)*t)^(-1/C.θ) # Generator -ϕ⁻¹(C::ClaytonCopula,t) = sign(C.θ)*(t^(-C.θ)-1) # Inverse Generator -τ(C::ClaytonCopula) = C.θ/(C.θ+2) # θ -> τ -τ⁻¹(::Type{ClaytonCopula},τ) = 2τ/(1-τ) # τ -> θ -williamson_dist(C::ClaytonCopula{d,T}) where {d,T} = WilliamsonFromFrailty(Distributions.Gamma(1/C.θ,1),d) # Radial distribution -``` -The Archimedean API is modular: - -- To sample an archimedean, only `ϕ` is required. Indeed, the `williamson_dist` has a generic fallback that uses [WilliamsonTransforms.jl](https://www.github.com/lrnv/WilliamsonTransforms.jl) for any generator. Note however that providing the `williamson_dist` yourself if you know it will allow sampling to be an order of magnitude faster. -- To evaluate the cdf and (log-)density in any dimension, only `ϕ` and `ϕ⁻¹` are needed. -- Currently, to fit the copula `τ⁻¹` is needed as we use the inverse tau moment method. But we plan on also implementing inverse rho and MLE (density needed). -- Note that the generator `ϕ` follows the convention `ϕ(0)=1`, while others (e.g., https://en.wikipedia.org/wiki/Copula_(probability_theory)#Archimedean_copulas) use `ϕ⁻¹` as the generator. - -Please take a look at the [documentation](https://lrnv.github.io/Copulas.jl/dev) for more details. - -## Dev Roadmap - -**Next:** -- [ ] More documentation and tests for the current implementation. -- [ ] Docs: show how to use the WilliamsonCopula to implement generic archimedeans. -- [ ] Give the user the choice of fitting method via `fit(dist,data; method="MLE")` or `fit(dist,data; method="itau")` or `fit(dist,data; method="irho")`. -- [ ] Fitting a generic archimedean with an empirically produced generarator -- [ ] Automatic checking of generator d-monotonicity ? Dunno if it is even possible. +The list of availiable copula models is *very* large, check it out on our [documentation](https://lrnv.github.io/Copulas.jl/stable) ! -**Maybe later:** -- [ ] `NestedArchimedean`, with automatic checking of nesting conditions for generators. -- [ ] `Vines`? -- [ ] `Archimax` ? -- [ ] `BernsteinCopula` and `BetaCopula` could also be implemented. -- [ ] `PatchworkCopula` and `CheckerboardCopula`: could be nice things to have :) -- [ ] Goodness of fits tests ? +The general implementation philosophy is for the code to follow the mathematical boundaries of the implemented concepts. In particular, this is the only implementation in any language that allows for **all** Archimedean copulas to be sampled: we simply use the Williamson transformation for non-standard generators, you may even give you generator as a black-box function ! ## Contributions are welcome -If you want to contribute to the package, found a bug in it or simply want to chat, do not hesitate to open an issue on this repo. +If you want to contribute to the package, found a bug in it or simply want to chat, do not hesitate to open an issue and chat! ## Citation From 132c134189c60d800d6c68835723bb97f3e21586 Mon Sep 17 00:00:00 2001 From: Oskar Laverny Date: Fri, 15 Dec 2023 10:18:12 +0100 Subject: [PATCH 4/5] Update README.md (#104) --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index e2cf15f0..45424aa2 100644 --- a/README.md +++ b/README.md @@ -72,6 +72,8 @@ If you want to contribute to the package, found a bug in it or simply want to ch ## Citation +Do not hesitate to star this repository to show support ! You may also cite the package by using the following bibtex code: + ```bibtex @software{oskar_laverny_2023_10084669, author = {Oskar Laverny}, From 15be93bc14da9dd0b83ad487dfb85bb606704954 Mon Sep 17 00:00:00 2001 From: Oskar Laverny Date: Sat, 16 Dec 2023 08:38:03 +0100 Subject: [PATCH 5/5] Update README.md --- README.md | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 45424aa2..7261bfcc 100644 --- a/README.md +++ b/README.md @@ -22,12 +22,11 @@ Open in GitHub Codespaces

--> -`Copulas.jl` brings most standard [copula](https://en.wikipedia.org/wiki/Copula_(probability_theory)) features into native Julia: random number generation, pdf and cdf, fitting, copula-based multivariate distributions through Sklar's theorem, etc. Since copulas are distribution functions, we fully comply with the [`Distributions.jl`](https://github.com/JuliaStats/Distributions.jl) API. This complience allows interoperability with other packages based on this API such as, e.g., [`Turing.jl`](https://github.com/TuringLang/Turing.jl). +`Copulas.jl` brings most standard [copula](https://en.wikipedia.org/wiki/Copula_(probability_theory)) features into native Julia: random number generation, pdf and cdf, fitting, copula-based multivariate distributions through Sklar's theorem, etc. Since copulas are distribution functions, we fully comply with the [`Distributions.jl`](https://github.com/JuliaStats/Distributions.jl) API. This allows interoperability with the broader ecosystem, based on this API, such as, e.g., [`Turing.jl`](https://github.com/TuringLang/Turing.jl). -Usually, people that use and work with copulas turn to R, because of the amazing `R` package [`copula`](https://cran.r-project.org/web/packages/copula/copula.pdf). -While it is still well maintained and regularly updated, the `R` package `copula` is a mixture of obscure, heavily optimized `C` code and more standard `R` code, which makes it a complicated code base for readability, extensibility, reliability and maintenance. +Usually, people that use and work with copulas turn to R, because of the amazing package [`R::copula`](https://cran.r-project.org/web/packages/copula/copula.pdf). While well-maintained and regularly updated, `R::copula` is a mixture of obscure, heavily optimized `C` code and more standard `R` code, which makes it a complicated code base for readability, extensibility, reliability and maintenance. -This is an attempt to provide a very light, fast, reliable and maintainable copula implementation in native Julia. Among others, one of the notable benefits of such a native implementatioon is the floating point type agnosticity, i.e. compatibility with `BigFloat`, [`DoubleFloats`](https://github.com/JuliaMath/DoubleFloats.jl), [`MultiFloats`](https://github.com/dzhang314/MultiFloats.jl) and other kind of numbers. +This is an attempt to provide a very light, fast, reliable and maintainable copula implementation in native Julia. One of the notable benefits of such a native implementation (among others) is the floating point type agnosticity, i.e. compatibility with `BigFloat`, [`DoubleFloats`](https://github.com/JuliaMath/DoubleFloats.jl), [`MultiFloats`](https://github.com/dzhang314/MultiFloats.jl), etc. The package revolves around two main types: @@ -54,21 +53,20 @@ X₃ = LogNormal(0,1) C = ClaytonCopula(3,0.7) # A 3-variate Clayton Copula with θ = 0.7 D = SklarDist(C,(X₁,X₂,X₃)) # The final distribution -# This generates a (3,1000)-sized dataset from the multivariate distribution D -simu = rand(D,1000) +simu = rand(D,1000) # Generate a dataset -# While the following estimates the parameters of the model from a dataset: +# You may estimate a copula using the `fit` function: D̂ = fit(SklarDist{FrankCopula,Tuple{Gamma,Normal,LogNormal}}, simu) # Increase the number of observations to get a beter fit (or not?) ``` The list of availiable copula models is *very* large, check it out on our [documentation](https://lrnv.github.io/Copulas.jl/stable) ! -The general implementation philosophy is for the code to follow the mathematical boundaries of the implemented concepts. In particular, this is the only implementation in any language that allows for **all** Archimedean copulas to be sampled: we simply use the Williamson transformation for non-standard generators, you may even give you generator as a black-box function ! +The general implementation philosophy is for the code to follow the mathematical boundaries of the implemented concepts. For example, this is the only implementation we know (in any language) that allows for **all** Archimedean copulas to be sampled: we use the Williamson transformation for non-standard generators, including user-provided black-box ones. ## Contributions are welcome -If you want to contribute to the package, found a bug in it or simply want to chat, do not hesitate to open an issue and chat! +If you want to contribute to the package, found a bug in it or simply want to chat, simply open an issue! ## Citation