def _create_w_objective(m, X, R):
    """
    Creates an objective function and its derivative for W, given M and X (data)

    Args:
        m (array): genes x clusters
        X (array): genes x cells
        R (array): 1 x genes
    """
    genes, clusters = m.shape
    cells = X.shape[1]
    R1 = R.reshape((genes, 1)).dot(np.ones((1, cells)))
    def objective(w):
        # convert w into a matrix first... because it's a vector for
        # optimization purposes
        w = w.reshape((m.shape[1], X.shape[1]))
        d = m.dot(w)+eps
        return np.sum((X + R1)*np.log(d + R1) - X*np.log(d))/genes
    def deriv(w):
        # derivative of objective wrt all elements of w
        # for w_{ij}, the derivative is... m_j1+...+m_jn sum over genes minus 
        # x_ij
        w2 = w.reshape((m.shape[1], X.shape[1]))
        d = m.dot(w2)+eps
        temp = X/d
        temp2 = (X+R1)/(d+R1)
        m1 = m.T.dot(temp2)
        m2 = m.T.dot(temp)
        deriv = m1 - m2
        return deriv.flatten()/genes
    return objective, deriv