public void Pimh_BayesPointMachine()
        {
            var posterior = BpmUpdate(BpmPrior, BpmObserved);
            var samples   = Samples(Pimh.Create(500, 50, posterior).SampleNParallel(100).SelectMany(d => d).SelectMany(d => d));

            var approxPosterior = CategoricalF(samples.Normalize());

            Debug.WriteLine(BpmPredict(approxPosterior, Person1));
            Debug.WriteLine(BpmPredict(approxPosterior, Person2));
            Debug.WriteLine(BpmPredict(approxPosterior, Person3));
        }
        public void Pimh_HiddenMarkov()
        {
            var hmmModel = Hmm(ObservedHmmData1);

            var smcHmmSamples = Pimh.Create(100, 100, hmmModel).Sample();

            var topSamples = Samples((from samples in smcHmmSamples
                                      from sample in samples.Weights
                                      select sample)
                                     .GroupBy(ip => ShowLatentList(ip.Item))
                                     .OrderByDescending(group => group.First().Prob.Value)
                                     .Take(5).Select(g => g.First()));

            Debug.WriteLine(Histogram.Finite(topSamples, ShowLatentList));
        }
        public void Pimh_LinReg()
        {
            var prior = from a in Normal(0, 100)
                        from b in Normal(0, 100)
                        select new Param(a, b);

            var sandLinReg = CreateLinearRegression(prior, BeachSandData);

            var pimhLinReg = Pimh.Create(100, 1000, sandLinReg).Sample();

            var paramA = from samples in pimhLinReg
                         from aProb in samples.MapSample(param => param.a)
                         select aProb;

            var paramB = from samples in pimhLinReg
                         from bProb in samples.MapSample(param => param.b)
                         select bProb;

            Debug.WriteLine(Histogram.Weighted(paramA));
            Debug.WriteLine(Histogram.Weighted(paramB));
        }
        public void Pimh_Dice()
        {
            // Exact posterior conditioned die
            var twoRollsExact = Dice.ConditionalDieExact(2);

            Debug.WriteLine(twoRollsExact.Histogram());

            // Posterior inferred with SMC
            var twoRolls      = Dice.ConditionalDie(2);
            var pimhPosterior = Pimh.Create(100, 1000, twoRolls).Sample();
            var weights       = from samples in pimhPosterior
                                from sample in samples
                                select sample;
            var klDivergence = KullbackLeibler.KLDivergence(Samples(weights), twoRollsExact, d => d);

            Debug.WriteLine($"KL divergence: {klDivergence}");
            Assert.IsTrue(klDivergence < 0.5);

            var doubleWeights = weights.Select(ip => ItemProb((double)ip.Item, ip.Prob));

            Debug.WriteLine(Histogram.Weighted(doubleWeights, scale: 60));
        }