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