def curvature_at_identity( self, tangent_vec_a, tangent_vec_b, tangent_vec_c): r"""Compute the curvature at identity. For three tangent vectors at identity :math: `x,y,z`, the curvature is defined by :math: `R(x, y)z = \nabla_{[x,y]}z - \nabla_x\nabla_y z + - \nabla_y\nabla_x z`. Parameters ---------- tangent_vec_a : array-like, shape=[..., n, n] Tangent vector at identity. tangent_vec_b : array-like, shape=[..., n, n] Tangent vector at identity. tangent_vec_c : array-like, shape=[..., n, n] Tangent vector at identity. Returns ------- curvature : array-like, shape=[..., n, n] Tangent vector at identity. """ bracket = GeneralLinear.bracket(tangent_vec_a, tangent_vec_b) bracket_term = self.connection_at_identity(bracket, tangent_vec_c) left_term = self.connection_at_identity( tangent_vec_a, self.connection_at_identity( tangent_vec_b, tangent_vec_c)) right_term = self.connection_at_identity( tangent_vec_b, self.connection_at_identity( tangent_vec_a, tangent_vec_c)) return bracket_term - left_term + right_term
def connection_at_identity(self, tangent_vec_a, tangent_vec_b): r"""Compute the Levi-Civita connection at identity. For two tangent vectors at identity :math: `x,y`, one can associate left (respectively right) invariant vector fields :math: `\tilde{x}, \tilde{y}`. Then the vector :math: `(\nabla_\tilde{x}(\tilde{x}))_{ Id}` is computed using the lie bracket and the dual adjoint map. This is a bilinear map that characterizes the connection [Gallier]_. Parameters ---------- tangent_vec_a : array-like, shape=[..., n, n] Tangent vector at identity. tangent_vec_b : array-like, shape=[..., n, n] Tangent vector at identity. Returns ------- nabla : array-like, shape=[..., n, n] Tangent vector at identity. References ---------- .. [Gallier] Gallier, Jean, and Jocelyn Quaintance. Differential Geometry and Lie Groups: A Computational Perspective. Geonger International Publishing, 2020. https://doi.org/10.1007/978-3-030-46040-2. """ sign = 1. if self.left_or_right == 'left' else -1. return sign / 2 * (GeneralLinear.bracket(tangent_vec_a, tangent_vec_b) - self.dual_adjoint(tangent_vec_a, tangent_vec_b) - self.dual_adjoint(tangent_vec_b, tangent_vec_a))
def structure_constant(self, tangent_vec_a, tangent_vec_b, tangent_vec_c): r"""Compute the structure constant of the metric. For three tangent vectors :math: `x, y, z` at identity, compute :math: `<[x,y], z>`. Parameters ---------- tangent_vec_a : array-like, shape=[..., n, n] Tangent vector at identity. tangent_vec_b : array-like, shape=[..., n, n] Tangent vector at identity. tangent_vec_c : array-like, shape=[..., n, n] Tangent vector at identity. Returns ------- structure_constant : array-like, shape=[...,] """ bracket = GeneralLinear.bracket(tangent_vec_a, tangent_vec_b) return self.inner_product_at_identity(bracket, tangent_vec_c)
def connection_at_identity(self, tangent_vec_a, tangent_vec_b): r"""Compute the Levi-Civita connection at identity. For two tangent vectors at identity :math: `x,y`, one can associate left (respectively right) invariant vector fields :math: `\tilde{x}, \tilde{y}`. Then the vector :math: `(\nabla_\tilde{x}(\tilde{x}))_{ Id}` is computed using the lie bracket and the dual adjoint map. This is a bilinear map that characterizes the connection. Parameters ---------- tangent_vec_a : array-like, shape=[..., dim] Tangent vector at identity. tangent_vec_b : array-like, shape=[..., dim] Tangent vector at identity. Returns ------- nabla : array-like, shape=[..., dim] Tangent vector at identity. """ return 1. / 2 * (GeneralLinear.bracket(tangent_vec_a, tangent_vec_b) - self.dual_adjoint(tangent_vec_a, tangent_vec_b) - self.dual_adjoint(tangent_vec_b, tangent_vec_a))