/** * {@inheritDoc} * * <p>Computes KL as follows, where Γ(x) is the gamma function and ψ(x) is the digamma * function. * * <p>(α<sub>P</sub>-α<sub>Q</sub>)ψ(α<sub>P</sub>) - * ln(Γ(α<sub>P</sub>)) + ln(Γ(α<sub>Q</sub>)) + * α<sub>Q</sub>(ln(β<sub>P</sub>/β<sub>Q</sub>)) + * α<sub>P</sub>(β<sub>Q</sub>-β<sub>P</sub>)/β<sub>P</sub> * * @see <a * href="http://en.wikipedia.org/wiki/Gamma_distribution#Kullback.E2.80.93Leibler_divergence" * >Gamma distribution (Wikipedia)</a> */ @Override public double computeKLDivergence(IParameterizedMessage that) { if (that instanceof GammaParameters) { // KL(P|Q) == (ap-aq)*digamma(ap) - log(gamma(ap)) + log(gamma(aq)) + aq*(log(bp)-log(bq)) + // ap*(bq-bp)/bp final GammaParameters P = this, Q = (GammaParameters) that; final double ap = P.getAlpha(), aq = Q.getAlpha(); final double bp = P.getBeta(), bq = Q.getBeta(); double divergence = 0.0; if (ap != aq) { divergence += (ap - aq) * digamma(ap); divergence -= logGamma(ap); divergence += logGamma(aq); } if (bp != bq) { divergence += aq * (Math.log(bp) - Math.log(bq)) + ap * ((bq - bp) / bp); } return divergence; } throw new IllegalArgumentException( String.format("Expected '%s' but got '%s'", getClass(), that.getClass())); }