function ehess = essential_ehessE2ehess(X, egradE, ehessE, S)
% Converts the Hessian in essential matrix E to the Hessian in X.
%
% function ehess = essential_ehessE2ehess(X, egradE, ehessE, S)
%
% egradE is the function handle for the gradient in E.
% ehessE is the function handle for the Hessian in E.
% S is the search direction in the space of X.
%
% The output is a matrix in the space of X.
%
% See also: essential_costE2cost essential_egradE2egrad


% This file is part of Manopt: www.manopt.org.
% Original author: Roberto Tron, Aug. 8, 2014
% Contributors: Bamdev Mishra, May 22, 2015.
   
   e3hat = [0 -1 0; 1 0 0; 0 0 0];
    
    RA = X(:,1:3,:); 
    RB = X(:,4:6,:);
    E = multiprod(multiprod(multitransp(RA), e3hat), RB); % M.E(X);
    G =  egradE(E); 
    
    V = essential_sharp(multiprod(essential_flat(X), essential_flat(S)));
    VA = V(:,1:3,:);
    VB = V(:,4:6,:);
    
    dE = multiprod(multiprod(multitransp(RA), e3hat), VB)...
        + multiprod(multiprod(multitransp(VA), e3hat), RB);
    dG = ehessE(E, dE);
    
    %The following is the vectorized version of ehess = e3hat*[(VB*G'+RB*H') -(VA*G+RA*H)]
    ehess = multiprod(e3hat,cat(2,...
        multiprod(VB, multitransp(G)) + multiprod(RB, multitransp(dG)),...
            -multiprod(VA, G) - multiprod(RA, dG)));
    
end