@@ -14,6 +14,8 @@ Base.@kwdef struct AlphaStable{T} <: Distributions.ContinuousUnivariateDistribut
1414 location:: T = zero (α)
1515end
1616
17+ AlphaStable (α:: Integer , β:: Integer , scale:: Integer , location:: Integer ) = AlphaStable (float (α), float (β), float (scale), float (location))
18+
1719
1820# sampler(d::AlphaStable) = error("Not implemented")
1921# pdf(d::AlphaStable, x::Real) = error("Not implemented")
@@ -267,31 +269,33 @@ This implementation is based on the method in J.M. Chambers, C.L. Mallows
267269and B.W. Stuck, "A Method for Simulating Stable Random Variables," JASA 71 (1976): 340-4.
268270McCulloch's MATLAB implementation (1996) served as a reference in developing this code.
269271"""
270- function Base. rand (rng:: AbstractRNG , d:: AlphaStable )
272+ function Base. rand (rng:: AbstractRNG , d:: AlphaStable{T} ) where {T <: Real }
271273 α= d. α; β= d. β; scale= d. scale; loc= d. location
272274 (α < 0.1 || α > 2 ) && throw (DomainError (α, " α must be in the range 0.1 to 2" ))
273275 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 (ϕ)
277279 end
278- w = - log (rand (rng))
280+ w = - log (rand (rng, T ))
279281 α == 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) / α)))
281283 cosϕ = cos (ϕ)
282- if abs (α- 1 ) > 1e-8
283- ζ = β * tan (π* α / 2 )
284+ if abs (α - one (T) ) > 1e-8
285+ ζ = β * tan (π * α / 2 )
284286 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 - α)/ α)) ))
287289 end
288290 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 ))
291293
292- return loc + scale* x
294+ return loc + scale * x
293295end
294296
297+ Base. eltype (:: Type{<:AlphaStable{T}} ) where {T<: AbstractFloat } = T
298+
295299
296300"""
297301
@@ -318,12 +322,16 @@ The maximum acceptable size of `R` is `10x10`
318322julia> x = rand(AlphaSubGaussian(n=1000))
319323```
320324"""
321- Base. @kwdef struct AlphaSubGaussian{T,M <: AbstractMatrix } <: Distributions.ContinuousUnivariateDistribution
325+ Base. @kwdef struct AlphaSubGaussian{T<: AbstractFloat } <: Distributions.ContinuousUnivariateDistribution
322326 α:: T = 1.50
323- R:: M = SMatrix {5,5} (collect (SymmetricToeplitz ([1.0000 , 0.5804 , 0.2140 , 0.1444 , - 0.0135 ])))
327+ R:: AbstractMatrix{T} = SMatrix {5,5} (collect (SymmetricToeplitz ([1.0000 , 0.5804 , 0.2140 , 0.1444 , - 0.0135 ])))
324328 n:: Int
325329end
326330
331+ AlphaSubGaussian (α:: T , n:: Int ) where {T<: AbstractFloat } = AlphaSubGaussian (α= α,
332+ R= SMatrix {5,5} (T .(collect (SymmetricToeplitz ([1.0000 , 0.5804 , 0.2140 , 0.1444 , - 0.0135 ])))),
333+ n= n)
334+
327335"""
328336Generates the conditional probability f(X2|X1) if [X1, X2] is a sub-Gaussian
329337stable random vector such that X1(i)~X2~S(alpha,delta) and rho is the correlation
@@ -366,10 +374,10 @@ function subgausscondprobtabulate(α, x1, x2_ind, invRx1, invR, vjoint, nmin, nm
366374end
367375
368376
369- function Random. rand! (rng:: AbstractRNG , d:: AlphaSubGaussian , x:: AbstractArray )
377+ function Random. rand! (rng:: AbstractRNG , d:: AlphaSubGaussian{T} , x:: AbstractArray{T} ) where {T <: Real }
370378 α= d. α; R= d. R; n= d. n
371379 length (x) >= n || throw (ArgumentError (" length of x must be at least n" ))
372- α ∈ 1.10 : 0.01 : 1.98 || throw (DomainError (α, " α must lie within `1.10:0.01:1.98`" ))
380+ α ∈ T .( 1.10 : 0.01 : 1.98 ) || throw (DomainError (α, " α must lie within `1.10:0.01:1.98`" ))
373381 m = size (R, 1 )- 1
374382 funk1 = x -> (2 ^ α)* sin (π* α/ 2 )* gamma ((α+ 2 )/ 2 )* gamma ((α+ x)/ 2 )/ (gamma (x/ 2 )* π* α/ 2 )
375383 funk2 = x -> 4 * gamma (x/ α)/ ((α* 2 ^ 2 )* gamma (x/ 2 )^ 2 )
@@ -388,11 +396,11 @@ function Random.rand!(rng::AbstractRNG, d::AlphaSubGaussian, x::AbstractArray)
388396 nmax, nmin, res, rind, vjoint = matdict[" Nmax" ]:: Float64 , matdict[" Nmin" ]:: Float64 , matdict[" res" ]:: Float64 , vec (matdict[" rind" ]):: Vector{Float64} , matdict[" vJoint" ]:: Matrix{Float64}
389397 step = (log10 (nmax)- log10 (nmin))/ res
390398 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))
399+ A = rand (AlphaStable (T ( α/ 2 ), one (T), T ( 2 * cos (π* α/ 4 )^ (2.0 / α)), zero (T) ))
400+ CT = rand (Chisq (m))
393401 S = randn (m)
394402 S = S/ sqrt (sum (abs2,S))
395- xtmp = ((sigrootx1* sqrt (A* T ))* S)'
403+ xtmp = ((sigrootx1* sqrt (A* CT ))* S)'
396404 if n<= m
397405 copyto! (x, @view (xtmp[1 : n]))
398406 else
@@ -421,7 +429,8 @@ function Random.rand!(rng::AbstractRNG, d::AlphaSubGaussian, x::AbstractArray)
421429end
422430
423431
424- Base. rand (rng:: AbstractRNG , d:: AlphaSubGaussian ) = rand! (rng, d, zeros (d. n))
432+ Base. rand (rng:: AbstractRNG , d:: AlphaSubGaussian ) = rand! (rng, d, zeros (eltype (d), d. n))
433+ Base. eltype (:: Type{<:AlphaSubGaussian{T}} ) where {T} = T
425434
426435"""
427436 fit(d::Type{<:AlphaSubGaussian}, x, m; p=1.0)
0 commit comments