Skip to content

Commit 5f5fba3

Browse files
Updated FFBS samplers etc so that the also work in Gibbs samplers with nSim = 1
1 parent 998c618 commit 5f5fba3

File tree

1 file changed

+58
-4
lines changed

1 file changed

+58
-4
lines changed

src/FFBSsamplers.jl

Lines changed: 58 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,61 @@
1+
# nSim = 1 method: Xdraws is (T + sample_t0) × n matrix
2+
@views function BackwardSampling!(Xdraws::AbstractMatrix, μ_filter, Σ_filter,
3+
μ_pred, Σ_pred, A, μ₀, Σ₀; sample_t0 = true)
14

2-
@views function BackwardSampling!(Xdraws, μ_filter, Σ_filter, μ_pred, Σ_pred, A, μ₀, Σ₀,
3-
nSim = 1; sample_t0 = true)
5+
T, n = size(μ_filter)
6+
x = zeros(n)
7+
μback = zeros(n)
8+
μ_zero = zeros(n)
9+
AS = zeros(n, n)
10+
G = zeros(n, n)
11+
12+
rand!(MvNormal(μ_filter[T,:], Hermitian(Σ_filter[:,:,T])), x)
13+
Xdraws[T + sample_t0, :] .= x
14+
15+
for t = (T-1):-1:1
16+
mul!(AS, A, Σ_filter[:,:,t])
17+
G .= (Σ_pred[:,:,t+1] \ AS)'
18+
Σback = Hermitian(Σ_filter[:,:,t] - G * AS)
19+
μback .= μ_filter[t,:] .+ G * (Xdraws[t+1+sample_t0,:] .- μ_pred[t+1,:])
20+
if isposdef(Σback)
21+
rand!(MvNormal(μ_zero, Σback), x)
22+
Xdraws[t+sample_t0,:] .= μback .+ x
23+
else
24+
Xdraws[t+sample_t0,:] .= Xdraws[t+1+sample_t0,:]
25+
end
26+
end
27+
28+
if sample_t0
29+
Σ₀mat = Matrix(Σ₀)
30+
mul!(AS, A, Σ₀mat)
31+
G .= (Σ_pred[:,:,1] \ AS)'
32+
Σback = Hermitian(Σ₀mat - G * AS)
33+
μback .= μ₀ .+ G * (Xdraws[2,:] .- μ_pred[1,:])
34+
if isposdef(Σback)
35+
rand!(MvNormal(μ_zero, Σback), x)
36+
Xdraws[1,:] .= μback .+ x
37+
else
38+
Xdraws[1,:] .= Xdraws[2,:]
39+
end
40+
end
41+
end
42+
43+
# Thin wrapper: loop over sims and delegate to 2D
44+
# Not used, but may try it to avoid code duplication.
45+
function BackwardSamplingThin!(Xdraws::AbstractArray{<:Real,3}, μ_filter, Σ_filter,
46+
μ_pred, Σ_pred, A, μ₀, Σ₀, nSim = 1; sample_t0 = true)
47+
for i = 1:nSim
48+
BackwardSampling!(@view(Xdraws[:,:,i]), μ_filter, Σ_filter, μ_pred, Σ_pred, A,
49+
μ₀, Σ₀; sample_t0 = sample_t0)
50+
end
51+
end
52+
53+
# nSim > 1 method: Xdraws is (T + sample_t0) × n × nSim array — dispatch on AbstractArray
54+
@views function BackwardSampling!(Xdraws::AbstractArray{<:Real,3}, μ_filter, Σ_filter,
55+
μ_pred, Σ_pred, A, μ₀, Σ₀; sample_t0 = true)
56+
457
T, n = size(μ_filter) # T does not include t=0, n is the dim of state
58+
nSim = size(Xdraws, 3) # number of draws
559
X = zeros(n, nSim) # buffer, reused every t
660
μback = zeros(n, nSim)
761
μ_zero = zeros(n) # pre-allocated zero mean for MvNormal
@@ -72,7 +126,7 @@ A, C, Σₑ and Σₙ can be deterministically time-varying by passing 3D arrays
72126
Note: If nSim == 1, the returned Xdraws is matrix, otherwise it is a 3D array of size T×n×nSim.
73127
74128
"""
75-
function FFBS!(Draws, U, Y, A, B, C, Σₑ, Σₙ, μ₀, Σ₀, nSim = 1;
129+
function FFBS!(Draws, U, Y, A, B, C, Σₑ, Σₙ, μ₀, Σ₀;
76130
filter_output = false, sample_t0 = true)
77131

78132
T = length(Y) # Number of time steps
@@ -106,7 +160,7 @@ function FFBS!(Draws, U, Y, A, B, C, Σₑ, Σₙ, μ₀, Σ₀, nSim = 1;
106160
Σ_pred[:,:,t] .= Σ̄
107161
end
108162

109-
BackwardSampling!(Draws, μ_filter, Σ_filter, μ_pred, Σ_pred, A, μ₀, Σ₀, nSim;
163+
BackwardSampling!(Draws, μ_filter, Σ_filter, μ_pred, Σ_pred, A, μ₀, Σ₀;
110164
sample_t0 = sample_t0)
111165

112166
if filter_output

0 commit comments

Comments
 (0)