function M = specialeuclideanfactory(n, k)
% Returns a manifold structure to optimize over the special Euclidean group
% 
% function M = specialeuclideanfactory(n)
% function M = specialeuclideanfactory(n, k)
%
% The special Euclidean group (the manifold of rigid transformations):
% This is a product manifold of the rotations group SO(n) and the
% translation group R^n, copied k times. (See note below.)
%
% Points on the manifold are represented as structures X with two fields.
% X.R is a 3D array of size nxnxk such that each slice X.R(:, :, i)
% corresponds to a rotation matrix (orthogonal with determinant 1).
% X.t is a matrix of size nxk such that each column X.t(:, i) corresponds
% to a translation vector.
%
% Tangent vectors are represented as structures with the same fields. Note
% that rotational components of the tangent vectors are represented in the
% Lie algebra, i.e., each slice Xdot.R(:, :, i) is a skew-symmetric matrix.
% Use M.tangent2ambient(X, Xdot) to obtain a representation in the ambient
% space. This is often necessary when defining problem.ehess(X, Xdot).
%
% This is a description of SE(n)^k with the induced metric from the
% embedding space (R^nxn)^k x (R^n)^k, i.e., this manifold is a Riemannian
% submanifold of the embedding Euclidean space with the usual inner
% product.
%
% By default, k = 1.
%
% Note: this is a product geometry: it may not be the "appropriate"
% geometry to give to SE(n) for your application. In particular, this is
% not the Lie geometry of SE(n), because SE(n) is not a direct product of
% SO(n) and R^n: it is only a semidirect product. Following a comment by
% Martijn Zeestraten on the Manopt forum, see this file for more
% information about the Lie geometry:
%   http://ethaneade.com/lie.pdf
%
% See rotationsfactory and euclideanfactory for details.
%
% See also: rotationsfactory euclideanfactory

% This file is part of Manopt: www.manopt.org.
% Original author: Nicolas Boumal, Sep. 23, 2014.
% Contributors: 
% Change log:

    
    if ~exist('k', 'var') || isempty(k)
        k = 1;
    end
    
    elements = struct();
    elements.R = rotationsfactory(n, k);
    elements.t = euclideanfactory(n, k);
    
    M = productmanifold(elements);

end
