Skip to content

Commit 372c2a9

Browse files
committed
Add effective sample size to Population
1 parent b3e7fbc commit 372c2a9

File tree

1 file changed

+27
-0
lines changed

1 file changed

+27
-0
lines changed

src/Control/Monad/Bayes/Population.hs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ module Control.Monad.Bayes.Population
2727
resampleSystematic,
2828
stratified,
2929
resampleStratified,
30+
onlyBelowEffectiveSampleSize,
31+
effectiveSampleSize,
3032
extractEvidence,
3133
pushEvidence,
3234
proper,
@@ -244,6 +246,31 @@ resampleMultinomial ::
244246
PopulationT m a
245247
resampleMultinomial = resampleGeneric multinomial
246248

249+
-- | Only use the given resampler when the effective sample size is below a certain threshold
250+
onlyBelowEffectiveSampleSize ::
251+
(MonadDistribution m) =>
252+
-- | The threshold under which the effective sample size must fall before the resampler is used.
253+
-- For example, this may be half of the number of particles.
254+
Double ->
255+
-- | The resampler to user under the threshold
256+
((MonadDistribution m) => PopulationT m a -> PopulationT m a) ->
257+
-- | The new resampler
258+
(PopulationT m a -> PopulationT m a)
259+
onlyBelowEffectiveSampleSize threshold resampler pop = do
260+
ess <- lift $ effectiveSampleSize pop
261+
if ess < threshold then resampler pop else pop
262+
263+
-- | Compute the effective sample size of a population from the weights.
264+
--
265+
-- See https://en.wikipedia.org/wiki/Design_effect#Effective_sample_size
266+
effectiveSampleSize :: (Functor m) => PopulationT m a -> m Double
267+
effectiveSampleSize = fmap (effectiveSampleSizeKish . map (exp . ln . snd)) . runPopulationT
268+
where
269+
effectiveSampleSizeKish :: [Double] -> Double
270+
effectiveSampleSizeKish weights = square (Data.List.sum weights) / Data.List.sum (square <$> weights)
271+
square :: Double -> Double
272+
square x = x * x
273+
247274
-- | Separate the sum of weights into the 'WeightedT' transformer.
248275
-- Weights are normalized after this operation.
249276
extractEvidence ::

0 commit comments

Comments
 (0)