public static double klDivergence(double[] p, double[] q) {
        if (p.length != q.length) {
            throw new IllegalStateException("The length of p and q must be the same.");
        }
        double delta = 1e-8;
        if (!Multinomials.isMultinomial(p, delta)) {
            throw new IllegalStateException("p is not a multinomial");
        }
        if (!Multinomials.isMultinomial(q, delta)) {
            throw new IllegalStateException("q is not a multinomial");
        }
        
        double kl = 0.0;
        for (int i=0; i<p.length; i++) {
            if (p[i] == 0.0 || q[i] == 0.0) {
                continue;
            }
            kl += p[i] * FastMath.log(p[i] / q[i]);
        }
        return kl;
    }
public static double klDivergence ( double [ ] p , double [ ] q ) { if ( p . length != q . length ) { throw new IllegalStateException ( "The length of p and q must be the same." ) ; } double delta = 1e-8 ; if ( ! Multinomials . isMultinomial ( p , delta ) ) { throw new IllegalStateException ( "p is not a multinomial" ) ; } if ( ! Multinomials . isMultinomial ( q , delta ) ) { throw new IllegalStateException ( "q is not a multinomial" ) ; } double kl = 0.0 ; for ( int i = 0 ; i < p . length ; i ++ ) { if ( p [ i ] == 0.0 || q [ i ] == 0.0 ) { continue ; } kl += p [ i ] * FastMath . log ( p [ i ] / q [ i ] ) ; } return kl ; }
Gets the KL divergence between two multinomial distributions p and q.

@param p Array representing a multinomial distribution, p.
@param q Array representing a multinomial distribution, q.
@return KL(p || q)