-
Notifications
You must be signed in to change notification settings - Fork 62
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add effective sample size to Population #268
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -27,6 +27,8 @@ module Control.Monad.Bayes.Population | |
resampleSystematic, | ||
stratified, | ||
resampleStratified, | ||
onlyBelowEffectiveSampleSize, | ||
effectiveSampleSize, | ||
extractEvidence, | ||
pushEvidence, | ||
proper, | ||
|
@@ -210,6 +212,31 @@ resampleMultinomial :: | |
Population m a | ||
resampleMultinomial = resampleGeneric multinomial | ||
|
||
-- | Only use the given resampler when the effective sample size is below a certain threshold | ||
onlyBelowEffectiveSampleSize :: | ||
MonadDistribution m => | ||
-- | The threshold under which the effective sample size must fall before the resampler is used. | ||
-- For example, this may be half of the number of particles. | ||
Double -> | ||
-- | The resampler to user under the threshold | ||
(MonadDistribution m => Population m a -> Population m a) -> | ||
-- | The new resampler | ||
(Population m a -> Population m a) | ||
onlyBelowEffectiveSampleSize threshold resampler pop = do | ||
ess <- lift $ effectiveSampleSize pop | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this is wrong because it will execute the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It might be better to have a function |
||
if ess < threshold then resampler pop else pop | ||
|
||
-- | Compute the effective sample size of a population from the weights. | ||
-- | ||
-- See https://en.wikipedia.org/wiki/Design_effect#Effective_sample_size | ||
effectiveSampleSize :: Functor m => Population m a -> m Double | ||
effectiveSampleSize = fmap (effectiveSampleSizeKish . map (exp . ln . snd)) . runPopulation | ||
where | ||
effectiveSampleSizeKish :: [Double] -> Double | ||
effectiveSampleSizeKish weights = square (Data.List.sum weights) / Data.List.sum (square <$> weights) | ||
square :: Double -> Double | ||
square x = x * x | ||
|
||
-- | Separate the sum of weights into the 'Weighted' transformer. | ||
-- Weights are normalized after this operation. | ||
extractEvidence :: | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I should have one fixture test and a unit test where this is used.