Skip to content

Commit

Permalink
Add example for particle collapse
Browse files Browse the repository at this point in the history
  • Loading branch information
turion committed Oct 4, 2023
1 parent afa0564 commit 80c23a9
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 10 deletions.
71 changes: 61 additions & 10 deletions rhine-bayes/app/Main.hs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@ import Control.Monad.Bayes.Class hiding (posterior, prior)
import Control.Monad.Bayes.Population hiding (hoist)
import Control.Monad.Bayes.Sampler.Strict

-- dunai
import Control.Monad.Trans.MSF.Except

-- rhine
import FRP.Rhine

Expand Down Expand Up @@ -264,6 +267,7 @@ glossSettings =
mains :: [(String, IO ())]
mains =
[ ("single rate", mainSingleRate)
, ("single rate, parameter collapse", mainSingleRateCollapse)
, ("multi rate, temperature process", mainMultiRate)
]

Expand All @@ -275,6 +279,63 @@ main = do

-- ** Single-rate : One simulation step = one inference step = one display step

-- | Rescale to the 'Double' time domain
type GlossClock = RescaledClock GlossSimClockIO Double

glossClock :: GlossClock
glossClock =
RescaledClock
{ unscaledClock = GlossSimClockIO
, rescale = float2Double
}

-- *** Poor attempt at temperature inference: Particle collapse

-- | Choose an exponential distribution as prior for the temperature
temperaturePrior :: (MonadDistribution m) => m Temperature
temperaturePrior = gamma 1 7

{- | On startup, sample values from the temperature prior.
Then keep sampling from the position prior and condition by the likelihood of the measured sensor position.
-}
posteriorTemperatureCollapse :: (MonadMeasure m, Diff td ~ Double) => BehaviourF m td Sensor (Temperature, Pos)
posteriorTemperatureCollapse = proc sensor -> do
temperature <- performOnFirstSample (arr_ <$> temperaturePrior) -< ()
latent <- prior -< temperature
arrM score -< sensorLikelihood latent sensor
returnA -< (temperature, latent)

{- | Given an actual temperature, simulate a latent position and measured sensor position,
and based on the sensor data infer the latent position and the temperature.
-}
filteredCollapse :: (Diff td ~ Double) => BehaviourF App td Temperature Result
filteredCollapse = proc temperature -> do
(measured, latent) <- genModelWithoutTemperature -< temperature
particlesAndTemperature <- runPopulationCl nParticles resampleSystematic posteriorTemperatureCollapse -< measured
returnA
-<
Result
{ temperature
, measured
, latent
, particlesPosition = first snd <$> particlesAndTemperature
, particlesTemperature = first fst <$> particlesAndTemperature
}

-- | Run simulation, inference, and visualization synchronously
mainClSFCollapse :: (Diff td ~ Double) => BehaviourF App td () ()
mainClSFCollapse = proc () -> do
output <- filteredCollapse -< initialTemperature
visualisation -< output

mainSingleRateCollapse =
void $
sampleIO $
launchInGlossThread glossSettings $
reactimateCl glossClock mainClSFCollapse

-- *** Infer temperature with a stochastic process

{- | Given an actual temperature, simulate a latent position and measured sensor position,
and based on the sensor data infer the latent position and the temperature.
-}
Expand All @@ -298,16 +359,6 @@ mainClSF = proc () -> do
output <- filtered -< initialTemperature
visualisation -< output

-- | Rescale to the 'Double' time domain
type GlossClock = RescaledClock GlossSimClockIO Double

glossClock :: GlossClock
glossClock =
RescaledClock
{ unscaledClock = GlossSimClockIO
, rescale = float2Double
}

mainSingleRate =
void $
sampleIO $
Expand Down
1 change: 1 addition & 0 deletions rhine-bayes/rhine-bayes.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ executable rhine-bayes-gloss
, rhine
, rhine-bayes
, rhine-gloss
, dunai
, monad-bayes
, transformers
, log-domain
Expand Down

0 comments on commit 80c23a9

Please sign in to comment.