From 69f4f3302880aa74d6a9513c77d4cc91ae224010 Mon Sep 17 00:00:00 2001 From: Oskar Laverny Date: Tue, 24 Oct 2023 17:38:53 +0200 Subject: [PATCH 1/5] Remove AlphaStableDistributions --- Project.toml | 2 - src/ArchimedeanCopulas/GumbelCopula.jl | 2 +- src/Copulas.jl | 49 ++++++++++------- src/univariate_distributions/AlphaStable.jl | 60 +++++++++++++++++++++ 4 files changed, 91 insertions(+), 22 deletions(-) create mode 100644 src/univariate_distributions/AlphaStable.jl diff --git a/Project.toml b/Project.toml index b31aa137..7b6dabc9 100644 --- a/Project.toml +++ b/Project.toml @@ -4,7 +4,6 @@ authors = ["Oskar Laverny"] version = "0.1.11" [deps] -AlphaStableDistributions = "f20549b4-2d50-407f-863c-cdd202ba59a3" Cubature = "667455a9-e2ce-5579-9412-b964f529a492" Distributions = "31c24e10-a181-5473-b8eb-7969acd0382f" ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210" @@ -18,7 +17,6 @@ StatsBase = "2913bbd2-ae8a-5f71-8c99-4fb6c76f3a91" TaylorSeries = "6aa5eb33-94cf-58f4-a9d0-e4b2c4fc25ea" [compat] -AlphaStableDistributions = "1" Cubature = "1.5" Distributions = "0.25" ForwardDiff = "0.10" diff --git a/src/ArchimedeanCopulas/GumbelCopula.jl b/src/ArchimedeanCopulas/GumbelCopula.jl index 447072aa..9dffe04d 100644 --- a/src/ArchimedeanCopulas/GumbelCopula.jl +++ b/src/ArchimedeanCopulas/GumbelCopula.jl @@ -23,7 +23,7 @@ GumbelCopula(d,θ) = θ >= 1 ? GumbelCopula{d,typeof(θ)}(θ) : @error "Theta mu τ(C::GumbelCopula) = ifelse(isfinite(C.θ), (C.θ-1)/C.θ, 1) τ⁻¹(::Type{GumbelCopula},τ) =ifelse(τ == 1, Inf, 1/(1-τ)) -radial_dist(C::GumbelCopula) = AlphaStableDistributions.AlphaStable(α = 1/C.θ, β = 1,scale = cos(π/(2C.θ))^C.θ, location = (C.θ == 1 ? 1 : 0)) +radial_dist(C::GumbelCopula) = AlphaStable(α = 1/C.θ, β = 1,scale = cos(π/(2C.θ))^C.θ, location = (C.θ == 1 ? 1 : 0)) # S(α, β, γ , δ) denotes a stable distribution in diff --git a/src/Copulas.jl b/src/Copulas.jl index eca3ed81..d0f0943a 100644 --- a/src/Copulas.jl +++ b/src/Copulas.jl @@ -2,9 +2,9 @@ module Copulas @doc let - path = joinpath(dirname(@__DIR__), "README.md") - include_dependency(path) - read(path, String) + path = joinpath(dirname(@__DIR__), "README.md") + include_dependency(path) + read(path, String) end Copulas import Base @@ -18,7 +18,6 @@ end Copulas import ForwardDiff import Cubature import MvNormalCDF - import AlphaStableDistributions using PrecompileTools # Standard copulas and stuff. @@ -33,6 +32,7 @@ end Copulas # These three distributions might be merged in Distrbutions.jl one day. include("univariate_distributions/Sibuya.jl") include("univariate_distributions/Logarithmic.jl") + include("univariate_distributions/AlphaStable.jl") # Elliptical copulas include("EllipticalCopula.jl") @@ -64,20 +64,31 @@ end Copulas WCopula, SurvivalCopula - # PrecompileTools stuff - @setup_workload begin - biv_cops = [GaussianCopula([1 0.7; 0.7 1]), TCopula(2,[1 0.7; 0.7 1]),ClaytonCopula(2,7),JoeCopula(2,3),GumbelCopula(2,8),FrankCopula(2,0.5), AMHCopula(2,0.7)] - @compile_workload begin - for C in biv_cops - u = Random.rand(C,10) - pdf(C,[0.5,0.5]) - cdf(C,[0.5,0.5]) - D = SklarDist(C,[Gamma(1,1),Normal(1,1)]) - u = Random.rand(D,10) - pdf(D,[0.5,0.5]) - cdf(D,[0.5,0.5]) - end - end - end + # PrecompileTools stuff + @setup_workload begin + biv_cops = [ + GaussianCopula([1 0.7; 0.7 1]), + TCopula(2,[1 0.7; 0.7 1]), + ClaytonCopula(2,7), + JoeCopula(2,3), + GumbelCopula(2,8), + FrankCopula(2,0.5), + AMHCopula(2,0.7), + WCopula(2), + IndependentCopula(2), + MCopula(2) + ] + @compile_workload begin + for C in biv_cops + u = Random.rand(C,10) + pdf(C,[0.5,0.5]) + cdf(C,[0.5,0.5]) + D = SklarDist(C,[Gamma(1,1),Normal(1,1)]) + u = Random.rand(D,10) + pdf(D,[0.5,0.5]) + cdf(D,[0.5,0.5]) + end + end + end end diff --git a/src/univariate_distributions/AlphaStable.jl b/src/univariate_distributions/AlphaStable.jl new file mode 100644 index 00000000..dfd2154a --- /dev/null +++ b/src/univariate_distributions/AlphaStable.jl @@ -0,0 +1,60 @@ +########## +########## Copied from https://github.com/org-arl/AlphaStableDistributions.jl +########## To avoid too many dependencies and fasten the package. +########## Probably we can do better by integrating with them... but they use too much. +########## + +Base.@kwdef struct AlphaStable{T} <: Distributions.ContinuousUnivariateDistribution + α::T = 1.5 + β::T = zero(α) + scale::T = one(α) + location::T = zero(α) +end + +AlphaStable(α::Integer, β::Integer, scale::Integer, location::Integer) = AlphaStable(float(α), float(β), float(scale), float(location)) +function AlphaStable(α,β,scale,location) + αT,βT,scaleT,locationT = promote(α,β,scale,location) + AlphaStable(αT,βT,scaleT,locationT) +end +Distributions.params(d::AlphaStable) = (d.α, d.β, d.scale, d.location) + +""" +Generate independent stable random numbers. + +:param α: characteristic exponent (0.1 to 2.0) +:param β: skew (-1 to +1) +:param scale: scale parameter +:param loc: location parameter (mean for α > 1, median/mode when β=0) + + +This implementation is based on the method in J.M. Chambers, C.L. Mallows +and B.W. Stuck, "A Method for Simulating Stable Random Variables," JASA 71 (1976): 340-4. +McCulloch's MATLAB implementation (1996) served as a reference in developing this code. +""" +function Base.rand(rng::Distributions.AbstractRNG, d::AlphaStable{T}) where {T<:AbstractFloat} + α=d.α; β=d.β; sc=d.scale; loc=d.location + (α < 0.1 || α > 2) && throw(DomainError(α, "α must be in the range 0.1 to 2")) + abs(β) > 1 && throw(DomainError(β, "β must be in the range -1 to 1")) + # added eps(T) to prevent DomainError: x ^ y where x < 0 + ϕ = (rand(rng, T) - T(0.5)) * π * (one(T) - eps(T)) + if α == one(T) && β == zero(T) + return loc + sc * tan(ϕ) + end + w = -log(rand(rng, T)) + α == 2 && (return loc + 2*sc*sqrt(w)*sin(ϕ)) + β == zero(T) && (return loc + sc * ((cos((one(T)-α)*ϕ) / w)^(one(T)/α - one(T)) * sin(α * ϕ) / cos(ϕ)^(one(T)/α))) + cosϕ = cos(ϕ) + if abs(α - one(T)) > 1e-8 + ζ = β * tan(π * α / 2) + aϕ = α * ϕ + a1ϕ = (one(T) - α) * ϕ + return loc + sc * ((((sin(aϕ) + ζ * cos(aϕ))/cosϕ) * ((cos(a1ϕ) + ζ*sin(a1ϕ)) / (w*cosϕ))^((one(T)-α)/α))) + end + bϕ = π/2 + β*ϕ + x = 2/π * (bϕ * tan(ϕ) - β * log(π/2*w*cosϕ/bϕ)) + α == one(T) || (x += β * tan(π*α/2)) + return loc + sc * x +end + +Base.eltype(::Type{<:AlphaStable{T}}) where {T<:AbstractFloat} = T + From 3e74a5c82c8404b59303bbba9277cbad6f0697c0 Mon Sep 17 00:00:00 2001 From: Oskar Laverny Date: Wed, 25 Oct 2023 10:52:39 +0200 Subject: [PATCH 2/5] Remove precompiletools --- Project.toml | 2 -- src/Copulas.jl | 28 ---------------------------- 2 files changed, 30 deletions(-) diff --git a/Project.toml b/Project.toml index 7b6dabc9..e7d3a527 100644 --- a/Project.toml +++ b/Project.toml @@ -9,7 +9,6 @@ Distributions = "31c24e10-a181-5473-b8eb-7969acd0382f" ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210" GSL = "92c85e6c-cbff-5e0c-80f7-495c94daaecd" MvNormalCDF = "37188c8d-bc69-4638-b057-733e744175ec" -PrecompileTools = "aea7be01-6a6a-4083-8856-8a6e6704d82a" Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" Roots = "f2b01f46-fcfa-551c-844a-d8ac1e96c665" SpecialFunctions = "276daf66-3868-5448-9aa4-cd146d93841b" @@ -22,7 +21,6 @@ Distributions = "0.25" ForwardDiff = "0.10" GSL = "1" MvNormalCDF = "0.2, 0.3" -PrecompileTools = "1" Roots = "1, 2" SpecialFunctions = "2" StatsBase = "0.33, 0.34" diff --git a/src/Copulas.jl b/src/Copulas.jl index d0f0943a..2f25dbf3 100644 --- a/src/Copulas.jl +++ b/src/Copulas.jl @@ -18,7 +18,6 @@ end Copulas import ForwardDiff import Cubature import MvNormalCDF - using PrecompileTools # Standard copulas and stuff. include("utils.jl") @@ -64,31 +63,4 @@ end Copulas WCopula, SurvivalCopula - # PrecompileTools stuff - @setup_workload begin - biv_cops = [ - GaussianCopula([1 0.7; 0.7 1]), - TCopula(2,[1 0.7; 0.7 1]), - ClaytonCopula(2,7), - JoeCopula(2,3), - GumbelCopula(2,8), - FrankCopula(2,0.5), - AMHCopula(2,0.7), - WCopula(2), - IndependentCopula(2), - MCopula(2) - ] - @compile_workload begin - for C in biv_cops - u = Random.rand(C,10) - pdf(C,[0.5,0.5]) - cdf(C,[0.5,0.5]) - D = SklarDist(C,[Gamma(1,1),Normal(1,1)]) - u = Random.rand(D,10) - pdf(D,[0.5,0.5]) - cdf(D,[0.5,0.5]) - end - end - end - end From ddcbaaa2605b77201bf05bf88c907d43dfcce891 Mon Sep 17 00:00:00 2001 From: Oskar Laverny Date: Wed, 25 Oct 2023 11:18:34 +0200 Subject: [PATCH 3/5] add tests --- test/old_precompile_workflow.jl | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 test/old_precompile_workflow.jl diff --git a/test/old_precompile_workflow.jl b/test/old_precompile_workflow.jl new file mode 100644 index 00000000..92186c08 --- /dev/null +++ b/test/old_precompile_workflow.jl @@ -0,0 +1,21 @@ + +@testitem "standard functionality test" begin + biv_cops = [ + GaussianCopula([1 0.7; 0.7 1]), + TCopula(2,[1 0.7; 0.7 1]), + ClaytonCopula(2,7), + JoeCopula(2,3), + GumbelCopula(2,8), + FrankCopula(2,0.5), + AMHCopula(2,0.7) + ] + for C in biv_cops + u = Random.rand(C,10) + pdf(C,[0.5,0.5]) + cdf(C,[0.5,0.5]) + D = SklarDist(C,[Gamma(1,1),Normal(1,1)]) + u = Random.rand(D,10) + pdf(D,[0.5,0.5]) + cdf(D,[0.5,0.5]) + end +end From 1be5dfac18387e50454de383ab46c00c01509eab Mon Sep 17 00:00:00 2001 From: Oskar Laverny Date: Wed, 25 Oct 2023 11:21:27 +0200 Subject: [PATCH 4/5] typo in test --- test/old_precompile_workflow.jl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/old_precompile_workflow.jl b/test/old_precompile_workflow.jl index 92186c08..3687f200 100644 --- a/test/old_precompile_workflow.jl +++ b/test/old_precompile_workflow.jl @@ -1,5 +1,6 @@ @testitem "standard functionality test" begin + using Random, Distributions biv_cops = [ GaussianCopula([1 0.7; 0.7 1]), TCopula(2,[1 0.7; 0.7 1]), @@ -18,4 +19,5 @@ pdf(D,[0.5,0.5]) cdf(D,[0.5,0.5]) end + @test true end From 9288f337e72eb23961bcb0edfd1fbedb0a368829 Mon Sep 17 00:00:00 2001 From: Oskar Laverny Date: Wed, 25 Oct 2023 11:35:12 +0200 Subject: [PATCH 5/5] up test --- test/old_precompile_workflow.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/old_precompile_workflow.jl b/test/old_precompile_workflow.jl index 3687f200..4db0eb5d 100644 --- a/test/old_precompile_workflow.jl +++ b/test/old_precompile_workflow.jl @@ -16,8 +16,8 @@ cdf(C,[0.5,0.5]) D = SklarDist(C,[Gamma(1,1),Normal(1,1)]) u = Random.rand(D,10) - pdf(D,[0.5,0.5]) - cdf(D,[0.5,0.5]) + pdf(D,[0.5,0]) + cdf(D,[0.5,0]) end @test true end