def compute_kl(mean_1, log_prec_1, mean_2, log_prec_2):
    mean_1 = np.asarray(mean_1)
    log_prec_1 = np.asarray(log_prec_1)
    mean_2 = np.asarray(mean_2)
    log_prec_2 = np.asarray(log_prec_2)
    len_1 = len(mean_1)
    len_2 = len(mean_2)
    len_max = max(len_1, len_2)
    var_1, var_2 = np.exp(-log_prec_1), np.exp(-log_prec_2)     # computationally more stable?
    kl = 0.5 * ( log_prec_1 - log_prec_2 - 1 + np.exp(log_prec_2 - log_prec_1) + np.power(mean_1-mean_2,2)/var_2 )
    # when log_prec_2 > -np.inf, log_prec_1=-np.inf leads to infinite kl
    if len_1 == 1:
        cond = np.logical_and(np.isinf(log_prec_1), log_prec_1 < 0)
        idx_log_prec_1_neginf = np.ones(len_max) * cond
        if cond:
            kl = np.inf * np.ones(len_max)
    else:
        idx_log_prec_1_neginf = np.logical_and(np.isinf(log_prec_1), log_prec_1 < 0)
        kl[idx_log_prec_1_neginf] = np.inf
    if len_2 == 1:
        cond = np.logical_and(np.isinf(log_prec_2), log_prec_2 < 0)
        idx_log_prec_2_neginf = np.ones(len_max) * cond
    else:
        idx_log_prec_2_neginf = np.logical_and(np.isinf(log_prec_2), log_prec_2 < 0)
    # when log_prec_2 = -np.inf, log_prec_1=-np.inf leads to zero kl
    idx_both_log_prec_neginf = np.logical_and(idx_log_prec_1_neginf, idx_log_prec_2_neginf)
    kl[idx_both_log_prec_neginf] = 0.
    # when log_prec_2 = np.inf, any value of log_prec_1 leads to infinite kl
    idx_log_prec_2_posinf = np.logical_and(np.isinf(log_prec_2), log_prec_2 > 0)
    if (len_2 == 1) and idx_log_prec_2_posinf:
        kl = np.inf * np.ones(len_max)
    else:
        kl[idx_log_prec_2_posinf] = np.inf
    if False:
        print 'log_prec_1 = %s, log_prec_2 = %s, kl = %s' % (log_prec_1, log_prec_2, kl)
    if np.any(np.isnan(kl)):
        print '\nsomething went wrong with kl computation'
        print 'var_1 = %s, var_2 = %s' % (var_1, var_2)
        print 'log_prec_1 = %s, log_prec_2 = %s' % (log_prec_1, log_prec_2)
        print 'idx_log_prec_1_neginf = %s' % idx_log_prec_1_neginf
        print 'idx_log_prec_2_neginf = %s' % idx_log_prec_2_neginf
        print 'idx_log_prec_2_posinf = %s' % idx_log_prec_2_posinf
        print 'kl = %s' % kl
        raise Exception
    return kl
compute KL between two Gaussian distributions
dataset/ETHPy150Open balajiln/mondrianforest/src/utils.py/compute_kl