Пример #1
0
def test_transform():  # TODO : class test for class CovEmbedding
    """Testing fit_transform method for class CovEmbedding"""
    n_subjects = random.randint(3, 50)
    shape = random.randint(1, 10)
    n_samples = 300
    covs = []
    signals = []
    for k in xrange(n_subjects):
        signal = np.random.randn(n_samples, shape)
        signals.append(signal)
        signal -= signal.mean(axis=0)
        covs.append((signal.T).dot(signal) / n_samples)
    for kind in ["correlation", "precision", "partial correlation", "tangent"]:
        estimators = {'kind': kind, 'cov_estimator': None}
        cov_embedding = my_con.CovEmbedding(**estimators)
        covs_transformed = cov_embedding.fit_transform(signals)

        # Generic
        assert_is_instance(covs_transformed, np.ndarray)
        assert_equal(len(covs_transformed), len(covs))

        for k, vec in enumerate(covs_transformed):
            assert_equal(vec.size, shape * (shape + 1) / 2)
            cov_new = my_con.vec_to_sym(vec)
            assert_true(my_mfd.is_spd(covs[k]))
            if estimators["kind"] == "tangent":
                assert_array_almost_equal(cov_new, cov_new.T)
                fre_sqrt = my_mfd.sqrtm(cov_embedding.mean_cov_)
                assert_true(my_mfd.is_spd(fre_sqrt))
                assert_true(my_mfd.is_spd(cov_embedding.whitening_))
                assert_array_almost_equal(
                cov_embedding.whitening_.dot(fre_sqrt), np.eye(shape))
                assert_array_almost_equal(
                fre_sqrt.dot(my_mfd.expm(cov_new)).dot(fre_sqrt), covs[k])
            if estimators["kind"] == "precision":
                assert_true(my_mfd.is_spd(cov_new))
                assert_array_almost_equal(cov_new.dot(covs[k]), np.eye(shape))
            if estimators["kind"] == "correlation":
                assert_true(my_mfd.is_spd(cov_new))
                d = np.sqrt(np.diag(np.diag(covs[k])))
                assert_array_almost_equal(d.dot(cov_new).dot(d), covs[k])
            if estimators["kind"] == "partial correlation":
                assert_true(my_mfd.is_spd(cov_new))
                prec = linalg.inv(covs[k])
                d = np.sqrt(np.diag(np.diag(prec)))
                assert_array_almost_equal(
                d.dot(cov_new).dot(d), -prec + 2 * np.diag(np.diag(prec)))
Пример #2
0
def test_frechet_mean():  # TODO: test suite and split in several tests
    """Testing frechet_mean function"""
    n = random.randint(3, 50)
    shape = random.randint(1, 50)
    spds = []
    for k in xrange(n):
        eig_min = random.uniform(1e-7, 1.)
        eig_max = random.uniform(1., 1e7)
        spds.append(my_mfd.random_spd(shape, eig_min, eig_max))
    fre = my_mfd.frechet_mean(spds)

    # Generic
    assert_tuple_equal(fre.shape, spds[0].shape)
    assert_array_almost_equal(fre, fre.T)
    assert_array_less(0., linalg.eigvals(fre))

    # Check error for non spd enteries
    mat1 = np.ones((shape, shape))
    with assert_raises_regexp(ValueError, "at least one matrix is not real " +\
    "spd"):
        my_mfd.frechet_mean([mat1])

    # Check warning if gradient norm in the last step is less than tolerance
    for (tol, max_iter) in [(1e-10, 1), (1e-3, 50)]:
        with warnings.catch_warnings(record=True) as w:
            fre = my_mfd.frechet_mean(spds, max_iter=max_iter, tol=tol)
            grad_norm = my_mfd.grad_frechet_mean(spds, max_iter=max_iter,
                                                  tol=tol)
            if grad_norm[-1] > tol:
                assert_equal(len(w), 2)
                assert_equal(len(grad_norm), max_iter)

    # Gradient norm is decreasing
    assert_array_less(np.diff(grad_norm), 0.)

    decimal = 5
    tol = 10 ** (-2 * decimal)
    fre = my_mfd.frechet_mean(spds, tol=tol)

    # Adaptative version requires less iterations than non adaptaive
    grad_norm = my_mfd.grad_frechet_mean(spds, tol=tol)
    grad_norm_fast = my_mfd.grad_frechet_mean(spds, tol=tol, adaptative=True)
    assert(len(grad_norm_fast) == len(grad_norm))

    # Invariance under reordering
    spds.reverse()
    spds.insert(0, spds[2])
    spds.pop(3)
    fre_new = my_mfd.frechet_mean(spds, tol=tol)
    assert_array_almost_equal(fre_new, fre)

    # Invariance under congruant transformation
    c = my_mfd.random_non_singular(shape)
    spds_cong = [c.dot(spd).dot(c.T) for spd in spds]
    fre_new = my_mfd.frechet_mean(spds_cong, tol=tol)
    assert_array_almost_equal(fre_new, c.dot(fre).dot(c.T))

    # Invariance under inversion
    spds_inv = [linalg.inv(spd) for spd in spds]
    fre_new = my_mfd.frechet_mean(spds_inv, tol=tol)
    assert_array_almost_equal(fre_new, linalg.inv(fre), decimal=decimal)

    # Approximate Frechet mean is close to the exact one
    decimal = 7
    tol = 0.5 * 10 ** (-decimal)

    # Diagonal matrices: exact Frechet mean is geometric mean
    diags = []
    for k in xrange(n):
        diags.append(my_mfd.random_diagonal_spd(shape, 1e-5, 1e5))
    exact_fre = np.prod(my_mfd.my_stack(diags), axis=0) ** \
                (1 / float(len(diags)))
    app_fre = my_mfd.frechet_mean(diags, max_iter=10, tol=tol)
    assert_array_almost_equal(app_fre, exact_fre, decimal)

    # 2 matrices
    spd1 = my_mfd.random_spd(shape)
    spd2 = my_mfd.random_spd(shape)
    spd2_sqrt = my_mfd.sqrtm(spd2)
    spd2_inv_sqrt = my_mfd.inv_sqrtm(spd2)
    exact_fre = spd2_sqrt.dot(
    my_mfd.sqrtm(spd2_inv_sqrt.dot(spd1).dot(spd2_inv_sqrt))).dot(spd2_sqrt)
    app_fre = my_mfd.frechet_mean([spd1, spd2], tol=tol)
    assert_array_almost_equal(app_fre, exact_fre, decimal)

    # Single geodesic matrices : TODO
    S = np.random.rand(shape, shape)
    S = S + S.T
    times = np.empty(n, dtype=float)
    spds = []
    for k in xrange(n):
        t_k = random.uniform(-2., -1.)
        times[k] = t_k
        spds.append(c.dot(my_mfd.expm(t_k * S)).dot(c.T))
Пример #3
0
def test_sqrtm():
    """Testing sqrtm function"""
    m = my_mfd.random_spd(12)
    m_sqrt = my_mfd.sqrtm(m)
    assert_array_almost_equal(m_sqrt.T, m_sqrt)
    assert_array_almost_equal(m_sqrt.dot(m_sqrt), m)