As is, Manopt will approximate the Hessian with finite differences, automatically, if the Hessian is not provided by the user. Typically, this works quite nicely. In your code, when you call trustregions, this is what happens under the hood.
This being said, if you want to provide the Hessian in closed form as well, the easiest way is to provide the Euclidean Hessian. Then, problem.ehess = @ehess, where ehess is a function of 2 inputs: X, a structure containing R and t, is the root point; and Xdot is a structure with also fields R and t, which are the directions in which X.R moves and X.t move. To obtain expressions for the output, say H, also a structure with fields R and t, you need to compute the directional derivatives of G.R and G.t (the gradient) when moving in the direction Xdot.R and Xdot.t. See
http://www.manopt.org/manifold_documentation_rotations.html for how to deal with the rotations, in particular.
(There is some subtlety with how tangent vectors are represented, as skew-symmetric matrices. In particular, you probably want to start the code in ehess with "Xdot = problem.M.tangent2ambient(X, Xdot);")
The code is below.
That is not included, unfortunately. This is part of a bigger missing feature: to have automatic differentiation.
I would also like to provide some uncertainty measurements. If I consider my measurements V as a random variable, I can consider the reconstruction also as a random variable. I want to estimate the variance of the reconstruction given the variance of V.
This exceeds Manopt's purposes, as it becomes quite specific to the particular problem at hand. One simple way of estimating the variance though is as follows:
* for repeated realizations of the random noise variable
* compute the estimator X_estim
* compute the error vector: E = problem.M.log(X_true, X_estim)
Average the error vectors E over the repetitions to estimate the bias (a tangent vector at X_true) ; remove the bias, then average the norms of estimate the variance. More about bias and variance on manifolds can be found here:
(Ref. 2 focuses on rotations.)
Best,
Nicolas
function [I]=foo(U,V)
n=size(U,2);
problem.M=specialeuclideanfactory(3);
% Residual
res = @(X) X.R*U + X.t*ones(1,n)-V;
% Cost function
problem.cost=@(X) .5*norm(res(X), 'fro')^2;
% Gradient
problem.egrad = @egrad;
function G=egrad(X)
r = res(X);
G.R = r*U';
G.t = sum(r, 2);
end
% Hessian
problem.ehess = @ehess;
function H = ehess(X, Xdot)
Xdot = problem.M.tangent2ambient(X, Xdot);
dres = Xdot.R*U + Xdot.t*ones(1,n);
H.R = dres*U';
H.t = sum(dres, 2);
end
% checkgradient(problem); pause;
% checkhessian(problem); pause;