Basic usage
You can calculate Riemannian gradient of a function defined in its embedding in multiple ways. DifferentiationInterface.jl
can be used to select the backend.
using ManifoldDiff
using DifferentiationInterface
using Manifolds, FiniteDifferences, ForwardDiff, Zygote
rb_onb_fd51 = TangentDiffBackend(AutoFiniteDifferences(central_fdm(5, 1)))
rb_onb_fwdd = TangentDiffBackend(AutoForwardDiff())
rb_proj_zyg = RiemannianProjectionBackend(AutoZygote())
s2 = Sphere(2)
A = [1.0 2.0 5.0; 2.0 -1.0 4.0; 5.0 4.0 0.0]
f(p) = p' * A * p
q = [0.0, 1.0, 0.0]
println(ManifoldDiff.gradient(s2, f, q, rb_onb_fd51))
println(ManifoldDiff.gradient(s2, f, q, rb_onb_fwdd))
println(ManifoldDiff.gradient(s2, f, q, rb_proj_zyg))
[3.999999999999511, 0.0, 7.999999999999624]
[4.0, 0.0, 8.0]
[4.0, 0.0, 8.0]
In this example rb_onb_fd51
corresponds to a finite differencing scheme, rb_onb_fwdd
calculates gradient using ForwardDiff.jl
and rb_proj_zyg
uses Zygote.jl
for reverse mode automatic differentiation.
TangentDiffBackend
reduces dimensionality of the problem to the intrinsic dimension of the manifold, while RiemannianProjectionBackend
relies on converting Euclidean gradient in the embedding to the Riemannian one.