def log(self, point, base_point, **kwargs): """Compute the Cholesky logarithm map. Compute the Riemannian logarithm at point base_point, of point wrt the Cholesky metric. This gives a tangent vector at point base_point. Parameters ---------- point : array-like, shape=[..., n, n] Point. base_point : array-like, shape=[..., n, n] Base point. Returns ------- log : array-like, shape=[..., n, n] Riemannian logarithm. """ sl_base_point = Matrices.to_strictly_lower_triangular(base_point) sl_point = Matrices.to_strictly_lower_triangular(point) diag_base_point = Matrices.diagonal(base_point) diag_point = Matrices.diagonal(point) diag_product_logm = gs.log(gs.divide(diag_point, diag_base_point)) sl_log = sl_point - sl_base_point diag_log = gs.vec_to_diag(diag_base_point * diag_product_logm) log = sl_log + diag_log return log
def squared_dist(self, point_a, point_b, **kwargs): """Compute the Cholesky Metric squared distance. Compute the Riemannian squared distance between point_a and point_b. Parameters ---------- point_a : array-like, shape=[..., n, n] Point. point_b : array-like, shape=[..., n, n] Point. Returns ------- _ : array-like, shape=[...] Riemannian squared distance. """ log_diag_a = gs.log(Matrices.diagonal(point_a)) log_diag_b = gs.log(Matrices.diagonal(point_b)) diag_diff = log_diag_a - log_diag_b squared_dist_diag = gs.sum((diag_diff) ** 2, axis=-1) sl_a = Matrices.to_strictly_lower_triangular(point_a) sl_b = Matrices.to_strictly_lower_triangular(point_b) sl_diff = sl_a - sl_b squared_dist_sl = Matrices.frobenius_product(sl_diff, sl_diff) return squared_dist_sl + squared_dist_diag
def exp(self, tangent_vec, base_point, **kwargs): """Compute the Cholesky exponential map. Compute the Riemannian exponential at point base_point of tangent vector tangent_vec wrt the Cholesky metric. This gives a lower triangular matrix with positive elements. Parameters ---------- tangent_vec : array-like, shape=[..., n, n] Tangent vector at base point. base_point : array-like, shape=[..., n, n] Base point. Returns ------- exp : array-like, shape=[..., n, n] Riemannian exponential. """ sl_base_point = Matrices.to_strictly_lower_triangular(base_point) sl_tangent_vec = Matrices.to_strictly_lower_triangular(tangent_vec) diag_base_point = Matrices.diagonal(base_point) diag_tangent_vec = Matrices.diagonal(tangent_vec) diag_product_expm = gs.exp(gs.divide(diag_tangent_vec, diag_base_point)) sl_exp = sl_base_point + sl_tangent_vec diag_exp = gs.vec_to_diag(diag_base_point * diag_product_expm) exp = sl_exp + diag_exp return exp