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)))
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))
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)