Skip to content

Commit 90960b2

Browse files
authored
Merge pull request #47 from org-arl/fix-rand
Fix bugs
2 parents f5b082c + 8ed5754 commit 90960b2

File tree

3 files changed

+54
-42
lines changed

3 files changed

+54
-42
lines changed

Project.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
name = "AlphaStableDistributions"
22
uuid = "f20549b4-2d50-407f-863c-cdd202ba59a3"
33
authors = ["Fredrik Bagge Carlson", "Too Yuen Min"]
4-
version = "1.1.5"
4+
version = "1.1.6"
55

66
[deps]
77
Distributions = "31c24e10-a181-5473-b8eb-7969acd0382f"

src/AlphaStableDistributions.jl

Lines changed: 32 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -172,22 +172,22 @@ const ϕ₃ = [
172172
1.908 1.908 1.908 1.908 1.908
173173
]
174174
const ϕ₅ = [
175-
0.0 0.0 0.0 0.0 0.0
176-
0.0 -0.017 -0.032 -0.049 -0.064
177-
0.0 -0.030 -0.061 -0.092 -0.123
178-
0.0 -0.043 -0.088 -0.132 -0.179
179-
0.0 -0.056 -0.111 -0.170 -0.232
180-
0.0 -0.066 -0.134 -0.206 -0.283
181-
0.0 -0.075 -0.154 -0.241 -0.335
182-
0.0 -0.084 -0.173 -0.276 -0.390
183-
0.0 -0.090 -0.192 -0.310 -0.447
184-
0.0 -0.095 -0.208 -0.346 -0.508
185-
0.0 -0.098 -0.223 -0.383 -0.576
186-
0.0 -0.099 -0.237 -0.424 -0.652
187-
0.0 -0.096 -0.250 -0.469 -0.742
188-
0.0 -0.089 -0.262 -0.520 -0.853
189-
0.0 -0.078 -0.272 -0.581 -0.997
190-
0.0 -0.061 -0.279 -0.659 -1.198
175+
0.0 -0.061 -0.279 -0.659 -1.198
176+
0.0 -0.078 -0.272 -0.581 -0.997
177+
0.0 -0.089 -0.262 -0.52 -0.853
178+
0.0 -0.096 -0.25 -0.469 -0.742
179+
0.0 -0.099 -0.237 -0.424 -0.652
180+
0.0 -0.098 -0.223 -0.383 -0.576
181+
0.0 -0.095 -0.208 -0.346 -0.508
182+
0.0 -0.09 -0.192 -0.31 -0.447
183+
0.0 -0.084 -0.173 -0.276 -0.39
184+
0.0 -0.075 -0.154 -0.241 -0.335
185+
0.0 -0.066 -0.134 -0.206 -0.283
186+
0.0 -0.056 -0.111 -0.17 -0.232
187+
0.0 -0.043 -0.088 -0.132 -0.179
188+
0.0 -0.03 -0.061 -0.092 -0.123
189+
0.0 -0.017 -0.032 -0.049 -0.064
190+
0.0 0.0 0.0 0.0 0.0
191191
]
192192

193193
"""
@@ -221,7 +221,7 @@ function Distributions.fit(::Type{<:AlphaStable}, x::AbstractArray{T}, alg=Quick
221221
c = (p[6]-p[2]) / itp₃(α, abs(β))
222222
itp₄ = interpolate((_α, _β), ϕ₅, Gridded(Linear()))
223223
ζ = p[4] + c * sign(β) * itp₄(α, abs(β))
224-
if abs- 1.0) < 0.1
224+
if abs- 1.0) < 0.05
225225
δ = ζ
226226
else
227227
δ = ζ - β * c * tan*α/2)
@@ -237,6 +237,7 @@ end
237237
Distributions.params(d::SymmetricAlphaStable) = (d.α, d.scale, d.location)
238238
Distributions.cf(d::SymmetricAlphaStable, t::Real) = cf(AlphaStable(d), t)
239239
Random.rand(rng::AbstractRNG, d::SymmetricAlphaStable) = rand(rng, AlphaStable(d))
240+
Base.eltype(::Type{<:SymmetricAlphaStable{T}}) where {T<:AbstractFloat} = T
240241

241242
function AlphaStable(d::SymmetricAlphaStable)
242243
AlphaStable=d.α,scale=d.scale,location=d.location)
@@ -290,29 +291,29 @@ This implementation is based on the method in J.M. Chambers, C.L. Mallows
290291
and B.W. Stuck, "A Method for Simulating Stable Random Variables," JASA 71 (1976): 340-4.
291292
McCulloch's MATLAB implementation (1996) served as a reference in developing this code.
292293
"""
293-
function Base.rand(rng::AbstractRNG, d::AlphaStable{T}) where {T<:AbstractFloat}
294-
α=d.α; β=d.β; scale=d.scale; loc=d.location
294+
function Base.rand(rng::AbstractRNG, d::AlphaStable{T}) where {T<:AbstractFloat}
295+
α=d.α; β=d.β; sc=d.scale; loc=d.location
295296
< 0.1 || α > 2) && throw(DomainError(α, "α must be in the range 0.1 to 2"))
296297
abs(β) > 1 && throw(DomainError(β, "β must be in the range -1 to 1"))
297-
ϕ = (rand(rng, T) - 0.5) * π
298+
# added eps(T) to prevent DomainError: x ^ y where x < 0
299+
ϕ = (rand(rng, T) - T(0.5)) * π * (one(T) - eps(T))
298300
if α == one(T) && β == zero(T)
299-
return loc + scale * tan(ϕ)
301+
return loc + sc * tan(ϕ)
300302
end
301303
w = -log(rand(rng, T))
302-
α == 2 && (return loc + 2*scale*sqrt(w)*sin(ϕ))
303-
β == zero(T) && (return loc + scale * ((cos((1-α)*ϕ) / w)^(one(T)/α - one(T)) * sin* ϕ) / cos(ϕ)^(one(T)/α)))
304+
α == 2 && (return loc + 2*sc*sqrt(w)*sin(ϕ))
305+
β == zero(T) && (return loc + sc * ((cos((one(T)-α)*ϕ) / w)^(one(T)/α - one(T)) * sin* ϕ) / cos(ϕ)^(one(T)/α)))
304306
cosϕ = cos(ϕ)
305307
if abs- one(T)) > 1e-8
306308
ζ = β * tan* α / 2)
307309
= α * ϕ
308310
a1ϕ = (one(T) - α) * ϕ
309-
return loc + scale * (( (sin(aϕ) + ζ * cos(aϕ))/cosϕ * ((cos(a1ϕ) + ζ*sin(a1ϕ))) / ((w*cosϕ)^((1-α)/α)) ))
311+
return loc + sc * ((((sin(aϕ) + ζ * cos(aϕ))/cosϕ) * ((cos(a1ϕ) + ζ*sin(a1ϕ)) / (w*cosϕ))^((one(T)-α)/α)))
310312
end
311313
= π/2 + β*ϕ
312314
x = 2/π * (bϕ * tan(ϕ) - β * log/2*w*cosϕ/bϕ))
313315
α == one(T) || (x += β * tan*α/2))
314-
315-
return loc + scale * x
316+
return loc + sc * x
316317
end
317318

318319
Base.eltype(::Type{<:AlphaStable{T}}) where {T<:AbstractFloat} = T
@@ -466,10 +467,10 @@ with memory", Signal Processing, Volume 131, Pages 271-279, 2017.
466467
"""
467468
function Distributions.fit(d::Type{<:AlphaSubGaussian}, x::AbstractVector{T}, m::Integer; p=one(T)) where T
468469
d1 = fit(AlphaStable, x)
469-
α = d1.α; scale=d1.scale
470+
α = d1.α; sc=d1.scale
470471
cov = zeros(T, m+1, m+1)
471472
xlen = length(x)
472-
c = ((sum(x->abs(x)^p, x)/xlen)^(1/p))/scale
473+
c = ((sum(x->abs(x)^p, x)/xlen)^(1/p))/sc
473474
for i in 1:m
474475
tempxlen = xlen-mod(xlen, i)
475476
xtemp = reshape(x[1:end-mod(xlen, i)], i, tempxlen÷i)
@@ -478,11 +479,11 @@ function Distributions.fit(d::Type{<:AlphaSubGaussian}, x::AbstractVector{T}, m:
478479
tempxlen = size(xtemp, 1)*size(xtemp, 2)
479480
end
480481
xtemp = reshape(xtemp', 2, tempxlen÷2)
481-
@views r = (2/(c^p))*(scale^(2-p))*(xtemp[1, :]'*((sign.(xtemp[2, :]).*(abs.(xtemp[2, :]).^(p-1)))))/(tempxlen/2)
482+
@views r = (2/(c^p))*(sc^(2-p))*(xtemp[1, :]'*((sign.(xtemp[2, :]).*(abs.(xtemp[2, :]).^(p-1)))))/(tempxlen/2)
482483
cov[diagind(cov, i)] .+= r
483484
end
484-
cov = (cov+cov')+2*(scale^2)*I(m+1)
485-
cov ./= 2*scale^2
485+
cov = (cov+cov')+2*(sc^2)*I(m+1)
486+
cov ./= 2*sc^2
486487
AlphaSubGaussian=α, R=cov, n=length(x))
487488
end
488489

test/runtests.jl

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -76,20 +76,31 @@ end
7676
sampletypes = [Float32,Float64]
7777
stabletypes = [AlphaStable,SymmetricAlphaStable]
7878
αs = [0.6:0.1:2,1:0.1:2]
79+
betas = [-1:0.5:1,0.0]
80+
sc = 2.0
7981
for sampletype sampletypes
8082
for (i, stabletype) in enumerate(stabletypes)
8183
for α in αs[i]
82-
d1 = AlphaStable=sampletype(α))
83-
s = rand(rng,d1, 200000)
84-
@test eltype(s) == sampletype
84+
for β in betas[i]
85+
d1 = if stabletype == AlphaStable
86+
stabletype=sampletype(α), β=sampletype(β), scale=sampletype(sc))
87+
else
88+
stabletype=sampletype(α), scale=sampletype(sc))
89+
end
90+
s = rand(rng, d1, 10^6)
91+
@test eltype(s) == sampletype
8592

86-
d2 = fit(stabletype, s)
87-
@test typeof(d2.α) == sampletype
93+
d2 = fit(stabletype, s)
94+
@test typeof(d2.α) == sampletype
8895

89-
@test d1.α d2.α rtol=0.1
90-
stabletype != SymmetricAlphaStable && @test d1.β d2.β atol=0.2
91-
@test d1.scale d2.scale rtol=0.1
92-
@test d1.location d2.location atol=0.1
96+
@test d1.α d2.α rtol=0.1
97+
if (stabletype != SymmetricAlphaStable) &&!= 2)
98+
@test d1.β d2.β atol=0.2
99+
end
100+
# the quantile method is less accurate
101+
@test d1.scale d2.scale rtol=0.2 * sc
102+
@test d1.location d2.location atol=0.9 * sc
103+
end
93104
end
94105

95106
xnormal = rand(rng,Normal(3.0, 4.0), 96000)
@@ -119,7 +130,7 @@ end
119130
@test d3.α α rtol=0.2
120131
@test d3.β 0 atol=0.2
121132
@test d3.scale 1 rtol=0.2
122-
@test d3.location 0 atol=0.1
133+
@test d3.location 0 atol=0.2
123134
end
124135

125136
d4 = AlphaSubGaussian=1.5, n=96000)

0 commit comments

Comments
 (0)