/// <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); }
/// <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); }
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)); }
/// <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); }
/// <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)); }
/// <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)); }
/// <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)); }
/// <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)); }