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