/// <include file='FactorDocs.xml' path='factor_docs/message_op_class[@name="SumVectorGaussianOp"]/message_doc[@name="ArrayAverageConditional{TVectorGaussianList}(VectorGaussian, VectorGaussian, IList{VectorGaussian}, TVectorGaussianList)"]/*'/> public static TVectorGaussianList ArrayAverageConditional <TVectorGaussianList>( [SkipIfUniform] VectorGaussian sum, [Fresh] VectorGaussian to_sum, IList <VectorGaussian> array, TVectorGaussianList result) where TVectorGaussianList : IList <VectorGaussian>, SettableToUniform { // Check inputs for consistency int dimension = CheckArgumentConsistency(sum, to_sum, array, result); if (array.Count == 0) { return(result); } // It is tempting to put SkipIfAllUniform on array but this isn't correct if the array has one element if (array.Count == 1) { result[0].SetTo(sum); return(result); } if (!sum.IsProper()) { foreach (VectorGaussian element in result) { element.SetTo(sum); } return(result); } var elementMean = Vector.Zero(dimension); var elementVariance = PositiveDefiniteMatrix.Identity(dimension); // Check if an element of the array is uniform int indexOfUniform = -1; for (int i = 0; i < array.Count; i++) { array[i].GetMeanAndVariance(elementMean, elementVariance); // Instead of testing IsUniform, we need to test the more strict requirement that all diagonal // elements of variance are infinite due to the way we are doing the computations if (IsUniform(elementVariance)) { if (indexOfUniform >= 0) { // More than one element of array is uniform result.SetToUniform(); return(result); } indexOfUniform = i; } } Vector sumMean = Vector.Zero(dimension); PositiveDefiniteMatrix sumVariance = PositiveDefiniteMatrix.Identity(dimension); sum.GetMeanAndVariance(sumMean, sumVariance); Vector totalMean = Vector.Zero(sum.Dimension); PositiveDefiniteMatrix totalVariance = PositiveDefiniteMatrix.IdentityScaledBy(sum.Dimension, 0.0); if (indexOfUniform >= 0) { // Exactly one element of array is uniform for (int i = 0; i < array.Count; i++) { if (i == indexOfUniform) { continue; } array[i].GetMeanAndVariance(elementMean, elementVariance); totalMean.SetToSum(totalMean, elementMean); totalVariance.SetToSum(totalVariance, elementVariance); result[i].SetToUniform(); } // totalMean = sum_{i except indexOfUniform} array[i].GetMean() // totalVariance = sum_{i except indexOfUniform} array[i].GetVariance() totalMean.SetToDifference(sumMean, totalMean); totalVariance.SetToSum(sumVariance, totalVariance); result[indexOfUniform].SetMeanAndVariance(totalMean, totalVariance); return(result); } // At this point, the array has no uniform elements // Get the mean and variance of sum of all Gaussians to_sum.GetMeanAndVariance(totalMean, totalVariance); // Subtract it off from the mean and variance of the incoming Gaussian from Sum totalMean.SetToDifference(sumMean, totalMean); totalVariance.SetToSum(totalVariance, sumVariance); for (int i = 0; i < array.Count; i++) { array[i].GetMeanAndVariance(elementMean, elementVariance); elementMean.SetToSum(elementMean, totalMean); elementVariance.SetToDifference(totalVariance, elementVariance); result[i].SetMeanAndVariance(elementMean, elementVariance); } return(result); }