@@ -3,6 +3,7 @@ using AdvancedPS
33using Random
44using Distributions
55using Plots
6+ using SSMProblems
67
78# We consider the following linear state-space model with Gaussian innovations. The latent state is a simple gaussian random walk
89# and the observation is linear in the latent states, namely:
@@ -33,32 +34,45 @@ Parameters = @NamedTuple begin
3334 r:: Float64
3435end
3536
36- mutable struct LinearSSM <: AdvancedPS .AbstractStateSpaceModel
37+ mutable struct LinearSSM <: SSMProblems .AbstractStateSpaceModel
3738 X:: Vector{Float64}
39+ observations:: Vector{Float64}
3840 θ:: Parameters
3941 LinearSSM (θ:: Parameters ) = new (Vector {Float64} (), θ)
42+ LinearSSM (y:: Vector , θ:: Parameters ) = new (Vector {Float64} (), y, θ)
4043end
4144
4245# and the densities defined above.
43- f (m :: LinearSSM , state, t) = Normal (m . θ. a * state, m . θ. q) # Transition density
44- g (m :: LinearSSM , state, t) = Normal (state, m . θ. r) # Observation density
45- f₀ (m :: LinearSSM ) = Normal (0 , m . θ. q^ 2 / (1 - m . θ. a^ 2 )) # Initial state density
46+ f (θ :: Parameters , state, t) = Normal (θ. a * state, θ. q) # Transition density
47+ g (θ :: Parameters , state, t) = Normal (state, θ. r) # Observation density
48+ f₀ (θ :: Parameters ) = Normal (0 , θ. q^ 2 / (1 - θ. a^ 2 )) # Initial state density
4649# md nothing #hide
4750
4851# We also need to specify the dynamics of the system through the transition equations:
4952# - `AdvancedPS.initialization`: the initial state density
5053# - `AdvancedPS.transition`: the state transition density
5154# - `AdvancedPS.observation`: the observation score given the observed data
5255# - `AdvancedPS.isdone`: signals the end of the execution for the model
53- AdvancedPS. initialization (model:: LinearSSM ) = f₀ (model)
54- AdvancedPS. transition (model:: LinearSSM , state, step) = f (model, state, step)
55- function AdvancedPS. observation (model:: LinearSSM , state, step)
56- return logpdf (g (model, state, step), y[step])
56+ SSMProblems. transition!! (rng:: AbstractRNG , model:: LinearSSM ) = rand (rng, f₀ (model. θ))
57+ function SSMProblems. transition!! (
58+ rng:: AbstractRNG , model:: LinearSSM , state:: Float64 , step:: Int
59+ )
60+ return rand (rng, f (model. θ, state, step))
61+ end
62+
63+ function SSMProblems. emission_logdensity (modeL:: LinearSSM , state:: Float64 , step:: Int )
64+ return logpdf (g (model. θ, state, step), model. observations[step])
65+ end
66+ function SSMProblems. transition_logdensity (
67+ model:: LinearSSM , prev_state, current_state, step
68+ )
69+ return logpdf (f (model. θ, prev_state, step), current_state)
5770end
71+
72+ # We need to think seriously about how the data is handled
5873AdvancedPS. isdone (:: LinearSSM , step) = step > Tₘ
5974
6075# Everything is now ready to simulate some data.
61-
6276a = 0.9 # Scale
6377q = 0.32 # State variance
6478r = 1 # Observation variance
@@ -72,14 +86,12 @@ rng = Random.MersenneTwister(seed)
7286
7387x = zeros (Tₘ)
7488y = zeros (Tₘ)
75-
76- reference = LinearSSM (θ₀)
77- x[1 ] = rand (rng, f₀ (reference))
89+ x[1 ] = rand (rng, f₀ (θ₀))
7890for t in 1 : Tₘ
7991 if t < Tₘ
80- x[t + 1 ] = rand (rng, f (reference , x[t], t))
92+ x[t + 1 ] = rand (rng, f (θ₀ , x[t], t))
8193 end
82- y[t] = rand (rng, g (reference , x[t], t))
94+ y[t] = rand (rng, g (θ₀ , x[t], t))
8395end
8496
8597# Here are the latent and obseravation timeseries
@@ -88,7 +100,7 @@ plot!(y; seriestype=:scatter, label="y", xlabel="t", mc=:red, ms=2, ma=0.5)
88100
89101# `AdvancedPS` subscribes to the `AbstractMCMC` API. To sample we just need to define a Particle Gibbs kernel
90102# and a model interface.
91- model = LinearSSM (θ₀)
103+ model = LinearSSM (y, θ₀)
92104pgas = AdvancedPS. PGAS (Nₚ)
93105chains = sample (rng, model, pgas, Nₛ; progress= false );
94106# md nothing #hide
0 commit comments