Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
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_exp_and_dist_and_projection_to_tangent_space_vec(self):
with self.test_session():
base_point = gs.array([[16., -2., -2.5, 84., 3.],
[16., -2., -2.5, 84., 3.]])
base_single_point = gs.array([16., -2., -2.5, 84., 3.])
scalar_norm = gs.linalg.norm(base_single_point)
base_point = base_point / scalar_norm
vector = gs.array([[9., 0., -1., -2., 1.], [9., 0., -1., -2., 1]])
tangent_vec = self.space.projection_to_tangent_space(
vector=vector,
base_point=base_point)
exp = self.metric.exp(tangent_vec=tangent_vec,
base_point=base_point)
result = self.metric.dist(base_point, exp)
expected = gs.linalg.norm(tangent_vec, axis=-1) % (2 * gs.pi)
expected = helper.to_scalar(expected)
self.assertAllClose(gs.eval(result), gs.eval(expected))
# Riemannian Exp then Riemannian Log
# General case
# NB: Riemannian log gives a regularized tangent vector,
# so we take the norm modulo 2 * pi.
base_point = gs.array([0., -3., 0., 3., 4.])
base_point = base_point / gs.linalg.norm(base_point)
vector = gs.array([9., 5., 0., 0., -1.])
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 = vector
norm_expected = gs.linalg.norm(expected)
regularized_norm_expected = gs.mod(norm_expected, 2 * gs.pi)
expected = expected / norm_expected * regularized_norm_expected
expected = helper.to_vector(expected)
# TODO(nina): this test fails
rot_vec_3 = 1e-11 * gs.array([12., 1., -81.])
angle = gs.linalg.norm(rot_vec_3)
skew_rot_vec_3 = 1e-11 * gs.array([[0., 81., 1.],
[-81., 0., -12.],
[-1., 12., 0.]])
coef_1 = gs.sin(angle) / angle
coef_2 = (1 - gs.cos(angle)) / (angle ** 2)
expected_rot_mat_3 = (gs.identity(3)
+ coef_1 * skew_rot_vec_3
+ coef_2 * gs.dot(skew_rot_vec_3,
skew_rot_vec_3))
rot_mat_3 = group.matrix_from_rotation_vector(rot_vec_3)
self.assertTrue(gs.allclose(rot_mat_3, expected_rot_mat_3))
rot_vec_6 = gs.array([.1, 1.3, -.5])
angle = gs.linalg.norm(rot_vec_6)
skew_rot_vec_6 = gs.array([[0., .5, 1.3],
[-.5, 0., -.1],
[-1.3, .1, 0.]])
coef_1 = gs.sin(angle) / angle
coef_2 = (1 - gs.cos(angle)) / (angle ** 2)
rot_mat_6 = group.matrix_from_rotation_vector(rot_vec_6)
expected_rot_mat_6 = (gs.identity(3)
+ coef_1 * skew_rot_vec_6
+ coef_2 * gs.dot(skew_rot_vec_6,
skew_rot_vec_6))
self.assertTrue(gs.allclose(rot_mat_6, expected_rot_mat_6))
# Riemannian Exp then Riemannian Log
# General case
# NB: Riemannian log gives a regularized tangent vector,
# so we take the norm modulo 2 * pi.
base_point = gs.array([0., -3., 0., 3., 4.])
base_point = base_point / gs.linalg.norm(base_point)
vector = gs.array([9., 5., 0., 0., -1.])
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 = vector
norm_expected = gs.linalg.norm(expected)
regularized_norm_expected = gs.mod(norm_expected, 2 * gs.pi)
expected = expected / norm_expected * regularized_norm_expected
expected = helper.to_vector(expected)
# TODO(nina): this test fails
iteration = 0
grad_norm = 0.
while iteration < max_iter:
if not (grad_norm > epsilon or iteration == 0):
break
inv_mean = group.inverse(mean)
centered_points = group.compose(inv_mean, points)
logs = group.log(point=centered_points)
tangent_mean = step * gs.einsum(
'n, nk...->k...', weights / sum_weights, logs)
mean_next = group.compose(
mean,
group.exp(tangent_vec=tangent_mean))
grad_norm = gs.linalg.norm(tangent_mean)
sq_dists_between_iterates.append(grad_norm)
mean = mean_next
iteration += 1
if iteration == max_iter:
logging.warning(
'Maximum number of iterations {} reached. '
'The mean may be inaccurate'.format(max_iter))
if verbose:
logging.info(
'n_iter: {}, final gradient norm: {}'.format(iteration, grad_norm))
return mean
Convert from the intrinsic coordinates in the hypersphere,
to the extrinsic coordinates in Euclidean space.
Parameters
----------
point_intrinsic : array-like, shape=[..., dim]
Point on the hypersphere, in intrinsic coordinates.
Returns
-------
point_extrinsic : array-like, shape=[..., dim + 1]
Point on the hypersphere, in extrinsic coordinates in
Euclidean space.
"""
sq_coord_0 = 1. - gs.linalg.norm(point_intrinsic, axis=-1) ** 2
if gs.any(gs.less(sq_coord_0, 0.)):
raise ValueError('Square-root of a negative number.')
coord_0 = gs.sqrt(sq_coord_0)
coord_0 = gs.to_ndarray(coord_0, to_ndim=2, axis=-1)
point_extrinsic = gs.concatenate([coord_0, point_intrinsic], axis=-1)
return point_extrinsic
def quaternion_from_rotation_vector(self, rot_vec):
"""
Convert a rotation vector into a unit quaternion.
"""
assert self.n == 3, ('The quaternion representation does not exist'
' for rotations in %d dimensions.' % self.n)
rot_vec = self.regularize(rot_vec, point_type='vector')
n_rot_vecs, _ = rot_vec.shape
angle = gs.linalg.norm(rot_vec, axis=1)
angle = gs.to_ndarray(angle, to_ndim=2, axis=1)
rotation_axis = gs.zeros_like(rot_vec)
mask_0 = gs.isclose(angle, 0.)
mask_0 = gs.squeeze(mask_0, axis=1)
mask_not_0 = ~mask_0
rotation_axis[mask_not_0] = rot_vec[mask_not_0] / angle[mask_not_0]
n_quaternions, _ = rot_vec.shape
quaternion = gs.zeros((n_quaternions, 4))
quaternion[:, :1] = gs.cos(angle / 2)
quaternion[:, 1:] = gs.sin(angle / 2) * rotation_axis[:]
return quaternion
def matrix_from_rotation_vector(self, rot_vec):
"""Convert rotation vector to rotation matrix.
Parameters
----------
rot_vec: array-like, shape=[n_samples, 3]
Returns
-------
rot_mat: array-like, shape=[n_samples, 3]
"""
rot_vec = self.regularize(rot_vec)
angle = gs.linalg.norm(rot_vec, axis=1)
angle = gs.to_ndarray(angle, to_ndim=2, axis=1)
skew_rot_vec = self.skew_matrix_from_vector(rot_vec)
coef_1 = gs.zeros_like(angle)
coef_2 = gs.zeros_like(angle)
# This avoids dividing by 0.
mask_0 = gs.isclose(angle, 0.)
mask_0_float = gs.cast(mask_0, gs.float32) + self.epsilon
coef_1 += mask_0_float * (1. - (angle ** 2) / 6.)
coef_2 += mask_0_float * (1. / 2. - angle ** 2)
# This avoids dividing by 0.
mask_else = ~mask_0
def convert_to_klein_coordinates(points):
poincare_coords = points[:, 1:] / (1 + points[:, :1])
poincare_radius = gs.linalg.norm(
poincare_coords, axis=1)
poincare_angle = gs.arctan2(
poincare_coords[:, 1], poincare_coords[:, 0])
klein_radius = 2 * poincare_radius / (1 + poincare_radius ** 2)
klein_angle = poincare_angle
coords_0 = gs.expand_dims(
klein_radius * gs.cos(klein_angle), axis=1)
coords_1 = gs.expand_dims(
klein_radius * gs.sin(klein_angle), axis=1)
klein_coords = gs.concatenate([coords_0, coords_1], axis=1)
return klein_coords