@@ -14,6 +14,8 @@ Base.@kwdef struct AlphaStable{T} <: Distributions.ContinuousUnivariateDistribut
14
14
location:: T = zero (α)
15
15
end
16
16
17
+ AlphaStable (α:: Integer , β:: Integer , scale:: Integer , location:: Integer ) = AlphaStable (float (α), float (β), float (scale), float (location))
18
+
17
19
18
20
# sampler(d::AlphaStable) = error("Not implemented")
19
21
# pdf(d::AlphaStable, x::Real) = error("Not implemented")
@@ -186,7 +188,7 @@ skewness parameter, scale parameter (dispersion^1/α) and location parameter res
186
188
187
189
α, β, c and δ are computed based on McCulloch (1986) fractile.
188
190
"""
189
- function Distributions. fit (:: Type{<:AlphaStable} , x, alg= QuickSort)
191
+ function Distributions. fit (:: Type{<:AlphaStable} , x:: AbstractArray{T} , alg= QuickSort) where {T <: AbstractFloat }
190
192
sx = sort (x, alg= alg)
191
193
p = quantile .(Ref (sx), (0.05 , 0.25 , 0.28 , 0.5 , 0.72 , 0.75 , 0.95 ), sorted= true )
192
194
να = (p[7 ]- p[1 ]) / (p[6 ]- p[2 ])
@@ -210,7 +212,7 @@ function Distributions.fit(::Type{<:AlphaStable}, x, alg=QuickSort)
210
212
else
211
213
δ = ζ - β * c * tan (π* α/ 2 )
212
214
end
213
- return AlphaStable (α= α , β= β , scale= c , location= oftype (α, δ))
215
+ return AlphaStable (α= T (α) , β= T (β) , scale= T (c) , location= T ( δ))
214
216
end
215
217
216
218
Base. @kwdef struct SymmetricAlphaStable{T} <: Distributions.ContinuousUnivariateDistribution
@@ -233,12 +235,12 @@ returns `SymmetricAlphaStable`
233
235
scale is computed based on Fama & Roll (1971) fractile.
234
236
location is the 50% trimmed mean of the sample.
235
237
"""
236
- function Distributions. fit (:: Type{<:SymmetricAlphaStable} , x, alg= QuickSort)
238
+ function Distributions. fit (:: Type{<:SymmetricAlphaStable} , x:: AbstractArray{T} , alg= QuickSort) where {T <: AbstractFloat }
237
239
sx = sort (x, alg= alg)
238
240
δ = mean (@view (sx[end ÷ 4 : (3 * end )÷ 4 ]))
239
241
p = quantile .(Ref (sx), (0.05 , 0.25 , 0.28 , 0.72 , 0.75 , 0.95 ), sorted= true )
240
- c = (p[4 ]- p[3 ])/ 1.654
241
- an = (p[6 ]- p[1 ])/ (p[5 ]- p[2 ])
242
+ c = (p[4 ]- p[3 ]) / 1.654
243
+ an = (p[6 ]- p[1 ]) / (p[5 ]- p[2 ])
242
244
if an < 2.4388
243
245
α = 2.
244
246
else
@@ -251,7 +253,7 @@ function Distributions.fit(::Type{<:SymmetricAlphaStable}, x, alg=QuickSort)
251
253
if α < 0.5
252
254
α = 0.5
253
255
end
254
- return SymmetricAlphaStable (α= α , scale= c , location= oftype (α, δ))
256
+ return SymmetricAlphaStable (α= T (α) , scale= T (c) , location= T ( δ))
255
257
end
256
258
257
259
"""
@@ -267,31 +269,33 @@ This implementation is based on the method in J.M. Chambers, C.L. Mallows
267
269
and B.W. Stuck, "A Method for Simulating Stable Random Variables," JASA 71 (1976): 340-4.
268
270
McCulloch's MATLAB implementation (1996) served as a reference in developing this code.
269
271
"""
270
- function Base. rand (rng:: AbstractRNG , d:: AlphaStable )
272
+ function Base. rand (rng:: AbstractRNG , d:: AlphaStable{T} ) where {T <: AbstractFloat }
271
273
α= d. α; β= d. β; scale= d. scale; loc= d. location
272
274
(α < 0.1 || α > 2 ) && throw (DomainError (α, " α must be in the range 0.1 to 2" ))
273
275
abs (β) > 1 && throw (DomainError (β, " β must be in the range -1 to 1" ))
274
- ϕ = (rand (rng) - 0.5 ) * π
275
- if α == 1 && β == 0
276
- return loc + scale* tan (ϕ)
276
+ ϕ = (rand (rng, T ) - 0.5 ) * π
277
+ if α == one (T) && β == zero (T)
278
+ return loc + scale * tan (ϕ)
277
279
end
278
- w = - log (rand (rng))
280
+ w = - log (rand (rng, T ))
279
281
α == 2 && (return loc + 2 * scale* sqrt (w)* sin (ϕ))
280
- β == 0 && (return loc + scale * ((cos ((1 - α)* ϕ) / w)^ (1.0 / α - 1 ) * sin (α * ϕ) / cos (ϕ)^ (1.0 / α)))
282
+ β == zero (T) && (return loc + scale * ((cos ((1 - α)* ϕ) / w)^ (one (T) / α - one (T)) * sin (α * ϕ) / cos (ϕ)^ (one (T) / α)))
281
283
cosϕ = cos (ϕ)
282
- if abs (α- 1 ) > 1e-8
283
- ζ = β * tan (π* α / 2 )
284
+ if abs (α - one (T) ) > 1e-8
285
+ ζ = β * tan (π * α / 2 )
284
286
aϕ = α * ϕ
285
- a1ϕ = (1 - α) * ϕ
286
- return loc + scale * (( (sin (aϕ)+ ζ * cos (aϕ))/ cosϕ * ((cos (a1ϕ)+ ζ* sin (a1ϕ))) / ((w* cosϕ)^ ((1 - α)/ α)) ))
287
+ a1ϕ = (one (T) - α) * ϕ
288
+ return loc + scale * (( (sin (aϕ) + ζ * cos (aϕ))/ cosϕ * ((cos (a1ϕ) + ζ* sin (a1ϕ))) / ((w* cosϕ)^ ((1 - α)/ α)) ))
287
289
end
288
290
bϕ = π/ 2 + β* ϕ
289
- x = 2 / π * (bϕ* tan (ϕ) - β* log (π/ 2 * w* cosϕ/ bϕ))
290
- α == 1 || (x += β * tan (π* α/ 2 ))
291
+ x = 2 / π * (bϕ * tan (ϕ) - β * log (π/ 2 * w* cosϕ/ bϕ))
292
+ α == one (T) || (x += β * tan (π* α/ 2 ))
291
293
292
- return loc + scale* x
294
+ return loc + scale * x
293
295
end
294
296
297
+ Base. eltype (:: Type{<:AlphaStable{T}} ) where {T<: AbstractFloat } = T
298
+
295
299
296
300
"""
297
301
@@ -318,7 +322,7 @@ The maximum acceptable size of `R` is `10x10`
318
322
julia> x = rand(AlphaSubGaussian(n=1000))
319
323
```
320
324
"""
321
- Base. @kwdef struct AlphaSubGaussian{T,M<: AbstractMatrix } <: Distributions.ContinuousUnivariateDistribution
325
+ Base. @kwdef struct AlphaSubGaussian{T<: AbstractFloat ,M<: AbstractMatrix } <: Distributions.ContinuousUnivariateDistribution
322
326
α:: T = 1.50
323
327
R:: M = SMatrix {5,5} (collect (SymmetricToeplitz ([1.0000 , 0.5804 , 0.2140 , 0.1444 , - 0.0135 ])))
324
328
n:: Int
@@ -366,7 +370,7 @@ function subgausscondprobtabulate(α, x1, x2_ind, invRx1, invR, vjoint, nmin, nm
366
370
end
367
371
368
372
369
- function Random. rand! (rng:: AbstractRNG , d:: AlphaSubGaussian , x:: AbstractArray )
373
+ function Random. rand! (rng:: AbstractRNG , d:: AlphaSubGaussian{T} , x:: AbstractArray{T} ) where {T <: AbstractFloat }
370
374
α= d. α; R= d. R; n= d. n
371
375
length (x) >= n || throw (ArgumentError (" length of x must be at least n" ))
372
376
α ∈ 1.10 : 0.01 : 1.98 || throw (DomainError (α, " α must lie within `1.10:0.01:1.98`" ))
@@ -388,11 +392,11 @@ function Random.rand!(rng::AbstractRNG, d::AlphaSubGaussian, x::AbstractArray)
388
392
nmax, nmin, res, rind, vjoint = matdict[" Nmax" ]:: Float64 , matdict[" Nmin" ]:: Float64 , matdict[" res" ]:: Float64 , vec (matdict[" rind" ]):: Vector{Float64} , matdict[" vJoint" ]:: Matrix{Float64}
389
393
step = (log10 (nmax)- log10 (nmin))/ res
390
394
m> size (vjoint, 1 )- 1 && throw (DomainError (R, " The dimensions of `R` exceed the maximum possible 10x10" ))
391
- A = rand (AlphaStable (α/ 2 , 1.0 , 2 * cos (π* α/ 4 )^ (2.0 / α), 0.0 ))
392
- T = rand (Chisq (m))
395
+ A = rand (AlphaStable (T ( α/ 2 ), one (T), T ( 2 * cos (π* α/ 4 )^ (2.0 / α)), zero (T) ))
396
+ CT = rand (Chisq (m))
393
397
S = randn (m)
394
398
S = S/ sqrt (sum (abs2,S))
395
- xtmp = ((sigrootx1* sqrt (A* T ))* S)'
399
+ xtmp = ((sigrootx1* sqrt (A* CT ))* S)'
396
400
if n<= m
397
401
copyto! (x, @view (xtmp[1 : n]))
398
402
else
@@ -421,7 +425,8 @@ function Random.rand!(rng::AbstractRNG, d::AlphaSubGaussian, x::AbstractArray)
421
425
end
422
426
423
427
424
- Base. rand (rng:: AbstractRNG , d:: AlphaSubGaussian ) = rand! (rng, d, zeros (d. n))
428
+ Base. rand (rng:: AbstractRNG , d:: AlphaSubGaussian ) = rand! (rng, d, zeros (eltype (d), d. n))
429
+ Base. eltype (:: Type{<:AlphaSubGaussian} ) = Float64
425
430
426
431
"""
427
432
fit(d::Type{<:AlphaSubGaussian}, x, m; p=1.0)
0 commit comments