monad-bayes-0.1.0.0: models/NonlinearSSM.hs
module NonlinearSSM where
import Control.Monad.Bayes.Class
param :: MonadSample m => m (Double, Double)
param = do
let a = 0.01
let b = 0.01
precX <- gamma a b
let sigmaX = 1 / sqrt precX
precY <- gamma a b
let sigmaY = 1 / sqrt precY
return (sigmaX, sigmaY)
-- | A nonlinear series model from Doucet et al. (2000)
-- "On sequential Monte Carlo sampling methods" section VI.B
model :: (MonadInfer m)
=> [Double] -- ^ observed data
-> (Double, Double) -- ^ prior on the parameters
-> m [Double] -- ^ list of latent states from t=1
model obs (sigmaX, sigmaY) = do
let sq x = x * x
simulate [] _ acc = return acc
simulate (y:ys) x acc = do
let n = length acc
let mean = 0.5 * x + 25 * x / (1 + sq x) +
8 * cos (1.2 * fromIntegral n)
x' <- normal mean sigmaX
factor $ normalPdf (sq x' / 20) sigmaY y
simulate ys x' (x':acc)
x0 <- normal 0 (sqrt 5)
xs <- simulate obs x0 []
return $ reverse xs
generateData :: MonadSample m
=> Int -- ^ T
-> m [(Double,Double)] -- ^ list of latent and observable states from t=1
generateData t = do
(sigmaX, sigmaY) <- param
let sq x = x * x
simulate 0 _ acc = return acc
simulate k x acc = do
let n = length acc
let mean = 0.5 * x + 25 * x / (1 + sq x) +
8 * cos (1.2 * fromIntegral n)
x' <- normal mean sigmaX
y' <- normal (sq x' / 20) sigmaY
simulate (k-1) x' ((x',y'):acc)
x0 <- normal 0 (sqrt 5)
xys <- simulate t x0 []
return $ reverse xys