def test_exp_and_log_and_projection_to_tangent_space_edge_case(self): """ Test that the riemannian exponential and the riemannian logarithm are inverse. Expect their composition to give the identity function. NB: points on the n-dimensional sphere are (n+1)-D vectors of norm 1. """ # Riemannian Exp then Riemannian Log # Edge case: tangent vector has norm < epsilon base_point = tf.convert_to_tensor([10., -2., -.5, 34., 3.]) base_point = base_point / gs.linalg.norm(base_point) vector = 1e-10 * tf.convert_to_tensor([.06, -51., 6., 5., 3.]) vector = self.space.projection_to_tangent_space(vector=vector, base_point=base_point) exp = self.metric.exp(tangent_vec=vector, base_point=base_point) result = self.metric.log(point=exp, base_point=base_point) expected = self.space.projection_to_tangent_space( vector=vector, base_point=base_point) expected = helper.to_vector(expected) with self.test_session(): self.assertAllClose(gs.eval(result), gs.eval(expected), atol=1e-8)
def test_intrinsic_and_extrinsic_coords(self): """ Test that the composition of intrinsic_to_extrinsic_coords and extrinsic_to_intrinsic_coords gives the identity. """ point_int = tf.convert_to_tensor([.1, 0., 0., .1]) point_ext = self.space.intrinsic_to_extrinsic_coords(point_int) result = self.space.extrinsic_to_intrinsic_coords(point_ext) expected = point_int expected = helper.to_vector(expected) with self.test_session(): self.assertAllClose(gs.eval(result), gs.eval(expected)) # TODO(nina): Fix that the test fails if point_ext generated # with tf.random_uniform point_ext = (1. / (gs.sqrt(6.)) * tf.convert_to_tensor([1., 0., 0., 1., 2.])) point_int = self.space.extrinsic_to_intrinsic_coords(point_ext) result = self.space.intrinsic_to_extrinsic_coords(point_int) expected = point_ext expected = helper.to_vector(expected) with self.test_session(): self.assertAllClose(gs.eval(result), gs.eval(expected))
def test_intrinsic_and_extrinsic_coords_vectorization(self): """ Test that the composition of intrinsic_to_extrinsic_coords and extrinsic_to_intrinsic_coords gives the identity. """ point_int = gs.array([[.1, 0., 0., .1, 0., 0.], [.1, .1, .1, .4, .1, 0.], [.1, .3, 0., .1, 0., 0.], [-0.1, .1, -.4, .1, -.01, 0.], [0., 0., .1, .1, -0.08, -0.1], [.1, .1, .1, .1, 0., -0.5]]) point_ext = self.space.intrinsic_to_extrinsic_coords(point_int) result = self.space.extrinsic_to_intrinsic_coords(point_ext) expected = point_int expected = helper.to_vector(expected) with self.test_session(): self.assertAllClose(gs.eval(result), gs.eval(expected)) point_ext = tf.convert_to_tensor([[2.0, 1.0, 1.0, 1.0], [4.0, 1., 3.0, math.sqrt(5)], [3.0, 2.0, 0.0, 2.0]]) point_int = self.space.extrinsic_to_intrinsic_coords(point_ext) result = self.space.intrinsic_to_extrinsic_coords(point_int) # TODO(nina): Make sure this holds for (x, y, z, ..) AND (-x, y,z) expected = point_ext expected = helper.to_vector(expected) with self.test_session(): self.assertAllClose(gs.eval(result), gs.eval(expected))
def test_intrinsic_and_extrinsic_coords_vectorization(self): """ Test that the composition of intrinsic_to_extrinsic_coords and extrinsic_to_intrinsic_coords gives the identity. """ point_int = tf.convert_to_tensor([[.1, 0., 0., .1], [.1, .1, .1, .4], [.1, .3, 0., .1], [-0.1, .1, -.4, .1], [0., 0., .1, .1], [.1, .1, .1, .1]]) point_ext = self.space.intrinsic_to_extrinsic_coords(point_int) result = self.space.extrinsic_to_intrinsic_coords(point_ext) expected = point_int expected = helper.to_vector(expected) with self.test_session(): self.assertAllClose(gs.eval(result), gs.eval(expected)) sqrt_3 = np.sqrt(3.) point_ext = tf.convert_to_tensor( [[1. / sqrt_3, 0., 0., 1. / sqrt_3, 1. / sqrt_3], [1. / sqrt_3, 1. / sqrt_3, 1. / sqrt_3, 0., 0.], [0., 0., 1. / sqrt_3, 1. / sqrt_3, 1. / sqrt_3]], dtype=np.float64) point_int = self.space.extrinsic_to_intrinsic_coords(point_ext) result = self.space.intrinsic_to_extrinsic_coords(point_int) expected = point_ext expected = helper.to_vector(expected) with self.test_session(): self.assertAllClose(gs.eval(result), gs.eval(expected))
def test_log_vectorization(self): n_samples = 3 dim = self.dimension + 1 one_point = tf.convert_to_tensor([2.0, 1.0, 1.0, 1.0]) one_base_point = tf.convert_to_tensor([4.0, 3., 1.0, math.sqrt(5)]) n_points = tf.convert_to_tensor([[2.0, 1.0, 1.0, 1.0], [4.0, 1., 3.0, math.sqrt(5)], [3.0, 2.0, 0.0, 2.0]]) n_base_points = tf.convert_to_tensor( [[2.0, 0.0, 1.0, math.sqrt(2)], [5.0, math.sqrt(8), math.sqrt(8), math.sqrt(8)], [1.0, 0.0, 0.0, 0.0]]) result = self.metric.log(one_point, one_base_point) with self.test_session(): self.assertAllClose(gs.eval(result).shape, (1, dim)) result = self.metric.log(n_points, one_base_point) with self.test_session(): self.assertAllClose(gs.eval(result).shape, (n_samples, dim)) result = self.metric.log(one_point, n_base_points) with self.test_session(): self.assertAllClose(gs.eval(result).shape, (n_samples, dim)) result = self.metric.log(n_points, n_base_points) with self.test_session(): self.assertAllClose(gs.eval(result).shape, (n_samples, dim))
def test_log_vectorization(self): dim = self.dimension n_samples = 3 one_point = tf.convert_to_tensor([[-1., 0.]]) one_base_point = tf.convert_to_tensor([[1.0, 0.]]) n_points = tf.convert_to_tensor([[-1., 0.], [1., 0.], [2., math.sqrt(3)]]) n_base_points = tf.convert_to_tensor([[2., -math.sqrt(3)], [4.0, math.sqrt(15)], [-4.0, math.sqrt(15)]]) result = self.metric.log(one_point, one_base_point) expected = one_point - one_base_point expected = helper.to_vector(expected) with self.test_session(): self.assertAllClose(gs.eval(result), gs.eval(expected)) result = self.metric.log(n_points, one_base_point) self.assertAllClose(gs.eval(result).shape, (n_samples, dim)) result = self.metric.log(one_point, n_base_points) self.assertAllClose(gs.eval(result).shape, (n_samples, dim)) result = self.metric.log(n_points, n_base_points) self.assertAllClose(gs.eval(result).shape, (n_samples, dim))
def test_inner_product_vectorization(self): n_samples = 3 one_point_a = gs.array([[-1., 0.]]) one_point_b = gs.array([[1.0, 0.]]) n_points_a = gs.array([[-1., 0.], [1., 0.], [2., math.sqrt(3)]]) n_points_b = gs.array([[2., -math.sqrt(3)], [4.0, math.sqrt(15)], [-4.0, math.sqrt(15)]]) result = self.metric.inner_product(one_point_a, one_point_b) expected = gs.dot(one_point_a, gs.transpose(one_point_b)) expected -= (2 * one_point_a[:, self.time_like_dim] * one_point_b[:, self.time_like_dim]) expected = helper.to_scalar(expected) result_no = self.metric.inner_product(n_points_a, one_point_b) result_on = self.metric.inner_product(one_point_a, n_points_b) result_nn = self.metric.inner_product(n_points_a, n_points_b) self.assertAllClose(result, expected) self.assertAllClose(gs.shape(result_no), (n_samples, 1)) self.assertAllClose(gs.shape(result_on), (n_samples, 1)) self.assertAllClose(gs.shape(result_nn), (n_samples, 1)) with self.session(): expected = np.zeros(n_samples) for i in range(n_samples): expected[i] = gs.eval(gs.dot(n_points_a[i], n_points_b[i])) expected[i] -= (2 * gs.eval(n_points_a[i, self.time_like_dim]) * gs.eval(n_points_b[i, self.time_like_dim])) expected = helper.to_scalar(gs.array(expected)) self.assertAllClose(result_nn, expected)
def test_belongs(self): point = self.space.random_uniform() bool_belongs = self.space.belongs(point) expected = tf.convert_to_tensor([[True]]) with self.test_session(): self.assertAllClose(gs.eval(expected), gs.eval(bool_belongs))
def test_squared_dist_vectorization(self): n_samples = self.n_samples one_point_a = self.space.random_uniform() one_point_b = self.space.random_uniform() n_points_a = self.space.random_uniform(n_samples=n_samples) n_points_b = self.space.random_uniform(n_samples=n_samples) result = self.metric.squared_dist(one_point_a, one_point_b) point_numpy = np.random.uniform(size=(1, 1)) with self.test_session(): # TODO(nina): Fix that this test fails with assertShapeEqual self.assertAllClose(point_numpy.shape, gs.eval(gs.shape(result))) result = self.metric.squared_dist(n_points_a, one_point_b) point_numpy = np.random.uniform(size=(n_samples, 1)) with self.test_session(): # TODO(nina): Fix that this test fails with assertShapeEqual self.assertAllClose(point_numpy.shape, gs.eval(gs.shape(result))) result = self.metric.squared_dist(one_point_a, n_points_b) point_numpy = np.random.uniform(size=(n_samples, 1)) with self.test_session(): # TODO(nina): Fix that this test fails with assertShapeEqual self.assertAllClose(point_numpy.shape, gs.eval(gs.shape(result))) result = self.metric.squared_dist(n_points_a, n_points_b) point_numpy = np.random.uniform(size=(n_samples, 1)) with self.test_session(): # TODO(nina): Fix that this test fails with assertShapeEqual self.assertAllClose(point_numpy.shape, gs.eval(gs.shape(result)))
def test_inner_product_vectorization(self): n_samples = 3 one_point_a = tf.convert_to_tensor([0., 1.]) one_point_b = tf.convert_to_tensor([2., 10.]) n_points_a = tf.convert_to_tensor([[2., 1.], [-2., -4.], [-5., 1.]]) n_points_b = tf.convert_to_tensor([[2., 10.], [8., -1.], [-3., 6.]]) result = self.metric.inner_product(one_point_a, one_point_b) expected = gs.dot(one_point_a, gs.transpose(one_point_b)) expected = helper.to_scalar(expected) with self.test_session(): self.assertAllClose(gs.eval(result), gs.eval(expected)) result = self.metric.inner_product(n_points_a, one_point_b) point_numpy = np.random.uniform(size=(n_samples, 1)) # TODO(nina): Fix this test with assertShapeEqual with self.test_session(): self.assertAllClose(point_numpy.shape, gs.eval(gs.shape(result))) result = self.metric.inner_product(one_point_a, n_points_b) point_numpy = np.random.uniform(size=(n_samples, 1)) # TODO(nina): Fix this test with assertShapeEqual with self.test_session(): self.assertAllClose(point_numpy.shape, gs.eval(gs.shape(result))) result = self.metric.inner_product(n_points_a, n_points_b) point_numpy = np.random.uniform(size=(n_samples, 1)) # TODO(nina): Fix this test with assertShapeEqual with self.test_session(): self.assertAllClose(point_numpy.shape, gs.eval(gs.shape(result)))
def test_compose_and_inverse(self): # 1. Compose transformation by its inverse on the right # Expect the group identity rot_vec = tf.convert_to_tensor([0.2, 0.1, 0.1]) mat = self.so3_group.matrix_from_rotation_vector(rot_vec) inv_mat = self.group.inverse(mat) result = self.group.compose(mat, inv_mat) expected = self.group.identity expected = helper.to_matrix(expected) with self.test_session(): self.assertAllClose(gs.eval(result), gs.eval(expected)) # 2. Compose transformation by its inverse on the left # Expect the group identity rot_vec = tf.convert_to_tensor([0.7, 0.1, 0.1]) mat = self.so3_group.matrix_from_rotation_vector(rot_vec) inv_mat = self.group.inverse(mat) result = self.group.compose(inv_mat, mat) expected = self.group.identity expected = helper.to_matrix(expected) with self.test_session(): self.assertAllClose(gs.eval(result), gs.eval(expected))
def test_log_and_exp_edge_case(self): """ Test that the riemannian exponential and the riemannian logarithm are inverse. Expect their composition to give the identity function. NB: points on the n-dimensional sphere are (n+1)-D vectors of norm 1. """ # Riemannian Log then Riemannian Exp # Edge case: two very close points, base_point_2 and point_2, # form an angle < epsilon base_point = tf.convert_to_tensor([1., 2., 3., 4., 6.]) base_point = base_point / gs.linalg.norm(base_point) point = (base_point + 1e-12 * tf.convert_to_tensor([-1., -2., 1., 1., .1])) point = point / gs.linalg.norm(point) log = self.metric.log(point=point, base_point=base_point) result = self.metric.exp(tangent_vec=log, base_point=base_point) expected = point expected = helper.to_vector(expected) with self.test_session(): self.assertAllClose(gs.eval(result), gs.eval(expected))
def test_squared_dist_and_squared_norm_right_metrics(self): result = self.right_metric.squared_dist(self.point_1, self.point_2) log = self.right_diag_metric.log(base_point=self.point_1, point=self.point_2) expected = self.right_metric.squared_norm(vector=log, base_point=self.point_1) with self.test_session(): self.assertAllClose(gs.eval(result), gs.eval(expected))
def test_left_log_and_log_from_identity_left_diag_metrics(self): left_log_from_id = self.left_diag_metric.left_log_from_identity( self.point_1) log_from_id = self.left_diag_metric.log_from_identity(self.point_1) with self.test_session(): self.assertAllClose(gs.eval(left_log_from_id), gs.eval(log_from_id))
def test_inner_product_matrix(self): result = self.metric.inner_product_matrix() expected = gs.eye(self.dimension) expected = helper.to_matrix(expected) with self.test_session(): self.assertAllClose(gs.eval(result), gs.eval(expected))
def test_exp_vectorization(self): n_samples = 3 dim = self.dimension + 1 one_vec = gs.array([2.0, 1.0, 1.0, 1.0]) one_base_point = gs.array([4.0, 3., 1.0, math.sqrt(5)]) n_vecs = gs.array([[2., 1., 1., 1.], [4., 1., 3., math.sqrt(5.)], [3., 2., 0., 2.]]) n_base_points = gs.array( [[2.0, 0.0, 1.0, math.sqrt(2)], [5.0, math.sqrt(8), math.sqrt(8), math.sqrt(8)], [1.0, 0.0, 0.0, 0.0]]) one_tangent_vec = self.space.projection_to_tangent_space( one_vec, base_point=one_base_point) result = self.metric.exp(one_tangent_vec, one_base_point) self.assertAllClose(gs.shape(result), (1, dim)) n_tangent_vecs = self.space.projection_to_tangent_space( n_vecs, base_point=one_base_point) result = self.metric.exp(n_tangent_vecs, one_base_point) self.assertAllClose(gs.shape(result), (n_samples, dim)) expected = np.zeros((n_samples, dim)) with self.session(): for i in range(n_samples): expected[i] = gs.eval( self.metric.exp(n_tangent_vecs[i], one_base_point)) expected = helper.to_vector(gs.array(expected)) self.assertAllClose(result, expected) one_tangent_vec = self.space.projection_to_tangent_space( one_vec, base_point=n_base_points) result = self.metric.exp(one_tangent_vec, n_base_points) self.assertAllClose(gs.shape(result), (n_samples, dim)) expected = np.zeros((n_samples, dim)) with self.session(): for i in range(n_samples): expected[i] = gs.eval( self.metric.exp(one_tangent_vec[i], n_base_points[i])) expected = helper.to_vector(gs.array(expected)) self.assertAllClose(result, expected) n_tangent_vecs = self.space.projection_to_tangent_space( n_vecs, base_point=n_base_points) result = self.metric.exp(n_tangent_vecs, n_base_points) self.assertAllClose(gs.shape(result), (n_samples, dim)) expected = np.zeros((n_samples, dim)) with self.session(): for i in range(n_samples): expected[i] = gs.eval( self.metric.exp(n_tangent_vecs[i], n_base_points[i])) expected = helper.to_vector(gs.array(expected)) self.assertAllClose(result, expected)
def test_squared_norm(self): point = tf.convert_to_tensor([-2., 4.]) result = self.metric.squared_norm(point) expected = gs.dot(point, point) expected -= 2 * point[self.time_like_dim] * point[self.time_like_dim] expected = helper.to_scalar(expected) with self.test_session(): self.assertAllClose(gs.eval(result), gs.eval(expected))
def test_exp(self): base_point = tf.convert_to_tensor([1.0, 0.]) vector = tf.convert_to_tensor([2., math.sqrt(3)]) result = self.metric.exp(tangent_vec=vector, base_point=base_point) expected = base_point + vector expected = helper.to_vector(expected) with self.test_session(): self.assertAllClose(gs.eval(result), gs.eval(expected))
def test_log(self): base_point = tf.convert_to_tensor([-1., 0.]) point = tf.convert_to_tensor([2., math.sqrt(3)]) result = self.metric.log(point=point, base_point=base_point) expected = point - base_point expected = helper.to_vector(expected) with self.test_session(): self.assertAllClose(gs.eval(result), gs.eval(expected))
def test_dist(self): # Distance between a point and itself is 0. point_a = tf.convert_to_tensor([4.0, 1., 3.0, math.sqrt(5)]) point_b = point_a result = self.metric.dist(point_a, point_b) expected = tf.convert_to_tensor([[0]]) with self.test_session(): self.assertAllClose(gs.eval(result), gs.eval(expected))
def test_inner_product_matrix_and_its_inverse(self): inner_prod_mat = self.left_diag_metric.inner_product_mat_at_identity inv_inner_prod_mat = gs.linalg.inv(inner_prod_mat) result = gs.matmul(inv_inner_prod_mat, inner_prod_mat) expected = gs.eye(self.group.dimension) expected = gs.to_ndarray(expected, to_ndim=3, axis=0) with self.test_session(): self.assertAllClose(gs.eval(result), gs.eval(expected))
def test_norm(self): point = tf.convert_to_tensor([-2., 4.]) result = self.metric.norm(point) expected = gs.linalg.norm(point) expected = helper.to_scalar(expected) with self.test_session(): self.assertAllClose(gs.eval(result), gs.eval(expected))
def test_inverse(self): mat = tf.convert_to_tensor([[1., 2., 3.], [4., 5., 6.], [7., 8., 10.]]) result = self.group.inverse(mat) expected = 1. / 3. * tf.convert_to_tensor( [[-2., -4., 3.], [-2., 11., -6.], [3., -6., 3.]]) expected = helper.to_matrix(expected) with self.test_session(): self.assertAllClose(gs.eval(result), gs.eval(expected))
def test_dist(self): point_a = tf.convert_to_tensor([0., 1.]) point_b = tf.convert_to_tensor([2., 10.]) result = self.metric.dist(point_a, point_b) expected = gs.linalg.norm(point_b - point_a) expected = helper.to_scalar(expected) with self.test_session(): self.assertAllClose(gs.eval(result), gs.eval(expected))
def test_inner_product(self): point_a = tf.convert_to_tensor([0., 1.]) point_b = tf.convert_to_tensor([2., 10.]) result = self.metric.inner_product(point_a, point_b) expected = gs.dot(point_a, point_b) expected = helper.to_scalar(expected) with self.test_session(): self.assertAllClose(gs.eval(result), gs.eval(expected))
def test_squared_dist(self): point_a = tf.convert_to_tensor([-1., 4.]) point_b = tf.convert_to_tensor([1., 1.]) result = self.metric.squared_dist(point_a, point_b) vec = point_b - point_a expected = gs.dot(vec, vec) expected = helper.to_scalar(expected) with self.test_session(): self.assertAllClose(gs.eval(result), gs.eval(expected))
def test_squared_dist(self): point_a = tf.convert_to_tensor([2., -math.sqrt(3)]) point_b = tf.convert_to_tensor([4.0, math.sqrt(15)]) result = self.metric.squared_dist(point_a, point_b) vec = point_b - point_a expected = gs.dot(vec, vec) expected -= 2 * vec[self.time_like_dim] * vec[self.time_like_dim] expected = helper.to_scalar(expected) with self.test_session(): self.assertAllClose(gs.eval(result), gs.eval(expected))
def test_variance(self): points = tf.convert_to_tensor([[1., 0.], [2., math.sqrt(3)], [3., math.sqrt(8)], [4., math.sqrt(24)]]) weights = tf.convert_to_tensor([1., 2., 1., 2.]) base_point = tf.convert_to_tensor([-1., 0.]) result = self.metric.variance(points, weights, base_point) # we expect the average of the points' Minkowski sq norms. expected = helper.to_scalar(tf.convert_to_tensor([True])) with self.test_session(): self.assertAllClose(gs.eval(result) != 0, gs.eval(expected))
def test_dist_point_and_itself(self): # Distance between a point and itself is 0 point_a = (1. / gs.sqrt(129.) * tf.convert_to_tensor([10., -2., -5., 0., 0.])) point_b = point_a result = self.metric.dist(point_a, point_b) expected = 0. expected = helper.to_scalar(expected) with self.test_session(): self.assertAllClose(gs.eval(result), gs.eval(expected))
def test_variance(self): points = tf.convert_to_tensor([[1., 2.], [2., 3.], [3., 4.], [4., 5.]]) weights = tf.convert_to_tensor([1., 2., 1., 2.]) base_point = gs.zeros(2) result = self.metric.variance(points, weights, base_point) # we expect the average of the points' sq norms. expected = (1 * 5. + 2 * 13. + 1 * 25. + 2 * 41.) / 6. expected = helper.to_scalar(expected) with self.test_session(): self.assertAllClose(gs.eval(result), gs.eval(expected))