Пример #1
0
        /// <summary>EP message to <c>mean</c>.</summary>
        /// <param name="sample">Incoming message from <c>sample</c>. Must be a proper distribution. If uniform, the result will be uniform.</param>
        /// <param name="mean">Incoming message from <c>mean</c>. Must be a proper distribution. If uniform, the result will be uniform.</param>
        /// <returns>The outgoing EP message to the <c>mean</c> argument.</returns>
        /// <remarks>
        ///   <para>The outgoing message is a distribution matching the moments of <c>mean</c> as the random arguments are varied. The formula is <c>proj[p(mean) sum_(sample) p(sample) factor(sample,mean)]/p(mean)</c>.</para>
        /// </remarks>
        /// <exception cref="ImproperMessageException">
        ///   <paramref name="sample" /> is not a proper distribution.</exception>
        /// <exception cref="ImproperMessageException">
        ///   <paramref name="mean" /> is not a proper distribution.</exception>
        public static Gamma MeanAverageConditional([SkipIfUniform] Poisson sample, [Proper] Gamma mean)
        {
            if (sample.IsUniform())
            {
                return(Gamma.Uniform());
            }
            if (sample.IsPointMass)
            {
                return(MeanAverageConditional(sample.Point));
            }
            if (sample.Precision != 0)
            {
                throw new NotImplementedException("sample.Precision != 0 is not implemented");
            }
            // Z = int_m sum_x r^x m^x exp(-m)/x! q(m)
            //   = int_m exp(rm -m) q(m)
            //   = (1 + (1-r)/b)^(-a)
            // logZ = -a log(1 + (1-r)/b)
            // alpha = -b dlogZ/db
            //       = -a(1-r)/(b + (1-r))
            // beta = -b dalpha/db
            //      = -ba(1-r)/(b + (1-r))^2
            double omr   = 1 - sample.Rate;
            double denom = 1 / (mean.Rate + omr);
            double alpha = -mean.Shape * omr * denom;
            double beta  = mean.Rate * alpha * denom;

            return(GaussianOp.GammaFromAlphaBeta(mean, alpha, beta, ForceProper));
        }
Пример #2
0
        public static GammaPower GammaPowerFromDerivLogZ(GammaPower a, double dlogZ, double ddlogZ)
        {
            bool method1 = false;

            if (method1)
            {
                GetPosteriorMeanAndVariance(Gamma.FromShapeAndRate(a.Shape, a.Rate), dlogZ, ddlogZ, out double iaMean, out double iaVariance);
                Gamma ia = Gamma.FromMeanAndVariance(iaMean, iaVariance);
                return(GammaPower.FromShapeAndRate(ia.Shape, ia.Rate, a.Power) / a);
            }
            else
            {
                double alpha = -a.Rate * dlogZ;
                // dalpha/dr = -dlogZ - r*ddlogZ
                // beta = -r * dalpha/dr
                double beta  = a.Rate * dlogZ + a.Rate * a.Rate * ddlogZ;
                Gamma  prior = Gamma.FromShapeAndRate(a.Shape, a.Rate);
                // ia is the marginal of a^(1/a.Power)
                Gamma ia = GaussianOp.GammaFromAlphaBeta(prior, alpha, beta, true) * prior;
                return(GammaPower.FromShapeAndRate(ia.Shape, ia.Rate, a.Power) / a);
            }
        }