Skip to content

Commit

Permalink
Fix generics for cdf, \tau and \rho (#133)
Browse files Browse the repository at this point in the history
  • Loading branch information
lrnv authored Feb 9, 2024
1 parent b7baf5e commit 4e7262a
Show file tree
Hide file tree
Showing 8 changed files with 59 additions and 46 deletions.
8 changes: 5 additions & 3 deletions docs/src/dependence_measures.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,11 @@

Although the copula is an object that summarizes completely the dependence structure of any random vector, it is an infinite dimensional object and the interpretation of its properties can be difficult when the dimension gets high. Therefore, the literature has come up with some quantification of the dependence structure that might be used as univariate summaries, of course imperfect, of certain properties of the copula at hand.


!!! note "Unfinished work"
Unfortunately these dependence measures are not yet well-specified in the package and their implementation is experimental for the moment. These functions might change in the future, in particular see https://github.com/lrnv/Copulas.jl/issues/134 for future improvements.


## Kendall's Tau

> **Definition (Kendall' τ):** For a copula $C$ with a density $c$, Kendall's τ is defined as:
Expand Down Expand Up @@ -52,9 +57,6 @@ The graph of $u \to \chi(u)$ over $[\frac{1}{2},1]$ is an interesting tool to as
All these coefficients quantify the behavior of the dependence structure, generally or in the extremes, and are therefore widely used in the literature either as verification tools to assess the quality of fits, or even as parameters. Many parametric copulas families have simple surjections, injections, or even bijections between these coefficients and their parametrization, allowing matching procedures of estimation (a lot like moments matching algorithm for fitting standard random variables).
!!! note "Unfinished work"
Unfortunately these coefficients are not yet well-specified in the package and implemented for all dependence structure, there is still work to do.
```@bibliography
Pages = ["dependence_measures.md"]
Expand Down
5 changes: 0 additions & 5 deletions src/ArchimedeanCopula.jl
Original file line number Diff line number Diff line change
Expand Up @@ -131,11 +131,6 @@ end
function τ⁻¹(::Type{T},τ_val) where {T<:ArchimedeanCopula}
return τ⁻¹(generatorof(T),τ_val)
end
ρ(C::ArchimedeanCopula{d,TG}) where {d,TG} = ρ(C.G)
function ρ⁻¹(::Type{T},ρ_val) where {T<:ArchimedeanCopula}
return ρ⁻¹(generatorof(T),ρ_val)
end


################################################################################################
################ ################
Expand Down
9 changes: 7 additions & 2 deletions src/Copula.jl
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,20 @@ function Distributions.cdf(C::Copula{d},A::AbstractMatrix) where d
return [_cdf(C,u) for u in eachcol(A)]
end
function _cdf(C::CT,u) where {CT<:Copula}
if any(iszero.(u))
return zero(u[1])
elseif all(isone.(u))
return one(u[1])
end
f(x) = Distributions.pdf(C,x)
z = zeros(eltype(u),length(C))
return Cubature.pcubature(f,z,u,reltol=sqrt(eps()))[1]
return Cubature.hcubature(f,z,u,reltol=sqrt(eps()))[1]
end
function ρ(C::Copula{d}) where d
F(x) = Distributions.cdf(C,x)
z = zeros(d)
i = ones(d)
r = Cubature.pcubature(F,z,i,reltop=sqrt(eps()))[1]
r = Cubature.hcubature(F,z,i,reltol=sqrt(eps()))[1]
return 12*r-3
end
function τ(C::Copula)
Expand Down
6 changes: 3 additions & 3 deletions test/archimedean_tests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -126,9 +126,9 @@ end

@testitem "Archimedeans - Spearman correlation" begin

@test_broken Copulas.ρ(ClaytonCopula(2,3.)) 0.78645 atol=1.0e-4
@test_broken Copulas.ρ(ClaytonCopula(2,0.001)) 0. atol=1.0e-2
@test_broken Copulas.ρ(GumbelCopula(2,3.)) 0.8489 atol=1.0e-4
@test Copulas.ρ(ClaytonCopula(2,3.)) 0.78645 atol=1.0e-4
@test Copulas.ρ(ClaytonCopula(2,0.001)) 0. atol=1.0e-2
@test Copulas.ρ(GumbelCopula(2,3.)) 0.8489 atol=1.0e-4

@test_broken Copulas.ρ⁻¹(ClaytonCopula, 1/3) 0.58754 atol=1.0e-5
@test_broken Copulas.ρ⁻¹(ClaytonCopula, 0.01) 0. atol=1.0e-1
Expand Down
39 changes: 39 additions & 0 deletions test/kendall_tau_notnan.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
@testitem "Check non-nan in kendall taus and spearman rhos." begin
using Copulas, Distributions

cops = (
IndependentCopula(3),
AMHCopula(3,0.6),
AMHCopula(4,-0.3),
ClaytonCopula(2,-0.7),
ClaytonCopula(3,-0.1),
ClaytonCopula(4,7.),
FrankCopula(2,-5.),
FrankCopula(3,12.),
FrankCopula(4,6.),
FrankCopula(4,150.),
JoeCopula(3,7.),
GumbelCopula(4,7.),
GumbelCopula(4,20.),
GumbelBarnettCopula(3,0.7),
InvGaussianCopula(4,0.05),
InvGaussianCopula(3,8.),
GaussianCopula([1 0.5; 0.5 1]),
# TCopula(4, [1 0.5; 0.5 1]), # this one takes a while.
FGMCopula(2,1),
MCopula(4),
WCopula(2),
PlackettCopula(2.0),
EmpiricalCopula(randn(2,100),pseudo_values=false),
SurvivalCopula(ClaytonCopula(2,-0.7),(1,2)),
RafteryCopula(2, 0.2),
RafteryCopula(3, 0.5),
# Others ? Yes probably others too !
)

for C in cops
@show C
@test !isnan(Copulas.τ(C))
end
@test_broken Copulas.τ(ArchimedeanCopula(2,i𝒲(LogNormal(),2))) # not implemented.
end
12 changes: 2 additions & 10 deletions test/margins_uniformity.jl
Original file line number Diff line number Diff line change
Expand Up @@ -121,20 +121,12 @@
u = ones(d)
for val in [0,1,rand(rng,10)...]
u[i] = val
if typeof(C)<:TCopula
@test_broken cdf(C,u) val
else
@test cdf(C,u) val atol=1e-5
end
@test cdf(C,u) val atol=1e-5
end
# extra check for zeros:
u = rand(rng,d)
u[i] = 0
if typeof(C)<:TCopula
@test_broken cdf(C,u) val
else
@test iszero(cdf(C,u))
end
@test iszero(cdf(C,u))
end
end

Expand Down
File renamed without changes.
26 changes: 3 additions & 23 deletions test/some_tests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -48,22 +48,16 @@ end
ClaytonCopula(4,7.0),
GaussianCopula([1 0.3; 0.3 1]),
FrankCopula(5,6.0),
AMHCopula(3,0.7)
AMHCopula(3,0.7),
TCopula(4,[1 0.5; 0.5 1])
)


for C in Copula_Zoo
d = length(C)

@test cdf(C,ones(d)) 1
@test cdf(C,zeros(d)) 0
end

for C in (TCopula(4,[1 0.5; 0.5 1]),)
d = length(C)
@test_broken cdf(C,ones(d)) 1
@test_broken cdf(C,zeros(d)) 0
end
end

@testitem "pdf/cdf archimedean" begin
Expand Down Expand Up @@ -126,7 +120,7 @@ end
using StableRNGs
rng = StableRNG(123)

for C in (ClaytonCopula(4,7.0),GumbelCopula(2, 1.2))
for C in (ClaytonCopula(4,7.0),GumbelCopula(2, 1.2), TCopula(4,[1 0.5; 0.5 1]))
d = length(C)
u = zeros(d)
v = ones(d)
Expand All @@ -139,20 +133,6 @@ end
end
@test Copulas.measure(C,u,v) >= 0
end

for C in (TCopula(4,[1 0.5; 0.5 1]),)
d = length(C)
u = zeros(d)
v = ones(d)

@test_broken Copulas.measure(C,u,v) >= 0

for i in 1:d
u[i] = rand(rng)
v[i] = u[i] + rand(rng)*(1-u[i])
end
@test_broken Copulas.measure(C,u,v) >= 0
end
end


Expand Down

0 comments on commit 4e7262a

Please sign in to comment.