/// <summary> /// VMP message to 'B'. /// </summary> /// <param name="X">Incoming message from 'X'. Must be a proper distribution. If any element is uniform, the result will be uniform.</param> /// <param name="A">Incoming message from 'A'.</param> /// <param name="result">Modified to contain the outgoing message.</param> /// <returns><paramref name="result"/></returns> /// <remarks><para> /// The outgoing message is the exponential of the integral of the log-factor times incoming messages, over all arguments except 'A'. /// The formula is <c>int log(f(A,x)) q(x) dx</c> where <c>x = (X,B)</c>. /// </para></remarks> /// <exception cref="ImproperMessageException"><paramref name="X"/> is not a proper distribution</exception> /// <exception cref="ImproperMessageException"><paramref name="B"/> is not a proper distribution</exception> public static VectorGaussianArray BAverageLogarithm([SkipIfAllUniform] GaussianArray2D X, [SkipIfAllUniform] VectorGaussianArray A, VectorGaussianArray result) { int I = X.GetLength(0), J = X.GetLength(1), K = A[0].Dimension; var Eaap = new PositiveDefiniteMatrix[I]; var ma = new Vector[I]; for (int i = 0; i < I; i++) { Eaap[i] = new PositiveDefiniteMatrix(K, K); ma[i] = Vector.Zero(K); A[i].GetMeanAndVariance(ma[i], Eaap[i]); Eaap[i].SetToSumWithOuter(Eaap[i], 1, ma[i], ma[i]); } for (int j = 0; j < J; j++) { result[j].Precision.SetAllElementsTo(0); result[j].MeanTimesPrecision.SetAllElementsTo(0); for (int i = 0; i < I; i++) { // nb: would be more memory efficient to have a SetToAPlusCB routine result[j].Precision.SetToSum(result[j].Precision, Eaap[i] * X[i, j].Precision); result[j].MeanTimesPrecision.SetToSum(result[j].MeanTimesPrecision, ma[i] * X[i, j].MeanTimesPrecision); } } return result; }
/// <summary> /// VMP message to 'innerProduct' /// </summary> /// <param name="AMean">Buffer 'AMean'.</param> /// <param name="AVariance">Buffer 'AVariance'.</param> /// <param name="BMean">Buffer 'BMean'.</param> /// <param name="BVariance">Buffer 'BVariance'.</param> /// <returns>The outgoing VMP message to the 'innerProduct' argument</returns> /// <remarks><para> /// The outgoing message is the factor viewed as a function of 'innerProduct' conditioned on the given values. /// </para></remarks> public static Gaussian InnerProductAverageLogarithm(Vector AMean, PositiveDefiniteMatrix AVariance, Vector BMean, PositiveDefiniteMatrix BVariance) { Gaussian result = new Gaussian(); // p(x|a,b) = N(E[a]'*E[b], E[b]'*var(a)*E[b] + E[a]'*var(b)*E[a] + trace(var(a)*var(b))) // Uses John Winn's rule for deterministic factors. // Strict variational inference would set the variance to 0. result.SetMeanAndVariance(AMean.Inner(BMean), AVariance.QuadraticForm(BMean) + BVariance.QuadraticForm(AMean) + AVariance.Inner(BVariance)); return result; }
/// <summary> /// VMP message to 'innerProduct' /// </summary> /// <param name="A">Constant value for 'a'.</param> /// <param name="BMean">Buffer 'BMean'.</param> /// <param name="BVariance">Buffer 'BVariance'.</param> /// <returns>The outgoing VMP message to the 'innerProduct' argument</returns> /// <remarks><para> /// The outgoing message is the factor viewed as a function of 'innerProduct' conditioned on the given values. /// </para></remarks> public static Gaussian InnerProductAverageLogarithm(Vector A, Vector BMean, PositiveDefiniteMatrix BVariance) { Gaussian result = new Gaussian(); // Uses John Winn's rule for deterministic factors. // Strict variational inference would set the variance to 0. // p(x) = N(a' E[b], a' var(b) a) result.SetMeanAndVariance(A.Inner(BMean), BVariance.QuadraticForm(A)); return result; }
/// <summary> /// Update the buffer 'CovarianceOfB' /// </summary> /// <param name="B">Incoming message from 'B'. Must be a proper distribution. If any element is uniform, the result will be uniform.</param> /// <returns>New value of buffer 'CovarianceOfB'</returns> /// <exception cref="ImproperMessageException"><paramref name="B"/> is not a proper distribution</exception> public static PositiveDefiniteMatrix Eaat(GaussianArray A, PositiveDefiniteMatrix result) { int inner = A.Count; var VarianceOfA = Vector.Zero(inner); var MeanOfA = Vector.Zero(inner); for (int k = 0; k < inner; k++) { MeanOfA[k] = A[k].GetMean(); VarianceOfA[k] = A[k].GetVariance(); } result.SetToDiagonal(VarianceOfA); result.SetToSumWithOuter(result, 1, MeanOfA, MeanOfA); return result; }
// Actually it doesn't require matrix to be positive semidefinite public static PositiveDefiniteMatrix Invert(PositiveDefiniteMatrix matrix) { Debug.Assert(matrix.Rows == 2 && matrix.Cols == 2); double determinant = matrix[0, 0] * matrix[1, 1] - matrix[0, 1] * matrix[1, 0]; Debug.Assert(Math.Abs(determinant) > 1e-10); double invDeterminant = 1.0 / determinant; PositiveDefiniteMatrix result = new PositiveDefiniteMatrix(2, 2); result[0, 0] = invDeterminant * matrix[1, 1]; result[0, 1] = -invDeterminant * matrix[0, 1]; result[1, 0] = -invDeterminant * matrix[1, 0]; result[1, 1] = invDeterminant * matrix[0, 0]; return result; }
public static Gamma BAverageConditional(PositiveDefiniteMatrix Product, PositiveDefiniteMatrix A) { if (Product.Count == 0) return Gamma.Uniform(); bool allZeroA = true; double ratio = 0; for (int i = 0; i < Product.Count; i++) { if (A[i] != 0) { ratio = Product[i]/A[i]; allZeroA = false; } } if (allZeroA) return Gamma.Uniform(); for (int i = 0; i < Product.Count; i++) { if (Math.Abs(Product[i] - A[i]*ratio) > 1e-15) throw new ConstraintViolatedException("Product is not a multiple of B"); } return Gamma.PointMass(ratio); }
/// <summary> /// Generates a data set from a particular true model. /// </summary> public Vector[] GenerateData(int nData) { Vector trueM1 = Vector.FromArray(2.0, 3.0); Vector trueM2 = Vector.FromArray(7.0, 5.0); PositiveDefiniteMatrix trueP1 = new PositiveDefiniteMatrix( new double[,] { { 3.0, 0.2 }, { 0.2, 2.0 } }); PositiveDefiniteMatrix trueP2 = new PositiveDefiniteMatrix( new double[,] { { 2.0, 0.4 }, { 0.4, 4.0 } }); VectorGaussian trueVG1 = VectorGaussian.FromMeanAndPrecision(trueM1, trueP1); VectorGaussian trueVG2 = VectorGaussian.FromMeanAndPrecision(trueM2, trueP2); double truePi = 0.6; Bernoulli trueB = new Bernoulli(truePi); // Restart the infer.NET random number generator Rand.Restart(12347); Vector[] data = new Vector[nData]; for (int j = 0; j < nData; j++) { bool bSamp = trueB.Sample(); data[j] = bSamp ? trueVG1.Sample() : trueVG2.Sample(); } return data; }
public static VectorGaussianWishart Combine(VectorGaussian position, Wishart orientation, VectorGaussianWishart result) { if (orientation.IsUniform()) { result.SetToUniform(); } else if (position.IsUniform()) { result.SetTo(orientation.Shape, orientation.Rate, Vector.Zero(2), 0); } else { PositiveDefiniteMatrix rateTimesPrecision = new PositiveDefiniteMatrix(2, 2); rateTimesPrecision.SetToProduct(orientation.Rate, position.Precision); double trace = MathHelpers.Invert(rateTimesPrecision).Trace(); Vector positionMean = position.MeanTimesPrecision * MathHelpers.Invert(position.Precision); result.SetTo(orientation.Shape, orientation.Rate, positionMean, orientation.Dimension / (orientation.Shape * trace)); } return result; }
/// <summary> /// VMP message to 'mean' /// </summary> /// <param name="Sample">Constant value for 'sample'.</param> /// <param name="Precision">Constant value for 'precision'.</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 'mean' conditioned on the given values. /// </para></remarks> public static VectorGaussian MeanAverageLogarithm(Vector Sample, PositiveDefiniteMatrix Precision, VectorGaussian result) { return SampleConditional(Sample, Precision, result); }
public DistributionArray <Bernoulli> TestBPM_NoisePrecisionVMP(double noiseRate, out double noiseEstimate) { int K = xtrain[0].Count; // Create target y VariableArray <bool> y = Variable.Observed(ytrain).Named("y"); Variable <Vector> w = Variable.VectorGaussianFromMeanAndPrecision(Vector.Zero(K), Variable.WishartFromShapeAndScale(.1, PositiveDefiniteMatrix.Identity(K))).Named("w"); var mean = Variable.GaussianFromMeanAndPrecision(0, .1); var noise = Variable.GammaFromShapeAndRate(2, noiseRate); //var noise = Variable.Random(Gamma.PointMass(.1)); BayesPointMachine_NoisePrecisionVMP(xtrain, w, y, mean, noise); InferenceEngine engine = new InferenceEngine(new VariationalMessagePassing()); VectorGaussian wPosterior = engine.Infer <VectorGaussian>(w); var noisePost = engine.Infer <Gamma>(noise); noiseEstimate = 1.0 / noisePost.GetMean(); //Console.WriteLine("Dist over w=\n" + wPosterior); //Console.WriteLine("Dist over noise=\n" + noisePost); var meanPost = engine.Infer <Gaussian>(mean); VariableArray <bool> yt = Variable.Array <bool>(new Range(ytest.Length)).Named("ytest"); BayesPointMachine_NoisePrecisionVMP(xtest, Variable.Random(wPosterior).Named("w"), yt, Variable.Random(meanPost), Variable.Random(noisePost)); return(engine.Infer <DistributionArray <Bernoulli> >(yt)); }
/// <summary> /// Helper method for computing average log factor /// </summary> /// <param name="sample">Constant value for 'sample'.</param> /// <param name="mean">Constant value for 'mean'.</param> /// <param name="precision_Elogx">Expected log value of the incoming message from 'precision'</param> /// <param name="precision_Ex">Expected value of incoming message from 'precision'</param> /// <returns>Computed average log factor</returns> private static double ComputeAverageLogFactor(Vector sample, Vector mean, double precision_Elogx, PositiveDefiniteMatrix precision_Ex) { int dim = mean.Count; int nonzeroDims = 0; double precTimesDiff = 0.0; for (int i = 0; i < dim; i++) { if (double.IsPositiveInfinity(precision_Ex[i, i])) { if (sample[i] != mean[i]) return double.NegativeInfinity; } else { nonzeroDims++; double sum = 0.0; for (int j = 0; j < dim; j++) { sum += precision_Ex[i, j]*(sample[j] - mean[j]); } precTimesDiff += sum*(sample[i]-mean[i]); } } return -nonzeroDims * MMath.LnSqrt2PI + 0.5 * (precision_Elogx - precTimesDiff); }
/// <summary> /// Update the buffer 'SampleMean' /// </summary> /// <param name="Sample">Incoming message from 'sample'. Must be a proper distribution. If any element is uniform, the result will be uniform.</param> /// <param name="SampleVariance">Buffer 'SampleVariance'.</param> /// <param name="result">Modified to contain the outgoing message</param> /// <returns><paramref name="result"/></returns> /// <remarks><para> /// /// </para></remarks> /// <exception cref="ImproperMessageException"><paramref name="Sample"/> is not a proper distribution</exception> public static Vector SampleMean([Proper] VectorGaussian Sample, [Fresh] PositiveDefiniteMatrix SampleVariance, Vector result) { return(Sample.GetMean(result, SampleVariance)); }
/// <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> /// Update the buffer 'CovarianceOfB' /// </summary> /// <param name="B">Incoming message from 'B'. Must be a proper distribution. If any element is uniform, the result will be uniform.</param> /// <returns>New value of buffer 'CovarianceOfB'</returns> /// <exception cref="ImproperMessageException"><paramref name="B"/> is not a proper distribution</exception> public static PositiveDefiniteMatrix Ebbt(PositiveDefiniteMatrix CovarianceOfB, Vector MeanOfB, PositiveDefiniteMatrix result) { result.SetToSumWithOuter(CovarianceOfB, 1, MeanOfB, MeanOfB); return result; }
/// <summary> /// Update the buffer 'PrecisionMeanLogDet' /// </summary> /// <param name="Precision">Incoming message from 'precision'.</param> /// <returns>New value of buffer 'PrecisionMeanLogDet'</returns> /// <remarks><para> /// /// </para></remarks> public static double PrecisionMeanLogDet([Proper] PositiveDefiniteMatrix Precision) { return(Precision.LogDeterminant()); }
/// <include file='FactorDocs.xml' path='factor_docs/message_op_class[@name="InnerProductPartialCovarianceOp"]/message_doc[@name="XAverageLogarithm(double[], VectorGaussian, Vector, PositiveDefiniteMatrix)"]/*'/> public static Gaussian XAverageLogarithm([SkipIfAllUniform] double[] A, [SkipIfAllUniform] VectorGaussian B, Vector MeanOfB, PositiveDefiniteMatrix CovarianceOfB) { // p(x|a,b) = N(E[a]'*E[b], E[b]'*var(a)*E[b] + E[a]'*var(b)*E[a] + trace(var(a)*var(b))) var ma = Vector.FromArray(A); // Uses John Winn's rule for deterministic factors. // Strict variational inference would set the variance to 0. Gaussian result = new Gaussian(); result.SetMeanAndVariance(ma.Inner(MeanOfB), CovarianceOfB.QuadraticForm(ma)); if (result.Precision < 0) { throw new InferRuntimeException("improper message"); } return(result); }
/// <include file='FactorDocs.xml' path='factor_docs/message_op_class[@name="InnerProductPartialCovarianceOp"]/message_doc[@name="XAverageLogarithm(DistributionStructArray{Gaussian, double}, VectorGaussian, Vector, PositiveDefiniteMatrix)"]/*'/> public static Gaussian XAverageLogarithm([SkipIfAllUniform] GaussianArray A, [SkipIfAllUniform] VectorGaussian B, Vector MeanOfB, PositiveDefiniteMatrix CovarianceOfB) { int K = MeanOfB.Count; // p(x|a,b) = N(E[a]'*E[b], E[b]'*var(a)*E[b] + E[a]'*var(b)*E[a] + trace(var(a)*var(b))) var ma = Vector.Zero(K); var va = Vector.Zero(K); for (int k = 0; k < K; k++) { double m, v; A[k].GetMeanAndVariance(out m, out v); ma[k] = m; va[k] = v; } // Uses John Winn's rule for deterministic factors. // Strict variational inference would set the variance to 0. var mbj2 = Vector.Zero(K); mbj2.SetToFunction(MeanOfB, x => x * x); // slooow Gaussian result = new Gaussian(); result.SetMeanAndVariance(ma.Inner(MeanOfB), va.Inner(mbj2) + CovarianceOfB.QuadraticForm(ma) + va.Inner(CovarianceOfB.Diagonal())); if (result.Precision < 0) { throw new InferRuntimeException("improper message"); } return(result); }
/// <include file='FactorDocs.xml' path='factor_docs/message_op_class[@name="MatrixVectorProductOp"]/message_doc[@name="LogAverageFactor(Vector, Matrix, VectorGaussian, Vector, PositiveDefiniteMatrix)"]/*'/> public static double LogAverageFactor(Vector product, Matrix A, VectorGaussian B, Vector BMean, PositiveDefiniteMatrix BVariance) { VectorGaussian toProduct = ProductAverageConditional(A, BMean, BVariance, new VectorGaussian(A.Rows)); return(toProduct.GetLogProb(product)); }
/// <include file='FactorDocs.xml' path='factor_docs/message_op_class[@name="MatrixVectorProductOp"]/message_doc[@name="LogEvidenceRatio(Vector, Matrix, VectorGaussian, Vector, PositiveDefiniteMatrix)"]/*'/> public static double LogEvidenceRatio(Vector product, Matrix A, VectorGaussian B, Vector BMean, PositiveDefiniteMatrix BVariance) { return(LogAverageFactor(product, A, B, BMean, BVariance)); }
public static Vector BMean([Proper] VectorGaussian B, PositiveDefiniteMatrix BVariance, Vector result) { return(B.GetMean(result, BVariance)); }
/// <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)' pProduct 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); bool check = false; if (check) { double logZ(Matrix m) { var vgm = ProductAverageConditional(m, BMean, BVariance, new VectorGaussianMoments(m.Rows)); return(VectorGaussian.GetLogProb(product.GetMean(), vgm.Mean, product.GetVariance() + vgm.Variance)); } var Amatrix2 = (Matrix)Amatrix.Clone(); double delta = 1e-4; Amatrix2[i, j] += delta; double dlogp2 = (logZ(Amatrix2) - logZ(Amatrix)) / delta; if (MMath.AbsDiff(dlogp, dlogp2, 1e-10) > 1e-5) { throw new Exception(); } } } } return(result); }
/// <include file='FactorDocs.xml' path='factor_docs/message_op_class[@name="MatrixVectorProductOp"]/message_doc[@name="ProductAverageLogarithm(double[,], Vector, PositiveDefiniteMatrix, VectorGaussianMoments)"]/*'/> public static VectorGaussianMoments ProductAverageLogarithm(double[,] A, Vector BMean, PositiveDefiniteMatrix BVariance, VectorGaussianMoments result) { return(ProductAverageConditional(A, BMean, BVariance, result)); }
/// <summary> /// Update the buffer 'MeanVariance' /// </summary> /// <param name="Mean">Incoming message from 'mean'. Must be a proper distribution. If any element is uniform, the result will be uniform.</param> /// <param name="result">Modified to contain the outgoing message</param> /// <returns><paramref name="result"/></returns> /// <remarks><para> /// /// </para></remarks> /// <exception cref="ImproperMessageException"><paramref name="Mean"/> is not a proper distribution</exception> public static PositiveDefiniteMatrix MeanVariance([Proper] VectorGaussian Mean, PositiveDefiniteMatrix result) { return Mean.GetVariance(result); }
/// <include file='FactorDocs.xml' path='factor_docs/message_op_class[@name="InnerProductPartialCovarianceOp"]/message_doc[@name="Ebbt(PositiveDefiniteMatrix, Vector, PositiveDefiniteMatrix)"]/*'/> public static PositiveDefiniteMatrix Ebbt(PositiveDefiniteMatrix CovarianceOfB, Vector MeanOfB, PositiveDefiniteMatrix result) { result.SetToSumWithOuter(CovarianceOfB, 1, MeanOfB, MeanOfB); return(result); }
/// <summary> /// VMP message to 'A' /// </summary> /// <param name="X">Incoming message from 'X'. Must be a proper distribution. If uniform, the result will be uniform.</param> /// <param name="A">Incoming message from 'A'.</param> /// <param name="B">Incoming message from 'B'. Must be a proper distribution. If any element is uniform, the result will be uniform.</param> /// <param name="MeanOfB">Buffer 'MeanOfB'.</param> /// <param name="CovarianceOfB">Buffer 'CovarianceOfB'.</param> /// <param name="result">Modified to contain the outgoing message</param> /// <returns><paramref name="result"/></returns> /// <remarks><para> /// The outgoing message is the exponential of the average log-factor value, where the average is over all arguments except 'A'. /// Because the factor is deterministic, 'X' is integrated out before taking the logarithm. /// The formula is <c>exp(sum_(B) p(B) log(sum_X p(X) factor(X,A,B)))</c>. /// </para></remarks> /// <exception cref="ImproperMessageException"><paramref name="X"/> is not a proper distribution</exception> /// <exception cref="ImproperMessageException"><paramref name="B"/> is not a proper distribution</exception> public static GaussianArray AAverageLogarithm([SkipIfUniform] Gaussian X, GaussianArray A, [SkipIfUniform] VectorGaussian B, Vector MeanOfB, PositiveDefiniteMatrix CovarianceOfB, /*PositiveDefiniteMatrix Ebbt,*/ GaussianArray result) { int inner = MeanOfB.Count; if (result == null) result = new GaussianArray(inner); // E[log N(x[i,j]; a[i,:]*b[:,j], 0)] = -0.5 E[(x[i,j]- sum_k a[i,k]*b[k,j])^2]/0 // = -0.5 (E[x[i,j]^2] - 2 E[x[i,j]] a[i,k] E[b[k,j]] + a[i,k] a[i,k2] E(b[k,j] b[k2,j]))/0 // a[i,k] * (-2 E[x[i,j]] E[b[k,j]] + sum_{k2 not k} E[a[i,k2]] E(b[k,j] b[k2,j])) // a[i,k]^2 * E(b[k,j]^2) // message to a[i,k] = N(a; inv(prec[i,k])*(sum_j E[b[k,j]]*res[i,j,k]/var(x[i,j])), inv(prec[i,k])) // where res[i,j,k] = E[x[i,j]] - sum_{k2 not k} E[a[i,k2]] E[b[k2,j]] // prec[i,k] = sum_j E(b[k,j]^2)/var(x[i,j]) // result.Precision = prec[i,k] // result.MeanTimesPrecision = sum_j E[b[k,j]]*res[i,j,k]/var(x[i,j]) // = sum_j E[b[k,j]]*(X.MeanTimesPrecision - X.precision*(sum_{k2 not k})) var Ebbt = new PositiveDefiniteMatrix(inner, inner); // should we be caching this too? Ebbt.SetToSumWithOuter(CovarianceOfB, 1, MeanOfB, MeanOfB); //var ma = A.Select(z => z.GetMean()).ToArray(); var ma = new double[inner]; for (int k = 0; k < inner; k++) ma[k] = A[k].GetMean(); for (int k = 0; k < inner; k++) { double prec = 0.0; double pm = 0.0; prec += Ebbt[k, k] * X.Precision; double sum = 0.0; for (int r = 0; r < inner; r++) if (r != k) sum += Ebbt[r, k] * ma[r]; pm += MeanOfB[k] * X.MeanTimesPrecision - X.Precision * sum; Gaussian rk = result[k]; rk.Precision = prec; if (prec < 0) throw new ApplicationException("improper message"); rk.MeanTimesPrecision = pm; result[k] = rk; } return result; }
/// <include file='FactorDocs.xml' path='factor_docs/message_op_class[@name="InnerProductPartialCovarianceOp"]/message_doc[@name="CovarianceOfB(VectorGaussian, PositiveDefiniteMatrix)"]/*'/> public static PositiveDefiniteMatrix CovarianceOfB([Proper] VectorGaussian B, PositiveDefiniteMatrix result) { return(B.GetVariance(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; }
/// <include file='FactorDocs.xml' path='factor_docs/message_op_class[@name="InnerProductPartialCovarianceOp"]/message_doc[@name="MeanOfB(VectorGaussian, PositiveDefiniteMatrix, Vector)"]/*'/> public static Vector MeanOfB([Proper] VectorGaussian B, PositiveDefiniteMatrix CovarianceOfB, Vector result) { return(B.GetMean(result, CovarianceOfB)); }
/// <include file='FactorDocs.xml' path='factor_docs/message_op_class[@name="MatrixVectorProductOp"]/message_doc[@name="ProductAverageConditional(double[,], Vector, PositiveDefiniteMatrix, VectorGaussianMoments)"]/*'/> public static VectorGaussianMoments ProductAverageConditional(DistributionArray2D <Gaussian, double> A, Vector BMean, PositiveDefiniteMatrix BVariance, VectorGaussianMoments result) { if (!A.IsPointMass) { throw new ArgumentException("A is not a point mass"); } return(ProductAverageConditional(new Matrix(A.Point), BMean, BVariance, result)); }
/// <include file='FactorDocs.xml' path='factor_docs/message_op_class[@name="InnerProductPartialCovarianceOp"]/message_doc[@name="AAverageLogarithm(Gaussian, DistributionStructArray{Gaussian, double}, VectorGaussian, Vector, PositiveDefiniteMatrix, DistributionStructArray{Gaussian, double})"]/*'/> public static GaussianArray AAverageLogarithm( [SkipIfUniform] Gaussian X, GaussianArray A, [SkipIfUniform] VectorGaussian B, Vector MeanOfB, PositiveDefiniteMatrix CovarianceOfB, /*PositiveDefiniteMatrix Ebbt,*/ GaussianArray result) { int inner = MeanOfB.Count; if (result == null) { result = new GaussianArray(inner); } // E[log N(x[i,j]; a[i,:]*b[:,j], 0)] = -0.5 E[(x[i,j]- sum_k a[i,k]*b[k,j])^2]/0 // = -0.5 (E[x[i,j]^2] - 2 E[x[i,j]] a[i,k] E[b[k,j]] + a[i,k] a[i,k2] E(b[k,j] b[k2,j]))/0 // a[i,k] * (-2 E[x[i,j]] E[b[k,j]] + sum_{k2 not k} E[a[i,k2]] E(b[k,j] b[k2,j])) // a[i,k]^2 * E(b[k,j]^2) // message to a[i,k] = N(a; inv(prec[i,k])*(sum_j E[b[k,j]]*res[i,j,k]/var(x[i,j])), inv(prec[i,k])) // where res[i,j,k] = E[x[i,j]] - sum_{k2 not k} E[a[i,k2]] E[b[k2,j]] // prec[i,k] = sum_j E(b[k,j]^2)/var(x[i,j]) // result.Precision = prec[i,k] // result.MeanTimesPrecision = sum_j E[b[k,j]]*res[i,j,k]/var(x[i,j]) // = sum_j E[b[k,j]]*(X.MeanTimesPrecision - X.precision*(sum_{k2 not k})) var Ebbt = new PositiveDefiniteMatrix(inner, inner); // should we be caching this too? Ebbt.SetToSumWithOuter(CovarianceOfB, 1, MeanOfB, MeanOfB); //var ma = A.Select(z => z.GetMean()).ToArray(); var ma = new double[inner]; for (int k = 0; k < inner; k++) { ma[k] = A[k].GetMean(); } for (int k = 0; k < inner; k++) { double prec = 0.0; double pm = 0.0; prec += Ebbt[k, k] * X.Precision; double sum = 0.0; for (int r = 0; r < inner; r++) { if (r != k) { sum += Ebbt[r, k] * ma[r]; } } pm += MeanOfB[k] * X.MeanTimesPrecision - X.Precision * sum; Gaussian rk = result[k]; rk.Precision = prec; if (prec < 0) { throw new InferRuntimeException("improper message"); } rk.MeanTimesPrecision = pm; result[k] = rk; } return(result); }
/// <include file='FactorDocs.xml' path='factor_docs/message_op_class[@name="MatrixVectorProductOp"]/message_doc[@name="ProductAverageConditional(Matrix, Vector, PositiveDefiniteMatrix, VectorGaussianMoments)"]/*'/> public static VectorGaussianMoments ProductAverageConditional(Matrix A, Vector BMean, PositiveDefiniteMatrix BVariance, VectorGaussianMoments result) { GetProductMoments(A, BMean, BVariance, result.Mean, result.Variance); return(result); }
public static Gaussian GPPrediction(Vector x, Vector[] xData, Gaussian[] y, KernelFunction kf, PositiveDefiniteMatrix spec) { var KxD = Vector.FromArray(xData.Select(o => kf.EvaluateX1X2(x, o)).ToArray()); double mean = spec.QuadraticForm(KxD, Vector.FromArray(y.Select(o => o.GetMean()).ToArray())); double variance = kf.EvaluateX1X2(x, x) - spec.QuadraticForm(KxD); return(Gaussian.FromMeanAndVariance(mean, variance)); }
// Modifies mean and variance // If BVariance is infinity, results may contain NaN private static void GetProductMoments(Matrix A, Vector BMean, PositiveDefiniteMatrix BVariance, Vector mean, PositiveDefiniteMatrix variance) { // P.mean = A*B.mean // P.var = A*B.var*A' mean.SetToProduct(A, BMean); if (UseAccurateMethod) { int dim = BVariance.Rows; LowerTriangularMatrix cholesky = new LowerTriangularMatrix(dim, dim); cholesky.SetToCholesky(BVariance); Matrix AL = A * cholesky; variance.SetToOuter(AL); } else { variance.SetToProduct(A, (A * BVariance).Transpose()); variance.Symmetrize(); } }
public IRating RecommendSubject(IRater rater, ISubject subject) { var raters = ratings.Select(r => r.Rater.Id).ToArray(); var subjects = ratings.Select(r => r.Subject.Id).ToArray(); var rates = ratings.Select(r => r.Value).ToArray(); Vector[] xData = new Vector[raters.Length]; for (int i = 0; i < xData.Length; ++i) { xData[i] = Vector.FromArray(raters[i], subjects[i], 1); } VariableArray <Vector> x = Variable.Observed(xData); var Y = Variable.Observed(rates, x.Range); Variable <Vector> w = Variable.Random(new VectorGaussian(Vector.Zero(3), PositiveDefiniteMatrix.Identity(3))); Range j = Y.Range; double noise = 0.1; Y[j] = Variable.GaussianFromMeanAndVariance(Variable.InnerProduct(w, x[j]), noise); var Engine = new InferenceEngine(new ExpectationPropagation()); var WPosterior = Engine.Infer <VectorGaussian>(w); double [] ratersTest = new double[1]; ratersTest[0] = rater.Id; double [] subjectsTest = new double[1]; subjectsTest[0] = subject.Id; var yTest = BayesPointMachine(ratersTest, subjectsTest, WPosterior); var pred = Engine.Infer <DistributionStructArray <Gaussian, double> >(yTest); return(new SimpleRating(rater, subject, pred[0].Point)); }
/// <summary> /// Helper method for computing average log factor /// </summary> /// <param name="SampleMean">Mean of incoming message from 'sample'</param> /// <param name="SampleVariance">Variance of incoming message from 'sample'</param> /// <param name="MeanMean">Mean of incoming message from 'mean'</param> /// <param name="MeanVariance">Variance of incoming message from 'mean'</param> /// <param name="precision_Elogx">Expected log value of the incoming message from 'precision'</param> /// <param name="precision_Ex">Expected value of incoming message from 'precision'</param> /// <returns>Computed average log factor</returns> private static double ComputeAverageLogFactor( [Fresh] Vector SampleMean, [Fresh] PositiveDefiniteMatrix SampleVariance, [Fresh] Vector MeanMean, [Fresh] PositiveDefiniteMatrix MeanVariance, double precision_Elogx, PositiveDefiniteMatrix precision_Ex) { int dim = SampleMean.Count; int nonzeroDims = 0; double precTimesVariance = 0.0; double precTimesDiff = 0.0; for (int i = 0; i < dim; i++) { if (double.IsPositiveInfinity(precision_Ex[i, i])) { if (SampleMean[i] != MeanMean[i] || SampleVariance[i, i]+MeanVariance[i,i] > 0) return double.NegativeInfinity; } else { nonzeroDims++; double sum = 0.0; for (int j = 0; j < dim; j++) { sum += precision_Ex[i, j]*(SampleMean[j] - MeanMean[j]); precTimesVariance += precision_Ex[i, j]*(SampleVariance[i, j] + MeanVariance[i,j]); } precTimesDiff += sum*(SampleMean[i] - MeanMean[i]); } } return -nonzeroDims * MMath.LnSqrt2PI + 0.5 * (precision_Elogx - precTimesVariance - precTimesDiff); }
public IEnumerable <IRating> RecommendSubjects(IRater rater, IEnumerable <ISubject> subjects, int take = -1, int skip = 0) { var raters = ratings.Select(r => r.Rater.Id).ToArray(); var subjectsInit = ratings.Select(r => r.Subject.Id).ToArray(); var rates = ratings.Select(r => r.Value).ToArray(); Vector[] xData = new Vector[raters.Length]; for (int i = 0; i < xData.Length; ++i) { xData[i] = Vector.FromArray(raters[i], subjectsInit[i], 1); } VariableArray <Vector> x = Variable.Observed(xData); var Y = Variable.Observed(rates, x.Range); Variable <Vector> w = Variable.Random(new VectorGaussian(Vector.Zero(3), PositiveDefiniteMatrix.Identity(3))); Range j = Y.Range; double noise = 0.1; Y[j] = Variable.GaussianFromMeanAndVariance(Variable.InnerProduct(w, x[j]), noise); var Engine = new InferenceEngine(new ExpectationPropagation()); var WPosterior = Engine.Infer <VectorGaussian>(w); var subjectsArray = subjects.ToArray(); var ratersTest = Enumerable.Repeat((double)rater.Id, subjectsArray.Length).ToArray(); var subjectsIdsTest = subjects.Select(s => (double)s.Id).ToArray(); var yTest = BayesPointMachine(ratersTest, subjectsIdsTest, WPosterior); var pred = Engine.Infer <DistributionStructArray <Gaussian, double> >(yTest); var results = new List <IRating>(); for (int i = 0; i < subjectsArray.Length; ++i) { results.Add(new SimpleRating(rater, subjectsArray[i], pred[i].Point)); } return(results.OrderBy(r => r.Value).Skip(skip).Take(take)); }
/// <summary> /// VMP message to 'sample' /// </summary> /// <param name="mean">Incoming message from 'mean'. Must be a proper distribution. If any element is uniform, the result will be uniform.</param> /// <param name="MeanMean">Buffer 'MeanMean'.</param> /// <param name="Precision">Constant value for 'precision'.</param> /// <param name="result">Modified to contain the outgoing message</param> /// <returns><paramref name="result"/></returns> /// <remarks><para> /// The outgoing message is the exponential of the average log-factor value, where the average is over all arguments except 'sample'. /// The formula is <c>exp(sum_(mean) p(mean) log(factor(sample,mean,precision)))</c>. /// </para></remarks> /// <exception cref="ImproperMessageException"><paramref name="mean"/> is not a proper distribution</exception> public static VectorGaussian SampleAverageLogarithm([Proper] VectorGaussian mean, [Fresh] Vector MeanMean, PositiveDefiniteMatrix Precision, VectorGaussian result) { if (result == default(VectorGaussian)) result = new VectorGaussian(MeanMean.Count); result.Precision.SetTo(Precision); result.MeanTimesPrecision.SetToProduct(result.Precision, MeanMean); return result; }
/// <summary>Computations that depend on the observed value of vVector__169</summary> private void Changed_vVector__169() { if (this.Changed_vVector__169_iterationsDone == 1) { return; } this.vVector__169_marginal = new PointMass <Vector[]>(this.VVector__169); // The constant 'vVectorGaussian169' VectorGaussian vVectorGaussian169 = VectorGaussian.FromNatural(DenseVector.FromArray(new double[3] { 1547829870.0, 525077980.0, 200270.0 }), new PositiveDefiniteMatrix(new double[3, 3] { { 4254590363351.0, 1127383488860.0, 433199230.0 }, { 1127383488860.0, 482723521821.0, 146764360.0 }, { 433199230.0, 146764360.0, 56221.0 } })); this.vVector507_marginal_F = ArrayHelper.MakeUniform <VectorGaussian>(vVectorGaussian169); // Buffer for ReplicateOp_Divide.Marginal<VectorGaussian> VectorGaussian vVector507_rep_B_toDef = default(VectorGaussian); // Message to 'vVector507_rep' from Replicate factor vVector507_rep_B_toDef = ReplicateOp_Divide.ToDefInit <VectorGaussian>(vVectorGaussian169); // Message to 'vVector507_marginal' from Variable factor this.vVector507_marginal_F = VariableOp.MarginalAverageConditional <VectorGaussian>(vVector507_rep_B_toDef, vVectorGaussian169, this.vVector507_marginal_F); DistributionStructArray <Gaussian, double> vdouble__507_F = default(DistributionStructArray <Gaussian, double>); // Create array for 'vdouble__507' Forwards messages. vdouble__507_F = new DistributionStructArray <Gaussian, double>(1); for (int index169 = 0; index169 < 1; index169++) { vdouble__507_F[index169] = Gaussian.Uniform(); } DistributionStructArray <Gaussian, double> vdouble__508_F = default(DistributionStructArray <Gaussian, double>); // Create array for 'vdouble__508' Forwards messages. vdouble__508_F = new DistributionStructArray <Gaussian, double>(1); for (int index169 = 0; index169 < 1; index169++) { vdouble__508_F[index169] = Gaussian.Uniform(); } DistributionRefArray <VectorGaussian, Vector> vVector507_rep_F = default(DistributionRefArray <VectorGaussian, Vector>); DistributionRefArray <VectorGaussian, Vector> vVector507_rep_B = default(DistributionRefArray <VectorGaussian, Vector>); // Create array for 'vVector507_rep' Forwards messages. vVector507_rep_F = new DistributionRefArray <VectorGaussian, Vector>(1); // Create array for 'vVector507_rep' Backwards messages. vVector507_rep_B = new DistributionRefArray <VectorGaussian, Vector>(1); for (int index169 = 0; index169 < 1; index169++) { vVector507_rep_B[index169] = ArrayHelper.MakeUniform <VectorGaussian>(vVectorGaussian169); vVector507_rep_F[index169] = ArrayHelper.MakeUniform <VectorGaussian>(vVectorGaussian169); } // Buffer for ReplicateOp_Divide.UsesAverageConditional<VectorGaussian> VectorGaussian vVector507_rep_F_marginal = default(VectorGaussian); // Message to 'vVector507_rep' from Replicate factor vVector507_rep_F_marginal = ReplicateOp_Divide.MarginalInit <VectorGaussian>(vVectorGaussian169); // Message to 'vVector507_rep' from Replicate factor vVector507_rep_F_marginal = ReplicateOp_Divide.Marginal <VectorGaussian>(vVector507_rep_B_toDef, vVectorGaussian169, vVector507_rep_F_marginal); // Buffer for InnerProductOp.InnerProductAverageConditional // Create array for replicates of 'vVector507_rep_F_index169__AMean' Vector[] vVector507_rep_F_index169__AMean = new Vector[1]; for (int index169 = 0; index169 < 1; index169++) { // Message to 'vdouble__508' from InnerProduct factor vVector507_rep_F_index169__AMean[index169] = InnerProductOp.AMeanInit(vVector507_rep_F[index169]); } // Buffer for InnerProductOp.AMean // Create array for replicates of 'vVector507_rep_F_index169__AVariance' PositiveDefiniteMatrix[] vVector507_rep_F_index169__AVariance = new PositiveDefiniteMatrix[1]; for (int index169 = 0; index169 < 1; index169++) { // Message to 'vdouble__508' from InnerProduct factor vVector507_rep_F_index169__AVariance[index169] = InnerProductOp.AVarianceInit(vVector507_rep_F[index169]); // Message to 'vVector507_rep' from Replicate factor vVector507_rep_F[index169] = ReplicateOp_Divide.UsesAverageConditional <VectorGaussian>(vVector507_rep_B[index169], vVector507_rep_F_marginal, index169, vVector507_rep_F[index169]); } // Create array for 'vdouble__508_marginal' Forwards messages. this.vdouble__508_marginal_F = new DistributionStructArray <Gaussian, double>(1); for (int index169 = 0; index169 < 1; index169++) { this.vdouble__508_marginal_F[index169] = Gaussian.Uniform(); } // Message from use of 'vdouble__508' DistributionStructArray <Gaussian, double> vdouble__508_use_B = default(DistributionStructArray <Gaussian, double>); // Create array for 'vdouble__508_use' Backwards messages. vdouble__508_use_B = new DistributionStructArray <Gaussian, double>(1); for (int index169 = 0; index169 < 1; index169++) { vdouble__508_use_B[index169] = Gaussian.Uniform(); // Message to 'vdouble__508' from InnerProduct factor vVector507_rep_F_index169__AVariance[index169] = InnerProductOp.AVariance(vVector507_rep_F[index169], vVector507_rep_F_index169__AVariance[index169]); // Message to 'vdouble__508' from InnerProduct factor vVector507_rep_F_index169__AMean[index169] = InnerProductOp.AMean(vVector507_rep_F[index169], vVector507_rep_F_index169__AVariance[index169], vVector507_rep_F_index169__AMean[index169]); // Message to 'vdouble__508' from InnerProduct factor vdouble__508_F[index169] = InnerProductOp.InnerProductAverageConditional(vVector507_rep_F_index169__AMean[index169], vVector507_rep_F_index169__AVariance[index169], this.VVector__169[index169]); // Message to 'vdouble__508_marginal' from DerivedVariable factor this.vdouble__508_marginal_F[index169] = DerivedVariableOp.MarginalAverageConditional <Gaussian>(vdouble__508_use_B[index169], vdouble__508_F[index169], this.vdouble__508_marginal_F[index169]); } // Create array for 'vdouble__507_marginal' Forwards messages. this.vdouble__507_marginal_F = new DistributionStructArray <Gaussian, double>(1); for (int index169 = 0; index169 < 1; index169++) { this.vdouble__507_marginal_F[index169] = Gaussian.Uniform(); } // Message from use of 'vdouble__507' DistributionStructArray <Gaussian, double> vdouble__507_use_B = default(DistributionStructArray <Gaussian, double>); // Create array for 'vdouble__507_use' Backwards messages. vdouble__507_use_B = new DistributionStructArray <Gaussian, double>(1); for (int index169 = 0; index169 < 1; index169++) { vdouble__507_use_B[index169] = Gaussian.Uniform(); // Message to 'vdouble__507' from GaussianFromMeanAndVariance factor vdouble__507_F[index169] = GaussianFromMeanAndVarianceOp.SampleAverageConditional(vdouble__508_F[index169], 0.1); // Message to 'vdouble__507_marginal' from Variable factor this.vdouble__507_marginal_F[index169] = VariableOp.MarginalAverageConditional <Gaussian>(vdouble__507_use_B[index169], vdouble__507_F[index169], this.vdouble__507_marginal_F[index169]); } this.Changed_vVector__169_iterationsDone = 1; }
/// <summary> /// VMP message to 'mean' /// </summary> /// <param name="Sample">Incoming message from 'sample'. Must be a proper distribution. If any element is uniform, the result will be uniform.</param> /// <param name="SampleMean">Buffer 'SampleMean'.</param> /// <param name="Precision">Constant value for 'precision'.</param> /// <param name="result">Modified to contain the outgoing message</param> /// <returns><paramref name="result"/></returns> /// <remarks><para> /// The outgoing message is the exponential of the average log-factor value, where the average is over all arguments except 'mean'. /// The formula is <c>exp(sum_(sample) p(sample) log(factor(sample,mean,precision)))</c>. /// </para></remarks> /// <exception cref="ImproperMessageException"><paramref name="Sample"/> is not a proper distribution</exception> public static VectorGaussian MeanAverageLogarithm([Proper] VectorGaussian Sample, [Fresh] Vector SampleMean, PositiveDefiniteMatrix Precision, VectorGaussian result) { return SampleAverageLogarithm(Sample, SampleMean, Precision, 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; }
/// <summary> /// Update the buffer 'MeanOfB' /// </summary> /// <param name="B">Incoming message from 'B'. Must be a proper distribution. If any element is uniform, the result will be uniform.</param> /// <param name="CovarianceOfB">Buffer 'CovarianceOfB'.</param> /// <param name="result">Storage for result</param> /// <returns>New value of buffer 'MeanOfB'</returns> /// <exception cref="ImproperMessageException"><paramref name="B"/> is not a proper distribution</exception> public static Vector MeanOfB([Proper] VectorGaussian B, PositiveDefiniteMatrix CovarianceOfB, Vector result) { return B.GetMean(result, CovarianceOfB); }
/// <summary> /// EP message to 'Sum' /// </summary> /// <param name="A">Constant value for 'A'.</param> /// <param name="B">Incoming message from 'B'. Must be a proper distribution. If any element is uniform, the result will be uniform.</param> /// <param name="MeanOfB">Buffer 'MeanOfB'.</param> /// <param name="CovarianceOfB">Buffer 'CovarianceOfB'.</param> /// <returns>The outgoing EP message to the 'Sum' argument</returns> /// <remarks><para> /// The outgoing message is a distribution matching the moments of 'Sum' as the random arguments are varied. /// The formula is <c>proj[p(Sum) sum_(B) p(B) factor(Sum,A,B)]/p(Sum)</c>. /// </para></remarks> /// <exception cref="ImproperMessageException"><paramref name="B"/> is not a proper distribution</exception> public static Gaussian SumAverageConditional(bool[] A, [SkipIfUniform] VectorGaussian B, Vector MeanOfB, PositiveDefiniteMatrix CovarianceOfB) { return SumAverageLogarithm(A, B, MeanOfB, CovarianceOfB); }
/// <summary> /// VMP message to 'X' /// </summary> /// <param name="A">Incoming message from 'A'. Must be a proper distribution. If all elements are uniform, the result will be uniform.</param> /// <param name="B">Incoming message from 'B'. Must be a proper distribution. If all elements are uniform, the result will be uniform.</param> /// <param name="MeanOfB">Buffer 'MeanOfB'.</param> /// <param name="CovarianceOfB">Buffer 'CovarianceOfB'.</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 'X' as the random arguments are varied. /// The formula is <c>proj[sum_(A,B) p(A,B) factor(X,A,B)]</c>. /// </para></remarks> /// <exception cref="ImproperMessageException"><paramref name="A"/> is not a proper distribution</exception> /// <exception cref="ImproperMessageException"><paramref name="B"/> is not a proper distribution</exception> public static Gaussian XAverageLogarithm([SkipIfAllUniform] GaussianArray A, [SkipIfAllUniform] VectorGaussian B, Vector MeanOfB, PositiveDefiniteMatrix CovarianceOfB) { int K = MeanOfB.Count; // p(x|a,b) = N(E[a]'*E[b], E[b]'*var(a)*E[b] + E[a]'*var(b)*E[a] + trace(var(a)*var(b))) var ma = Vector.Zero(K); var va = Vector.Zero(K); for (int k = 0; k < K; k++) { double m, v; A[k].GetMeanAndVariance(out m, out v); ma[k] = m; va[k] = v; } // Uses John Winn's rule for deterministic factors. // Strict variational inference would set the variance to 0. var mbj2 = Vector.Zero(K); mbj2.SetToFunction(MeanOfB, x => x * x); // slooow Gaussian result = new Gaussian(); result.SetMeanAndVariance(ma.Inner(MeanOfB), va.Inner(mbj2) + CovarianceOfB.QuadraticForm(ma) + va.Inner(CovarianceOfB.Diagonal())); if (result.Precision < 0) throw new ApplicationException("improper message"); return result; }
/// <summary> /// Update the buffer 'MeanOfB' /// </summary> /// <param name="B">Incoming message from 'B'. Must be a proper distribution. If any element is uniform, the result will be uniform.</param> /// <param name="CovarianceOfB">Buffer 'CovarianceOfB'.</param> /// <returns>New value of buffer 'MeanOfB'</returns> /// <remarks><para> /// /// </para></remarks> /// <exception cref="ImproperMessageException"><paramref name="B"/> is not a proper distribution</exception> public static Vector MeanOfB([Proper] VectorGaussian B, PositiveDefiniteMatrix CovarianceOfB) { return CovarianceOfB * B.MeanTimesPrecision; }
/// <summary> /// Creates a new VectorGaussian estimator of a given dimension /// </summary> /// <param name="dimension">The dimension</param> public VectorGaussianEstimator(int dimension) { x = Vector.Zero(dimension); noiseVariance = new PositiveDefiniteMatrix(dimension, dimension); mva = new VectorMeanVarianceAccumulator(dimension); }
/// <summary> /// VMP message to 'Sum' /// </summary> /// <param name="A">Constant value for 'A'.</param> /// <param name="B">Incoming message from 'B'. Must be a proper distribution. If any element is uniform, the result will be uniform.</param> /// <param name="MeanOfB">Buffer 'MeanOfB'.</param> /// <param name="CovarianceOfB">Buffer 'CovarianceOfB'.</param> /// <returns>The outgoing VMP message to the 'Sum' argument</returns> /// <remarks><para> /// The outgoing message is a distribution matching the moments of 'Sum' as the random arguments are varied. /// The formula is <c>proj[sum_(B) p(B) factor(Sum,A,B)]</c>. /// </para><para> /// Uses John Winn's rule for deterministic factors. /// </para></remarks> /// <exception cref="ImproperMessageException"><paramref name="B"/> is not a proper distribution</exception> public static Gaussian SumAverageLogarithm(bool[] A, [SkipIfUniform] VectorGaussian B, Vector MeanOfB, PositiveDefiniteMatrix CovarianceOfB) { Gaussian result = new Gaussian(); // p(x|a,b) = N(E[a]'*E[b], E[b]'*var(a)*E[b] + E[a]'*var(b)*E[a] + trace(var(a)*var(b))) Vector ma = Vector.FromArray(A.Select(x => x?1.0:0.0).ToArray()); // Uses John Winn's rule for deterministic factors. // Strict variational inference would set the variance to 0. result.SetMeanAndVariance(ma.Inner(MeanOfB), CovarianceOfB.QuadraticForm(ma)); return result; }
/// <summary> /// VMP message to 'X'. /// </summary> /// <param name="A">Incoming message from 'a'. Must be a proper distribution. If uniform, the result will be uniform.</param> /// <param name="B">Incoming message from 'b'. Must be a proper distribution. If uniform, the result will be uniform.</param> /// <returns>The outgoing VMP message to the 'X' argument.</returns> /// <remarks><para> /// The outgoing message is the exponential of the integral of the log-factor times incoming messages, over all arguments except 'innerProduct'. /// The formula is <c>int log(f(innerProduct,x)) q(x) dx</c> where <c>x = (a,b)</c>. /// </para></remarks> /// <exception cref="ImproperMessageException"><paramref name="A"/> is not a proper distribution</exception> /// <exception cref="ImproperMessageException"><paramref name="A"/> is not a proper distribution</exception> public static GaussianArray2D XAverageLogarithm([SkipIfAllUniform] VectorGaussianArray A, [SkipIfAllUniform] VectorGaussianArray B, GaussianArray2D result) { int I = A.GetLength(0), J = B.Count, K = A[0].Dimension; if (result == null) result = new DistributionStructArray2D<Gaussian, double>(I, J); // p(x|a,b) = N(E[a]'*E[b], E[b]'*var(a)*E[b] + E[a]'*var(b)*E[a] + trace(var(a)*var(b))) var ma = new Vector[I]; var mb = new Vector[J]; var va = new PositiveDefiniteMatrix[I]; var vb = new PositiveDefiniteMatrix[J]; for (int i = 0; i < I; i++) { ma[i] = Vector.Zero(K); va[i] = new PositiveDefiniteMatrix(K, K); A[i].GetMeanAndVariance(ma[i], va[i]); } for (int j = 0; j < J; j++) { mb[j] = Vector.Zero(K); vb[j] = new PositiveDefiniteMatrix(K, K); B[j].GetMeanAndVariance(mb[j], vb[j]); } // Uses John Winn's rule for deterministic factors. // Strict variational inference would set the variance to 0. for (int i = 0; i < I; i++) for (int j = 0; j < J; j++) { var rij = result[i, j]; rij.SetMeanAndVariance(ma[i].Inner(mb[j]), va[i].QuadraticForm(mb[j]) + vb[j].QuadraticForm(ma[i]) + va[i].Inner(vb[j])); result[i, j] = rij; } return result; }
/// <summary> /// EP message to 'A' /// </summary> /// <param name="matrixMultiply">Incoming message from 'matrixMultiply'. Must be a proper distribution. If any element is uniform, the result will be uniform.</param> /// <param name="A">Incoming message from 'A'. Must be a proper distribution. If any element is uniform, the result will be uniform.</param> /// <param name="B">Constant value for 'B'.</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 'A' as the random arguments are varied. /// The formula is <c>proj[p(A) sum_(matrixMultiply) p(matrixMultiply) factor(matrixMultiply,A,B)]/p(A)</c>. /// </para></remarks> /// <exception cref="ImproperMessageException"><paramref name="matrixMultiply"/> is not a proper distribution</exception> /// <exception cref="ImproperMessageException"><paramref name="A"/> is not a proper distribution</exception> public static GaussianArray2D AAverageConditional([SkipIfUniform] GaussianArray2D matrixMultiply, [SkipIfUniform] GaussianArray2D A, double[,] B, GaussianArray2D result) { int rows = matrixMultiply.GetLength(0); int cols = matrixMultiply.GetLength(1); int inner = B.GetLength(0); if (result == null) result = new GaussianArray2D(rows, inner); // sum_{i,j} (m[i,j] - a[i,:]*b[:,j])^2/v[i,j] = // sum_{i,j} (m[i,j]^2 - 2m[i,j]a[i,:]*b[:,j] + a[i,:]*(b[:,j] b[:,j]')*a[i,:]')/v[i,j] // meanTimesPrec(a[i,:]) = sum_j (m[i,j]/v[i,j]) b[:,j] // prec(a[i,:]) = sum_j b[:,j]*b[:,j]'/v[i,j] Vector bj = Vector.Zero(inner); Vector mean = Vector.Zero(inner); VectorGaussian ai = new VectorGaussian(inner); PositiveDefiniteMatrix variance = new PositiveDefiniteMatrix(inner, inner); for (int i = 0; i < rows; i++) { ai.Precision.SetAllElementsTo(0.0); ai.MeanTimesPrecision.SetAllElementsTo(0.0); // we are projecting from family of full covariance Gaussians to diagonal // covariance, so we should include the context for (int c = 0; c < inner; c++) { ai.Precision[c, c] = A[i, c].Precision; ai.MeanTimesPrecision[c] = A[i, c].MeanTimesPrecision; } for (int j = 0; j < cols; j++) { Gaussian xij = matrixMultiply[i, j]; for (int k = 0; k < inner; k++) { bj[k] = B[k, j]; } if (xij.IsPointMass) throw new NotImplementedException(LowRankNotSupportedMessage); ai.Precision.SetToSumWithOuter(ai.Precision, xij.Precision, bj, bj); ai.MeanTimesPrecision.SetToSum(1.0, ai.MeanTimesPrecision, xij.MeanTimesPrecision, bj); } ai.GetMeanAndVariance(mean, variance); for (int k = 0; k < inner; k++) { Gaussian rik = result[i, k]; rik.SetMeanAndVariance(mean[k], variance[k, k]); result[i, k] = rik / A[i, k]; } } return result; }
/// <summary>EP message to <c>Sum</c>.</summary> /// <param name="A">Constant value for <c>A</c>.</param> /// <param name="B">Incoming message from <c>B</c>. Must be a proper distribution. If any element is uniform, the result will be uniform.</param> /// <param name="MeanOfB">Buffer <c>MeanOfB</c>.</param> /// <param name="CovarianceOfB">Buffer <c>CovarianceOfB</c>.</param> /// <returns>The outgoing EP message to the <c>Sum</c> argument.</returns> /// <remarks> /// <para>The outgoing message is a distribution matching the moments of <c>Sum</c> as the random arguments are varied. The formula is <c>proj[p(Sum) sum_(B) p(B) factor(Sum,A,B)]/p(Sum)</c>.</para> /// </remarks> /// <exception cref="ImproperMessageException"> /// <paramref name="B" /> is not a proper distribution.</exception> public static Gaussian SumAverageConditional(bool[] A, [SkipIfUniform] VectorGaussian B, Vector MeanOfB, PositiveDefiniteMatrix CovarianceOfB) { return(SumAverageLogarithm(A, B, MeanOfB, CovarianceOfB)); }
/// <include file='FactorDocs.xml' path='factor_docs/message_op_class[@name="MatrixVectorProductOp"]/message_doc[@name="ProductAverageConditional(double[,], Vector, PositiveDefiniteMatrix, VectorGaussian)"]/*'/> public static VectorGaussian ProductAverageConditional(double[,] A, Vector BMean, PositiveDefiniteMatrix BVariance, VectorGaussian result) { return(ProductAverageConditional(new Matrix(A), BMean, BVariance, result)); }
/// <summary> /// Update the buffer 'BVariance' /// </summary> /// <param name="B">Incoming message from 'b'. Must be a proper distribution. If any element is uniform, the result will be uniform.</param> /// <param name="result">Modified to contain the outgoing message</param> /// <returns><paramref name="result"/></returns> /// <remarks><para> /// /// </para></remarks> /// <exception cref="ImproperMessageException"><paramref name="B"/> is not a proper distribution</exception> public static PositiveDefiniteMatrix BVariance([Proper] VectorGaussian B, PositiveDefiniteMatrix result) { return B.GetVariance(result); }
/// <summary>Update the buffer <c>MeanOfB</c>.</summary> /// <param name="B">Incoming message from <c>B</c>. Must be a proper distribution. If any element is uniform, the result will be uniform.</param> /// <param name="CovarianceOfB">Buffer <c>CovarianceOfB</c>.</param> /// <returns>New value of buffer <c>MeanOfB</c>.</returns> /// <remarks> /// <para /> /// </remarks> /// <exception cref="ImproperMessageException"> /// <paramref name="B" /> is not a proper distribution.</exception> public static Vector MeanOfB([Proper] VectorGaussian B, PositiveDefiniteMatrix CovarianceOfB) { return(CovarianceOfB * B.MeanTimesPrecision); }
/// <summary> /// Evidence message for EP /// </summary> /// <param name="sum">Constant value for 'Sum'.</param> /// <param name="A">Constant value for 'A'.</param> /// <param name="B">Incoming message from 'B'. Must be a proper distribution. If any element is uniform, the result will be uniform.</param> /// <param name="MeanOfB">Buffer 'MeanOfB'.</param> /// <param name="CovarianceOfB">Buffer 'CovarianceOfB'.</param> /// <returns>Logarithm of the factor's average value across the given argument distributions</returns> /// <remarks><para> /// The formula for the result is <c>log(sum_(B) p(B) factor(Sum,A,B))</c>. /// </para></remarks> /// <exception cref="ImproperMessageException"><paramref name="B"/> is not a proper distribution</exception> public static double LogAverageFactor(double sum, bool[] A, [SkipIfUniform] VectorGaussian B, Vector MeanOfB, PositiveDefiniteMatrix CovarianceOfB) { Gaussian to_sum = SumAverageConditional(A, B, MeanOfB, CovarianceOfB); return to_sum.GetLogProb(sum); }
/// <summary>VMP message to <c>Sum</c>.</summary> /// <param name="A">Incoming message from <c>A</c>.</param> /// <param name="B">Incoming message from <c>B</c>. Must be a proper distribution. If any element is uniform, the result will be uniform.</param> /// <param name="MeanOfB">Buffer <c>MeanOfB</c>.</param> /// <param name="CovarianceOfB">Buffer <c>CovarianceOfB</c>.</param> /// <returns>The outgoing VMP message to the <c>Sum</c> argument.</returns> /// <remarks> /// <para>The outgoing message is a distribution matching the moments of <c>Sum</c> as the random arguments are varied. The formula is <c>proj[sum_(A,B) p(A,B) factor(Sum,A,B)]</c>.</para> /// </remarks> /// <exception cref="ImproperMessageException"> /// <paramref name="B" /> is not a proper distribution.</exception> public static Gaussian SumAverageLogarithm( DistributionStructArray <Bernoulli, bool> A, [SkipIfUniform] VectorGaussian B, Vector MeanOfB, PositiveDefiniteMatrix CovarianceOfB) { Gaussian result = new Gaussian(); // p(x|a,b) = N(E[a]'*E[b], E[b]'*var(a)*E[b] + E[a]'*var(b)*E[a] + trace(var(a)*var(b))) Vector ma = Vector.Zero(A.Count); Vector va = Vector.Zero(A.Count); for (int i = 0; i < A.Count; i++) { ma[i] = A[i].GetMean(); va[i] = A[i].GetVariance(); } // Uses John Winn's rule for deterministic factors. // Strict variational inference would set the variance to 0. var MeanOfBSquared = Vector.Zero(MeanOfB.Count); MeanOfBSquared.SetToFunction(MeanOfB, x => x * x); result.SetMeanAndVariance(ma.Inner(MeanOfB), va.Inner(MeanOfBSquared) + CovarianceOfB.QuadraticForm(ma) + va.Inner(CovarianceOfB.Diagonal())); return(result); }
/// <summary> /// VMP message to 'Sum' /// </summary> /// <param name="A">Incoming message from 'A'.</param> /// <param name="B">Incoming message from 'B'. Must be a proper distribution. If any element is uniform, the result will be uniform.</param> /// <param name="MeanOfB">Buffer 'MeanOfB'.</param> /// <param name="CovarianceOfB">Buffer 'CovarianceOfB'.</param> /// <returns>The outgoing VMP message to the 'Sum' argument</returns> /// <remarks><para> /// The outgoing message is a distribution matching the moments of 'Sum' as the random arguments are varied. /// The formula is <c>proj[sum_(A,B) p(A,B) factor(Sum,A,B)]</c>. /// </para></remarks> /// <exception cref="ImproperMessageException"><paramref name="B"/> is not a proper distribution</exception> public static Gaussian SumAverageLogarithm(DistributionStructArray<Bernoulli, bool> A, [SkipIfUniform] VectorGaussian B, Vector MeanOfB, PositiveDefiniteMatrix CovarianceOfB) { Gaussian result = new Gaussian(); // p(x|a,b) = N(E[a]'*E[b], E[b]'*var(a)*E[b] + E[a]'*var(b)*E[a] + trace(var(a)*var(b))) Vector ma = Vector.Zero(A.Count); Vector va = Vector.Zero(A.Count); for (int i = 0; i < A.Count; i++) { ma[i] = A[i].GetMean(); va[i] = A[i].GetVariance(); } // Uses John Winn's rule for deterministic factors. // Strict variational inference would set the variance to 0. var MeanOfBSquared = Vector.Zero(MeanOfB.Count); MeanOfBSquared.SetToFunction(MeanOfB, x => x * x); result.SetMeanAndVariance(ma.Inner(MeanOfB), va.Inner(MeanOfBSquared) + CovarianceOfB.QuadraticForm(ma) + va.Inner(CovarianceOfB.Diagonal())); return result; }
/// <summary>VMP message to <c>Sum</c>.</summary> /// <param name="A">Constant value for <c>A</c>.</param> /// <param name="B">Incoming message from <c>B</c>. Must be a proper distribution. If any element is uniform, the result will be uniform.</param> /// <param name="MeanOfB">Buffer <c>MeanOfB</c>.</param> /// <param name="CovarianceOfB">Buffer <c>CovarianceOfB</c>.</param> /// <returns>The outgoing VMP message to the <c>Sum</c> argument.</returns> /// <remarks> /// <para>The outgoing message is a distribution matching the moments of <c>Sum</c> as the random arguments are varied. The formula is <c>proj[sum_(B) p(B) factor(Sum,A,B)]</c>.</para> /// </remarks> /// <exception cref="ImproperMessageException"> /// <paramref name="B" /> is not a proper distribution.</exception> public static Gaussian SumAverageLogarithm(bool[] A, [SkipIfUniform] VectorGaussian B, Vector MeanOfB, PositiveDefiniteMatrix CovarianceOfB) { Gaussian result = new Gaussian(); // p(x|a,b) = N(E[a]'*E[b], E[b]'*var(a)*E[b] + E[a]'*var(b)*E[a] + trace(var(a)*var(b))) Vector ma = Vector.FromArray(A.Select(x => x ? 1.0 : 0.0).ToArray()); // Uses John Winn's rule for deterministic factors. // Strict variational inference would set the variance to 0. result.SetMeanAndVariance(ma.Inner(MeanOfB), CovarianceOfB.QuadraticForm(ma)); return(result); }
/// <summary> /// VMP message to 'A' /// </summary> /// <param name="sum">Incoming message from 'Sum'. Must be a proper distribution. If uniform, the result will be uniform.</param> /// <param name="A">Incoming message from 'A'. Must be a proper distribution. If all elements are uniform, the result will be uniform.</param> /// <param name="B">Incoming message from 'B'. Must be a proper distribution. If any element is uniform, the result will be uniform.</param> /// <param name="MeanOfB">Buffer 'MeanOfB'.</param> /// <param name="CovarianceOfB">Buffer 'CovarianceOfB'.</param> /// <param name="result">Modified to contain the outgoing message</param> /// <returns><paramref name="result"/></returns> /// <remarks><para> /// The outgoing message is the exponential of the average log-factor value, where the average is over all arguments except 'A'. /// Because the factor is deterministic, 'Sum' is integrated out before taking the logarithm. /// The formula is <c>exp(sum_(B) p(B) log(sum_Sum p(Sum) factor(Sum,A,B)))</c>. /// </para></remarks> /// <exception cref="ImproperMessageException"><paramref name="sum"/> is not a proper distribution</exception> /// <exception cref="ImproperMessageException"><paramref name="A"/> is not a proper distribution</exception> /// <exception cref="ImproperMessageException"><paramref name="B"/> is not a proper distribution</exception> public static DistributionStructArray<Bernoulli, bool> AAverageLogarithm([SkipIfUniform] Gaussian sum, [Proper] DistributionStructArray<Bernoulli, bool> A, [Proper] VectorGaussian B, Vector MeanOfB, PositiveDefiniteMatrix CovarianceOfB, DistributionStructArray<Bernoulli, bool> result) { double mu = sum.GetMean(); var Ebbt = new PositiveDefiniteMatrix(A.Count, A.Count); Ebbt.SetToSumWithOuter(CovarianceOfB, 1, MeanOfB, MeanOfB); var ma = A.Select(x => x.GetMean()).ToArray(); for (int i = 0; i < A.Count; i++) { double term1 = 0.0; for (int j = 0; j < A.Count; j++) if (j != i) term1 += ma[i] * Ebbt[i, j]; var ri = result[i]; ri.LogOdds = -.5 * sum.Precision * (2.0 * term1 + Ebbt[i, i] - 2.0 * mu * MeanOfB[i]); result[i] = ri; } return result; }
public static void Main(string[] args) { // The labeled training data double[] strikes = { 2, 1, 2, 0, 1, 0 }; bool[] fastball = { true, false, true, true, false, false }; double[] balls = { 3, 3, 0, 2, 1, 0 }; double[] outs = { 0, 1, 1, 2, 0, 2 }; double[] scoreDifferential = { 0, 3, 2, 1, 1, 2 }; double[] basesLoaded = { 1, 0, 0, 0, 1, 0 }; double[] inning = { 1, 5, 7, 2, 1, 4 }; double[] handedness = { 1, 1, 1, 1, 1, 0 }; double[] numPitches = { 18, 32, 9, 1, 88, 34 }; double[] homePrior = { .25, .36, .88, .75, .99, .92 }; double[] battingTeamPrior = { .15, .78, .59, .75, .14, .06 }; double[] countPrior = { .89, .18, .72, .72, .1, .49 }; double[] batterPrior = { .7, .53, .91, .56, .9, .8 }; double[] homePriorSupport = { 180, 58, 75, 234, 75, 250 }; double[] battingTeamPriorSupport = { 44, 58, 59, 204, 167, 61 }; double[] countPriorSupport = { 32, 237, 151, 56, 58, 131 }; double[] batterPriorSupport = { 193, 226, 244, 9, 153, 122 }; double[] batterSlugging = { .182, .493, .337, .155, .157, .372 }; double[] batterRuns = { 37, 84, 12, 35, 53, 74 }; double[] previousPitchType = { 1, 0, 1, 1, 0, 1 }; double[] previousPitchResult = { 1, 0, 0, 1, 1, 0 }; double[] previousPitchVelocity = { 87, 85, 89, 91, 97, 101 }; double[] previousPitchVelocityGradient = { 12, 1, -13, 1, 13, 12 }; // Create target vector and weights VariableArray <bool> y = Variable.Observed(fastball).Named("y"); Variable <Vector> w = Variable.Random(new VectorGaussian(Vector.Zero(23), PositiveDefiniteMatrix.Identity(23))).Named("w"); BayesPointMachine(strikes, balls, outs, scoreDifferential, basesLoaded, inning, handedness, numPitches, homePrior, battingTeamPrior, countPrior, batterPrior, homePriorSupport, battingTeamPriorSupport, countPriorSupport, batterPriorSupport, batterSlugging, batterRuns, previousPitchType, previousPitchResult, previousPitchVelocity, previousPitchVelocityGradient, w, y); //create inference engine object and infer posterior distribution //of weights InferenceEngine engine = new InferenceEngine(); VectorGaussian wPosterior = engine.Infer <VectorGaussian>(w); Console.WriteLine("Dist over w=\n" + wPosterior); //make predictions on test data double[] strikesTest = { 2, 1, 2 }; double[] ballsTest = { 3, 2, 0 }; double[] outsTest = { 1, 1, 0, 0, 2, 2 }; double[] scoreDifferentialTest = { 1, 0, 1, 2, 1, 3 }; double[] basesLoadedTest = { 0, 0, 0, 1, 0, 0 }; double[] inningTest = { 3, 1, 3, 2, 9, 6 }; double[] handednessTest = { 0, 1, 1, 0, 1, 1 }; double[] numPitchesTest = { 36, 20, 29, 11, 68, 5 }; double[] homePriorTest = { .05, .87, .77, .62, .86, .70 }; double[] battingTeamPriorTest = { .4, .45, .58, .02, 1, .7 }; double[] countPriorTest = { .03, .38, .92, .06, .7, .23 }; double[] batterPriorTest = { .08, .1, .04, .59, .90, .11 }; double[] homePriorSupportTest = { 10, 115, 104, 166, 171, 173 }; double[] battingTeamPriorSupportTest = { 162, 151, 27, 207, 144, 163 }; double[] countPriorSupportTest = { 38, 22, 114, 130, 195, 182 }; double[] batterPriorSupportTest = { 140, 190, 57, 233, 194, 9 }; double[] batterSluggingTest = { .237, .172, .222, .2, .393, .282 }; double[] batterRunsTest = { 24, 48, 90, 54, 89, 75 }; double[] previousPitchTypeTest = { 1, 1, 1, 0, 1, 1 }; double[] previousPitchResultTest = { 1, 0, 1, 0, 0, 0 }; double[] previousPitchVelocityTest = { 94, 88, 84, 101, 101, 110 }; double[] previousPitchVelocityGradientTest = { -5, -11, -2, -9, 1, 1 }; VariableArray <bool> ytest = Variable.Array <bool>(new Range(strikesTest.Length)).Named("ytest"); BayesPointMachine(strikesTest, ballsTest, outsTest, scoreDifferentialTest, basesLoadedTest, inningTest, handednessTest, numPitchesTest, homePriorTest, battingTeamPriorTest, countPriorTest, batterPriorTest, homePriorSupportTest, battingTeamPriorSupportTest, countPriorSupportTest, batterPriorSupportTest, batterSluggingTest, batterRunsTest, previousPitchTypeTest, previousPitchResultTest, previousPitchVelocityTest, previousPitchVelocityGradientTest, Variable.Random(wPosterior).Named("w"), ytest); Console.WriteLine("output=\n" + engine.Infer(ytest)); }
/// <summary> /// EP message to 'B' /// </summary> /// <param name="matrixMultiply">Incoming message from 'matrixMultiply'. Must be a proper distribution. If any element is uniform, the result will be uniform.</param> /// <param name="A">Constant value for 'A'.</param> /// <param name="B">Incoming message from 'B'. Must be a proper distribution. If any element is 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 'B' as the random arguments are varied. /// The formula is <c>proj[p(B) sum_(matrixMultiply) p(matrixMultiply) factor(matrixMultiply,A,B)]/p(B)</c>. /// </para></remarks> /// <exception cref="ImproperMessageException"><paramref name="matrixMultiply"/> is not a proper distribution</exception> /// <exception cref="ImproperMessageException"><paramref name="B"/> is not a proper distribution</exception> public static GaussianArray2D BAverageConditional([SkipIfUniform] GaussianArray2D matrixMultiply, double[,] A, [SkipIfUniform] GaussianArray2D B, GaussianArray2D result) { int rows = matrixMultiply.GetLength(0); int cols = matrixMultiply.GetLength(1); int inner = A.GetLength(1); if (result == null) result = new GaussianArray2D(inner, cols); var ai = DenseVector.Zero(inner); var mean = DenseVector.Zero(inner); PositiveDefiniteMatrix variance = new PositiveDefiniteMatrix(inner, inner); var bj = new VectorGaussian(inner); for (int j = 0; j < cols; j++) { bj.Precision.SetAllElementsTo(0); bj.MeanTimesPrecision.SetAllElementsTo(0); // we are projecting from family of full covariance Gaussians to diagonal // covariance, so we should include the context for (int c = 0; c < inner; c++) { bj.Precision[c, c] = B[c, j].Precision; bj.MeanTimesPrecision[c] = B[c, j].MeanTimesPrecision; } for (int i = 0; i < rows; i++) { Gaussian xij = matrixMultiply[i, j]; for (int k = 0; k < inner; k++) { ai[k] = A[i, k]; } if (xij.IsPointMass) throw new NotImplementedException(LowRankNotSupportedMessage); bj.Precision.SetToSumWithOuter(bj.Precision, xij.Precision, ai, ai); bj.MeanTimesPrecision.SetToSum(1.0, bj.MeanTimesPrecision, xij.MeanTimesPrecision, ai); } bj.GetMeanAndVariance(mean, variance); for (int k = 0; k < inner; k++) { Gaussian rkj = result[k, j]; rkj.SetMeanAndVariance(mean[k], variance[k, k]); result[k, j] = rkj / B[k, j]; } } return result; }
/// <summary>Computations that depend on the observed value of vVector__34 and vdouble__102</summary> private void Changed_vVector__34_vdouble__102() { if (this.Changed_vVector__34_vdouble__102_iterationsDone == 1) { return; } this.vVector__34_marginal = new PointMass <Vector[]>(this.VVector__34); this.vdouble__102_marginal = new DistributionStructArray <Gaussian, double>(5622, delegate(int index34) { return(Gaussian.Uniform()); }); this.vdouble__102_marginal = Distribution.SetPoint <DistributionStructArray <Gaussian, double>, double[]>(this.vdouble__102_marginal, this.Vdouble__102); // The constant 'vVectorGaussian34' VectorGaussian vVectorGaussian34 = VectorGaussian.FromNatural(DenseVector.FromArray(new double[3] { 0.0, 0.0, 0.0 }), new PositiveDefiniteMatrix(new double[3, 3] { { 1.0, 0.0, 0.0 }, { 0.0, 1.0, 0.0 }, { 0.0, 0.0, 1.0 } })); this.vVector103_marginal_F = ArrayHelper.MakeUniform <VectorGaussian>(vVectorGaussian34); // Message from use of 'vdouble__103' DistributionStructArray <Gaussian, double> vdouble__103_use_B = default(DistributionStructArray <Gaussian, double>); // Create array for 'vdouble__103_use' Backwards messages. vdouble__103_use_B = new DistributionStructArray <Gaussian, double>(5622); for (int index34 = 0; index34 < 5622; index34++) { vdouble__103_use_B[index34] = Gaussian.Uniform(); // Message to 'vdouble__103_use' from GaussianFromMeanAndVariance factor vdouble__103_use_B[index34] = GaussianFromMeanAndVarianceOp.MeanAverageConditional(this.Vdouble__102[index34], 0.1); } DistributionRefArray <VectorGaussian, Vector> vVector103_rep_B = default(DistributionRefArray <VectorGaussian, Vector>); // Create array for 'vVector103_rep' Backwards messages. vVector103_rep_B = new DistributionRefArray <VectorGaussian, Vector>(5622); for (int index34 = 0; index34 < 5622; index34++) { vVector103_rep_B[index34] = ArrayHelper.MakeUniform <VectorGaussian>(vVectorGaussian34); // Message to 'vVector103_rep' from InnerProduct factor vVector103_rep_B[index34] = InnerProductOp.AAverageConditional(vdouble__103_use_B[index34], this.VVector__34[index34], vVector103_rep_B[index34]); } // Buffer for ReplicateOp_Divide.Marginal<VectorGaussian> VectorGaussian vVector103_rep_B_toDef = default(VectorGaussian); // Message to 'vVector103_rep' from Replicate factor vVector103_rep_B_toDef = ReplicateOp_Divide.ToDefInit <VectorGaussian>(vVectorGaussian34); // Message to 'vVector103_rep' from Replicate factor vVector103_rep_B_toDef = ReplicateOp_Divide.ToDef <VectorGaussian>(vVector103_rep_B, vVector103_rep_B_toDef); // Message to 'vVector103_marginal' from Variable factor this.vVector103_marginal_F = VariableOp.MarginalAverageConditional <VectorGaussian>(vVector103_rep_B_toDef, vVectorGaussian34, this.vVector103_marginal_F); DistributionStructArray <Gaussian, double> vdouble__103_F = default(DistributionStructArray <Gaussian, double>); // Create array for 'vdouble__103' Forwards messages. vdouble__103_F = new DistributionStructArray <Gaussian, double>(5622); for (int index34 = 0; index34 < 5622; index34++) { vdouble__103_F[index34] = Gaussian.Uniform(); } DistributionRefArray <VectorGaussian, Vector> vVector103_rep_F = default(DistributionRefArray <VectorGaussian, Vector>); // Create array for 'vVector103_rep' Forwards messages. vVector103_rep_F = new DistributionRefArray <VectorGaussian, Vector>(5622); for (int index34 = 0; index34 < 5622; index34++) { vVector103_rep_F[index34] = ArrayHelper.MakeUniform <VectorGaussian>(vVectorGaussian34); } // Buffer for ReplicateOp_Divide.UsesAverageConditional<VectorGaussian> VectorGaussian vVector103_rep_F_marginal = default(VectorGaussian); // Message to 'vVector103_rep' from Replicate factor vVector103_rep_F_marginal = ReplicateOp_Divide.MarginalInit <VectorGaussian>(vVectorGaussian34); // Message to 'vVector103_rep' from Replicate factor vVector103_rep_F_marginal = ReplicateOp_Divide.Marginal <VectorGaussian>(vVector103_rep_B_toDef, vVectorGaussian34, vVector103_rep_F_marginal); // Buffer for InnerProductOp.InnerProductAverageConditional // Create array for replicates of 'vVector103_rep_F_index34__AMean' Vector[] vVector103_rep_F_index34__AMean = new Vector[5622]; for (int index34 = 0; index34 < 5622; index34++) { // Message to 'vdouble__103' from InnerProduct factor vVector103_rep_F_index34__AMean[index34] = InnerProductOp.AMeanInit(vVector103_rep_F[index34]); } // Buffer for InnerProductOp.AMean // Create array for replicates of 'vVector103_rep_F_index34__AVariance' PositiveDefiniteMatrix[] vVector103_rep_F_index34__AVariance = new PositiveDefiniteMatrix[5622]; for (int index34 = 0; index34 < 5622; index34++) { // Message to 'vdouble__103' from InnerProduct factor vVector103_rep_F_index34__AVariance[index34] = InnerProductOp.AVarianceInit(vVector103_rep_F[index34]); // Message to 'vVector103_rep' from Replicate factor vVector103_rep_F[index34] = ReplicateOp_Divide.UsesAverageConditional <VectorGaussian>(vVector103_rep_B[index34], vVector103_rep_F_marginal, index34, vVector103_rep_F[index34]); } // Create array for 'vdouble__103_marginal' Forwards messages. this.vdouble__103_marginal_F = new DistributionStructArray <Gaussian, double>(5622); for (int index34 = 0; index34 < 5622; index34++) { this.vdouble__103_marginal_F[index34] = Gaussian.Uniform(); // Message to 'vdouble__103' from InnerProduct factor vVector103_rep_F_index34__AVariance[index34] = InnerProductOp.AVariance(vVector103_rep_F[index34], vVector103_rep_F_index34__AVariance[index34]); // Message to 'vdouble__103' from InnerProduct factor vVector103_rep_F_index34__AMean[index34] = InnerProductOp.AMean(vVector103_rep_F[index34], vVector103_rep_F_index34__AVariance[index34], vVector103_rep_F_index34__AMean[index34]); // Message to 'vdouble__103' from InnerProduct factor vdouble__103_F[index34] = InnerProductOp.InnerProductAverageConditional(vVector103_rep_F_index34__AMean[index34], vVector103_rep_F_index34__AVariance[index34], this.VVector__34[index34]); // Message to 'vdouble__103_marginal' from DerivedVariable factor this.vdouble__103_marginal_F[index34] = DerivedVariableOp.MarginalAverageConditional <Gaussian>(vdouble__103_use_B[index34], vdouble__103_F[index34], this.vdouble__103_marginal_F[index34]); } this.Changed_vVector__34_vdouble__102_iterationsDone = 1; }