'The Equivalence covariance structure can represent an
exchangeable covariance structure.  Here we check that the
results are identical using the two approaches.'

def test_equivalence(self):

    np.random.seed(3424)
    endog = np.random.normal(size=20)
    exog = np.random.normal(size=(20, 2))
    exog[:, 0] = 1
    groups = np.kron(np.arange(5), np.ones(4))
    groups[12:] = 3
    pairs = {}
    start = [0, 4, 8, 12]
    for k in range(4):
        pairs[k] = {}
        if (k < 3):
            pairs[k][0] = ((start[k] + np.r_[(0, 1, 2, 3)]), (start[k] + np.r_[(0, 1, 2, 3)]))
        else:
            pairs[k][0] = ((start[k] + np.r_[(0, 1, 2, 3, 4, 5, 6, 7)]), (start[k] + np.r_[(0, 1, 2, 3, 4, 5, 6, 7)]))
        if (k < 3):
            (a, b) = np.tril_indices(4, (-1))
            pairs[k][1] = ((start[k] + a), (start[k] + b))
        else:
            (a, b) = np.tril_indices(8, (-1))
            pairs[k][1] = ((start[k] + a), (start[k] + b))
    ex = sm.cov_struct.Exchangeable()
    model1 = sm.GEE(endog, exog, groups, cov_struct=ex)
    result1 = model1.fit()
    for return_cov in (False, True):
        ec = sm.cov_struct.Equivalence(pairs, return_cov=return_cov)
        model2 = sm.GEE(endog, exog, groups, cov_struct=ec)
        result2 = model2.fit()
        if (return_cov is True):
            (atol, rtol) = (1e-06, 1e-06)
        else:
            (atol, rtol) = (0.001, 0.001)
        assert_allclose(result1.params, result2.params, atol=atol, rtol=rtol)
        assert_allclose(result1.bse, result2.bse, atol=atol, rtol=rtol)
        assert_allclose(result1.scale, result2.scale, atol=atol, rtol=rtol)
