Exemplo n.º 1
0
 /// <summary>
 /// Sets the parameters to represent the ratio of two Gammas
 /// </summary>
 /// <param name="numerator">The numerator Gamma.  Can be the same object as this.</param>
 /// <param name="denominator">The denominator Gamma.  Can be the same object as this.</param>
 /// <param name="forceProper">If true, the result has shape >= 1 and rate >= 0, under the constraint that result*denominator has the same mean as numerator</param>
 public void SetToRatio(Gamma numerator, Gamma denominator, bool forceProper = false)
 {
     if (numerator.IsPointMass)
     {
         if (denominator.IsPointMass)
         {
             if (numerator.Point.Equals(denominator.Point))
             {
                 SetToUniform();
             }
             else
             {
                 throw new DivideByZeroException();
             }
         }
         else
         {
             Point = numerator.Point;
         }
     }
     else if (denominator.IsPointMass)
     {
         throw new DivideByZeroException();
     }
     else if (forceProper && numerator.Rate == 0)
     {
         Rate  = 0;
         Shape = 1 + Math.Max(0, numerator.Shape - denominator.Shape);
     }
     else if (forceProper && (numerator.Shape < denominator.Shape || numerator.Rate < denominator.Rate))
     {
         double mean  = numerator.GetMean();
         double shape = mean * denominator.Rate + (1 - denominator.Shape);
         if (shape < 1)
         {
             Rate  = denominator.Shape / mean - denominator.Rate;
             Shape = 1;
         }
         else
         {
             Shape = shape;
             Rate  = 0;
         }
     }
     else
     {
         if (Math.Abs(denominator.Shape) > 10)
         {
             Shape = (numerator.Shape - denominator.Shape) + 1;
         }
         else
         {
             // avoid roundoff errors when numerator shape is below eps
             Shape = numerator.Shape + (1 - denominator.Shape);
         }
         Rate = numerator.Rate - denominator.Rate;
     }
 }
Exemplo n.º 2
0
 /// <summary>
 /// Sets the parameters to represent the product of two Gammas.
 /// </summary>
 /// <param name="a">The first Gamma</param>
 /// <param name="b">The second Gamma</param>
 /// <remarks>
 /// The result may not be proper. No error is thrown in this case.
 /// </remarks>
 public void SetToProduct(Gamma a, Gamma b)
 {
     if (a.IsPointMass)
     {
         if (b.IsPointMass && !a.Point.Equals(b.Point))
         {
             throw new AllZeroException();
         }
         Point = a.Point;
         return;
     }
     else if (b.IsPointMass)
     {
         Point = b.Point;
         return;
     }
     else
     {
         // avoid roundoff errors when a shape is below eps
         if (a.Shape < b.Shape)
         {
             Shape = a.Shape + (b.Shape - 1);
         }
         else
         {
             Shape = b.Shape + (a.Shape - 1);
         }
         Rate = a.Rate + b.Rate;
         if (Shape > double.MaxValue || Rate > double.MaxValue)
         {
             // (as + bs - 1)/(ar + br) = (am*ar + bm*br - 1)/(ar + br) = am*w + bm*(1-w) - 1/(ar + br)
             // w = ar/(ar + br)
             double w = 1 / (1 + b.Rate / a.Rate);
             Point = a.GetMean() * w + b.GetMean() * (1 - w) - 1 / Rate;
         }
     }
 }