Ejemplo n.º 1
0
 /// <summary>
 /// Sets this instance to the product of two sparse GPs.
 /// </summary>
 /// <param name="a">Sparse GP</param>
 /// <param name="b">Sparse GP</param>
 public void SetToProduct(SparseGP a, SparseGP b)
 {
     if (a.FixedParameters != b.FixedParameters)
     {
         throw new ArgumentException("SparseGPs do not have the same FixedParameters.  a.FixedParameters = " + a.FixedParameters + ", b.FixedParameters = " +
                                     b.FixedParameters);
     }
     FixedParameters = a.FixedParameters;
     if (a.IncludePrior && b.IncludePrior)
     {
         throw new ArgumentException("Both SparseGPs include the prior.  Cannot multiply.");
     }
     IncludePrior = a.IncludePrior || b.IncludePrior;
     if (a.IsPointMass)
     {
         if (b.IsPointMass && !a.Point.Equals(b.Point))
         {
             throw new AllZeroException();
         }
         Point = a.Point;
     }
     else if (b.IsPointMass)
     {
         Point = b.Point;
     }
     else
     {
         InducingDist.SetToProduct(a.InducingDist, b.InducingDist);
         pointFunc = null;
         ClearCachedValues();
     }
 }
Ejemplo n.º 2
0
        /// <summary>EP message to <c>second</c>.</summary>
        /// <param name="concat">Incoming message from <c>concat</c>. Must be a proper distribution. If any element is uniform, the result will be uniform.</param>
        /// <param name="first">Incoming message from <c>first</c>.</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>second</c> as the random arguments are varied. The formula is <c>proj[p(second) sum_(concat,first) p(concat,first) factor(concat,first,second)]/p(second)</c>.</para>
        /// </remarks>
        /// <exception cref="ImproperMessageException">
        ///   <paramref name="concat" /> is not a proper distribution.</exception>
        public static VectorGaussian SecondAverageConditional([SkipIfUniform] VectorGaussian concat, VectorGaussian first, VectorGaussian result)
        {
            if (first.IsPointMass)
            {
                return(SecondAverageConditional(concat, first.Point, result));
            }
            int            dim1             = first.Dimension;
            VectorGaussian concatTimesFirst = new VectorGaussian(concat.Dimension);

            concatTimesFirst.MeanTimesPrecision.SetSubvector(0, first.MeanTimesPrecision);
            concatTimesFirst.Precision.SetSubmatrix(0, 0, first.Precision);
            concatTimesFirst.SetToProduct(concatTimesFirst, concat);
            concatTimesFirst.GetMarginal(dim1, result);
            return(result);
        }
Ejemplo n.º 3
0
        /// <summary>EP message to <c>first</c>.</summary>
        /// <param name="concat">Incoming message from <c>concat</c>. Must be a proper distribution. If any element is uniform, the result will be uniform.</param>
        /// <param name="second">Incoming message from <c>second</c>.</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>first</c> as the random arguments are varied. The formula is <c>proj[p(first) sum_(concat,second) p(concat,second) factor(concat,first,second)]/p(first)</c>.</para>
        /// </remarks>
        /// <exception cref="ImproperMessageException">
        ///   <paramref name="concat" /> is not a proper distribution.</exception>
        public static VectorGaussian FirstAverageConditional([SkipIfUniform] VectorGaussian concat, VectorGaussian second, VectorGaussian result)
        {
            if (second.IsPointMass)
            {
                return(FirstAverageConditional(concat, second.Point, result));
            }
            int            dim1 = result.Dimension;
            VectorGaussian concatTimesSecond = new VectorGaussian(concat.Dimension);

            concatTimesSecond.MeanTimesPrecision.SetSubvector(dim1, second.MeanTimesPrecision);
            concatTimesSecond.Precision.SetSubmatrix(dim1, dim1, second.Precision);
            concatTimesSecond.SetToProduct(concatTimesSecond, concat);
            concatTimesSecond.GetMarginal(0, result);
            return(result);
        }
        /// <include file='FactorDocs.xml' path='factor_docs/message_op_class[@name="SumVectorGaussianOp"]/message_doc[@name="ArrayAverageLogarithm1{TVectorGaussianList}(VectorGaussian, IList{VectorGaussian}, TVectorGaussianList)"]/*'/>
        /// <typeparam name="TVectorGaussianList">A list of <see cref="VectorGaussian"/> distributions.</typeparam>
        public static TVectorGaussianList ArrayAverageLogarithm1 <TVectorGaussianList>(
            [SkipIfUniform] VectorGaussian sum,
            [Stochastic, Proper] IList <VectorGaussian> array,
            TVectorGaussianList to_array)
            where TVectorGaussianList : IList <VectorGaussian>
        {
            // Check inputs for consistency
            int dimension = CheckArgumentConsistency(sum, sum, array, to_array);

            TVectorGaussianList result = to_array;

            var sumMean     = Vector.Zero(dimension);
            var sumVariance = PositiveDefiniteMatrix.Identity(dimension);

            sum.GetMeanAndVariance(sumMean, sumVariance);

            // This version does one update of q(array[i]) for each array element in turn.
            Vector arraySumOfMean = Vector.Zero(dimension);

            foreach (VectorGaussian element in array)
            {
                arraySumOfMean.SetToSum(arraySumOfMean, element.GetMean());
            }

            for (int i = 0; i < result.Count; i++)
            {
                arraySumOfMean.SetToDifference(arraySumOfMean, array[i].GetMean());

                VectorGaussian oldResult = result[i];
                result[i] = new VectorGaussian(sumMean - arraySumOfMean, sumVariance);

                oldResult.SetToRatio(result[i], oldResult);
                oldResult.SetToProduct(array[i], oldResult);

                arraySumOfMean.SetToSum(arraySumOfMean, oldResult.GetMean());
            }

            return(result);
        }
        /// <summary>
        /// EP message to 'array'
        /// </summary>
        /// <param name="array">Incoming message from 'array'.</param>
        /// <param name="vector">Incoming message from 'vector'. Must be a proper distribution.  If any element is uniform, the result will be uniform.</param>
        /// <param name="to_vector">Outgoing message to 'vector'.</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 'array' as the random arguments are varied.
        /// The formula is <c>proj[p(array) sum_(vector) p(vector) factor(array,vector)]/p(array)</c>.
        /// </para></remarks>
        /// <exception cref="ImproperMessageException"><paramref name="vector"/> is not a proper distribution</exception>
        public static GaussianList ArrayAverageConditional <GaussianList>(IList <Gaussian> array, [SkipIfUniform] VectorGaussian vector, [Fresh] VectorGaussian to_vector, GaussianList result)
            where GaussianList : IList <Gaussian>
        {
            if (result.Count != vector.Dimension)
            {
                throw new ArgumentException("vector.Dimension (" + vector.Dimension + ") != result.Count (" + result.Count + ")");
            }
            int            length           = result.Count;
            VectorGaussian vectorTimesArray = new VectorGaussian(vector.Dimension);

            vectorTimesArray.SetToProduct(vector, to_vector);
            Vector mean = Vector.Zero(length);
            PositiveDefiniteMatrix variance = new PositiveDefiniteMatrix(length, length);

            vectorTimesArray.GetMeanAndVariance(mean, variance);
            for (int i = 0; i < length; i++)
            {
                Gaussian marginal = Gaussian.FromMeanAndVariance(mean[i], variance[i, i]);
                marginal.SetToRatio(marginal, array[i]);
                result[i] = marginal;
            }
            return(result);
        }
		/// <summary>
		/// EP message to 'second'
		/// </summary>
		/// <param name="concat">Incoming message from 'concat'. Must be a proper distribution.  If any element is uniform, the result will be uniform.</param>
		/// <param name="first">Incoming message from 'first'.</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 'second' as the random arguments are varied.
		/// The formula is <c>proj[p(second) sum_(concat,first) p(concat,first) factor(concat,first,second)]/p(second)</c>.
		/// </para></remarks>
		/// <exception cref="ImproperMessageException"><paramref name="concat"/> is not a proper distribution</exception>
		public static VectorGaussian SecondAverageConditional([SkipIfUniform] VectorGaussian concat, VectorGaussian first, VectorGaussian result)
		{
			if (first.IsPointMass) return SecondAverageConditional(concat, first.Point, result);
			int dim1 = first.Dimension;
			VectorGaussian concatTimesFirst = new VectorGaussian(concat.Dimension);
			concatTimesFirst.MeanTimesPrecision.SetSubvector(0, first.MeanTimesPrecision);
			concatTimesFirst.Precision.SetSubmatrix(0, 0, first.Precision);
			concatTimesFirst.SetToProduct(concatTimesFirst, concat);
			concatTimesFirst.GetMarginal(dim1, result);
			return result;
		}
		/// <summary>
		/// EP message to 'first'
		/// </summary>
		/// <param name="concat">Incoming message from 'concat'. Must be a proper distribution.  If any element is uniform, the result will be uniform.</param>
		/// <param name="second">Incoming message from 'second'.</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 'first' as the random arguments are varied.
		/// The formula is <c>proj[p(first) sum_(concat,second) p(concat,second) factor(concat,first,second)]/p(first)</c>.
		/// </para></remarks>
		/// <exception cref="ImproperMessageException"><paramref name="concat"/> is not a proper distribution</exception>
		public static VectorGaussian FirstAverageConditional([SkipIfUniform] VectorGaussian concat, VectorGaussian second, VectorGaussian result)
		{
			if (second.IsPointMass) return FirstAverageConditional(concat, second.Point, result);
			int dim1 = result.Dimension;
			VectorGaussian concatTimesSecond = new VectorGaussian(concat.Dimension);
			concatTimesSecond.MeanTimesPrecision.SetSubvector(dim1, second.MeanTimesPrecision);
			concatTimesSecond.Precision.SetSubmatrix(dim1, dim1, second.Precision);
			concatTimesSecond.SetToProduct(concatTimesSecond, concat);
			concatTimesSecond.GetMarginal(0, result);
			return result;
		}
Ejemplo n.º 8
0
 private static VectorGaussian ShapeLocationTimesFactor(
     Vector point, Gaussian shapeX, Gaussian shapeY, PositiveDefiniteMatrix shapeOrientation)
 {
     VectorGaussian shapeLocationDistr = VectorGaussian.FromMeanAndVariance(
         Vector.FromArray(shapeX.GetMean(), shapeY.GetMean()),
         new PositiveDefiniteMatrix(new double[,] { { shapeX.GetVariance(), 0.0 }, { 0.0, shapeY.GetVariance() } }));
     VectorGaussian factorDistribution = VectorGaussian.FromMeanAndPrecision(point, shapeOrientation);
     VectorGaussian result = new VectorGaussian(2);
     result.SetToProduct(shapeLocationDistr, factorDistribution);
     return result;
 }