Skip to content

Commit e4a0eda

Browse files
committed
Add effective sample size to Population
1 parent 256aad7 commit e4a0eda

File tree

1 file changed

+28
-0
lines changed

1 file changed

+28
-0
lines changed

src/Control/Monad/Bayes/Population.hs

Lines changed: 28 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,
@@ -210,6 +212,32 @@ resampleMultinomial ::
210212
Population m a
211213
resampleMultinomial = resampleGeneric multinomial
212214

215+
-- | Only use the given resampler when the effective sample size is below a certain threshold
216+
onlyBelowEffectiveSampleSize ::
217+
MonadDistribution m =>
218+
-- | The threshold under which the effective sample size must fall before the resampler is used.
219+
-- For example, this may be half of the number of particles.
220+
Double ->
221+
-- | The resampler to user under the threshold
222+
(MonadDistribution m => Population m a -> Population m a) ->
223+
-- | The new resampler
224+
(Population m a -> Population m a)
225+
onlyBelowEffectiveSampleSize threshold resampler pop = do
226+
ess <- lift $ effectiveSampleSize pop
227+
if ess < threshold then resampler pop else pop
228+
229+
{- | Compute the effective sample size of a population from the weights.
230+
231+
See https://en.wikipedia.org/wiki/Design_effect#Effective_sample_size
232+
-}
233+
effectiveSampleSize :: Functor m => Population m a -> m Double
234+
effectiveSampleSize = fmap (effectiveSampleSizeKish . map (exp . ln . snd)) . runPopulation
235+
where
236+
effectiveSampleSizeKish :: [Double] -> Double
237+
effectiveSampleSizeKish weights = square (Data.List.sum weights) / Data.List.sum (square <$> weights)
238+
square :: Double -> Double
239+
square x = x * x
240+
213241
-- | Separate the sum of weights into the 'Weighted' transformer.
214242
-- Weights are normalized after this operation.
215243
extractEvidence ::

0 commit comments

Comments
 (0)