Exemplo n.º 1
0
        /// <include file='FactorDocs.xml' path='factor_docs/message_op_class[@name="MatrixVectorProductOp"]/message_doc[@name="ProductAverageConditional(Matrix, Vector, PositiveDefiniteMatrix, VectorGaussian)"]/*'/>
        public static VectorGaussian ProductAverageConditional(Matrix A, Vector BMean, PositiveDefiniteMatrix BVariance, VectorGaussian result)
        {
            Vector mean = Vector.Zero(result.Dimension);
            PositiveDefiniteMatrix variance = result.Precision;

            GetProductMoments(A, BMean, BVariance, mean, variance);
            result.SetMeanAndVariance(mean, variance);
            return(result);
        }
        /// <summary>
        /// EP message to 'subvector'
        /// </summary>
        /// <param name="SourceMean">Buffer 'SourceMean'.</param>
        /// <param name="SourceVariance">Buffer 'SourceVariance'.</param>
        /// <param name="startIndex">Constant value for 'startIndex'.</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 'subvector' conditioned on the given values.
        /// </para></remarks>
        public static VectorGaussian SubvectorAverageConditional([Fresh] Vector SourceMean, [Fresh] PositiveDefiniteMatrix SourceVariance, int startIndex, VectorGaussian result)
        {
            PositiveDefiniteMatrix subVariance = new PositiveDefiniteMatrix(result.Dimension, result.Dimension);

            subVariance.SetToSubmatrix(SourceVariance, startIndex, startIndex);
            Vector subMean = Vector.Zero(result.Dimension);

            subMean.SetToSubvector(SourceMean, startIndex);
            result.SetMeanAndVariance(subMean, subVariance);
            return(result);
        }
        /// <include file='FactorDocs.xml' path='factor_docs/message_op_class[@name="SumVectorGaussianOp"]/message_doc[@name="SumAverageConditional(IList{VectorGaussian}, VectorGaussian)"]/*'/>
        public static VectorGaussian SumAverageConditional([SkipIfAnyUniform] IList <VectorGaussian> array, VectorGaussian result)
        {
            if (array == null)
            {
                throw new ArgumentNullException(nameof(array));
            }

            if (result == null)
            {
                throw new ArgumentNullException(nameof(result));
            }

            if (array.Count < 1)
            {
                result.Point = Vector.Zero(result.Dimension);
                return(result);
            }

            if (array.Any(element => element == null))
            {
                throw new ArgumentNullException(nameof(array));
            }

            int dimension = result.Dimension;

            if (array.Any(element => element.Dimension != dimension))
            {
                throw new ArgumentException("The result and all elements of the array must have the same number of dimensions.");
            }

            var sumMean         = Vector.Zero(dimension);
            var sumVariance     = PositiveDefiniteMatrix.IdentityScaledBy(dimension, 0);
            var elementMean     = Vector.Zero(dimension);
            var elementVariance = PositiveDefiniteMatrix.Identity(dimension);

            foreach (var element in array)
            {
                if (!element.IsProper())
                {
                    return(element);
                }

                element.GetMeanAndVariance(elementMean, elementVariance);

                sumMean.SetToSum(sumMean, elementMean);
                sumVariance.SetToSum(sumVariance, elementVariance);
            }

            result.SetMeanAndVariance(sumMean, sumVariance);

            return(result);
        }
Exemplo n.º 4
0
        /// <summary>VMP message to <c>rotate</c>.</summary>
        /// <param name="x">Incoming message from <c>x</c>. Must be a proper distribution. If uniform, the result will be uniform.</param>
        /// <param name="y">Incoming message from <c>y</c>. Must be a proper distribution. If uniform, the result will be uniform.</param>
        /// <param name="angle">Incoming message from <c>angle</c>. Must be a proper distribution. If uniform, the result will be uniform.</param>
        /// <param name="result">Modified to contain the outgoing message.</param>
        /// <returns>
        ///   <paramref name="result" />
        /// </returns>
        /// <remarks>
        ///   <para>The outgoing message is a distribution matching the moments of <c>rotate</c> as the random arguments are varied. The formula is <c>proj[sum_(x,y,angle) p(x,y,angle) factor(rotate,x,y,angle)]</c>.</para>
        /// </remarks>
        /// <exception cref="ImproperMessageException">
        ///   <paramref name="x" /> is not a proper distribution.</exception>
        /// <exception cref="ImproperMessageException">
        ///   <paramref name="y" /> is not a proper distribution.</exception>
        /// <exception cref="ImproperMessageException">
        ///   <paramref name="angle" /> is not a proper distribution.</exception>
        public static VectorGaussian RotateAverageLogarithm(
            [SkipIfUniform] Gaussian x, [SkipIfUniform] Gaussian y, [Proper] WrappedGaussian angle, VectorGaussian result)
        {
            // for x ~ N(m,v):
            // E[cos(x)] = cos(m)*exp(-v/2)
            // E[sin(x)] = sin(m)*exp(-v/2)
            if (angle.Period != 2 * Math.PI)
            {
                throw new ArgumentException("angle.Period (" + angle.Period + ") != 2*PI (" + 2 * Math.PI + ")");
            }
            double angleMean, angleVar;

            angle.Gaussian.GetMeanAndVariance(out angleMean, out angleVar);
            double expHalfVar = Math.Exp(-0.5 * angleVar);
            double mCos       = Math.Cos(angleMean) * expHalfVar;
            double mSin       = Math.Sin(angleMean) * expHalfVar;
            double mCos2      = mCos * mCos;
            double mSin2      = mSin * mSin;
            //  E[cos(x)^2] = 0.5 E[1+cos(2x)] = 0.5 (1 + cos(2m) exp(-2v))
            //  E[sin(x)^2] = E[1 - cos(x)^2] = 0.5 (1 - cos(2m) exp(-2v))
            double expVar = expHalfVar * expHalfVar;
            // cos2m = cos(2m)*exp(-v)
            double cos2m   = 2 * mCos2 - expVar;
            double mCosSqr = 0.5 * (1 + cos2m * expVar);
            double mSinSqr = 1 - mCosSqr;
            double mSinCos = mSin * mCos * expVar;

            if (result.Dimension != 2)
            {
                throw new ArgumentException("result.Dimension (" + result.Dimension + ") != 2");
            }
            double mx, vx, my, vy;

            x.GetMeanAndVariance(out mx, out vx);
            y.GetMeanAndVariance(out my, out vy);
            Vector mean = Vector.Zero(2);

            mean[0] = mCos * mx - mSin * my;
            mean[1] = mSin * mx + mCos * my;
            double mx2 = mx * mx + vx;
            double my2 = my * my + vy;
            double mxy = mx * my;
            PositiveDefiniteMatrix variance = new PositiveDefiniteMatrix(2, 2);

            variance[0, 0] = mx2 * mCosSqr - 2 * mxy * mSinCos + my2 * mSinSqr - mean[0] * mean[0];
            variance[0, 1] = (mx2 - my2) * mSinCos + mxy * (mCosSqr - mSinSqr) - mean[0] * mean[1];
            variance[1, 0] = variance[0, 1];
            variance[1, 1] = mx2 * mSinSqr + 2 * mxy * mSinCos + my2 * mCosSqr - mean[1] * mean[1];
            result.SetMeanAndVariance(mean, variance);
            return(result);
        }
Exemplo n.º 5
0
        /// <summary>
        /// EP message to 'product'
        /// </summary>
        /// <param name="A">Constant value for 'a'.</param>
        /// <param name="BMean">Buffer 'BMean'.</param>
        /// <param name="BVariance">Buffer 'BVariance'.</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 'product' conditioned on the given values.
        /// </para></remarks>
        public static VectorGaussian ProductAverageConditional(Matrix A, [Fresh] Vector BMean, [Fresh] PositiveDefiniteMatrix BVariance, VectorGaussian result)
        {
            // P.mean = A*B.mean
            // P.var = A*B.var*A'
            // if A is invertible, then
            // P.prec = inv(A)'*inv(B.var)*inv(A)
            // P.precTimesMean = inv(A)'*B.precTimesMean
            Vector rmean = A * BMean;
            PositiveDefiniteMatrix rvariance = new PositiveDefiniteMatrix(result.Dimension, result.Dimension);
            Matrix temp = (A * BVariance).Transpose();

            rvariance.SetToProduct(A, temp);
            result.SetMeanAndVariance(rmean, rvariance);
            return(result);
        }
Exemplo n.º 6
0
        public static VectorGaussian AAverageConditional(
            Vector sumMean, PositiveDefiniteMatrix sumVariance,
            Vector bMean, PositiveDefiniteMatrix bVariance,
            VectorGaussian result)
        {
            if (result == null)
            {
                throw new ArgumentNullException(nameof(result));
            }

            int dimension = result.Dimension;

            var aMean     = Vector.Zero(dimension);
            var aVariance = PositiveDefiniteMatrix.IdentityScaledBy(dimension, 0);

            aMean.SetToDifference(sumMean, bMean);
            aVariance.SetToSum(sumVariance, bVariance);

            result.SetMeanAndVariance(aMean, aVariance);
            return(result);
        }
		/// <summary>
		/// EP message to 'product'
		/// </summary>
		/// <param name="A">Constant value for 'a'.</param>
		/// <param name="BMean">Buffer 'BMean'.</param>
		/// <param name="BVariance">Buffer 'BVariance'.</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 'product' conditioned on the given values.
		/// </para></remarks>
		public static VectorGaussian ProductAverageConditional(Matrix A, [Fresh] Vector BMean, [Fresh] PositiveDefiniteMatrix BVariance, VectorGaussian result)
		{
			// P.mean = A*B.mean
			// P.var = A*B.var*A'
			// if A is invertible, then
			// P.prec = inv(A)'*inv(B.var)*inv(A)
			// P.precTimesMean = inv(A)'*B.precTimesMean
			Vector rmean = A * BMean;
			PositiveDefiniteMatrix rvariance = new PositiveDefiniteMatrix(result.Dimension, result.Dimension);
			Matrix temp = (A*BVariance).Transpose();
			rvariance.SetToProduct(A, temp);
			result.SetMeanAndVariance(rmean, rvariance);
			return result;
		}
Exemplo n.º 8
0
		public static VectorGaussian RotateAverageLogarithm([SkipIfUniform] Gaussian x, [SkipIfUniform] Gaussian y, [Proper] WrappedGaussian angle, VectorGaussian result)
		{
			// for x ~ N(m,v):
			// E[cos(x)] = cos(m)*exp(-v/2)
			// E[sin(x)] = sin(m)*exp(-v/2)
			if (angle.Period != 2*Math.PI) throw new ArgumentException("angle.Period ("+angle.Period+") != 2*PI ("+2*Math.PI+")");
			double angleMean, angleVar;
			angle.Gaussian.GetMeanAndVariance(out angleMean, out angleVar);
			double expHalfVar = Math.Exp(-0.5*angleVar);
			double mCos = Math.Cos(angleMean)*expHalfVar;
			double mSin = Math.Sin(angleMean)*expHalfVar;
			double mCos2 = mCos*mCos;
			double mSin2 = mSin*mSin;
			//  E[cos(x)^2] = 0.5 E[1+cos(2x)] = 0.5 (1 + cos(2m) exp(-2v))
			//  E[sin(x)^2] = E[1 - cos(x)^2] = 0.5 (1 - cos(2m) exp(-2v))
			double expVar = expHalfVar*expHalfVar;
			// cos2m = cos(2m)*exp(-v)
			double cos2m = 2*mCos2 - expVar;
			double mCosSqr = 0.5*(1 + cos2m*expVar);
			double mSinSqr = 1 - mCosSqr;
			double mSinCos = mSin*mCos*expVar;
			if (result.Dimension != 2) throw new ArgumentException("result.Dimension ("+result.Dimension+") != 2");
			double mx, vx, my, vy;
			x.GetMeanAndVariance(out mx, out vx);
			y.GetMeanAndVariance(out my, out vy);
			Vector mean = Vector.Zero(2);
			mean[0] = mCos*mx - mSin*my;
			mean[1] = mSin*mx + mCos*my;
			double mx2 = mx*mx + vx;
			double my2 = my*my + vy;
			double mxy = mx*my;
			PositiveDefiniteMatrix variance = new PositiveDefiniteMatrix(2, 2);
			variance[0, 0] = mx2*mCosSqr - 2*mxy*mSinCos + my2*mSinSqr - mean[0]*mean[0];
			variance[0, 1] = (mx2 - my2)*mSinCos + mxy*(mCosSqr - mSinSqr) - mean[0]*mean[1];
			variance[1, 0] = variance[0, 1];
			variance[1, 1] = mx2*mSinSqr + 2*mxy*mSinCos + my2*mCosSqr - mean[1]*mean[1];
			result.SetMeanAndVariance(mean, variance);
			return result;
		}
		/// <summary>
		/// EP message to 'subvector'
		/// </summary>
		/// <param name="SourceMean">Buffer 'SourceMean'.</param>
		/// <param name="SourceVariance">Buffer 'SourceVariance'.</param>
		/// <param name="startIndex">Constant value for 'startIndex'.</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 'subvector' conditioned on the given values.
		/// </para></remarks>
		public static VectorGaussian SubvectorAverageConditional([Fresh] Vector SourceMean, [Fresh] PositiveDefiniteMatrix SourceVariance, int startIndex, VectorGaussian result)
		{
			PositiveDefiniteMatrix subVariance = new PositiveDefiniteMatrix(result.Dimension, result.Dimension);
			subVariance.SetToSubmatrix(SourceVariance, startIndex, startIndex);
			Vector subMean = Vector.Zero(result.Dimension);
			subMean.SetToSubvector(SourceMean, startIndex);
			result.SetMeanAndVariance(subMean, subVariance);
			return result;
		}