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)); }
public void GammaFromShapeAndRateOpTest4() { Gamma sample = Gamma.FromShapeAndRate(2, 0); Gamma rate = Gamma.FromShapeAndRate(4, 1); double shape = 1; Gamma rateExpected = GammaFromShapeAndRateOp_Slow.RateAverageConditional(sample, shape, rate); Gamma q = GammaFromShapeAndRateOp_Laplace.Q(sample, shape, rate); Gamma rateActual = GammaFromShapeAndRateOp_Laplace.RateAverageConditional(sample, shape, rate, q); Assert.True(rateExpected.MaxDiff(rateActual) < 1e-4); Gamma to_sample2 = GammaFromShapeAndRateOp_Laplace.SampleAverageConditional(sample, shape, rate, q); double evExpected = GammaFromShapeAndRateOp_Laplace.LogEvidenceRatio(sample, shape, rate, to_sample2, q); Console.WriteLine("sample = {0} to_sample = {1} evidence = {2}", sample, to_sample2, evExpected); for (int i = 40; i < 41; i++) { sample.Rate = System.Math.Pow(0.1, i); q = GammaFromShapeAndRateOp_Laplace.Q(sample, shape, rate); Gamma to_sample = GammaFromShapeAndRateOp_Laplace.SampleAverageConditional(sample, shape, rate, q); double evActual = GammaFromShapeAndRateOp_Laplace.LogEvidenceRatio(sample, shape, rate, to_sample, q); Console.WriteLine("sample = {0} to_sample = {1} evidence = {2}", sample, to_sample, evActual); Assert.True(to_sample2.MaxDiff(to_sample2) < 1e-4); Assert.True(MMath.AbsDiff(evExpected, evActual) < 1e-4); } }
public void GammaRatioOpTest() { Gamma ratio = new Gamma(2, 3); double shape = 4; Gamma A = new Gamma(shape, 1); Gamma B = new Gamma(5, 6); Gamma q = GammaFromShapeAndRateOp_Laplace.Q(ratio, shape, B); Gamma bExpected = GammaFromShapeAndRateOp_Laplace.RateAverageConditional(ratio, shape, B, q); Gamma rExpected = GammaFromShapeAndRateOp_Laplace.SampleAverageConditional(ratio, shape, B, q); q = GammaRatioOp_Laplace.Q(ratio, A, B); Gamma bActual = GammaRatioOp_Laplace.BAverageConditional(ratio, A, B, q); Gamma rActual = GammaRatioOp_Laplace.RatioAverageConditional(ratio, A, B); Console.WriteLine("b = {0} should be {1}", bActual, bExpected); Console.WriteLine("ratio = {0} should be {1}", rActual, rExpected); Assert.True(bExpected.MaxDiff(bActual) < 1e-4); Assert.True(rExpected.MaxDiff(rActual) < 1e-4); }
public void GammaFromShapeAndRateOpTest5() { Gamma sample; Gamma rate; double shape = 1; Gamma q, sampleExpected, sampleActual; sample = Gamma.FromShapeAndRate(101, 6.7234079315458819E-154); rate = Gamma.FromShapeAndRate(1, 1); q = GammaFromShapeAndRateOp_Laplace.Q(sample, shape, rate); Console.WriteLine(q); Assert.True(!double.IsNaN(q.Rate)); sampleExpected = GammaFromShapeAndRateOp_Slow.SampleAverageConditional(sample, shape, rate); sampleActual = GammaFromShapeAndRateOp_Laplace.SampleAverageConditional(sample, shape, rate, q); Console.WriteLine("sample = {0} should be {1}", sampleActual, sampleExpected); Assert.True(sampleExpected.MaxDiff(sampleActual) < 1e-4); sample = Gamma.FromShapeAndRate(1.4616957536444839, 6.2203585601953317E+36); rate = Gamma.FromShapeAndRate(2.5, 0.99222007168007165); sampleExpected = GammaFromShapeAndRateOp_Slow.SampleAverageConditional(sample, shape, rate); q = Gamma.FromShapeAndRate(3.5, 0.99222007168007154); sampleActual = GammaFromShapeAndRateOp_Laplace.SampleAverageConditional(sample, shape, rate, q); Console.WriteLine("sample = {0} should be {1}", sampleActual, sampleExpected); Assert.True(sampleExpected.MaxDiff(sampleActual) < 1e-4); sample = Gamma.FromShapeAndRate(1.9692446124520258, 1.0717828357423075E+77); rate = Gamma.FromShapeAndRate(101.0, 2.1709591889324445E-80); sampleExpected = GammaFromShapeAndRateOp_Slow.SampleAverageConditional(sample, shape, rate); q = GammaFromShapeAndRateOp_Laplace.Q(sample, shape, rate); sampleActual = GammaFromShapeAndRateOp_Laplace.SampleAverageConditional(sample, shape, rate, q); Console.WriteLine("sample = {0} should be {1}", sampleActual, sampleExpected); Assert.True(sampleExpected.MaxDiff(sampleActual) < 1e-4); Assert.Equal(0.0, GammaFromShapeAndRateOp_Laplace.LogEvidenceRatio(Gamma.Uniform(), 4.0, Gamma.PointMass(0.01), Gamma.FromShapeAndRate(4, 0.01), Gamma.PointMass(0.01))); }
public static Gamma Q(GammaPower product, [Proper] GammaPower A, [Proper] GammaPower B) { // ensure B has the larger shape if (B.Shape < A.Shape) { return(Q(product, B, A)); } if (B.IsPointMass) { return(Gamma.PointMass(B.Point)); } if (A.IsPointMass) { return(Gamma.FromShapeAndRate(B.Shape, B.Rate)); } if (A.Power != product.Power) { throw new NotSupportedException($"A.Power ({A.Power}) != product.Power ({product.Power})"); } if (B.Power != product.Power) { throw new NotSupportedException($"B.Power ({B.Power}) != product.Power ({product.Power})"); } double x; if (product.IsPointMass) { if (product.Point == 0) { return(Gamma.PointMass(0)); } double productPointPower = Math.Pow(product.Point, 1 / A.Power); // y = product^(1/power) // logf = -a_s*log(b) - y*a_r/b // logp = b_s*log(b) - b_r*b // dlogfp = (b_s-a_s)/b - b_r + y*a_r/b^2 = 0 // -b_r b^2 + (b_s-a_s) b + y*a_r = 0 double shape = B.Shape - A.Shape; x = (Math.Sqrt(shape * shape + 4 * B.Rate * A.Rate * productPointPower) + shape) / 2 / B.Rate; } else { double shape1 = GammaFromShapeAndRateOp_Slow.AddShapesMinus1(B.Shape, product.Shape) + (1 - product.Power); if (product.Rate == 0) { x = GammaFromShapeAndRateOp_Slow.FindMaximum(shape1, 0, A.Rate, B.Rate); } else { double shape2 = GammaFromShapeAndRateOp_Slow.AddShapesMinus1(A.Shape, product.Shape) + (1 - A.Power); // find the maximum of the factor marginalized over Product and A, times B // From above: // logf = (y_s/y_p-1)*pb*log(b) - (s+y_s-pa)*log(r + b^(pb/y_p)*y_r) x = GammaFromShapeAndRateOp_Slow.FindMaximum(shape1, shape2, A.Rate / product.Rate, B.Rate); } if (x == 0) { x = 1e-100; } } double[] dlogfss = dlogfs(x, product, A); double dlogf = dlogfss[0]; double ddlogf = dlogfss[1]; return(GammaFromShapeAndRateOp_Laplace.GammaFromDerivatives(Gamma.FromShapeAndRate(B.Shape, B.Rate), x, dlogf, ddlogf)); }