Source code for pymanopt.tools.testing

"""Tools for testing numerical correctness in Pymanopt.

Note:
    The functions :func:`rgrad`, :func:`euclidean_to_riemannian_gradient`,
    :func:`ehess` and :func:`euclidean_to_riemannian_hessian` will only be
    correct if the manifold is a submanifold of Euclidean space, that is if the
    projection is an orthogonal projection onto the tangent space.
"""

import numpy as np
from autograd import grad, jacobian


[docs]def riemannian_gradient(cost, projector): """Generates the Riemannian gradient of a cost function.""" def gradient_function(point): return projector(point, grad(cost)(point)) return gradient_function
[docs]def euclidean_to_riemannian_gradient(projector): """Generates an euclidean_to_riemannian_gradient function.""" def converter(point, euclidean_gradient): return projector(point, euclidean_gradient) return converter
[docs]def euclidean_to_riemannian_hessian(projector): """Generates an euclidean_to_riemannian_hessian function. Specifically, ``euclidean_to_riemannian_hessian(proj)(point, euclidean_gradient, euclidean_hessian, tangent_vector)`` converts the Euclidean Hessian-vector product ``euclidean_hessian`` at a point ``point`` to a Riemannian Hessian-vector product, i.e., the directional derivative of the gradient in the tangent direction ``tangent_vector``. Similar to :func:`riemannian_hessian`, this is not efficient as it computes the Jacobian explicitly. """ jacobian_projector = jacobian(projector) def converter( point, euclidean_gradient, euclidean_hessian, tangent_vector ): return projector( point, euclidean_hessian + np.tensordot( jacobian_projector(point, euclidean_gradient), tangent_vector, axes=tangent_vector.ndim, ), ) return converter