Beispiel #1
0
        /// <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);
        }
Beispiel #2
0
        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());
        }
Beispiel #3
0
        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);
        }
Beispiel #5
0
        /// <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);
        }
Beispiel #8
0
		/// <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);
		}