class TestSphereManifold(unittest.TestCase): def setUp(self): self.m = m = 100 self.n = n = 50 self.man = Sphere(m, n) # For automatic testing of ehess2rhess self.proj = lambda x, u: u - npa.tensordot(x, u, np.ndim(u)) * x def test_dim(self): assert self.man.dim == self.m * self.n - 1 def test_typicaldist(self): np_testing.assert_almost_equal(self.man.typicaldist, np.pi) def test_dist(self): s = self.man x = s.rand() y = s.rand() correct_dist = np.arccos(np.tensordot(x, y)) np.testing.assert_almost_equal(correct_dist, s.dist(x, y)) def test_inner(self): s = self.man x = s.rand() u = s.randvec(x) v = s.randvec(x) np.testing.assert_almost_equal(np.sum(u * v), s.inner(x, u, v)) def test_proj(self): # Construct a random point X on the manifold. X = rnd.randn(self.m, self.n) X /= la.norm(X, "fro") # Construct a vector H in the ambient space. H = rnd.randn(self.m, self.n) # Compare the projections. np_testing.assert_array_almost_equal(H - X * np.trace(X.T.dot(H)), self.man.proj(X, H)) def test_egrad2rgrad(self): # Should be the same as proj # Construct a random point X on the manifold. X = rnd.randn(self.m, self.n) X /= la.norm(X, "fro") # Construct a vector H in the ambient space. H = rnd.randn(self.m, self.n) # Compare the projections. np_testing.assert_array_almost_equal(H - X * np.trace(X.T.dot(H)), self.man.egrad2rgrad(X, H)) def test_ehess2rhess(self): x = self.man.rand() u = self.man.randvec(x) egrad = rnd.randn(self.m, self.n) ehess = rnd.randn(self.m, self.n) np_testing.assert_allclose(testing.ehess2rhess(self.proj)(x, egrad, ehess, u), self.man.ehess2rhess(x, egrad, ehess, u)) def test_retr(self): # Test that the result is on the manifold and that for small # tangent vectors it has little effect. x = self.man.rand() u = self.man.randvec(x) xretru = self.man.retr(x, u) np_testing.assert_almost_equal(la.norm(xretru), 1) u = u * 1e-6 xretru = self.man.retr(x, u) np_testing.assert_allclose(xretru, x + u) def test_norm(self): x = self.man.rand() u = self.man.randvec(x) np_testing.assert_almost_equal(self.man.norm(x, u), la.norm(u)) def test_rand(self): # Just make sure that things generated are on the manifold and that # if you generate two they are not equal. s = self.man x = s.rand() np_testing.assert_almost_equal(la.norm(x), 1) y = s.rand() assert np.linalg.norm(x - y) > 1e-3 def test_randvec(self): # Just make sure that things generated are in the tangent space and # that if you generate two they are not equal. s = self.man x = s.rand() u = s.randvec(x) v = s.randvec(x) np_testing.assert_almost_equal(np.tensordot(x, u), 0) assert np.linalg.norm(u - v) > 1e-3 def test_transp(self): # Should be the same as proj s = self.man x = s.rand() y = s.rand() u = s.randvec(x) np_testing.assert_allclose(s.transp(x, y, u), s.proj(y, u)) def test_exp_log_inverse(self): s = self.man X = s.rand() U = s.randvec(X) Uexplog = s.exp(X, s.log(X, U)) np_testing.assert_array_almost_equal(U, Uexplog) def test_log_exp_inverse(self): s = self.man X = s.rand() U = s.randvec(X) Ulogexp = s.log(X, s.exp(X, U)) np_testing.assert_array_almost_equal(U, Ulogexp) def test_pairmean(self): s = self.man X = s.rand() Y = s.rand() Z = s.pairmean(X, Y) np_testing.assert_array_almost_equal(s.dist(X, Z), s.dist(Y, Z))
class TestSphereManifold(ManifoldTestCase): def setUp(self): self.m = m = 100 self.n = n = 50 self.manifold = Sphere(m, n) # For automatic testing of euclidean_to_riemannian_hessian self.projection = lambda x, u: u - np.tensordot(x, u, np.ndim(u)) * x super().setUp() def test_dim(self): assert self.manifold.dim == self.m * self.n - 1 def test_typical_dist(self): np_testing.assert_almost_equal(self.manifold.typical_dist, np.pi) def test_dist(self): s = self.manifold x = s.random_point() y = s.random_point() correct_dist = np.arccos(np.tensordot(x, y)) np_testing.assert_almost_equal(correct_dist, s.dist(x, y)) def test_inner_product(self): s = self.manifold x = s.random_point() u = s.random_tangent_vector(x) v = s.random_tangent_vector(x) np_testing.assert_almost_equal(np.sum(u * v), s.inner_product(x, u, v)) def test_projection(self): # Construct a random point X on the manifold. X = np.random.normal(size=(self.m, self.n)) X /= np.linalg.norm(X, "fro") # Construct a vector H in the ambient space. H = np.random.normal(size=(self.m, self.n)) # Compare the projections. np_testing.assert_array_almost_equal(H - X * np.trace(X.T @ H), self.manifold.projection(X, H)) def test_euclidean_to_riemannian_gradient(self): # Should be the same as proj # Construct a random point X on the manifold. X = np.random.normal(size=(self.m, self.n)) X /= np.linalg.norm(X, "fro") # Construct a vector H in the ambient space. H = np.random.normal(size=(self.m, self.n)) # Compare the projections. np_testing.assert_array_almost_equal( H - X * np.trace(X.T @ H), self.manifold.euclidean_to_riemannian_gradient(X, H), ) def test_first_order_function_approximation(self): self.run_gradient_approximation_test() def test_second_order_function_approximation(self): self.run_hessian_approximation_test() def test_euclidean_to_riemannian_hessian(self): x = self.manifold.random_point() u = self.manifold.random_tangent_vector(x) egrad = np.random.normal(size=(self.m, self.n)) ehess = np.random.normal(size=(self.m, self.n)) np_testing.assert_allclose( testing.euclidean_to_riemannian_hessian(self.projection)(x, egrad, ehess, u), self.manifold.euclidean_to_riemannian_hessian(x, egrad, ehess, u), ) def test_retraction(self): # Test that the result is on the manifold and that for small # tangent vectors it has little effect. x = self.manifold.random_point() u = self.manifold.random_tangent_vector(x) xretru = self.manifold.retraction(x, u) np_testing.assert_almost_equal(np.linalg.norm(xretru), 1) u = u * 1e-6 xretru = self.manifold.retraction(x, u) np_testing.assert_allclose(xretru, x + u) def test_norm(self): x = self.manifold.random_point() u = self.manifold.random_tangent_vector(x) np_testing.assert_almost_equal(self.manifold.norm(x, u), np.linalg.norm(u)) def test_random_point(self): # Just make sure that things generated are on the manifold and that # if you generate two they are not equal. s = self.manifold x = s.random_point() np_testing.assert_almost_equal(np.linalg.norm(x), 1) y = s.random_point() assert np.linalg.norm(x - y) > 1e-3 def test_random_tangent_vector(self): # Just make sure that things generated are in the tangent space and # that if you generate two they are not equal. s = self.manifold x = s.random_point() u = s.random_tangent_vector(x) v = s.random_tangent_vector(x) np_testing.assert_almost_equal(np.tensordot(x, u), 0) assert np.linalg.norm(u - v) > 1e-3 def test_transport(self): # Should be the same as proj s = self.manifold x = s.random_point() y = s.random_point() u = s.random_tangent_vector(x) np_testing.assert_allclose(s.transport(x, y, u), s.projection(y, u)) def test_exp_log_inverse(self): s = self.manifold X = s.random_point() Y = s.random_point() Yexplog = s.exp(X, s.log(X, Y)) np_testing.assert_array_almost_equal(Y, Yexplog) def test_log_exp_inverse(self): s = self.manifold X = s.random_point() U = s.random_tangent_vector(X) Ulogexp = s.log(X, s.exp(X, U)) np_testing.assert_array_almost_equal(U, Ulogexp) def test_pair_mean(self): s = self.manifold X = s.random_point() Y = s.random_point() Z = s.pair_mean(X, Y) np_testing.assert_array_almost_equal(s.dist(X, Z), s.dist(Y, Z))
class TestSphereManifold(unittest.TestCase): def setUp(self): self.m = m = 100 self.n = n = 50 self.man = Sphere(m, n) # For automatic testing of ehess2rhess self.proj = lambda x, u: u - npa.tensordot(x, u, np.ndim(u)) * x def test_name(self): man = self.man m = self.m n = self.n assert "Sphere manifold of " + str(m) + "x" + str(n) in str(man) def test_dim(self): assert self.man.dim == self.m * self.n - 1 def test_typicaldist(self): np_testing.assert_almost_equal(self.man.typicaldist, np.pi) def test_dist(self): s = self.man x = s.rand() y = s.rand() correct_dist = np.arccos(np.tensordot(x, y)) np.testing.assert_almost_equal(correct_dist, s.dist(x, y)) def test_inner(self): s = self.man x = s.rand() u = s.randvec(x) v = s.randvec(x) np.testing.assert_almost_equal(np.sum(u * v), s.inner(x, u, v)) def test_proj(self): # Construct a random point X on the manifold. X = rnd.randn(self.m, self.n) X /= la.norm(X, "fro") # Construct a vector H in the ambient space. H = rnd.randn(self.m, self.n) # Compare the projections. np_testing.assert_array_almost_equal(H - X * np.trace(X.T.dot(H)), self.man.proj(X, H)) def test_egrad2rgrad(self): # Should be the same as proj # Construct a random point X on the manifold. X = rnd.randn(self.m, self.n) X /= la.norm(X, "fro") # Construct a vector H in the ambient space. H = rnd.randn(self.m, self.n) # Compare the projections. np_testing.assert_array_almost_equal(H - X * np.trace(X.T.dot(H)), self.man.egrad2rgrad(X, H)) def test_ehess2rhess(self): x = self.man.rand() u = self.man.randvec(x) egrad = rnd.randn(self.m, self.n) ehess = rnd.randn(self.m, self.n) np_testing.assert_allclose(testing.ehess2rhess(self.proj)(x, egrad, ehess, u), self.man.ehess2rhess(x, egrad, ehess, u)) def test_retr(self): # Test that the result is on the manifold and that for small # tangent vectors it has little effect. x = self.man.rand() u = self.man.randvec(x) xretru = self.man.retr(x, u) np_testing.assert_almost_equal(la.norm(xretru), 1) u = u * 1e-6 xretru = self.man.retr(x, u) np_testing.assert_allclose(xretru, x + u) def test_norm(self): x = self.man.rand() u = self.man.randvec(x) np_testing.assert_almost_equal(self.man.norm(x, u), la.norm(u)) def test_rand(self): # Just make sure that things generated are on the manifold and that # if you generate two they are not equal. s = self.man x = s.rand() np_testing.assert_almost_equal(la.norm(x), 1) y = s.rand() assert np.linalg.norm(x - y) > 1e-3 def test_randvec(self): # Just make sure that things generated are in the tangent space and # that if you generate two they are not equal. s = self.man x = s.rand() u = s.randvec(x) v = s.randvec(x) np_testing.assert_almost_equal(np.tensordot(x, u), 0) assert np.linalg.norm(u - v) > 1e-3 def test_transp(self): # Should be the same as proj s = self.man x = s.rand() y = s.rand() u = s.randvec(x) np_testing.assert_allclose(s.transp(x, y, u), s.proj(y, u)) def test_exp_log_inverse(self): s = self.man X = s.rand() U = s.randvec(X) Uexplog = s.exp(X, s.log(X, U)) np_testing.assert_array_almost_equal(U, Uexplog) def test_log_exp_inverse(self): s = self.man X = s.rand() U = s.randvec(X) Ulogexp = s.log(X, s.exp(X, U)) np_testing.assert_array_almost_equal(U, Ulogexp) def test_pairmean(self): s = self.man X = s.rand() Y = s.rand() Z = s.pairmean(X, Y) np_testing.assert_array_almost_equal(s.dist(X, Z), s.dist(Y, Z))