/// <include file='FactorDocs.xml' path='factor_docs/message_op_class[@name="WishartFromShapeAndRateOp_Laplace2"]/message_doc[@name="RateAverageConditional(Wishart, double, Wishart, Wishart, Wishart)"]/*'/> public static Wishart RateAverageConditional([SkipIfUniform] Wishart sample, double shape, Wishart rate, Wishart to_rate, Wishart result) { if (sample.IsPointMass) { return(WishartFromShapeAndRateOp.RateAverageConditional(sample.Point, shape, result)); } // f(Y,R) = |Y|^(a-c) |R|^a exp(-tr(YR)) // p(Y) = |Y|^(a_y-c) exp(-tr(YB_y) // p(R) = |R|^(a_r-c) exp(-tr(RB_r) // int_Y f(Y,R) p(Y) dY = |R|^a |R+B_y|^-(a+a_y-c) int dim = sample.Dimension; double c = 0.5 * (dim + 1); double shape2 = shape - c + sample.Shape; Wishart ratePost = rate * to_rate; PositiveDefiniteMatrix r = ratePost.GetMean(); PositiveDefiniteMatrix rby = r + sample.Rate; PositiveDefiniteMatrix invrby = rby.Inverse(); PositiveDefiniteMatrix rInvrby = rby; rInvrby.SetToProduct(r, invrby); double xxddlogp = Matrix.TraceOfProduct(rInvrby, rInvrby) * shape2; double delta = -xxddlogp / dim; PositiveDefiniteMatrix invR = r.Inverse(); PositiveDefiniteMatrix dlogp = invrby; dlogp.Scale(-shape2); LowerTriangularMatrix rChol = new LowerTriangularMatrix(dim, dim); rChol.SetToCholesky(r); result.SetDerivatives(rChol, invR, dlogp, xxddlogp, GammaFromShapeAndRateOp.ForceProper, shape); return(result); }
public static Vector VectorGaussianScaled(double scaling, PositiveDefiniteMatrix precision) { var scaledPrec = new PositiveDefiniteMatrix(precision); scaledPrec.Scale(scaling); return(VectorGaussian.FromMeanAndPrecision(Vector.Zero(precision.Cols), scaledPrec).Sample()); }
public void RandWishart() { // multivariate Gamma double a = 2.7; int d = 3; PositiveDefiniteMatrix mTrue = new PositiveDefiniteMatrix(d, d); mTrue.SetToIdentity(); mTrue.SetToProduct(mTrue, a); LowerTriangularMatrix L = new LowerTriangularMatrix(d, d); PositiveDefiniteMatrix X = new PositiveDefiniteMatrix(d, d); PositiveDefiniteMatrix m = new PositiveDefiniteMatrix(d, d); m.SetAllElementsTo(0); double s = 0; for (int i = 0; i < nsamples; i++) { Rand.Wishart(a, L); X.SetToProduct(L, L.Transpose()); m = m + X; s = s + X.LogDeterminant(); } double sTrue = 0; for (int i = 0; i < d; i++) { sTrue += MMath.Digamma(a - i * 0.5); } m.Scale(1.0 / nsamples); s = s / nsamples; Console.WriteLine(""); Console.WriteLine("Multivariate Gamma"); Console.WriteLine("-------------------"); Console.WriteLine("m = \n{0}", m); double dError = m.MaxDiff(mTrue); if (dError > TOLERANCE) { Assert.True(false, String.Format("Wishart({0}) mean: (should be {0}*I), error = {1}", a, dError)); } if (System.Math.Abs(s - sTrue) > TOLERANCE) { Assert.True(false, string.Format("E[logdet]: {0} (should be {1})", s, sTrue)); } }
/// <summary> /// Adds a weighted observation. /// </summary> /// <param name="x"></param> /// <param name="weight"></param> public void Add(Vector x, double weight) { // new_mean = mean + w/(count + w)*(x - mean) // new_cov = count/(count + w)*(cov + w/(count+w)*(x-mean)*(x-mean)') count += weight; if (count == 0) { return; } diff.SetToDifference(x, mean); double s = weight / count; mean.SetToSum(1.0, mean, s, diff); //outer.SetToOuter(diff,diff2); // this is more numerically stable: //outer.SetToOuter(diff, diff).Scale(s); cov.SetToSumWithOuter(cov, s, diff, diff); cov.Scale(1 - s); }
/// <include file='FactorDocs.xml' path='factor_docs/message_op_class[@name="WishartFromShapeAndRateOp_Laplace2"]/message_doc[@name="SampleAverageConditional(Wishart, double, Wishart, Wishart, Wishart, Wishart)"]/*'/> public static Wishart SampleAverageConditional([NoInit] Wishart sample, double shape, [Proper] Wishart rate, [NoInit] Wishart to_rate, [NoInit] Wishart to_sample, Wishart result) { if (sample.IsUniform()) { return(SampleAverageConditional2(shape, rate, to_rate, result)); } // f(Y,R) = |Y|^(a-c) |R|^a exp(-tr(YR)) // p(Y) = |Y|^(a_y-c) exp(-tr(YB_y) // p(R) = |R|^(a_r-c) exp(-tr(RB_r) // int_R f(Y,R) p(R) dR = |Y|^(a-c) |Y+B_r|^-(a+a_r) int dim = sample.Dimension; double c = 0.5 * (dim + 1); double shape2 = shape + rate.Shape; Wishart samplePost = sample * to_sample; if (!samplePost.IsProper()) { return(SampleAverageConditional2(shape, rate, to_rate, result)); } PositiveDefiniteMatrix y = samplePost.GetMean(); PositiveDefiniteMatrix yPlusBr = y + rate.Rate; PositiveDefiniteMatrix invyPlusBr = yPlusBr.Inverse(); PositiveDefiniteMatrix yInvyPlusBr = yPlusBr; yInvyPlusBr.SetToProduct(y, invyPlusBr); double xxddlogf = shape2 * Matrix.TraceOfProduct(yInvyPlusBr, yInvyPlusBr); PositiveDefiniteMatrix invY = y.Inverse(); //double delta = -xxddlogf / dim; //result.Shape = delta + shape; //result.Rate.SetToSum(delta, invY, shape2, invyPlusBr); LowerTriangularMatrix yChol = new LowerTriangularMatrix(dim, dim); yChol.SetToCholesky(y); PositiveDefiniteMatrix dlogp = invyPlusBr; dlogp.Scale(-shape2); result.SetDerivatives(yChol, invY, dlogp, xxddlogf, GammaFromShapeAndRateOp.ForceProper, shape - c); if (result.Rate.Any(x => double.IsNaN(x))) { throw new Exception("result.Rate is nan"); } return(result); }
/// <include file='FactorDocs.xml' path='factor_docs/message_op_class[@name="ProductWishartOp"]/message_doc[@name="ProductAverageLogarithm(Wishart, Gamma, Wishart)"]/*'/> public static Wishart ProductAverageLogarithm([SkipIfUniform] Wishart A, [SkipIfUniform] Gamma B, Wishart result) { if (B.IsPointMass) { return(ProductAverageLogarithm(A, B.Point, result)); } // E[x] = E[a]*E[b] // E[log(x)] = E[log(a)]+E[log(b)] PositiveDefiniteMatrix m = new PositiveDefiniteMatrix(A.Dimension, A.Dimension); A.GetMean(m); m.Scale(B.GetMean()); double meanLogDet = A.Dimension * B.GetMeanLog() + A.GetMeanLogDeterminant(); if (m.LogDeterminant() < meanLogDet) { throw new MatrixSingularException(m); } return(Wishart.FromMeanAndMeanLogDeterminant(m, meanLogDet, result)); }
/// <include file='FactorDocs.xml' path='factor_docs/message_op_class[@name="ProductWishartOp"]/message_doc[@name="ProductAverageConditional(Wishart, PositiveDefiniteMatrix, Gamma, Gamma, Wishart)"]/*'/> public static Wishart ProductAverageConditional(Wishart Product, PositiveDefiniteMatrix A, [SkipIfUniform] Gamma B, Gamma to_B, Wishart result) { if (B.IsPointMass) { return(ProductAverageConditional(A, B.Point, result)); } Gamma Bpost = B * to_B; // E[x] = a*E[b] // E[logdet(x)] = logdet(a) + d*E[log(b)] PositiveDefiniteMatrix m = new PositiveDefiniteMatrix(A.Rows, A.Cols); m.SetTo(A); m.Scale(Bpost.GetMean()); double meanLogDet = A.Rows * Bpost.GetMeanLog() + A.LogDeterminant(); if (m.LogDeterminant() < meanLogDet) { throw new MatrixSingularException(m); } Wishart.FromMeanAndMeanLogDeterminant(m, meanLogDet, result); result.SetToRatio(result, Product); return(result); }
/// <summary> /// VMP message to 'product' /// </summary> /// <param name="B">Incoming message from 'a'. Must be a proper distribution. If uniform, the result will be uniform.</param> /// <param name="A">Incoming message from 'b'. Must be a proper distribution. If uniform, the result will be uniform.</param> /// <returns>The outgoing VMP message to the 'product' argument</returns> /// <remarks><para> /// The outgoing message is a distribution matching the moments of 'product' as the random arguments are varied. /// The formula is <c>proj[sum_(a,b) p(a,b) factor(product,a,b)]</c>. /// </para></remarks> /// <exception cref="ImproperMessageException"><paramref name="B"/> is not a proper distribution</exception> /// <exception cref="ImproperMessageException"><paramref name="A"/> is not a proper distribution</exception> public static Wishart ProductAverageLogarithm([SkipIfUniform] Wishart A, [SkipIfUniform] Gamma B, Wishart result) { if (B.IsPointMass) return ProductAverageLogarithm(A, B.Point, result); // E[x] = E[a]*E[b] // E[log(x)] = E[log(a)]+E[log(b)] PositiveDefiniteMatrix m = new PositiveDefiniteMatrix(A.Dimension, A.Dimension); A.GetMean(m); m.Scale(B.GetMean()); double meanLogDet = A.Dimension*B.GetMeanLog() + A.GetMeanLogDeterminant(); if (m.LogDeterminant() < meanLogDet) throw new MatrixSingularException(m); return Wishart.FromMeanAndMeanLogDeterminant(m, meanLogDet, result); }