예제 #1
0
        /// <include file='FactorDocs.xml' path='factor_docs/message_op_class[@name="GammaRatioOp_Laplace"]/message_doc[@name="BAverageConditional(Gamma, Gamma, Gamma, Gamma)"]/*'/>
        public static Gamma BAverageConditional([SkipIfUniform] Gamma ratio, [Proper] Gamma A, [Proper] Gamma B, Gamma q)
        {
            if (ratio.IsPointMass)
            {
                // AAverageConditional computes (1st arg)/(2nd arg)
                return(GammaRatioOp.BAverageConditional(ratio.Point, A));
            }
            if (B.IsPointMass)
            {
                throw new NotImplementedException();
            }
            if (q.IsUniform())
            {
                q = Q(ratio, A, B);
            }
            double x = q.GetMean();

            double[] g = new double[] { x, 1, 0, 0 };
            double   bMean, bVariance;

            GaussianOp_Laplace.LaplaceMoments(q, g, dlogfs(x, ratio, A), out bMean, out bVariance);
            Gamma bMarginal = Gamma.FromMeanAndVariance(bMean, bVariance);
            Gamma result    = new Gamma();

            result.SetToRatio(bMarginal, B, GammaProductOp_Laplace.ForceProper);
            return(result);
        }
예제 #2
0
        /// <include file='FactorDocs.xml' path='factor_docs/message_op_class[@name="GammaRatioOp_Laplace"]/message_doc[@name="LogAverageFactor(Gamma, Gamma, Gamma, Gamma)"]/*'/>
        public static double LogAverageFactor(Gamma ratio, Gamma A, Gamma B, Gamma q)
        {
            if (B.IsPointMass)
            {
                return(GammaRatioOp.LogAverageFactor(ratio, A, B.Point));
            }
            if (A.IsPointMass)
            {
                // int Ga(a/b; y_s, y_r) Ga(b; s, r) db
                // = int a^(y_s-1) b^(-y_s+1) exp(-a/b y_r) y_r^(y_s)/Gamma(y_s) Ga(b; s, r) db
                // = a^(y_s-1) y_r^(y_s)/Gamma(y_s)/Gamma(s) r^s int b^(s-y_s) exp(-a/b y_r -rb) db
                // this requires BesselK
                throw new NotImplementedException();
            }
            if (ratio.IsPointMass)
            {
                return(GammaRatioOp.LogAverageFactor(ratio.Point, A, B));
            }
            // int Ga(a/b; y_s, y_r) Ga(a; s, r) da = b^s / (br + y_r)^(y_s + s-1)  Gamma(y_s+s-1)
            double x      = q.GetMean();
            double shape  = A.Shape;
            double shape2 = GammaFromShapeAndRateOp_Slow.AddShapesMinus1(ratio.Shape, shape);
            double logf   = shape * Math.Log(x) - shape2 * Math.Log(x * A.Rate + ratio.Rate) +
                            MMath.GammaLn(shape2) - A.GetLogNormalizer() - ratio.GetLogNormalizer();
            double logz = logf + B.GetLogProb(x) - q.GetLogProb(x);

            return(logz);
        }
예제 #3
0
        public static Gamma Q(Gamma ratio, [Proper] Gamma A, [Proper] Gamma B)
        {
            if (B.IsPointMass)
            {
                return(B);
            }
            if (ratio.IsPointMass)
            {
                return(GammaRatioOp.BAverageConditional(ratio.Point, A) * B);
            }
            double shape1 = A.Shape + B.Shape;
            double shape2 = GammaFromShapeAndRateOp_Slow.AddShapesMinus1(A.Shape, ratio.Shape);
            // find the maximum of the factor marginalized over Ratio and A, times B
            // logf = s*log(b) - (s+ya-1)*log(b*r + yb)
            // let b' = b*r and maximize over b'
            double x = GammaFromShapeAndRateOp_Slow.FindMaximum(shape1, shape2, ratio.Rate, B.Rate / A.Rate);

            if (x == 0)
            {
                return(B);
            }
            x /= A.Rate;
            double[] dlogfss = dlogfs(x, ratio, A);
            double   dlogf   = dlogfss[0];
            double   ddlogf  = dlogfss[1];

            return(GammaFromShapeAndRateOp_Laplace.GammaFromDerivatives(B, x, dlogf, ddlogf));
        }
예제 #4
0
        /// <include file='FactorDocs.xml' path='factor_docs/message_op_class[@name="GammaRatioOp_Laplace"]/message_doc[@name="AAverageConditional(Gamma, Gamma, Gamma, Gamma)"]/*'/>
        public static Gamma AAverageConditional(Gamma ratio, Gamma A, [SkipIfUniform] Gamma B, Gamma q)
        {
            if (ratio.IsPointMass)
            {
                return(GammaRatioOp.AAverageConditional(ratio.Point, B));
            }
            if (B.IsPointMass)
            {
                return(GammaRatioOp.AAverageConditional(ratio, B.Point));
            }
            if (A.IsPointMass)
            {
                throw new NotImplementedException();
            }

            double aMean, aVariance;
            double x      = q.GetMean();
            double x2     = x * x;
            double p      = 1 / (ratio.Rate + A.Rate * x);
            double p2     = p * p;
            double shape2 = GammaFromShapeAndRateOp_Slow.AddShapesMinus1(ratio.Shape, A.Shape);

            // aMean = shape2/(y_r/b + a_r)
            // aVariance = E[shape2*(shape2+1)/(y_r/b + a_r)^2] - aMean^2 = var(shape2/(y_r/b + a_r)) + E[shape2/(y_r/b + a_r)^2]
            //           = shape2^2*var(1/(y_r/b + a_r)) + shape2*(var(1/(y_r/b + a_r)) + (aMean/shape2)^2)
            double[] g = new double[] { x *p, ratio.Rate *p2, -2 *p2 *p *ratio.Rate *A.Rate, 6 *p2 *p2 *ratio.Rate *A.Rate *A.Rate };
            double   pMean, pVariance;
            GaussianOp_Laplace.LaplaceMoments(q, g, dlogfs(x, ratio, A), out pMean, out pVariance);
            aMean     = shape2 * pMean;
            aVariance = shape2 * shape2 * pVariance + shape2 * (pVariance + pMean * pMean);

            Gamma aMarginal = Gamma.FromMeanAndVariance(aMean, aVariance);
            Gamma result    = new Gamma();
            result.SetToRatio(aMarginal, A, GammaProductOp_Laplace.ForceProper);
            if (double.IsNaN(result.Shape) || double.IsNaN(result.Rate))
            {
                throw new InferRuntimeException("result is nan");
            }
            return(result);
        }
예제 #5
0
        /// <include file='FactorDocs.xml' path='factor_docs/message_op_class[@name="GammaRatioOp_Laplace"]/message_doc[@name="RatioAverageConditional(Gamma, Gamma, Gamma)"]/*'/>
        public static Gamma RatioAverageConditional(Gamma ratio, [Proper] Gamma A, [SkipIfUniform] Gamma B)
        {
            if (B.IsPointMass)
            {
                return(GammaRatioOp.RatioAverageConditional(A, B.Point));
            }
            if (A.IsPointMass)
            {
                throw new NotImplementedException();
            }
            if (ratio.Rate < 1e-20)
            {
                ratio.Rate = 1e-20;
            }
            // int delta(r - a/b) Ga(a; s_a, r_a) da = b Ga(rb; s_a, r_a)
            // int b Ga(rb; s_a, r_a) Ga(b; s_b, r_b) db = r^(s_a-1) / (r*r_a + r_b)^(s_a + s_b)
            Gamma A2 = Gamma.FromShapeAndRate(A.Shape - 1, A.Rate);
            Gamma B2 = Gamma.FromShapeAndRate(B.Shape + 2, B.Rate);
            Gamma q  = Q(B2, A2, ratio);

            return(BAverageConditional(B2, A2, ratio, q));
        }
예제 #6
0
 /// <include file='FactorDocs.xml' path='factor_docs/message_op_class[@name="GammaRatioVmpOp"]/message_doc[@name="AAverageLogarithm(double, double)"]/*'/>
 public static Gamma AAverageLogarithm(double ratio, double B)
 {
     return(GammaRatioOp.AAverageConditional(ratio, B));
 }
예제 #7
0
 /// <include file='FactorDocs.xml' path='factor_docs/message_op_class[@name="GammaRatioVmpOp"]/message_doc[@name="AAverageLogarithm(Gamma, double)"]/*'/>
 public static Gamma AAverageLogarithm([SkipIfUniform] Gamma ratio, double B)
 {
     return(GammaRatioOp.AAverageConditional(ratio, B));
 }
예제 #8
0
        /// <include file='FactorDocs.xml' path='factor_docs/message_op_class[@name="GammaRatioOp"]/message_doc[@name="LogAverageFactor(double, Gamma, double)"]/*'/>
        public static double LogAverageFactor(double ratio, Gamma a, double b)
        {
            Gamma to_ratio = GammaRatioOp.RatioAverageConditional(a, b);

            return(to_ratio.GetLogProb(ratio));
        }