Skip to content

Commit

Permalink
Add major precompile workflow
Browse files Browse the repository at this point in the history
  • Loading branch information
lrnv committed Dec 4, 2023
1 parent 458866b commit c9046d2
Show file tree
Hide file tree
Showing 8 changed files with 70 additions and 22 deletions.
2 changes: 2 additions & 0 deletions Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210"
InteractiveUtils = "b77e0a4c-d291-57a0-90e8-8db25a27a240"
LogExpFunctions = "2ab3a3ac-af41-5b50-aa03-7779005ae688"
MvNormalCDF = "37188c8d-bc69-4638-b057-733e744175ec"
PrecompileTools = "aea7be01-6a6a-4083-8856-8a6e6704d82a"
QuadGK = "1fd47b50-473d-5c70-9696-f719f8f3bcdc"
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
Roots = "f2b01f46-fcfa-551c-844a-d8ac1e96c665"
Expand All @@ -30,6 +31,7 @@ InteractiveUtils = "1.6"
LinearAlgebra = "1.6"
LogExpFunctions = "0.3"
MvNormalCDF = "0.2, 0.3"
PrecompileTools = "1"
QuadGK = "2"
Random = "1.6"
Roots = "1, 2"
Expand Down
6 changes: 3 additions & 3 deletions src/ArchimedeanCopula.jl
Original file line number Diff line number Diff line change
Expand Up @@ -192,18 +192,18 @@ function Distributions._rand!(rng::Distributions.AbstractRNG, ::ArchimedeanCopul
x[1] = rand(rng)
x[2] = 1-x[1]
end
function Distributions._rand!(rng::Distributions.AbstractRNG, C::ArchimedeanCopula{d,IndependentGenerator}, A::DenseMatrix{T}) where {T<:Real, d}
function Distributions._rand!(rng::Distributions.AbstractRNG, ::ArchimedeanCopula{d,IndependentGenerator}, A::DenseMatrix{T}) where {T<:Real, d}
Random.rand!(rng,A)
return A
end
function Distributions._rand!(rng::Distributions.AbstractRNG, C::ArchimedeanCopula{d,MGenerator}, A::DenseMatrix{T}) where {T<:Real, d}
function Distributions._rand!(rng::Distributions.AbstractRNG, ::ArchimedeanCopula{d,MGenerator}, A::DenseMatrix{T}) where {T<:Real, d}
A[1,:] .= rand(rng,size(A,2))
for i in 2:size(A,1)
A[i,:] .= A[1,:]
end
return A
end
function Distributions._rand!(rng::Distributions.AbstractRNG, C::ArchimedeanCopula{d,WGenerator}, A::DenseMatrix{T}) where {T<:Real, d}
function Distributions._rand!(rng::Distributions.AbstractRNG, ::ArchimedeanCopula{d,WGenerator}, A::DenseMatrix{T}) where {T<:Real, d}
@assert size(A,1) == 2
A[1,:] .= rand(rng,size(A,2))
A[2,:] .= 1 .- A[1,:]
Expand Down
7 changes: 4 additions & 3 deletions src/Copula.jl
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,13 @@ Base.length(::Copula{d}) where d = d
# Base.eltype
# τ, τ⁻¹
# Base.eltype
function Distributions.cdf(C::Copula{d},u::AbstractVector) where d
length(u) != length(C) && throw(ArgumentError("Dimension mismatch between copula and input vector"))
function Distributions.cdf(C::Copula{d},u::VT) where {d,VT<:AbstractVector}
length(u) != d && throw(ArgumentError("Dimension mismatch between copula and input vector"))
return _cdf(C,u)
end
function Distributions.cdf(C::Copula{d},A::AbstractMatrix) where d
return [Distributions.cdf(C,u) for u in eachcol(A)]
size(A,1) != d && throw(ArgumentError("Dimension mismatch between copula and input vector"))
return [_cdf(C,u) for u in eachcol(A)]
end
function _cdf(C::CT,u) where {CT<:Copula}
f(x) = Distributions.pdf(C,x)
Expand Down
63 changes: 53 additions & 10 deletions src/Copulas.jl
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,7 @@ module Copulas
include("MiscellaneousCopulas/EmpiricalCopula.jl")
include("MiscellaneousCopulas/FGMCopula.jl")
include("MiscellaneousCopulas/RafteryCopula.jl")
export MCopula,
WCopula,
SurvivalCopula,
export SurvivalCopula,
PlackettCopula,
EmpiricalCopula,
FGMCopula,
Expand All @@ -57,7 +55,6 @@ module Copulas

include("Generator/WilliamsonGenerator.jl")
export WilliamsonGenerator, i𝒲

include("Generator/ZeroVariateGenerator/IndependentGenerator.jl")
include("Generator/ZeroVariateGenerator/MGenerator.jl")
include("Generator/ZeroVariateGenerator/WGenerator.jl")
Expand All @@ -72,15 +69,61 @@ module Copulas
# Archimedean copulas
include("ArchimedeanCopula.jl")
export ArchimedeanCopula,
IndependentCopula,
IndependentCopula,
MCopula,
WCopula,
AMHCopula,
ClaytonCopula,
JoeCopula,
GumbelCopula,
FrankCopula,
AMHCopula,
GumbelBarnettCopula,
GumbelCopula,
InvGaussianCopula,
MCopula,
WCopula
JoeCopula



using PrecompileTools
@setup_workload begin
# Putting some things in `@setup_workload` instead of `@compile_workload` can reduce the size of the
# precompile file and potentially make loading faster.
@compile_workload begin
for C in (
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),
JoeCopula(3,7),
GumbelCopula(4,7),
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]),
FGMCopula(2,1),
MCopula(4),
ArchimedeanCopula(2,Copulas.i𝒲(Distributions.LogNormal(),2)),
PlackettCopula(2.0),
EmpiricalCopula(randn(2,100),pseudo_values=false),
SurvivalCopula(ClaytonCopula(2,-0.7),(1,2)),
# WCopula(2), ################ <<<<<<<<<-------------- Does not work and I cannot explain why !
# RafteryCopula(2, 0.2), ################ <<<<<<<<<<------------- BUGGY
# RafteryCopula(3, 0.5), ################ <<<<<<<<<<------------- BUGGY
# We should probably add others to speed up again.
)
u1 = rand(C)
u = rand(C,2)
if applicable(Distributions.pdf,C,u1) && !(typeof(C)<:EmpiricalCopula)
Distributions.pdf(C,u1)
Distributions.pdf(C,u)
end
Distributions.cdf(C,u1)
Distributions.cdf(C,u)
end
end
end

end
7 changes: 3 additions & 4 deletions src/Generator/UnivariateGenerator/GumbelBarnettGenerator.jl
Original file line number Diff line number Diff line change
Expand Up @@ -36,15 +36,14 @@ struct GumbelBarnettGenerator{T} <: UnivariateGenerator
end
max_monotony(G::GumbelBarnettGenerator) = Inf
ϕ( G::GumbelBarnettGenerator, t) = exp((1-exp(t))/G.θ)
ϕ⁻¹(G::GumbelBarnettGenerator, t) = log(1-G.θ*log(t))
ϕ⁻¹(G::GumbelBarnettGenerator, t) = log1p(-G.θ*log(t))
# ϕ⁽¹⁾(G::GumbelBarnettGenerator, t) = # First derivative of ϕ
# ϕ⁽ᵏ⁾(G::GumbelBarnettGenerator, k, t) = # kth derivative of ϕ

function τ(G::GumbelBarnettGenerator)
# Use a numerical integration method to obtain tau
result, _ = QuadGK.quadgk(x -> -((x-G.θ*x*log(x))*log(1-G.θ*log(x))/G.θ), 0, 1)

return 1+4*result
r, _ = QuadGK.quadgk(x -> (1-G.θ*log(x)) * log1p(-G.θ*log(x)) * x, 0, 1)
return 1-4*r/G.θ
end
function τ⁻¹(::Type{T}, tau) where T<:GumbelBarnettGenerator
if tau == 0
Expand Down
3 changes: 3 additions & 0 deletions src/MiscellaneousCopulas/EmpiricalCopula.jl
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ end
function _cdf(C::EmpiricalCopula{d,MT},u) where {d,MT}
return StatsBase.mean(all(C.u .<= u,dims=1)) # might not be very efficient implementation.
end
function Distributions._logpdf(C::EmpiricalCopula{d,MT}, u) where {d,MT}
any(C.u .== u) ? -log(size(C.u,2)) : -Inf
end
function Distributions._rand!(rng::Distributions.AbstractRNG, C::EmpiricalCopula{d,MT}, x::AbstractVector{T}) where {d,MT,T<:Real}
x .= C.u[:,Distributions.rand(rng,axes(C.u,2),1)[1]]
end
Expand Down
2 changes: 1 addition & 1 deletion src/MiscellaneousCopulas/FGMCopula.jl
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ end
function _cdf(fgm::FGMCopula, u::Vector{T}) where {T}
return prod(u) * (1 + _reduce_over_combinations(fgm, 1 .-u, prod))
end
function Distributions._logpdf(fgm::FGMCopula, u::Vector{T}) where {T}
function Distributions._logpdf(fgm::FGMCopula, u)
return log1p(_reduce_over_combinations(fgm, 1 .-2u, prod))
end
function Distributions._rand!(rng::Distributions.AbstractRNG, fgm::FGMCopula{d,Tθ}, x::AbstractVector{T}) where {d,Tθ, T <: Real}
Expand Down
2 changes: 1 addition & 1 deletion test/margins_uniformity.jl
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@
if typeof(C)<:TCopula
@test_broken cdf(C,u) val
else
@test cdf(C,u) val
@test cdf(C,u) val atol=1e-5
end
end
# extra check for zeros:
Expand Down

0 comments on commit c9046d2

Please sign in to comment.