コード例 #1
0
 /// <summary>
 /// Hard reweight by a condition that depends on associated item
 /// </summary>
 public static FiniteDist <A> ConditionHard <A>(this FiniteDist <A> distribution, Func <A, bool> condition)
 {
     return(new FiniteDist <A>(
                distribution.Explicit
                .Select(p => ItemProb(p.Item, condition(p.Item) ? p.Prob : Prob(0)))
                .Normalize()
                ));
 }
コード例 #2
0
 /// <summary>
 /// Display finite distribution as histogram
 /// </summary>
 /// <param name="showItem">Specifies a string representation of distribution item. Defaults to ToString.</param>
 public static string Histogram <A>(this FiniteDist <A> dist, Func <A, string> showItem = null, double scale = 100)
 {
     if (showItem == null)
     {
         showItem = a => a.ToString();
     }
     return(ProbCSharp.Histogram.Finite(dist.Explicit, showItem, scale));
 }
コード例 #3
0
 /// <summary>
 /// Reweight by a probability that depends on associated item
 /// </summary>
 public static FiniteDist <A> ConditionSoft <A>(this FiniteDist <A> distribution, Func <A, Prob> likelihood)
 {
     return(new FiniteDist <A>(
                distribution.Explicit
                .Select(p => ItemProb(p.Item, likelihood(p.Item).Mult(p.Prob)))
                .Normalize()
                ));
 }
コード例 #4
0
 /// <summary>
 /// Lifts a FiniteDist<A> into a SampleableDist<A>
 /// </summary>
 public static PrimitiveDist <A> ToSampleDist <A>(this FiniteDist <A> dist)
 {
     return(new SampleDist <A>(() =>
     {
         var rand = new MathNet.Numerics.Distributions.ContinuousUniform().Sample();
         return dist.Pick(Prob(rand));
     }));
 }
コード例 #5
0
        /// <summary>
        /// Returns the probability of a certain event
        /// </summary>
        public static Prob ProbOf <A>(this FiniteDist <A> dist, Func <A, bool> eventTest)
        {
            var matches = dist.Explicit.Weights.Where(p => eventTest(p.Item));

            if (!matches.Any())
            {
                return(Prob(0));
            }
            return(Prob(matches.Sum(p => p.Prob.Value)));
        }
コード例 #6
0
        /// <summary>
        /// (FiniteDist dist) >>= bind = FiniteDist $ do
        ///   (x,p) <- dist
        ///   (y,q) <- bind x
        ///   return (y,p*q)
        /// </summary>
        public static FiniteDist <C> SelectMany <A, B, C>(
            this FiniteDist <A> self,
            Func <A, FiniteDist <B> > bind,
            Func <A, B, C> project
            )
        {
            var itemProbs = from xp in self.Explicit.Weights
                            from yq in bind(xp.Item).Explicit.Weights
                            select ItemProb(project(xp.Item, yq.Item), xp.Prob.Mult(yq.Prob));

            return(new FiniteDist <C>(Samples(itemProbs)));
        }
コード例 #7
0
        /// <summary>
        /// Pick a value from a distribution using a probability
        /// </summary>
        public static A Pick <A>(this FiniteDist <A> distribution, Prob pickProb)
        {
            var probVal = pickProb.Value;

            foreach (var prob in distribution.Explicit.Weights)
            {
                if (probVal < prob.Prob.Value)
                {
                    return(prob.Item);
                }
                probVal -= prob.Prob.Value;
            }
            throw new ArgumentException("Sampling failed");
        }
コード例 #8
0
        /// <summary>
        /// Calculates KL divergence of two finite distributions
        /// </summary>
        /// <param name="keyFunc">Groups identical samples</param>
        public static double KLDivergenceF <A, Key>(FiniteDist <A> distQ, FiniteDist <A> distP, Func <A, Key> keyFunc) where A : IComparable <A>
        {
            var            qWeights = Enumerate(distQ, keyFunc);
            Func <A, Prob> qDensity = x =>
            {
                var weight = qWeights.FirstOrDefault(ip => keyFunc(ip.Item).Equals(keyFunc(x)));
                if (weight == null)
                {
                    return(Prob(0));
                }
                return(weight.Prob);
            };

            var pWeights = Enumerate(distP, keyFunc);

            return(pWeights.Weights
                   .Sum(w => w.Prob.Value * Math.Log(w.Prob.Div(qDensity(w.Item)).Value)));
        }
コード例 #9
0
 /// <summary>
 /// Computes the posterior distribution, given a list of data and a likelihood function
 /// </summary>
 public static FiniteDist <A> UpdateOn <A, D>(this FiniteDist <A> prior, Func <A, D, Prob> likelihood, IEnumerable <D> data)
 {
     return(data.Aggregate(prior, (dist, datum) => dist.UpdateOn(likelihood, datum)));
 }
コード例 #10
0
 /// <summary>
 /// Computes the posterior distribution, given a piece of data and a likelihood function
 /// </summary>
 public static FiniteDist <A> UpdateOn <A, D>(this FiniteDist <A> prior, Func <A, D, Prob> likelihood, D datum)
 {
     return(prior.ConditionSoft(w => likelihood(w, datum)));
 }
コード例 #11
0
 /// <summary>
 /// Join two independent distributions
 /// </summary>
 public static FiniteDist <Tuple <A, B> > Join <A, B>(this FiniteDist <A> self, FiniteDist <B> other)
 {
     return(from a in self
            from b in other
            select new Tuple <A, B>(a, b));
 }
コード例 #12
0
 /// <summary>
 /// Normalize a finite distribution
 /// </summary>
 public static FiniteDist <A> Normalize <A>(this FiniteDist <A> dist)
 {
     return(new FiniteDist <A>(dist.Explicit.Normalize()));
 }
コード例 #13
0
        /// <summary>
        /// Calculates KL divergence from list of samples and a finite distribution
        /// </summary>
        /// <param name="keyFunc">Groups identical samples</param>
        public static double KLDivergence <A, Key>(Samples <A> samples, FiniteDist <A> dist, Func <A, Key> keyFunc) where A : IComparable <A>
        {
            var sampleDist = CategoricalF(samples);

            return(KLDivergenceF(sampleDist, dist, keyFunc));
        }
コード例 #14
0
 /// <summary>
 /// Aggregate & normalize samples
 /// The samples are arranged in ascending order
 /// </summary>
 public static Samples <A> Enumerate <A, Key>(FiniteDist <A> dist, Func <A, Key> keyFunc) where A : IComparable <A>
 {
     return(Importance.Normalize(Compact(dist.Explicit, keyFunc)));
 }
コード例 #15
0
 /// <summary>
 /// Primitive constructor for finite dists
 /// </summary>
 public static Dist <A> Primitive <A>(FiniteDist <A> dist)
 {
     return(new Primitive <A>(dist.ToSampleDist()));
 }
コード例 #16
0
 /// <summary>
 /// fmap f (FiniteDist (Samples xs)) = FiniteDist $ Samples $ map (first f) xs
 /// </summary>
 public static FiniteDist <B> Select <A, B>(this FiniteDist <A> self, Func <A, B> select)
 {
     return(new FiniteDist <B>(Samples(self.Explicit.Weights.Select(i =>
                                                                    ItemProb(select(i.Item), i.Prob)))));
 }