{-# LANGUAGE ViewPatterns #-} {-# LANGUAGE BangPatterns #-} module PPL.Sampling where import Control.Monad.IO.Class import Control.Monad.Trans.State import Data.Bifunctor import Data.Monoid import Numeric.Log import PPL.Distr import PPL.Internal hiding (split) import System.Random (StdGen, random, randoms, split) import qualified Streaming as S import Streaming.Prelude (Stream, yield, Of) mh :: Monad m => StdGen -> Double -> Double -> Meas a -> Stream (Of (a, Log Double)) m () mh g p q m = step g2 t x w where t = randomTree g1 (g1,g2) = split g (x, w) = head $ samples m t step !g !t !x !w = do let (g1, g2) = split g t' = mutateTree p q g1 t (x', w') = head $ samples m t' ratio = w' / w (Exp . log -> r, g3) = random g2 (t'', x'', w'') = if r < ratio then (t', x', w') else (t, x, w) yield (x'', w'') step g3 t'' x'' w''