/// <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(); } }
/// <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); }
/// <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; }
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; }