turion / dunai-bayes

BSD 3-Clause "New" or "Revised" License
3 stars 0 forks source link

Adaptive SMC #4

Open reubenharry opened 1 year ago

reubenharry commented 1 year ago

It would be very nice to have the rate of resampling be variable. For instance, suppose that the variance of the particle filter starts growing at a particularly after a tricky series of observations. We might want to resample more often. We might also want to increase the population size.

Or we might even just want the user to be able to adjust the population size and resampling rate in real time manually.

(This has some overlap with rhine-bayes, but I think the fundamental solution will be at the dunai level)

turion commented 1 year ago

Resampling rate

The resampling rate is once per step. I think there is no real way around it. One can use mapMaybeS to skip resampling steps, like so:

justEvery10 = proc a -> do
  n <- count -< ()
  let input = if n `mod` 10 == 0 then Just a else Nothing
resampleEvery10 = justEvery10 >>> mapMaybeS (runPopulationS nParticles resampler msf)

But I'd rather use rhine-bayes in such a situation, and put the SMC part on a clock that runs 10 times slower than the rest. (Or on a clock that can have variable rate, depending on side effects.)

Population size

Adjusting the population size is a cool idea. Whan can already be done without extra definitions is calling arrM spawn -< n. But that only increases it by a factor of n. I don't know how to change the population size in monad-bayes arbitrarily. I'm guessing you need to use runPopulation or resampleGeneric for that. Assuming you have a function takePopulation :: Int -> Population m a -> Population m a, I could write:

takePopulationS :: MSF (Population m) a b -> MSF (Population m) (Int, a) b

If you think this is useful, and you can tell me how to write takePopulation in the best way, I'll implement it :)