def cross_H(P,Q):
    """
    P and Q are arrays of either dimension 1 or 2.

    If P is a matrix, then cross entropy is computed row-wise on P. (P
    is assumed to be left stochastic.) If Q is a matrix, cross entropy
    is computed column-wise on Q. (Q is assumed to be right
    stochastic.)
    """
    P = P.astype(np.float)
    Q = Q.astype(np.float)

    if P.ndim < 2:
        P = P.reshape((1,P.size))
    if Q.ndim < 2:
        Q = Q.reshape((Q.size,1))

    P_ = np.tile(P.reshape(P.shape[0], P.shape[1], 1), (1,1,Q.shape[1]))
    Q_ = np.tile(Q.reshape(1, Q.shape[0], Q.shape[1]), (P.shape[0],1,1))

    # Allow negative infinity without complaint
    old_settings = np.seterr(divide='ignore')
    logQ_ = np.tile(np.log2(Q.reshape(1, Q.shape[0], Q.shape[1])), 
                    (P.shape[0],1,1))
    np.seterr(**old_settings)

    out = (P_ * logQ_)

    P_zeros = (P_ == 0)
    Q_zeros = (Q_ == 0)
    PQ_zeros = np.bitwise_and(P_zeros, Q_zeros)
    out[PQ_zeros] = 0.

    out = np.squeeze(-1 * out.sum(1))
    if out.ndim == 0:
        return out[()]
    return out
dataset/ETHPy150Open inpho/vsm/vsm/spatial.py/cross_H/original