<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def poisson_ll(data, means):
 """ Calculates the Poisson log-likelihood. Args: data (array):
 2d numpy array of genes x cells means (array):
 2d numpy array of genes x k Returns: cells x k array of log-likelihood for each cell/cluster pair """

    if sparse.issparse(data):
        return sparse_poisson_ll(data, means)
    genes, cells = data.shape
    clusters = means.shape[1]
    ll = np.zeros((cells, clusters))
    for i in range(clusters):
        means_i = np.tile(means[:,i], (cells, 1))
        means_i = means_i.transpose() + eps
        #ll[:,i] = np.sum(xlogy(data, means_i) - gammaln(data+1) - means_i, 0)
        ll[:,i] = np.sum(xlogy(data, means_i) - means_i, 0)
    return ll