/// <summary> /// Adds a weighted observation /// </summary> /// <param name="x"></param> /// <param name="weight"></param> public void Add(Matrix x, double weight) { // new_mean = mean + w/(count + w)*(x - mean) // new_var = count/(count + w)*(var + w/(count+w)*(x-mean)*(x-mean)') Count += weight; if (Count == 0) { return; } diff.SetToDifference(x, Mean); double s = weight / Count; Mean.SetToSum(1, Mean, s, diff); diff.SetToElementwiseProduct(diff, diff); Variance.SetToSum(1 - s, Variance, s * (1 - s), diff); }
public static Gaussian BAverageConditional([SkipIfUniform] VectorGaussian product, [SkipIfUniform] VectorGaussian a, Gaussian b) { if (!b.IsPointMass) { throw new ArgumentException("b is not a point mass", nameof(b)); } double bPoint = b.Point; Vector productMean = Vector.Zero(product.Dimension); PositiveDefiniteMatrix productVariance = new PositiveDefiniteMatrix(product.Dimension, product.Dimension); product.GetMeanAndVariance(productMean, productVariance); Vector aMean = Vector.Zero(product.Dimension); PositiveDefiniteMatrix aVariance = new PositiveDefiniteMatrix(product.Dimension, product.Dimension); a.GetMeanAndVariance(aMean, aVariance); PositiveDefiniteMatrix variance = new PositiveDefiniteMatrix(product.Dimension, product.Dimension); variance.SetToSum(1, productVariance, bPoint * bPoint, aVariance); // variance = productVariance + aVariance * b^2 PositiveDefiniteMatrix precision = variance.Inverse(); Vector diff = aMean * bPoint; diff.SetToDifference(productMean, diff); // diff = productMean - aMean * b var precisionDiff = precision * diff; double dlogf = aMean.Inner(precisionDiff) + bPoint * (precisionDiff.Inner(aVariance * precisionDiff) - Matrix.TraceOfProduct(precision, aVariance)); double ddlogf = -1; return(Gaussian.FromDerivatives(bPoint, dlogf, ddlogf, GaussianProductOp.ForceProper)); }
/// <summary> /// Adds a noisy observation. /// </summary> /// <param name="x"></param> /// <param name="noiseVariance"></param> /// <param name="weight"></param> public void Add(Vector x, PositiveDefiniteMatrix noiseVariance, double weight) { // new_cov = count/(count + w)*(cov + w/(count+w)*(x-mean)*(x-mean)') + w/(count+w)*noiseVariance Add(x, weight); if (count == 0) { return; } double s = weight / count; cov.SetToSum(1, cov, s, noiseVariance); }
public static double LogAverageFactor([SkipIfUniform] VectorGaussian product, [SkipIfUniform] VectorGaussian a, Gaussian b) { if (!b.IsPointMass) { throw new ArgumentException("b is not a point mass", nameof(b)); } double bPoint = b.Point; Vector productMean = Vector.Zero(product.Dimension); PositiveDefiniteMatrix productVariance = new PositiveDefiniteMatrix(product.Dimension, product.Dimension); product.GetMeanAndVariance(productMean, productVariance); Vector aMean = Vector.Zero(product.Dimension); PositiveDefiniteMatrix aVariance = new PositiveDefiniteMatrix(product.Dimension, product.Dimension); a.GetMeanAndVariance(aMean, aVariance); PositiveDefiniteMatrix variance = new PositiveDefiniteMatrix(product.Dimension, product.Dimension); variance.SetToSum(1, productVariance, bPoint * bPoint, aVariance); // variance = productVariance + aVariance * b^2 return(VectorGaussian.GetLogProb(productMean, aMean * bPoint, variance)); }
/// <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); }
/// <include file='FactorDocs.xml' path='factor_docs/message_op_class[@name="MatrixVectorProductOp"]/message_doc[@name="AAverageConditional(VectorGaussian, DistributionArray2D{Gaussian, double}, Vector, PositiveDefiniteMatrix, DistributionStructArray2D{Gaussian, double})"]/*'/> public static DistributionStructArray2D <Gaussian, double> AAverageConditional([SkipIfUniform] VectorGaussian product, DistributionArray2D <Gaussian, double> A, Vector BMean, PositiveDefiniteMatrix BVariance, DistributionStructArray2D <Gaussian, double> result) { if (product.IsUniform()) { result.SetToUniform(); return(result); } if (!A.IsPointMass) { throw new ArgumentException("A is not a point mass"); } // logZ = log N(mProduct; A*BMean, vProduct + A*BVariance*A') // = -0.5 (mProduct - A*BMean)' inv(vProduct + A*BVariance*A') (mProduct - A*BMean) - 0.5 logdet(vProduct + A*BVariance*A') // = -0.5 (mProduct - A*BMean)' pPrec inv(pProduct + pProduct*A*BVariance*A'*pProduct) pProduct (mProduct - A*BMean) // - 0.5 logdet(pProduct + pProduct*A*BVariance*A'*pProduct) + logdet(pProduct) // dlogZ = 0.5 (dA*BMean)' pProduct inv(pProduct + pProduct*A*BVariance*A'*pProduct) pProduct (mProduct - A*BMean) // +0.5 (mProduct - A*BMean)' pProduct inv(pProduct + pProduct*A*BVariance*A'*pProduct) pProduct (dA*BMean) // +0.5 (mProduct - A*BMean)' pProduct inv(pProduct + pProduct*A*BVariance*A'*pProduct) (pProduct*dA*BVariance*A'*pProduct + pProduct*A*BVariance*dA'*pProduct) inv(pProduct + pProduct*A*BVariance*A'*pProduct) pProduct (mProduct - A*BMean) // - 0.5 tr(inv(pProduct + pProduct*A*BVariance*A'*pProduct) (pProduct*dA*BVariance*A'*pProduct + pProduct*A*BVariance*dA'*pProduct)) // dlogZ/dA = pProduct inv(pProduct + pProduct*A*BVariance*A'*pProduct) pProduct (mProduct - A*BMean) BMean' // + pProduct inv(pProduct + pProduct*A*BVariance*A'*pProduct) pProduct (mProduct - A*BMean) (mProduct - A*BMean)' pProduct inv(pProduct + pProduct*A*BVariance*A'*pProduct) pProduct*A*BVariance // - pProduct inv(pProduct + pProduct*A*BVariance*A'*pProduct) pProduct A*BVariance var Amatrix = new Matrix(A.Point); var pProductA = product.Precision * Amatrix; var pProductABV = pProductA * BVariance; PositiveDefiniteMatrix prec = new PositiveDefiniteMatrix(product.Dimension, product.Dimension); prec.SetToSum(product.Precision, pProductABV * pProductA.Transpose()); // pProductA is now free for (int i = 0; i < prec.Rows; i++) { if (prec[i, i] == 0) { prec[i, i] = 1; } } var v = prec.Inverse(); var ABM = Amatrix * BMean; var pProductABM = product.Precision * ABM; var diff = pProductABM; diff.SetToDifference(product.MeanTimesPrecision, pProductABM); // ABM is now free var pProductV = product.Precision * v; var pProductVdiff = ABM; pProductVdiff.SetToProduct(pProductV, diff); var Vdiff = v * diff; pProductV.Scale(-1); pProductV.SetToSumWithOuter(pProductV, 1, pProductVdiff, Vdiff); Matrix dlogZ = pProductA; dlogZ.SetToProduct(pProductV, pProductABV); dlogZ.SetToSumWithOuter(dlogZ, 1, pProductVdiff, BMean); int rows = A.GetLength(0); int cols = A.GetLength(1); for (int i = 0; i < rows; i++) { for (int j = 0; j < cols; j++) { double dlogp = dlogZ[i, j]; // for now, we don't compute the second derivative. double ddlogp = -1; result[i, j] = Gaussian.FromDerivatives(A[i, j].Point, dlogp, ddlogp, false); } } return(result); }