module Mcmc.Proposal.Generic
( proposalGenericContinuous,
proposalGenericDiscrete,
)
where
import Mcmc.Proposal
import Numeric.Log
import Statistics.Distribution
import System.Random.MWC
sampleCont ::
(ContDistr d, ContGen d) =>
d ->
(a -> Double -> a) ->
Maybe (Double -> Double) ->
a ->
GenIO ->
IO (a, Log Double)
sampleCont d f mfInv x g = do
dx <- genContVar d g
let r = case mfInv of
Nothing -> 1.0
Just fInv ->
let qXY = Exp $ logDensity d dx
qYX = Exp $ logDensity d (fInv dx)
in qYX / qXY
return (x `f` dx, r)
{-# INLINEABLE sampleCont #-}
proposalGenericContinuous ::
(ContDistr d, ContGen d) =>
d ->
(a -> Double -> a) ->
Maybe (Double -> Double) ->
ProposalSimple a
proposalGenericContinuous d f fInv = ProposalSimple $ sampleCont d f fInv
sampleDiscrete ::
(DiscreteDistr d, DiscreteGen d) =>
d ->
(a -> Int -> a) ->
Maybe (Int -> Int) ->
a ->
GenIO ->
IO (a, Log Double)
sampleDiscrete d f mfInv x g = do
dx <- genDiscreteVar d g
let r = case mfInv of
Nothing -> 1.0
Just fInv ->
let qXY = Exp $ logProbability d dx
qYX = Exp $ logProbability d (fInv dx)
in qYX / qXY
return (x `f` dx, r)
{-# INLINEABLE sampleDiscrete #-}
proposalGenericDiscrete ::
(DiscreteDistr d, DiscreteGen d) =>
d ->
(a -> Int -> a) ->
Maybe (Int -> Int) ->
ProposalSimple a
proposalGenericDiscrete fd f fInv = ProposalSimple $ sampleDiscrete fd f fInv