'Remove redundant constraints from A and G.
Parameters
data : dict
All the problem data.
Returns
str
A status indicating if infeasibility was detected.'

@staticmethod
def remove_redundant_rows(data):

    dims = data[s.DIMS]
    A = data[s.A]
    G = data[s.G]
    b = data[s.B]
    h = data[s.H]
    if (A.shape[0] > 0):
        (Q, R, P) = scipy.linalg.qr(A.todense(), pivoting=True)
        rows_to_keep = []
        for i in range(R.shape[0]):
            if (np.linalg.norm(R[i, :]) > 1e-10):
                rows_to_keep.append(i)
        R = R[rows_to_keep, :]
        Q = Q[:, rows_to_keep]
        Pinv = np.zeros(P.size, dtype='int')
        for i in range(P.size):
            Pinv[P[i]] = i
        R = R[:, Pinv]
        A = R
        b_old = b
        b = Q.T.dot(b)
        if (not np.allclose(b_old, Q.dot(b))):
            return s.INFEASIBLE
        dims[s.EQ_DIM] = int(b.shape[0])
        data['Q'] = intf.dense2cvxopt(Q)
    if (dims[s.LEQ_DIM] > 0):
        G = G.tocsr()
        G_leq = G[:dims[s.LEQ_DIM], :]
        h_leq = h[:dims[s.LEQ_DIM]].ravel()
        G_other = G[dims[s.LEQ_DIM]:, :]
        h_other = h[dims[s.LEQ_DIM]:].ravel()
        (G_leq, h_leq, P_leq) = compress_matrix(G_leq, h_leq)
        dims[s.LEQ_DIM] = int(h_leq.shape[0])
        data['P_leq'] = intf.sparse2cvxopt(P_leq)
        G = sp.vstack([G_leq, G_other])
        h = np.hstack([h_leq, h_other])
    data[s.A] = A
    data[s.G] = G
    data[s.B] = b
    data[s.H] = h
    return s.OPTIMAL
