[ANN] Copulas.jl : A fully `Distributions.jl`-compliant copula package

I’m not much involved, I just fixed a few things that were bothering me the other week and then decided that a more general package might be needed. However:

  • DatagenCopulaBased.jl is for the moment much better tested than Copulas.jl, therefore I’ll recommend to keep using it for now (and open issues / PR onto Copulas.jl for missing features if you have time / want, you’ll always be welcome :slight_smile: ). Hopefully in the few next months, the testing and feature levels of Copulas.jl will increase and allow you to switch over.

  • The main difference between the two is that DatagenCopulaBased.jl, as its name suggests, only provides random number generations, while Copulas.jl provides full interactivity with Distributions.jl’s methods, which allows to use Distributions.fit(), and possibility to interact with the broader ecosystem such as Turing.jl, StatsPlots.jl etc. There is also the new SklarDist{} type, which is also a Distributions.jl-complient type which is AFAIK completely new in the ecosystem.


PS: There are also more copulas available in DatagenCopulaBased. One of my goals is indeed parity, which will come someday, some of the code will be ported from one package to the other soon.


PPS: The SklarDist construct allows you to do stuff as :

julia> MyDist = SklarDist(SurvivalCopula(FrankCopula(4,7),(2,4)),(LogNormal(),Pareto(),Gamma(),Normal()));

julia> data = rand(MyDist,1000)
4×1000 Matrix{Float64}:
  2.35294     0.457584    2.44058   0.840622   1.81306   0.630984  …   2.22521     0.496158  0.525926   0.701049  0.87533      4.92817
  1.47767    42.4113      1.55615  14.7199     1.75489   1.01644      13.6979     80.3027    1.40588    1.51737   1.40788      1.16863
  3.40522     0.0811707   2.19233   0.154554   2.5537    0.342503      0.0466783   0.134426  0.943388   0.853033  0.557026     1.49137
 -0.0871605   1.1993     -2.18685   0.626663  -0.553239  0.133756      0.668708    0.81423   0.271098  -0.295031  0.00926165  -0.891382

julia> MyCop = SurvivalCopula{4,ClaytonCopula,(2,4)};

julia> MyMarginals = Tuple{LogNormal,Pareto,Gamma,Normal};

julia> fitted_model = fit(SklarDist{MyCop,MyMarginals},data)

Which works correctly, and estimates the Copula, taking into acount the fact that it is Survival in dimensions 2 and 4, (meaning that the pseudo-observations are flipped), together with the margins. I think SklarDist{Cop,Margins} is the right name for this distribution.

You could also prefer to keep the empirical copula in the multivariate distribution, which you can easily do via :

julia> MyCop = EmpiricalCopula;

julia> fitted_model = fit(SklarDist{MyCop,MyMarginals},data)
3 Likes