def zip_ll(data, means, M):
    """
    Calculates the zero-inflated Poisson log-likelihood.

    Args:
        data (array): genes x cells
        means (array): genes x k
        M (array): genes x k - this is the zero-inflation parameter.

    Returns:
        cells x k array of log-likelihood for each cell/cluster pair.
    """
    genes, cells = data.shape
    clusters = means.shape[1]
    ll = np.zeros((cells, clusters))
    d0 = (data==0)
    d1 = (data>0)
    for i in range(clusters):
        means_i = np.tile(means[:,i], (cells, 1))
        means_i = means_i.transpose()
        L_i = np.tile(M[:,i], (cells, 1))
        L_i = L_i.transpose()
        ll_0 = np.log(L_i + (1 - L_i)*np.exp(-means_i))
        ll_0 = np.where((L_i==0) & (means_i==0), -means_i, ll_0)
        # not including constant factors
        ll_1 = np.log(1 - L_i) + xlogy(data, means_i) -  means_i
        ll_0 = np.where(d0, ll_0, 0.0)
        ll_1 = np.where(d1, ll_1, 0.0)
        ll[:,i] = np.sum(ll_0 + ll_1, 0)
    return ll
def zip_ll ( data , means , M ) : genes , cells = data . shape clusters = means . shape [ 1 ] ll = np . zeros ( ( cells , clusters ) ) d0 = ( data == 0 ) d1 = ( data > 0 ) for i in range ( clusters ) : means_i = np . tile ( means [ : , i ] , ( cells , 1 ) ) means_i = means_i . transpose ( ) L_i = np . tile ( M [ : , i ] , ( cells , 1 ) ) L_i = L_i . transpose ( ) ll_0 = np . log ( L_i + ( 1 - L_i ) * np . exp ( - means_i ) ) ll_0 = np . where ( ( L_i == 0 ) & ( means_i == 0 ) , - means_i , ll_0 ) ll_1 = np . log ( 1 - L_i ) + xlogy ( data , means_i ) - means_i ll_0 = np . where ( d0 , ll_0 , 0.0 ) ll_1 = np . where ( d1 , ll_1 , 0.0 ) ll [ : , i ] = np . sum ( ll_0 + ll_1 , 0 ) return ll
Calculates the zero-inflated Poisson log-likelihood.

    Args:
        data (array): genes x cells
        means (array): genes x k
        M (array): genes x k - this is the zero-inflation parameter.

    Returns:
        cells x k array of log-likelihood for each cell/cluster pair.