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
        /// <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);
        }
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));
            }
        }
Beispiel #4
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);
        }
Beispiel #5
0
 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 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>
		/// 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;
		}