예제 #1
0
        /// <summary>VMP message to <c>A</c>.</summary>
        /// <param name="sum">Incoming message from <c>Sum</c>. Must be a proper distribution. If uniform, the result will be uniform.</param>
        /// <param name="A">Incoming message from <c>A</c>. Must be a proper distribution. If any element is uniform, the result will be uniform.</param>
        /// <param name="B">Incoming message from <c>B</c>. Must be a proper distribution. If any element is uniform, the result will be uniform.</param>
        /// <param name="MeanOfB">Buffer <c>MeanOfB</c>.</param>
        /// <param name="CovarianceOfB">Buffer <c>CovarianceOfB</c>.</param>
        /// <param name="result">Modified to contain the outgoing message.</param>
        /// <returns>
        ///   <paramref name="result" />
        /// </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>Sum</c> is integrated out before taking the logarithm. The formula is <c>exp(sum_(B) p(B) log(sum_Sum p(Sum) factor(Sum,A,B)))</c>.</para>
        /// </remarks>
        /// <exception cref="ImproperMessageException">
        ///   <paramref name="sum" /> is not a proper distribution.</exception>
        /// <exception cref="ImproperMessageException">
        ///   <paramref name="A" /> is not a proper distribution.</exception>
        /// <exception cref="ImproperMessageException">
        ///   <paramref name="B" /> is not a proper distribution.</exception>
        public static DistributionStructArray <Bernoulli, bool> AAverageLogarithm(
            [SkipIfUniform] Gaussian sum,
            [Proper] DistributionStructArray <Bernoulli, bool> A,
            [Proper] VectorGaussian B,
            Vector MeanOfB,
            PositiveDefiniteMatrix CovarianceOfB,
            DistributionStructArray <Bernoulli, bool> result)
        {
            double mu   = sum.GetMean();
            var    Ebbt = new PositiveDefiniteMatrix(A.Count, A.Count);

            Ebbt.SetToSumWithOuter(CovarianceOfB, 1, MeanOfB, MeanOfB);
            var ma = A.Select(x => x.GetMean()).ToArray();

            for (int i = 0; i < A.Count; i++)
            {
                double term1 = 0.0;
                for (int j = 0; j < A.Count; j++)
                {
                    if (j != i)
                    {
                        term1 += ma[i] * Ebbt[i, j];
                    }
                }
                var ri = result[i];
                ri.LogOdds = -.5 * sum.Precision * (2.0 * term1 + Ebbt[i, i] - 2.0 * mu * MeanOfB[i]);
                result[i]  = ri;
            }
            return(result);
        }
예제 #2
0
        /// <summary>
        /// VMP message to 'B'
        /// </summary>
        /// <param name="sum">Incoming message from 'Sum'. Must be a proper distribution.  If uniform, the result will be uniform.</param>
        /// <param name="A">Incoming message from 'A'.</param>
        /// <param name="result">Modified to contain the outgoing message</param>
        /// <returns><paramref name="result"/></returns>
        /// <remarks><para>
        /// The outgoing message is the exponential of the average log-factor value, where the average is over all arguments except 'B'.
        /// Because the factor is deterministic, 'Sum' is integrated out before taking the logarithm.
        /// The formula is <c>exp(sum_(A) p(A) log(sum_Sum p(Sum) factor(Sum,A,B)))</c>.
        /// </para></remarks>
        /// <exception cref="ImproperMessageException"><paramref name="sum"/> is not a proper distribution</exception>
        public static VectorGaussian BAverageLogarithm([SkipIfUniform] Gaussian sum, DistributionStructArray <Bernoulli, bool> A, VectorGaussian result)
        {
            if (result == default(VectorGaussian))
            {
                result = new VectorGaussian(A.Count);
            }
            // E[log N(x; ab, 0)] = -0.5 E[(x-ab)^2]/0 = -0.5 (E[x^2] - 2 E[x] a' E[b] + trace(aa' E[bb']))/0
            // message to a = N(a; E[x]*inv(var(b)+E[b]E[b]')*E[b], var(x)*inv(var(b)+E[b]E[b]'))
            // result.Precision = (var(b)+E[b]*E[b]')/var(x)
            // result.MeanTimesPrecision = E[x]/var(x)*E[b] = E[b]*X.MeanTimesPrecision
            Vector ma = Vector.FromArray(A.Select(x => x.GetMean()).ToArray());
            Vector va = Vector.FromArray(A.Select(x => x.GetVariance()).ToArray());

            result.Precision.SetToDiagonal(va);
            result.Precision.SetToSumWithOuter(result.Precision, 1, ma, ma);
            result.Precision.SetToProduct(result.Precision, sum.Precision);
            result.MeanTimesPrecision.SetToProduct(ma, sum.MeanTimesPrecision);
            return(result);
        }
예제 #3
0
        /// <summary>
        /// VMP message to 'A'
        /// </summary>
        /// <param name="sum">Incoming message from 'Sum'. Must be a proper distribution.  If uniform, the result will be uniform.</param>
        /// <param name="A">Incoming message from 'A'. Must be a proper distribution.  If all elements are uniform, the result will be uniform.</param>
        /// <param name="B">Constant value for 'B'.</param>
        /// <param name="result">Modified to contain the outgoing message</param>
        /// <returns><paramref name="result"/></returns>
        /// <remarks><para>
        /// The outgoing message is the factor viewed as a function of 'A' with 'Sum' integrated out.
        /// The formula is <c>sum_Sum p(Sum) factor(Sum,A,B)</c>.
        /// </para></remarks>
        /// <exception cref="ImproperMessageException"><paramref name="sum"/> is not a proper distribution</exception>
        /// <exception cref="ImproperMessageException"><paramref name="A"/> is not a proper distribution</exception>
        public static DistributionStructArray <Bernoulli, bool> AAverageLogarithm([SkipIfUniform] Gaussian sum, [SkipIfAllUniform] DistributionStructArray <Bernoulli, bool> A, Vector B, DistributionStructArray <Bernoulli, bool> result)
        {
            double mu = sum.GetMean();
            var    ma = A.Select(x => x.GetMean()).ToArray();

            for (int i = 0; i < A.Count; i++)
            {
                double term1 = 0.0;
                for (int j = 0; j < A.Count; j++)
                {
                    if (j != i)
                    {
                        term1 += ma[i] * B[i] * B[j];
                    }
                }
                var ri = result[i];
                ri.LogOdds = -.5 * sum.Precision * (2.0 * term1 + B[i] * B[i] - 2.0 * mu * B[i]);
                result[i]  = ri;
            }
            return(result);
        }
예제 #4
0
		/// <summary>
		/// VMP message to 'B'
		/// </summary>
		/// <param name="sum">Incoming message from 'Sum'. Must be a proper distribution.  If uniform, the result will be uniform.</param>
		/// <param name="A">Incoming message from 'A'.</param>
		/// <param name="result">Modified to contain the outgoing message</param>
		/// <returns><paramref name="result"/></returns>
		/// <remarks><para>
		/// The outgoing message is the exponential of the average log-factor value, where the average is over all arguments except 'B'.
		/// Because the factor is deterministic, 'Sum' is integrated out before taking the logarithm.
		/// The formula is <c>exp(sum_(A) p(A) log(sum_Sum p(Sum) factor(Sum,A,B)))</c>.
		/// </para></remarks>
		/// <exception cref="ImproperMessageException"><paramref name="sum"/> is not a proper distribution</exception>
		public static VectorGaussian BAverageLogarithm([SkipIfUniform] Gaussian sum, DistributionStructArray<Bernoulli, bool> A, VectorGaussian result)
		{
			if (result == default(VectorGaussian)) result = new VectorGaussian(A.Count);
			// E[log N(x; ab, 0)] = -0.5 E[(x-ab)^2]/0 = -0.5 (E[x^2] - 2 E[x] a' E[b] + trace(aa' E[bb']))/0
			// message to a = N(a; E[x]*inv(var(b)+E[b]E[b]')*E[b], var(x)*inv(var(b)+E[b]E[b]'))
			// result.Precision = (var(b)+E[b]*E[b]')/var(x)
			// result.MeanTimesPrecision = E[x]/var(x)*E[b] = E[b]*X.MeanTimesPrecision
			Vector ma = Vector.FromArray(A.Select(x => x.GetMean()).ToArray());
			Vector va = Vector.FromArray(A.Select(x => x.GetVariance()).ToArray());
			result.Precision.SetToDiagonal(va);
			result.Precision.SetToSumWithOuter(result.Precision, 1, ma, ma);
			result.Precision.SetToProduct(result.Precision, sum.Precision);
			result.MeanTimesPrecision.SetToProduct(ma, sum.MeanTimesPrecision);
			return result;
		}