コード例 #1
0
        /// <summary>EP message to <c>sample</c>.</summary>
        /// <param name="choice">Incoming message from <c>choice</c>.</param>
        /// <param name="probTrue0">Constant value for <c>probTrue0</c>.</param>
        /// <param name="probTrue1">Constant value for <c>probTrue1</c>.</param>
        /// <returns>The outgoing EP message to the <c>sample</c> argument.</returns>
        /// <remarks>
        ///   <para>The outgoing message is a distribution matching the moments of <c>sample</c> as the random arguments are varied. The formula is <c>proj[p(sample) sum_(choice) p(choice) factor(sample,choice,probTrue0,probTrue1)]/p(sample)</c>.</para>
        /// </remarks>
        public static Bernoulli SampleAverageConditional(Bernoulli choice, double probTrue0, double probTrue1)
        {
            Bernoulli result = new Bernoulli();

            if (choice.IsPointMass)
            {
                return(SampleConditional(choice.Point, probTrue0, probTrue1));
            }
#if FAST
            result.SetProbTrue(choice.GetProbFalse() * probTrue0 + choice.GetProbTrue() * probTrue1);
#else
            // This method is more numerically stable but slower.
            // let oX = log(p(X)/(1-p(X))
            // let oY = log(p(Y)/(1-p(Y))
            // oX = log( (TT*sigma(oY) + TF*sigma(-oY))/(FT*sigma(oY) + FF*sigma(-oY)) )
            //    = log( (TT*exp(oY) + TF)/(FT*exp(oY) + FF) )
            //    = log( (exp(oY) + TF/TT)/(exp(oY) + FF/FT) ) + log(TT/FT)
            // ay = log(TF/TT)
            // by = log(FF/FT)
            // offset = log(TT/FT)
            if (probTrue0 == 0 || probTrue1 == 0)
            {
                throw new ArgumentException("probTrue is zero");
            }
            double ay     = Math.Log(probTrue0 / probTrue1);
            double by     = Math.Log((1 - probTrue0) / (1 - probTrue1));
            double offset = MMath.Logit(probTrue1);
            result.LogOdds = MMath.DiffLogSumExp(choice.LogOdds, ay, by) + offset;
#endif
            return(result);
        }
        /// <summary>
        /// Gets the distribution over class labels in the standard data format.
        /// </summary>
        /// <param name="nativeLabelDistribution">The distribution over class labels in the native data format.</param>
        /// <returns>The class label distribution in standard data format.</returns>
        protected override IDictionary <TLabel, double> GetStandardLabelDistribution(Bernoulli nativeLabelDistribution)
        {
            var labelDistribution = new Dictionary <TLabel, double>
            {
                { this.GetStandardLabel(true), nativeLabelDistribution.GetProbTrue() },
                { this.GetStandardLabel(false), nativeLabelDistribution.GetProbFalse() }
            };

            return(labelDistribution);
        }
コード例 #3
0
        /// <summary>EP message to <c>probTrue</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="probTrue">Incoming message from <c>probTrue</c>.</param>
        /// <returns>The outgoing EP message to the <c>probTrue</c> argument.</returns>
        /// <remarks>
        ///   <para>The outgoing message is a distribution matching the moments of <c>probTrue</c> as the random arguments are varied. The formula is <c>proj[p(probTrue) sum_(sample) p(sample) factor(sample,probTrue)]/p(probTrue)</c>.</para>
        /// </remarks>
        /// <exception cref="ImproperMessageException">
        ///   <paramref name="sample" /> is not a proper distribution.</exception>
        public static Beta ProbTrueAverageConditional([SkipIfUniform] Bernoulli sample, Beta probTrue)
        {
            // this code is similar to DiscreteFromDirichletOp.PAverageConditional()
            if (probTrue.IsPointMass)
            {
                return(Beta.Uniform());
            }
            if (sample.IsPointMass)
            {
                // shortcut
                return(ProbTrueConditional(sample.Point));
            }
            if (!probTrue.IsProper())
            {
                throw new ImproperMessageException(probTrue);
            }
            // q(x) is the distribution stored in this.X.
            // q(p) is the distribution stored in this.P.
            // f(x,p) is the factor.
            // Z = sum_x q(x) int_p f(x,p)*q(p) = q(false)*E[1-p] + q(true)*E[p]
            // Ef[p] = 1/Z sum_x q(x) int_p p*f(x,p)*q(p) = 1/Z (q(false)*E[p(1-p)] + q(true)*E[p^2])
            // Ef[p^2] = 1/Z sum_x q(x) int_p p^2*f(x,p)*q(p) = 1/Z (q(false)*E[p^2(1-p)] + q(true)*E[p^3])
            // var_f(p) = Ef[p^2] - Ef[p]^2
            double mo  = probTrue.GetMean();
            double m2o = probTrue.GetMeanSquare();
            double pT  = sample.GetProbTrue();
            double pF  = sample.GetProbFalse();
            double Z   = pF * (1 - mo) + pT * mo;
            double m   = pF * (mo - m2o) + pT * m2o;

            m = m / Z;
            if (!Beta.AllowImproperSum)
            {
                if (pT < 0.5)
                {
                    double inc = probTrue.TotalCount * (mo / m - 1);
                    return(new Beta(1, 1 + inc));
                }
                else
                {
                    double inc = probTrue.TotalCount * ((1 - mo) / (1 - m) - 1);
                    return(new Beta(1 + inc, 1));
                }
            }
            else
            {
                double m3o = probTrue.GetMeanCube();
                double m2  = pF * (m2o - m3o) + pT * m3o;
                m2 = m2 / Z;
                Beta result = Beta.FromMeanAndVariance(m, m2 - m * m);
                result.SetToRatio(result, probTrue);
                return(result);
            }
        }
コード例 #4
0
        /// <summary>VMP message to <c>sample</c>.</summary>
        /// <param name="choice">Incoming message from <c>choice</c>.</param>
        /// <param name="probTrue0">Constant value for <c>probTrue0</c>.</param>
        /// <param name="probTrue1">Constant value for <c>probTrue1</c>.</param>
        /// <returns>The outgoing VMP message to the <c>sample</c> argument.</returns>
        /// <remarks>
        ///   <para>The outgoing message is the exponential of the average log-factor value, where the average is over all arguments except <c>sample</c>. The formula is <c>exp(sum_(choice) p(choice) log(factor(sample,choice,probTrue0,probTrue1)))</c>.</para>
        /// </remarks>
        public static Bernoulli SampleAverageLogarithm(Bernoulli choice, double probTrue0, double probTrue1)
        {
            Bernoulli result = new Bernoulli();

            if (choice.IsPointMass)
            {
                return(SampleConditional(choice.Point, probTrue0, probTrue1));
            }
            // log(p(X=true)/p(X=false)) = sum_k p(Y=k) log(ProbTrue[k]/(1-ProbTrue[k]))
            result.LogOdds = choice.GetProbFalse() * MMath.Logit(probTrue0) + choice.GetProbTrue() * MMath.Logit(probTrue1);
            return(result);
        }
コード例 #5
0
        /// <summary>EP message to <c>choice</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="probTrue0">Constant value for <c>probTrue0</c>.</param>
        /// <param name="probTrue1">Constant value for <c>probTrue1</c>.</param>
        /// <returns>The outgoing EP message to the <c>choice</c> argument.</returns>
        /// <remarks>
        ///   <para>The outgoing message is a distribution matching the moments of <c>choice</c> as the random arguments are varied. The formula is <c>proj[p(choice) sum_(sample) p(sample) factor(sample,choice,probTrue0,probTrue1)]/p(choice)</c>.</para>
        /// </remarks>
        /// <exception cref="ImproperMessageException">
        ///   <paramref name="sample" /> is not a proper distribution.</exception>
        public static Bernoulli ChoiceAverageConditional([SkipIfUniform] Bernoulli sample, double probTrue0, double probTrue1)
        {
            Bernoulli result = new Bernoulli();

            if (sample.IsPointMass)
            {
                return(ChoiceConditional(sample.Point, probTrue0, probTrue1));
            }
#if FAST
            double p1  = sample.GetProbFalse() * (1 - probTrue1) + sample.GetProbTrue() * probTrue1;
            double p0  = sample.GetProbFalse() * (1 - probTrue0) + sample.GetProbTrue() * probTrue0;
            double sum = p0 + p1;
            if (sum == 0.0)
            {
                throw new AllZeroException();
            }
            else
            {
                result.SetProbTrue(p1 / sum);
            }
#else
            // This method is more numerically stable but slower.
            // ax = log(FT/TT)
            // bx = log(FF/TF)
            // offset = log(TT/TF)
            if (probTrue0 == 0 || probTrue1 == 0)
            {
                throw new ArgumentException("probTrue is zero");
            }
            double ax     = -MMath.Logit(probTrue1);
            double bx     = -MMath.Logit(probTrue0);
            double offset = Math.Log(probTrue1 / probTrue0);
            result.LogOdds = MMath.DiffLogSumExp(sample.LogOdds, ax, bx) + offset;
#endif
            return(result);
        }
コード例 #6
0
        public static Beta ProbTrueAverageConditional([SkipIfUniform] Bernoulli sample, double probTrue)
        {
            // f(x,p) = q(T) p + q(F) (1-p)
            // dlogf/dp = (q(T) - q(F))/f(x,p)
            // ddlogf/dp^2 = -(q(T) - q(F))^2/f(x,p)^2
            double qT        = sample.GetProbTrue();
            double qF        = sample.GetProbFalse();
            double pTT       = qT * probTrue;
            double probFalse = 1 - probTrue;
            double pFF       = qF * probFalse;
            double Z         = pTT + pFF;
            double dlogp     = (qT - qF) / Z;
            double ddlogp    = -dlogp * dlogp;

            return(Beta.FromDerivatives(probTrue, dlogp, ddlogp, !Beta.AllowImproperSum));
        }
コード例 #7
0
        /// <include file='FactorDocs.xml' path='factor_docs/message_op_class[@name="StringsAreEqualOp"]/message_doc[@name="Str1AverageConditional(StringDistribution, Bernoulli, StringDistribution)"]/*'/>
        public static StringDistribution Str1AverageConditional(
            StringDistribution str2, [SkipIfUniform] Bernoulli areEqual, StringDistribution result)
        {
            StringDistribution uniform      = StringDistribution.Any();
            double             probNotEqual = areEqual.GetProbFalse();

            if (probNotEqual > 0.5)
            {
                throw new NotImplementedException("Non-equality case is not yet supported.");
            }

            double logWeight1 = Math.Log(1 - (2 * probNotEqual));
            double logWeight2 = Math.Log(probNotEqual) + uniform.GetLogNormalizer();

            result.SetToSumLog(logWeight1, str2, logWeight2, uniform);
            return(result);
        }
コード例 #8
0
 /// <summary>Evidence message for VMP.</summary>
 /// <param name="sample">Incoming message from <c>sample</c>.</param>
 /// <param name="logOdds">Constant value for <c>logOdds</c>.</param>
 /// <returns>Average of the factor's log-value across the given argument distributions.</returns>
 /// <remarks>
 ///   <para>The formula for the result is <c>sum_(sample) p(sample) log(factor(sample,logOdds))</c>. Adding up these values across all factors and variables gives the log-evidence estimate for VMP.</para>
 /// </remarks>
 public static double AverageLogFactor(Bernoulli sample, double logOdds)
 {
     if (sample.IsPointMass)
     {
         return(AverageLogFactor(sample.Point, logOdds));
     }
     // probTrue*log(sigma(logOdds)) + probFalse*log(sigma(-logOdds))
     // = -log(1+exp(-logOdds)) + probFalse*(-logOdds)
     // = probTrue*logOdds - log(1+exp(logOdds))
     if (logOdds >= 0)
     {
         double probFalse = sample.GetProbFalse();
         return(-probFalse * logOdds - MMath.Log1PlusExp(-logOdds));
     }
     else
     {
         double probTrue = sample.GetProbTrue();
         return(probTrue * logOdds - MMath.Log1PlusExp(logOdds));
     }
 }
コード例 #9
0
 /// <summary>
 /// Evidence message for EP.
 /// </summary>
 /// <param name="cases">Incoming message from 'cases'.</param>
 /// <param name="b">Incoming message from 'b'.</param>
 public static double LogEvidenceRatio(IList <Bernoulli> cases, Bernoulli b)
 {
     // result = log (p(data|b=true) p(b=true) + p(data|b=false) p(b=false))
     //          log (p(data|b=true) p(b=true) + p(data|b=false) (1-p(b=true))
     //          log ((p(data|b=true) - p(data|b=false)) p(b=true) + p(data|b=false))
     //          log ((p(data|b=true)/p(data|b=false) - 1) p(b=true) + 1) + log p(data|b=false)
     // where cases[0].LogOdds = log p(data|b=true)
     //       cases[1].LogOdds = log p(data|b=false)
     if (b.IsPointMass)
     {
         return(b.Point ? cases[0].LogOdds : cases[1].LogOdds);
     }
     //else return MMath.LogSumExp(cases[0].LogOdds + b.GetLogProbTrue(), cases[1].LogOdds + b.GetLogProbFalse());
     else
     {
         // the common case is when cases[0].LogOdds == cases[1].LogOdds.  we must not introduce rounding error in that case.
         if (cases[0].LogOdds >= cases[1].LogOdds)
         {
             if (Double.IsNegativeInfinity(cases[1].LogOdds))
             {
                 return(cases[0].LogOdds + b.GetLogProbTrue());
             }
             else
             {
                 return(cases[1].LogOdds + MMath.Log1Plus(b.GetProbTrue() * MMath.ExpMinus1(cases[0].LogOdds - cases[1].LogOdds)));
             }
         }
         else
         {
             if (Double.IsNegativeInfinity(cases[0].LogOdds))
             {
                 return(cases[1].LogOdds + b.GetLogProbFalse());
             }
             else
             {
                 return(cases[0].LogOdds + MMath.Log1Plus(b.GetProbFalse() * MMath.ExpMinus1(cases[1].LogOdds - cases[0].LogOdds)));
             }
         }
     }
 }
コード例 #10
0
        /// <summary>
        /// VMP message to 'choice'.
        /// </summary>
        /// <param name="sample">Incoming message from 'sample'.</param>
        /// <param name="probTrue0">Constant value for 'probTrue0'.</param>
        /// <param name="probTrue1">Constant value for 'probTrue1'.</param>
        /// <returns>The outgoing VMP message to the 'choice' argument.</returns>
        /// <remarks><para>
        /// The outgoing message is the exponential of the integral of the log-factor times incoming messages, over all arguments except 'choice'.
        /// The formula is <c>int log(f(choice,x)) q(x) dx</c> where <c>x = (sample,probTrue0,probTrue1)</c>.
        /// </para></remarks>
		public static Bernoulli ChoiceAverageLogarithm(Bernoulli sample, double probTrue0, double probTrue1)
		{
            Bernoulli result = new Bernoulli();
			if(sample.IsPointMass) return ChoiceConditional(sample.Point,probTrue0,probTrue1);
			// p(Y=k) =propto ProbTrue[k]^p(X=true) (1-ProbTrue[k])^p(X=false)
			// log(p(Y=true)/p(Y=false)) = p(X=true)*log(ProbTrue[1]/ProbTrue[0]) + p(X=false)*log((1-ProbTrue[1])/(1-ProbTrue[0]))
			//                           = p(X=false)*(log(ProbTrue[0]/(1-ProbTrue[0]) - log(ProbTrue[1]/(1-ProbTrue[1]))) + log(ProbTrue[1]/ProbTrue[0])
			if (probTrue0 == 0 || probTrue1 == 0) throw new ArgumentException("probTrue is zero");
			result.LogOdds = sample.GetProbTrue() * Math.Log(probTrue1 / probTrue0) + sample.GetProbFalse() * Math.Log((1 - probTrue1) / (1 - probTrue0));
			return result;
		}
コード例 #11
0
		/// <summary>
		/// Evidence message for VMP.
		/// </summary>
		/// <param name="sample">Incoming message from sample</param>
		/// <param name="logOdds">Fixed value for logOdds</param>
		/// <returns><c>sum_x marginal(x)*log(factor(x))</c></returns>
		/// <remarks><para>
		/// The formula for the result is <c>int log(f(x)) q(x) dx</c>
		/// where <c>x = (sample,logOdds)</c>.
		/// </para></remarks>
		public static double AverageLogFactor(Bernoulli sample, double logOdds)
		{
			if (sample.IsPointMass) return AverageLogFactor(sample.Point, logOdds);
			// probTrue*log(sigma(logOdds)) + probFalse*log(sigma(-logOdds))
			// = -log(1+exp(-logOdds)) + probFalse*(-logOdds)
			// = probTrue*logOdds - log(1+exp(logOdds))
			if (logOdds >= 0) {
				double probFalse = sample.GetProbFalse();
				return -probFalse * logOdds - MMath.Log1PlusExp(-logOdds);
			} else {
				double probTrue = sample.GetProbTrue();
				return probTrue * logOdds - MMath.Log1PlusExp(logOdds);
			}
		}
コード例 #12
0
        /// <summary>VMP message to <c>choice</c>.</summary>
        /// <param name="sample">Incoming message from <c>sample</c>.</param>
        /// <param name="probTrue0">Constant value for <c>probTrue0</c>.</param>
        /// <param name="probTrue1">Constant value for <c>probTrue1</c>.</param>
        /// <returns>The outgoing VMP message to the <c>choice</c> argument.</returns>
        /// <remarks>
        ///   <para>The outgoing message is the exponential of the average log-factor value, where the average is over all arguments except <c>choice</c>. The formula is <c>exp(sum_(sample) p(sample) log(factor(sample,choice,probTrue0,probTrue1)))</c>.</para>
        /// </remarks>
        public static Bernoulli ChoiceAverageLogarithm(Bernoulli sample, double probTrue0, double probTrue1)
        {
            Bernoulli result = new Bernoulli();

            if (sample.IsPointMass)
            {
                return(ChoiceConditional(sample.Point, probTrue0, probTrue1));
            }
            // p(Y=k) =propto ProbTrue[k]^p(X=true) (1-ProbTrue[k])^p(X=false)
            // log(p(Y=true)/p(Y=false)) = p(X=true)*log(ProbTrue[1]/ProbTrue[0]) + p(X=false)*log((1-ProbTrue[1])/(1-ProbTrue[0]))
            //                           = p(X=false)*(log(ProbTrue[0]/(1-ProbTrue[0]) - log(ProbTrue[1]/(1-ProbTrue[1]))) + log(ProbTrue[1]/ProbTrue[0])
            if (probTrue0 == 0 || probTrue1 == 0)
            {
                throw new ArgumentException("probTrue is zero");
            }
            result.LogOdds = sample.GetProbTrue() * Math.Log(probTrue1 / probTrue0) + sample.GetProbFalse() * Math.Log((1 - probTrue1) / (1 - probTrue0));
            return(result);
        }
コード例 #13
0
        public static VectorGaussianWishart ShapeParamsAverageConditional(
            Vector point, Bernoulli label, [Proper] VectorGaussianWishart shapeParams, VectorGaussianWishart result)
        {
            VectorGaussianWishart shapeParamsTimesFactor = DistributionTimesFactor(point, shapeParams);

            double labelProbFalse = label.GetProbFalse();
            double shapeParamsWeight = labelProbFalse;
            double shapeParamsTimesFactorWeight =
                Math.Exp(shapeParamsTimesFactor.GetLogNormalizer() - shapeParams.GetLogNormalizer()) *
                (1 - 2 * labelProbFalse);

            var projectionOfSum = new VectorGaussianWishart(2);
            projectionOfSum.SetToSum(shapeParamsWeight, shapeParams, shapeParamsTimesFactorWeight, shapeParamsTimesFactor);
            Debug.Assert(projectionOfSum.IsProper()); // TODO: remove me
            result.SetToRatio(projectionOfSum, shapeParams);

            return result;
        }
コード例 #14
0
 public static double LogAverageFactor(Bernoulli label, Vector point, GaussianGamma shapeParamsX, GaussianGamma shapeParamsY)
 {
     GaussianGamma shapeParamsXDistrTimesFactor = DistributionTimesFactor(point[0], shapeParamsX);
     GaussianGamma shapeParamsYDistrTimesFactor = DistributionTimesFactor(point[1], shapeParamsY);
     double labelProbFalse = label.GetProbFalse();
     double normalizerProduct = Math.Exp(
         shapeParamsXDistrTimesFactor.GetLogNormalizer() - shapeParamsX.GetLogNormalizer() +
         shapeParamsYDistrTimesFactor.GetLogNormalizer() - shapeParamsY.GetLogNormalizer());
     double averageFactor = labelProbFalse + (1 - 2 * labelProbFalse) * normalizerProduct;
     Debug.Assert(averageFactor > 0);
     return Math.Log(averageFactor);
 }
コード例 #15
0
        private static GaussianGamma ShapeParamsAverageConditional(
            double coord, double otherCoord, Bernoulli label, GaussianGamma shapeParamsDistr, GaussianGamma otherShapeParamsDistr, GaussianGamma result)
        {
            GaussianGamma shapeParamsDistrTimesFactor = DistributionTimesFactor(coord, shapeParamsDistr);
            GaussianGamma otherShapeParamsDistrTimesFactor = DistributionTimesFactor(otherCoord, otherShapeParamsDistr);
            double labelProbFalse = label.GetProbFalse();
            double weight1 = labelProbFalse;
            double weight2 = Math.Exp(
                shapeParamsDistrTimesFactor.GetLogNormalizer() - shapeParamsDistr.GetLogNormalizer() +
                otherShapeParamsDistrTimesFactor.GetLogNormalizer() - otherShapeParamsDistr.GetLogNormalizer()) *
                (1 - 2 * labelProbFalse);
            var projectionOfSum = new GaussianGamma();
            projectionOfSum.SetToSum(weight1, shapeParamsDistr, weight2, shapeParamsDistrTimesFactor);
            result.SetToRatio(projectionOfSum, shapeParamsDistr);

            return result;
        }
コード例 #16
0
ファイル: IsBetween.cs プロジェクト: xornand/Infer.Net
		/// <summary>
		/// Evidence message for EP
		/// </summary>
		/// <param name="isBetween">Incoming message from 'isBetween'.</param>
		/// <param name="X">Incoming message from 'x'.</param>
		/// <param name="lowerBound">Incoming message from 'lowerBound'.</param>
		/// <param name="upperBound">Incoming message from 'upperBound'.</param>
		/// <returns>Logarithm of the factor's average value across the given argument distributions</returns>
		/// <remarks><para>
		/// The formula for the result is <c>log(sum_(isBetween,x,lowerBound,upperBound) p(isBetween,x,lowerBound,upperBound) factor(isBetween,x,lowerBound,upperBound))</c>.
		/// </para></remarks>
		public static double LogAverageFactor(Bernoulli isBetween, Gaussian X, Gaussian lowerBound, Gaussian upperBound)
		{
			if (isBetween.LogOdds == 0.0) return -MMath.Ln2;
			else
			{
#if true
				double logitProbBetween = MMath.LogitFromLog(LogProbBetween(X, lowerBound, upperBound));
				return Bernoulli.LogProbEqual(isBetween.LogOdds, logitProbBetween);
#else
			double d_p = isBetween.GetProbTrue() - isBetween.GetProbFalse();
			return Math.Log(d_p * Math.Exp(LogProbBetween()) + isBetween.GetProbFalse());
#endif
			}
		}
コード例 #17
0
        private static Gaussian ShapeAverageConditional(
            Vector point, Bernoulli label, Gaussian shapeX, Gaussian shapeY, PositiveDefiniteMatrix shapeOrientation, bool resultForXCoord)
        {
            if (shapeX.IsPointMass && shapeY.IsPointMass)
            {
                double labelProbTrue = label.GetProbTrue();
                double labelProbFalse = 1.0 - labelProbTrue;
                double probDiff = labelProbTrue - labelProbFalse;

                Vector shapeLocation = Vector.FromArray(shapeX.Point, shapeY.Point);
                Vector diff = point - shapeLocation;
                Vector orientationTimesDiff = shapeOrientation * diff;
                Matrix orientationTimesDiffOuter = orientationTimesDiff.Outer(orientationTimesDiff);

                double factorValue = Math.Exp(-0.5 * shapeOrientation.QuadraticForm(diff));
                double funcValue = factorValue * probDiff + labelProbFalse;

                Vector dFunc = probDiff * factorValue * orientationTimesDiff;
                Vector dLogFunc = 1.0 / funcValue * dFunc;
                Matrix ddLogFunc =
                    ((orientationTimesDiffOuter + shapeOrientation) * factorValue * funcValue - orientationTimesDiffOuter * probDiff * factorValue * factorValue)
                    * (probDiff / (funcValue * funcValue));

                double x = resultForXCoord ? shapeX.Point : shapeY.Point;
                double d = resultForXCoord ? dLogFunc[0] : dLogFunc[1];
                double dd = resultForXCoord ? ddLogFunc[0, 0] : ddLogFunc[1, 1];
                return Gaussian.FromDerivatives(x, d, dd, forceProper: true);
            }
            else if (!shapeX.IsPointMass && !shapeY.IsPointMass)
            {
                VectorGaussian shapeLocationTimesFactor = ShapeLocationTimesFactor(point, shapeX, shapeY, shapeOrientation);
                double labelProbFalse = label.GetProbFalse();
                double shapeLocationWeight = labelProbFalse;
                double shapeLocationTimesFactorWeight =
                    Math.Exp(shapeLocationTimesFactor.GetLogNormalizer() - shapeX.GetLogNormalizer() - shapeY.GetLogNormalizer() - 0.5 * shapeOrientation.QuadraticForm(point)) *
                    (1 - 2 * labelProbFalse);

                var projectionOfSum = new Gaussian();
                projectionOfSum.SetToSum(
                    shapeLocationWeight,
                    resultForXCoord ? shapeX : shapeY,
                    shapeLocationTimesFactorWeight,
                    shapeLocationTimesFactor.GetMarginal(resultForXCoord ? 0 : 1));
                Gaussian result = new Gaussian();
                result.SetToRatio(projectionOfSum, resultForXCoord ? shapeX : shapeY);

                return result;
            }
            else
            {
                throw new NotSupportedException();
            }
        }
コード例 #18
0
 /// <summary>VMP message to <c>a</c>.</summary>
 /// <param name="or">Incoming message from <c>or</c>. Must be a proper distribution. If uniform, the result will be uniform.</param>
 /// <param name="B">Incoming message from <c>b</c>.</param>
 /// <returns>The outgoing VMP message to the <c>a</c> argument.</returns>
 /// <remarks>
 ///   <para>The outgoing message is the exponential of the average log-factor value, where the average is over all arguments except <c>a</c>. Because the factor is deterministic, <c>or</c> is integrated out before taking the logarithm. The formula is <c>exp(sum_(b) p(b) log(sum_or p(or) factor(or,a,b)))</c>.</para>
 /// </remarks>
 /// <exception cref="ImproperMessageException">
 ///   <paramref name="or" /> is not a proper distribution.</exception>
 public static Bernoulli AAverageLogarithm([SkipIfUniform] Bernoulli or, Bernoulli B)
 {
     // when 'or' is marginalized, the factor is proportional to exp((A|B)*or.LogOdds)
     return(Bernoulli.FromLogOdds(or.LogOdds * B.GetProbFalse()));
 }
コード例 #19
0
        /// <summary>
        /// VMP message to 'sample'.
        /// </summary>
        /// <param name="choice">Incoming message from 'choice'.</param>
        /// <param name="probTrue0">Constant value for 'probTrue0'.</param>
        /// <param name="probTrue1">Constant value for 'probTrue1'.</param>
        /// <returns>The outgoing VMP message to the 'sample' argument.</returns>
        /// <remarks><para>
        /// The outgoing message is the exponential of the integral of the log-factor times incoming messages, over all arguments except 'sample'.
        /// The formula is <c>int log(f(sample,x)) q(x) dx</c> where <c>x = (choice,probTrue0,probTrue1)</c>.
        /// </para></remarks>
        public static Bernoulli SampleAverageLogarithm(Bernoulli choice, double probTrue0, double probTrue1)
		{
            Bernoulli result = new Bernoulli();
			if(choice.IsPointMass) return SampleConditional(choice.Point,probTrue0,probTrue1);
			// log(p(X=true)/p(X=false)) = sum_k p(Y=k) log(ProbTrue[k]/(1-ProbTrue[k]))
			result.LogOdds = choice.GetProbFalse() * MMath.Logit(probTrue0) + choice.GetProbTrue() * MMath.Logit(probTrue1);
			return result;
		}
コード例 #20
0
        /// <summary>
        /// EP message to 'sample'.
        /// </summary>
        /// <param name="choice">Incoming message from 'choice'.</param>
        /// <param name="probTrue0">Constant value for 'probTrue0'.</param>
        /// <param name="probTrue1">Constant value for 'probTrue1'.</param>
        /// <returns>The outgoing EP message to the 'sample' argument.</returns>
        /// <remarks><para>
        /// The outgoing message is the integral of the factor times incoming messages, over all arguments except 'sample'.
        /// The formula is <c>int f(sample,x) q(x) dx</c> where <c>x = (choice,probTrue0,probTrue1)</c>.
        /// </para></remarks>
        public static Bernoulli SampleAverageConditional(Bernoulli choice, double probTrue0, double probTrue1)
		{
            Bernoulli result = new Bernoulli();
			if(choice.IsPointMass) return SampleConditional(choice.Point,probTrue0,probTrue1);
#if FAST
			result.SetProbTrue(choice.GetProbFalse() * probTrue0 + choice.GetProbTrue() * probTrue1);
#else
			// This method is more numerically stable but slower.
			// let oX = log(p(X)/(1-p(X))
			// let oY = log(p(Y)/(1-p(Y))
			// oX = log( (TT*sigma(oY) + TF*sigma(-oY))/(FT*sigma(oY) + FF*sigma(-oY)) )
			//    = log( (TT*exp(oY) + TF)/(FT*exp(oY) + FF) )
			//    = log( (exp(oY) + TF/TT)/(exp(oY) + FF/FT) ) + log(TT/FT)
			// ay = log(TF/TT)
			// by = log(FF/FT)
			// offset = log(TT/FT)
			if (probTrue0 == 0 || probTrue1 == 0) throw new ArgumentException("probTrue is zero");
			double ay = Math.Log(probTrue0 / probTrue1);
			double by = Math.Log((1 - probTrue0) / (1 - probTrue1));
			double offset = MMath.Logit(probTrue1);
			result.LogOdds = MMath.DiffLogSumExp(choice.LogOdds, ay, by) + offset;
#endif
			return result;
		}
コード例 #21
0
ファイル: Or.cs プロジェクト: xornand/Infer.Net
		/// <summary>
		/// VMP message to 'a'
		/// </summary>
		/// <param name="or">Incoming message from 'or'. Must be a proper distribution.  If uniform, the result will be uniform.</param>
		/// <param name="B">Incoming message from 'b'.</param>
		/// <returns>The outgoing VMP message to the 'a' argument</returns>
		/// <remarks><para>
		/// The outgoing message is the exponential of the average log-factor value, where the average is over all arguments except 'a'.
		/// Because the factor is deterministic, 'or' is integrated out before taking the logarithm.
		/// The formula is <c>exp(sum_(b) p(b) log(sum_or p(or) factor(or,a,b)))</c>.
		/// </para></remarks>
		/// <exception cref="ImproperMessageException"><paramref name="or"/> is not a proper distribution</exception>
		public static Bernoulli AAverageLogarithm([SkipIfUniform] Bernoulli or, Bernoulli B)
		{
			// when 'or' is marginalized, the factor is proportional to exp((A|B)*or.LogOdds)
			return Bernoulli.FromLogOdds(or.LogOdds * B.GetProbFalse());
		}
コード例 #22
0
        /// <summary>
        /// Tests EP and BP gate enter ops for Bernoulli random variable for correctness given message parameters.
        /// </summary>
        /// <param name="valueProbTrue">Probability of being true for the variable entering the gate.</param>
        /// <param name="enterOneProbTrue">Probability of being true for the variable approximation inside the gate when the selector is true.</param>
        /// <param name="selectorProbTrue">Probability of being true for the selector variable.</param>
        private void DoBernoulliEnterTest(double valueProbTrue, double enterOneProbTrue, double selectorProbTrue)
        {
            var value                   = new Bernoulli(valueProbTrue);
            var enterOne                = new Bernoulli(enterOneProbTrue);
            var selector                = new Bernoulli(selectorProbTrue);
            var selectorInverse         = new Bernoulli(selector.GetProbFalse());
            var discreteSelector        = new Discrete(selector.GetProbTrue(), selector.GetProbFalse());
            var discreteSelectorInverse = new Discrete(selector.GetProbFalse(), selector.GetProbTrue());
            var cases                   = new[] { Bernoulli.FromLogOdds(selector.GetLogProbTrue()), Bernoulli.FromLogOdds(selector.GetLogProbFalse()) };

            // Compute expected message
            double logShift           = enterOne.GetLogNormalizer() + value.GetLogNormalizer() - (value * enterOne).GetLogNormalizer();
            double expectedProbTrue   = selector.GetProbFalse() + (selector.GetProbTrue() * enterOne.GetProbTrue() * Math.Exp(logShift));
            double expectedProbFalse  = selector.GetProbFalse() + (selector.GetProbTrue() * enterOne.GetProbFalse() * Math.Exp(logShift));
            double expectedNormalizer = expectedProbTrue + expectedProbFalse;

            expectedProbTrue /= expectedNormalizer;

            Bernoulli value1, value2;

            // Enter partial (bernoulli selector, first case)
            value1 = GateEnterPartialOp <bool> .ValueAverageConditional(
                new[] { enterOne }, selector, value, new[] { 0 }, new Bernoulli());

            value2 = BeliefPropagationGateEnterPartialOp.ValueAverageConditional(
                new[] { enterOne }, selector, value, new[] { 0 }, new Bernoulli());
            Assert.Equal(expectedProbTrue, value1.GetProbTrue(), 1e-4);
            Assert.Equal(expectedProbTrue, value2.GetProbTrue(), 1e-4);

            // Enter partial (bernoulli selector, second case)
            value1 = GateEnterPartialOp <bool> .ValueAverageConditional(
                new[] { enterOne }, selectorInverse, value, new[] { 1 }, new Bernoulli());

            value2 = BeliefPropagationGateEnterPartialOp.ValueAverageConditional(
                new[] { enterOne }, selectorInverse, value, new[] { 1 }, new Bernoulli());
            Assert.Equal(expectedProbTrue, value1.GetProbTrue(), 1e-4);
            Assert.Equal(expectedProbTrue, value2.GetProbTrue(), 1e-4);

            // Enter partial (bernoulli selector, both cases)
            value1 = GateEnterPartialOp <bool> .ValueAverageConditional(
                new[] { enterOne, Bernoulli.Uniform() }, selector, value, new[] { 0, 1 }, new Bernoulli());

            value2 = BeliefPropagationGateEnterPartialOp.ValueAverageConditional(
                new[] { enterOne, Bernoulli.Uniform() }, selector, value, new[] { 0, 1 }, new Bernoulli());
            Assert.Equal(expectedProbTrue, value1.GetProbTrue(), 1e-4);
            Assert.Equal(expectedProbTrue, value2.GetProbTrue(), 1e-4);

            // Enter partial (discrete selector, first case)
            value1 = GateEnterPartialOp <bool> .ValueAverageConditional(
                new[] { enterOne }, discreteSelector, value, new[] { 0 }, new Bernoulli());

            value2 = BeliefPropagationGateEnterPartialOp.ValueAverageConditional(
                new[] { enterOne }, discreteSelector, value, new[] { 0 }, new Bernoulli());
            Assert.Equal(expectedProbTrue, value1.GetProbTrue(), 1e-4);
            Assert.Equal(expectedProbTrue, value2.GetProbTrue(), 1e-4);

            // Enter partial (discrete selector, second case)
            value1 = GateEnterPartialOp <bool> .ValueAverageConditional(
                new[] { enterOne }, discreteSelectorInverse, value, new[] { 1 }, new Bernoulli());

            value2 = BeliefPropagationGateEnterPartialOp.ValueAverageConditional(
                new[] { enterOne }, discreteSelectorInverse, value, new[] { 1 }, new Bernoulli());
            Assert.Equal(expectedProbTrue, value1.GetProbTrue(), 1e-4);
            Assert.Equal(expectedProbTrue, value2.GetProbTrue(), 1e-4);

            // Enter partial (discrete selector, both cases)
            value1 = GateEnterPartialOp <bool> .ValueAverageConditional(
                new[] { enterOne, Bernoulli.Uniform() }, discreteSelector, value, new[] { 0, 1 }, new Bernoulli());

            value2 = BeliefPropagationGateEnterPartialOp.ValueAverageConditional(
                new[] { enterOne, Bernoulli.Uniform() }, discreteSelector, value, new[] { 0, 1 }, new Bernoulli());
            Assert.Equal(expectedProbTrue, value1.GetProbTrue(), 1e-4);
            Assert.Equal(expectedProbTrue, value2.GetProbTrue(), 1e-4);

            // Enter one (discrete selector, first case)
            value1 = GateEnterOneOp <bool> .ValueAverageConditional(
                enterOne, discreteSelector, value, 0, new Bernoulli());

            value2 = BeliefPropagationGateEnterOneOp.ValueAverageConditional(
                enterOne, discreteSelector, value, 0, new Bernoulli());
            Assert.Equal(expectedProbTrue, value1.GetProbTrue(), 1e-4);
            Assert.Equal(expectedProbTrue, value2.GetProbTrue(), 1e-4);

            // Enter one (discrete selector, second case)
            value1 = GateEnterOneOp <bool> .ValueAverageConditional(
                enterOne, discreteSelectorInverse, value, 1, new Bernoulli());

            value2 = BeliefPropagationGateEnterOneOp.ValueAverageConditional(
                enterOne, discreteSelectorInverse, value, 1, new Bernoulli());
            Assert.Equal(expectedProbTrue, value1.GetProbTrue(), 1e-4);
            Assert.Equal(expectedProbTrue, value2.GetProbTrue(), 1e-4);

            // Enter partial two  (first case)
            value1 = GateEnterPartialTwoOp.ValueAverageConditional(
                new[] { enterOne }, cases[0], cases[1], value, new[] { 0 }, new Bernoulli());
            value2 = BeliefPropagationGateEnterPartialTwoOp.ValueAverageConditional(
                new[] { enterOne }, cases[0], cases[1], value, new[] { 0 }, new Bernoulli());
            Assert.Equal(expectedProbTrue, value1.GetProbTrue(), 1e-4);
            Assert.Equal(expectedProbTrue, value2.GetProbTrue(), 1e-4);

            // Enter partial two  (second case)
            value1 = GateEnterPartialTwoOp.ValueAverageConditional(
                new[] { enterOne }, cases[1], cases[0], value, new[] { 1 }, new Bernoulli());
            value2 = BeliefPropagationGateEnterPartialTwoOp.ValueAverageConditional(
                new[] { enterOne }, cases[1], cases[0], value, new[] { 1 }, new Bernoulli());
            Assert.Equal(expectedProbTrue, value1.GetProbTrue(), 1e-4);
            Assert.Equal(expectedProbTrue, value2.GetProbTrue(), 1e-4);

            // Enter partial two (both cases)
            value1 = GateEnterPartialTwoOp.ValueAverageConditional(
                new[] { enterOne, Bernoulli.Uniform() }, cases[0], cases[1], value, new[] { 0, 1 }, new Bernoulli());
            value2 = BeliefPropagationGateEnterPartialTwoOp.ValueAverageConditional(
                new[] { enterOne, Bernoulli.Uniform() }, cases[0], cases[1], value, new[] { 0, 1 }, new Bernoulli());
            Assert.Equal(expectedProbTrue, value1.GetProbTrue(), 1e-4);
            Assert.Equal(expectedProbTrue, value2.GetProbTrue(), 1e-4);

            // Enter (discrete selector)
            value1 = GateEnterOp <bool> .ValueAverageConditional(
                new[] { enterOne, Bernoulli.Uniform() }, discreteSelector, value, new Bernoulli());

            value2 = BeliefPropagationGateEnterOp.ValueAverageConditional(
                new[] { enterOne, Bernoulli.Uniform() }, discreteSelector, value, new Bernoulli());
            Assert.Equal(expectedProbTrue, value1.GetProbTrue(), 1e-4);
            Assert.Equal(expectedProbTrue, value2.GetProbTrue(), 1e-4);
        }
コード例 #23
0
 public static double LogAverageFactor(
     Bernoulli label, Vector point, Gaussian shapeX, Gaussian shapeY, PositiveDefiniteMatrix shapeOrientation)
 {
     VectorGaussian shapeLocationTimesFactor = ShapeLocationTimesFactor(point, shapeX, shapeY, shapeOrientation);
     double labelProbFalse = label.GetProbFalse();
     double normalizerProduct = Math.Exp(
         shapeLocationTimesFactor.GetLogNormalizer() - 0.5 * shapeOrientation.QuadraticForm(point)
         - shapeX.GetLogNormalizer() - shapeY.GetLogNormalizer());
     double averageFactor = labelProbFalse + (1 - 2 * labelProbFalse) * normalizerProduct;
     Debug.Assert(averageFactor > 0);
     return Math.Log(averageFactor);
 }