Skip to content

Commit 3746956

Browse files
committed
Improve type stability
1 parent a885938 commit 3746956

File tree

2 files changed

+45
-37
lines changed

2 files changed

+45
-37
lines changed

src/HAC.jl

+27-25
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,44 @@
1-
function avar(k::T, X::AbstractMatrix{F}; prewhite=false) where {T<:HAC,F<:AbstractFloat}
2-
if prewhite
3-
Z, D = fit_var(X)
4-
else
5-
Z = X
6-
end
1+
function avar(k::K, X::AbstractMatrix{F}; prewhite=false) where {K<:HAC,F<:Real}
2+
Z, D = finalize_prewhite(X, Val(prewhite))
3+
T, p = size(Z)
74
wlock = k.wlock[1]
85
setkernelweights!(k, X)
96
k.bw .= _optimalbandwidth(k, Z, prewhite)
107
k.wlock .= wlock
11-
idx = CovarianceMatrices.covindices(k, size(Z, 1))
12-
κ = [CovarianceMatrices.kernel(k, j ./ k.bw[1]) for j idx]
13-
V = zeros(F, size(Z, 2), size(Z, 2))
8+
V = zeros(F, p, p)
149
Q = similar(V)
15-
kernelestimator!(V, Q, Z, κ)
16-
if prewhite
17-
v = inv(I - D')
18-
return v * V * v'
19-
else
20-
return V
21-
end
10+
kernelestimator!(k, V, Q, Z)
11+
v = inv(one(F)*I - D')
12+
return v * V * v'
2213
end
2314

24-
function kernelestimator!(V, Q, Z, κ)
15+
finalize_prewhite(X, ::Val{true}) = fit_var(X)
16+
finalize_prewhite(X, ::Val{false}) = X, ZeroMat()
17+
18+
struct ZeroMat end
19+
Base.:-(J::UniformScaling, Z::ZeroMat) = J
20+
Base.:+(J::UniformScaling, Z::ZeroMat) = J
21+
LinearAlgebra.adjoint(Z::ZeroMat) = Z
22+
23+
function kernelestimator!(k::K, V::AbstractMatrix{F}, Q, Z) where {K<:HAC, F<:Real}
2524
## V is the final variance
2625
## Q is the temporary matrix
2726
## Z is the data matrix
2827
## κ is the kernel vector
29-
T, k = size(Z)
28+
T, _ = size(Z)
29+
idx = covindices(k, T)
30+
bw = convert(F, k.bw[1])
3031
## Calculate the variance at lag 0
3132
mul!(Q, Z', Z)
3233
copy!(V, Q)
3334
## Calculate Γ₁, Γ₂, ..., Γⱼ
34-
@inbounds for j 1:length)
35+
@inbounds for j eachindex(idx)
3536
Zₜ = view(Z, 1:(T - j), :)
3637
Zₜ₊₁ = view(Z, (1 + j):T, :)
3738
mul!(Q, Zₜ', Zₜ₊₁)
38-
@. V += κ[j] * Q
39-
@. V += κ[j] * Q'
39+
κ = kernel(k, j/bw)
40+
@. V += κ * Q
41+
@. V += κ * Q'
4042
end
4143
return V ./ T
4244
end
@@ -46,7 +48,7 @@ avarscaler(K::HAC, X; prewhite=false) = size(X, 1)
4648
covindices(k::T, n) where {T<:QuadraticSpectral} = 1:n
4749
covindices(k::T, n) where {T<:Bartlett} = 1:(floor(Int, k.bw[1]))
4850
covindices(k::HAC, n) = 1:floor(Int, k.bw[1])
49-
51+
covindices(k::T, n) where {T<:HR} = 1:0
5052
# -----------------------------------------------------------------------------
5153
# Kernels
5254
# -----------------------------------------------------------------------------
@@ -198,7 +200,7 @@ end
198200
# -----------------------------------------------------------------------------
199201
# Fit function
200202
# -----------------------------------------------------------------------------
201-
Base.@propagate_inbounds function fit_var(A::AbstractMatrix{T}) where {T}
203+
Base.@propagate_inbounds function fit_var(A::AbstractMatrix{T}) where T
202204
fi = firstindex(A, 1)
203205
li = lastindex(A, 1)
204206
Y = view(A, (fi + 1):li, :)
@@ -209,7 +211,7 @@ Base.@propagate_inbounds function fit_var(A::AbstractMatrix{T}) where {T}
209211
end
210212

211213

212-
Base.@propagate_inbounds function fit_ar(Z::AbstractMatrix{T}) where {T}
214+
Base.@propagate_inbounds function fit_ar(Z::AbstractMatrix{T}) where T
213215
## Estimate
214216
##
215217
## y_{t,j} = ρ y_{t-1,j} + ϵ
@@ -238,7 +240,7 @@ end
238240
# -----------------------------------------------------------------------------
239241
# Prewhiter
240242
# -----------------------------------------------------------------------------
241-
function prewhiter(M::AbstractMatrix{T}, prewhite::Bool) where {T<:AbstractFloat}
243+
function prewhiter(M::AbstractMatrix{T}, prewhite::Bool) where {T<:Real}
242244
if prewhite
243245
return fit_var(M)
244246
else

src/aVar.jl

+18-12
Original file line numberDiff line numberDiff line change
@@ -10,33 +10,39 @@ aVar(k::AVarEstimator, m::AbstractMatrix{T}; demean::Bool=true, dims::Int=1, mea
1010
- `dims=1`: the dimension along which the demeaning should be performed.
1111
- `means=nothing`: the means to be used for demeaning.
1212
- `prewhite=false`: should the data be prewithened. Relevant for `HAC` estimator.
13-
- `scale=true`: should the variance be scaled by the number of observations.
13+
- `scale`: should the variance be scaled by the number of observations. If scle is an
14+
`Int` that value is used to scale the variance. This is convenient for degrees
15+
of freedom correction or in cases where the variance is needed without
16+
scaling.
1417
"""
1518
aVar(k::AVarEstimator, m::AbstractMatrix; kwargs...) = aVar(k, float.(m), kwargs...)
1619

1720
function aVar(k::AVarEstimator, m::AbstractMatrix{T}; demean::Bool=true, dims::Int=1,
1821
means::Union{Nothing,AbstractArray}=nothing, prewhite::Bool=false,
19-
scale=true) where {T<:AbstractFloat}
22+
scale=true) where {T<:Real}
2023
Base.require_one_based_indexing(m)
2124
X = demean ? demeaner(m; means=means, dims=dims) : m
22-
Shat = avar(k, X; prewhite=prewhite)
23-
return scale ? Shat ./ size(X, dims) : Shat
25+
Shat = avar(k, X; prewhite=isa(k, HAC) ? prewhite : false)
26+
scalevar!(Shat, scale, size(X, dims))
27+
return Shat
28+
end
29+
30+
scalevar!(Shat, scale::Bool, n::Int) = scale ? rdiv!(Shat, n) : Shat
31+
scalevar!(Shat, scale::Int, n::Int) = rdiv!(Shat, scale)
32+
scalevar!(Shat, scale, n) = throw(ArgumentError("`scale` should be either an Int or a Bool."))
33+
function scalevar!(Shat, scale::Int, n)
34+
@warn "The variance is being scaled by an AbstractFloat"
35+
rdiv!(X, scale)
2436
end
2537

2638
function aVar(k::VARHAC, m::AbstractMatrix{T}; demean::Bool=true, dims::Int=1,
27-
means::Union{Nothing,AbstractArray}=nothing, kwargs...) where {T<:AbstractFloat}
39+
means::Union{Nothing,AbstractArray}=nothing, scale = true, kwargs...) where {T<:Real}
2840
Base.require_one_based_indexing(m)
2941
X = demean ? demeaner(m; means=means, dims=dims) : m
3042
Shat = avar(k, X)
3143
return Shat
3244
end
3345

34-
3546
const a𝕍ar = aVar
3647

37-
# function lrvar(k::AVarEstimator, m::AbstractMatrix{T}; demean::Bool=true, dims::Int=1,
38-
# means::Union{Nothing,AbstractArray}=nothing,
39-
# prewhite::Bool=false) where {T<:AbstractFloat}
40-
# Shat = aVar(k, m; demean=demean, dims=dims, means=means, prewhite=prewhite, scale=true)
41-
# return Shat ./ size(m, dims)
42-
# end
48+

0 commit comments

Comments
 (0)