/// <summary>
 /// The expected logarithm of that distribution under this distribution.
 /// </summary>
 /// <param name="that">The distribution to take the logarithm of.</param>
 /// <returns><c>sum_x this.Evaluate(x)*Math.Log(that.Evaluate(x))</c></returns>
 /// <remarks>This is also known as the cross entropy.</remarks>
 public double GetAverageLog(GammaPower that)
 {
     if (that.IsPointMass)
     {
         if (this.IsPointMass && this.Point.Equals(that.Point))
         {
             return(0.0);
         }
         else
         {
             return(Double.NegativeInfinity);
         }
     }
     else if (!IsProper())
     {
         throw new ImproperDistributionException(this);
     }
     else
     {
         // that is not a point mass.
         double invPower = 1.0 / that.Power;
         double result   = (that.Shape * invPower - 1) * GetMeanLog() - GetMeanPower(invPower) * that.Rate;
         result -= that.GetLogNormalizer();
         return(result);
     }
 }
 /// <summary>
 /// The log of the integral of the product of this Gamma and that Gamma
 /// </summary>
 /// <param name="that">That Gamma</param>
 /// <returns>The log inner product</returns>
 public double GetLogAverageOf(GammaPower that)
 {
     if (IsPointMass)
     {
         return(that.GetLogProb(Point));
     }
     else if (that.IsPointMass)
     {
         return(GetLogProb(that.Point));
     }
     else
     {
         GammaPower product = this * that;
         //if (!product.IsProper()) throw new ArgumentException("The product is improper");
         return(product.GetLogNormalizer() - this.GetLogNormalizer() - that.GetLogNormalizer());
     }
 }
 /// <summary>
 /// Get the integral of this distribution times another distribution raised to a power.
 /// </summary>
 /// <param name="that"></param>
 /// <param name="power"></param>
 /// <returns></returns>
 public double GetLogAverageOfPower(GammaPower that, double power)
 {
     if (IsPointMass)
     {
         return(power * that.GetLogProb(Point));
     }
     else if (that.IsPointMass)
     {
         if (power < 0)
         {
             throw new DivideByZeroException("The exponent is negative and the distribution is a point mass");
         }
         return(this.GetLogProb(that.Point));
     }
     else
     {
         var product = this * (that ^ power);
         return(product.GetLogNormalizer() - this.GetLogNormalizer() - power * that.GetLogNormalizer());
     }
 }