// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
// Copyright (C) 2009 Benoit Jacob <jacob.benoit.1@gmail.com>
// Copyright (C) 2010 Hauke Heibel <hauke.heibel@gmail.com>
//
// This Source Code Form is subject to the terms of the Mozilla
// Public License v. 2.0. If a copy of the MPL was not distributed
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
// SPDX-License-Identifier: MPL-2.0

#ifndef EIGEN_TRANSFORM_H
#define EIGEN_TRANSFORM_H

// IWYU pragma: private
#include "./InternalHeaderCheck.h"

namespace Eigen {

namespace internal {

template <typename Transform>
struct transform_traits {
  enum {
    Dim = Transform::Dim,
    HDim = Transform::HDim,
    Mode = Transform::Mode,
    IsProjective = (int(Mode) == int(Projective))
  };
};

template <typename TransformType, typename MatrixType,
          int Case = transform_traits<TransformType>::IsProjective                                      ? 0
                     : int(MatrixType::RowsAtCompileTime) == int(transform_traits<TransformType>::HDim) ? 1
                                                                                                        : 2,
          int RhsCols = MatrixType::ColsAtCompileTime>
struct transform_right_product_impl;

template <typename Other, int Mode, int Options, int Dim, int HDim, int OtherRows = Other::RowsAtCompileTime,
          int OtherCols = Other::ColsAtCompileTime>
struct transform_left_product_impl;

template <typename Lhs, typename Rhs,
          bool AnyProjective = transform_traits<Lhs>::IsProjective || transform_traits<Rhs>::IsProjective>
struct transform_transform_product_impl;

template <typename Other, int Mode, int Options, int Dim, int HDim, int OtherRows = Other::RowsAtCompileTime,
          int OtherCols = Other::ColsAtCompileTime>
struct transform_construct_from_matrix;

template <typename TransformType>
struct transform_take_affine_part;

template <typename Scalar_, int Dim_, int Mode_, int Options_>
struct traits<Transform<Scalar_, Dim_, Mode_, Options_> > {
  using Scalar = Scalar_;
  using StorageIndex = Eigen::Index;
  using StorageKind = Dense;
  enum {
    Dim1 = Dim_ == Dynamic ? Dim_ : Dim_ + 1,
    RowsAtCompileTime = Mode_ == Projective ? Dim1 : Dim_,
    ColsAtCompileTime = Dim1,
    MaxRowsAtCompileTime = RowsAtCompileTime,
    MaxColsAtCompileTime = ColsAtCompileTime,
    Flags = 0
  };
};

template <int Mode>
struct transform_make_affine;

}  // end namespace internal

/** \geometry_module \ingroup Geometry_Module
 *
 * \class Transform
 *
 * \brief Represents an homogeneous transformation in a N dimensional space
 *
 * \tparam Scalar_ the scalar type, i.e., the type of the coefficients
 * \tparam Dim_ the dimension of the space
 * \tparam Mode_ the type of the transformation. Can be:
 *              - #Affine: the transformation is stored as a (Dim+1)^2 matrix,
 *                         where the last row is assumed to be [0 ... 0 1].
 *              - #AffineCompact: the transformation is stored as a (Dim)x(Dim+1) matrix.
 *              - #Projective: the transformation is stored as a (Dim+1)^2 matrix
 *                             without any assumption.
 *              - #Isometry: same as #Affine with the additional assumption that
 *                           the linear part represents a rotation. This assumption is exploited
 *                           to speed up some functions such as inverse() and rotation().
 * \tparam Options_ has the same meaning as in class Matrix. It allows to specify DontAlign and/or RowMajor.
 *                  These Options are passed directly to the underlying matrix type.
 *
 * The homography is internally represented and stored by a matrix which
 * is available through the matrix() method. To understand the behavior of
 * this class you have to think a Transform object as its internal
 * matrix representation. The chosen convention is right multiply:
 *
 * \code v' = T * v \endcode
 *
 * Therefore, an affine transformation matrix M is shaped like this:
 *
 * \f$ \left( \begin{array}{cc}
 * linear & translation\\
 * 0 ... 0 & 1
 * \end{array} \right) \f$
 *
 * Note that for a projective transformation the last row can be anything,
 * and then the interpretation of different parts might be slightly different.
 *
 * However, unlike a plain matrix, the Transform class provides many features
 * simplifying both its assembly and usage. In particular, it can be composed
 * with any other transformations (Transform,Translation,RotationBase,DiagonalMatrix)
 * and can be directly used to transform implicit homogeneous vectors. All these
 * operations are handled via the operator*. For the composition of transformations,
 * its principle consists to first convert the right/left hand sides of the product
 * to a compatible (Dim+1)^2 matrix and then perform a pure matrix product.
 * Of course, internally, operator* tries to perform the minimal number of operations
 * according to the nature of each term. Likewise, when applying the transform
 * to points, the latter are automatically promoted to homogeneous vectors
 * before doing the matrix product. The conventions to homogeneous representations
 * are performed as follow:
 *
 * \b Translation t (Dim)x(1):
 * \f$ \left( \begin{array}{cc}
 * I & t \\
 * 0\,...\,0 & 1
 * \end{array} \right) \f$
 *
 * \b Rotation R (Dim)x(Dim):
 * \f$ \left( \begin{array}{cc}
 * R & 0\\
 * 0\,...\,0 & 1
 * \end{array} \right) \f$
 *<!--
 * \b Linear \b Matrix L (Dim)x(Dim):
 * \f$ \left( \begin{array}{cc}
 * L & 0\\
 * 0\,...\,0 & 1
 * \end{array} \right) \f$
 *
 * \b Affine \b Matrix A (Dim)x(Dim+1):
 * \f$ \left( \begin{array}{c}
 * A\\
 * 0\,...\,0\,1
 * \end{array} \right) \f$
 *-->
 * \b Scaling \b DiagonalMatrix S (Dim)x(Dim):
 * \f$ \left( \begin{array}{cc}
 * S & 0\\
 * 0\,...\,0 & 1
 * \end{array} \right) \f$
 *
 * \b Column \b point v (Dim)x(1):
 * \f$ \left( \begin{array}{c}
 * v\\
 * 1
 * \end{array} \right) \f$
 *
 * \b Set \b of \b column \b points V1...Vn (Dim)x(n):
 * \f$ \left( \begin{array}{ccc}
 * v_1 & ... & v_n\\
 * 1 & ... & 1
 * \end{array} \right) \f$
 *
 * The concatenation of a Transform object with any kind of other transformation
 * always returns a Transform object.
 *
 * A little exception to the "as pure matrix product" rule is the case of the
 * transformation of non homogeneous vectors by an affine transformation. In
 * that case the last matrix row can be ignored, and the product returns non
 * homogeneous vectors.
 *
 * In particular, a Dim x Dim matrix on the right-hand side of a Transform is not
 * interpreted as a linear transformation: like any Dim x n matrix, its columns are
 * transformed as points, so that for Mode!=Projective, T*m returns the Dim x Dim matrix
 * (T.linear()*m).colwise() + T.translation(). A Dim x Dim matrix is interpreted as a linear
 * transformation in the other direction of the product, and when it is assigned to a Transform,
 * passed to a Transform constructor, or given to rotate()/prerotate().
 * To obtain the result in homogeneous coordinates, make the points homogeneous explicitly:
 * \code
 * m' = T * m.colwise().homogeneous();
 * \endcode
 * Note that there is zero overhead.
 *
 * Conversion methods from/to Qt's QMatrix and QTransform are available if the
 * preprocessor token EIGEN_QT_SUPPORT is defined.
 *
 * This class can be extended with the help of the plugin mechanism described on the page
 * \ref TopicCustomizing_Plugins by defining the preprocessor symbol \c EIGEN_TRANSFORM_PLUGIN.
 *
 * \sa class Matrix, class Quaternion
 */
template <typename Scalar_, int Dim_, int Mode_, int Options_>
class Transform {
 public:
  EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF_VECTORIZABLE_FIXED_SIZE(Scalar_,
                                                             Dim_ == Dynamic ? Dynamic : (Dim_ + 1) * (Dim_ + 1))
  enum {
    Mode = Mode_,
    Options = Options_,
    Dim = Dim_,       ///< space dimension in which the transformation holds
    HDim = Dim_ + 1,  ///< size of a respective homogeneous vector
    Rows = int(Mode) == int(AffineCompact) ? Dim : HDim
  };
  /** the scalar type of the coefficients */
  using Scalar = Scalar_;
  using StorageIndex = Eigen::Index;
  using Index = Eigen::Index;  ///< \deprecated since Eigen 3.3
  /** type of the matrix used to represent the transformation */
  using MatrixType = typename internal::make_proper_matrix_type<Scalar, Rows, HDim, Options>::type;
  /** constified MatrixType */
  using ConstMatrixType = const MatrixType;
  /** type of the matrix used to represent the linear part of the transformation */
  using LinearMatrixType = Matrix<Scalar, Dim, Dim, Options>;
  /** type of read/write reference to the linear part of the transformation */
  using LinearPart = Block<MatrixType, Dim, Dim, int(Mode) == (AffineCompact) && (int(Options) & RowMajor) == 0>;
  /** type of read reference to the linear part of the transformation */
  using ConstLinearPart =
      const Block<ConstMatrixType, Dim, Dim, int(Mode) == (AffineCompact) && (int(Options) & RowMajor) == 0>;
  /** type of read/write reference to the affine part of the transformation */
  using AffinePart = std::conditional_t<int(Mode) == int(AffineCompact), MatrixType&, Block<MatrixType, Dim, HDim>>;
  /** type of read reference to the affine part of the transformation */
  using ConstAffinePart =
      std::conditional_t<int(Mode) == int(AffineCompact), const MatrixType&, const Block<const MatrixType, Dim, HDim>>;
  /** type of a vector */
  using VectorType = Matrix<Scalar, Dim, 1>;
  /** type of a read/write reference to the translation part of the rotation */
  using TranslationPart = Block<MatrixType, Dim, 1, !(internal::traits<MatrixType>::Flags & RowMajorBit)>;
  /** type of a read reference to the translation part of the rotation */
  using ConstTranslationPart =
      const Block<ConstMatrixType, Dim, 1, !(internal::traits<MatrixType>::Flags & RowMajorBit)>;
  /** corresponding translation type */
  using TranslationType = Translation<Scalar, Dim>;

  /** The return type of the product between a diagonal matrix and a transform */
  using TransformTimeDiagonalReturnType = Transform<Scalar, Dim, (Mode == int(Isometry)) ? int(Affine) : int(Mode)>;

 protected:
  MatrixType m_matrix;

 public:
  /** Default constructor without initialization of the meaningful coefficients.
   * If Mode==Affine or Mode==Isometry, then the last row is set to [0 ... 0 1] */
  EIGEN_DEVICE_FUNC inline Transform() {
    check_template_params();
    internal::transform_make_affine<(int(Mode) == Affine || int(Mode) == Isometry) ? Affine : AffineCompact>::run(
        m_matrix);
  }

  // These conversion ctors are intentionally `explicit`: keeping copy-init
  // (`Transform t = rot;`) from compiling stops a Dim+1 x Dim+1 matrix
  // from being silently materialized in function-call argument lists.
  // Use direct-init (`Transform t(rot);`) or assignment (`Transform t; t = rot;`)
  // instead. See bug #1209.
  EIGEN_DEVICE_FUNC inline explicit Transform(const TranslationType& t) {
    check_template_params();
    *this = t;
  }
  EIGEN_DEVICE_FUNC inline explicit Transform(const UniformScaling<Scalar>& s) {
    check_template_params();
    *this = s;
  }
  template <typename Derived>
  EIGEN_DEVICE_FUNC inline explicit Transform(const RotationBase<Derived, Dim>& r) {
    check_template_params();
    *this = r;
  }

  using take_affine_part = internal::transform_take_affine_part<Transform>;

  /** Constructs and initializes a transformation from a Dim^2 or a (Dim+1)^2 matrix. */
  template <typename OtherDerived>
  EIGEN_DEVICE_FUNC inline explicit Transform(const EigenBase<OtherDerived>& other) {
    EIGEN_STATIC_ASSERT(
        (std::is_same<Scalar, typename OtherDerived::Scalar>::value),
        YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY);

    check_template_params();
    internal::transform_construct_from_matrix<OtherDerived, Mode, Options, Dim, HDim>::run(this, other.derived());
  }

  /** Set \c *this from a Dim^2 or (Dim+1)^2 matrix. */
  template <typename OtherDerived>
  EIGEN_DEVICE_FUNC inline Transform& operator=(const EigenBase<OtherDerived>& other) {
    EIGEN_STATIC_ASSERT(
        (std::is_same<Scalar, typename OtherDerived::Scalar>::value),
        YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY);

    internal::transform_construct_from_matrix<OtherDerived, Mode, Options, Dim, HDim>::run(this, other.derived());
    return *this;
  }

  template <int OtherOptions>
  EIGEN_DEVICE_FUNC inline Transform(const Transform<Scalar, Dim, Mode, OtherOptions>& other) {
    check_template_params();
    // only the options change, we can directly copy the matrices
    m_matrix = other.matrix();
  }

  template <int OtherMode, int OtherOptions>
  EIGEN_DEVICE_FUNC inline Transform(const Transform<Scalar, Dim, OtherMode, OtherOptions>& other) {
    check_template_params();
    // prevent conversions as:
    // Affine | AffineCompact | Isometry = Projective
    EIGEN_STATIC_ASSERT(internal::check_implication(OtherMode == int(Projective), Mode == int(Projective)),
                        YOU_PERFORMED_AN_INVALID_TRANSFORMATION_CONVERSION)

    // prevent conversions as:
    // Isometry = Affine | AffineCompact
    EIGEN_STATIC_ASSERT(
        internal::check_implication(OtherMode == int(Affine) || OtherMode == int(AffineCompact), Mode != int(Isometry)),
        YOU_PERFORMED_AN_INVALID_TRANSFORMATION_CONVERSION)

    enum {
      ModeIsAffineCompact = Mode == int(AffineCompact),
      OtherModeIsAffineCompact = OtherMode == int(AffineCompact)
    };

    if (EIGEN_CONST_CONDITIONAL(ModeIsAffineCompact == OtherModeIsAffineCompact)) {
      // We need the block expression because the code is compiled for all
      // combinations of transformations and will trigger a compile time error
      // if one tries to assign the matrices directly
      m_matrix.template block<Dim, Dim + 1>(0, 0) = other.matrix().template block<Dim, Dim + 1>(0, 0);
      makeAffine();
    } else if (EIGEN_CONST_CONDITIONAL(OtherModeIsAffineCompact)) {
      using OtherMatrixType = typename Transform<Scalar, Dim, OtherMode, OtherOptions>::MatrixType;
      internal::transform_construct_from_matrix<OtherMatrixType, Mode, Options, Dim, HDim>::run(this, other.matrix());
    } else {
      // here we know that Mode == AffineCompact and OtherMode != AffineCompact.
      // if OtherMode were Projective, the static assert above would already have caught it.
      // So the only possibility is that OtherMode == Affine
      linear() = other.linear();
      translation() = other.translation();
    }
  }

  template <typename OtherDerived>
  EIGEN_DEVICE_FUNC Transform(const ReturnByValue<OtherDerived>& other) {
    check_template_params();
    other.evalTo(*this);
  }

  template <typename OtherDerived>
  EIGEN_DEVICE_FUNC Transform& operator=(const ReturnByValue<OtherDerived>& other) {
    other.evalTo(*this);
    return *this;
  }

#ifdef EIGEN_QT_SUPPORT
#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
  inline Transform(const QMatrix& other);
  inline Transform& operator=(const QMatrix& other);
  inline QMatrix toQMatrix(void) const;
#endif
  inline Transform(const QTransform& other);
  inline Transform& operator=(const QTransform& other);
  inline QTransform toQTransform(void) const;
#endif

  EIGEN_DEVICE_FUNC constexpr Index rows() const noexcept {
    return int(Mode) == int(Projective) ? m_matrix.cols() : (m_matrix.cols() - 1);
  }
  EIGEN_DEVICE_FUNC constexpr Index cols() const noexcept { return m_matrix.cols(); }

  /** shortcut for m_matrix(row,col);
   * \sa MatrixBase::operator(Index,Index) const */
  EIGEN_DEVICE_FUNC inline Scalar operator()(Index row, Index col) const { return m_matrix(row, col); }
  /** shortcut for m_matrix(row,col);
   * \sa MatrixBase::operator(Index,Index) */
  EIGEN_DEVICE_FUNC inline Scalar& operator()(Index row, Index col) { return m_matrix(row, col); }

#ifdef EIGEN_MULTIDIMENSIONAL_SUBSCRIPT
  /** shortcut for m_matrix(row,col);
   * \sa MatrixBase::operator(Index,Index) const */
  EIGEN_DEVICE_FUNC inline Scalar operator[](Index row, Index col) const { return m_matrix[row, col]; }
  /** shortcut for m_matrix(row,col);
   * \sa MatrixBase::operator(Index,Index) */
  EIGEN_DEVICE_FUNC inline Scalar& operator[](Index row, Index col) { return m_matrix[row, col]; }
#endif

  /** \returns a read-only expression of the transformation matrix */
  EIGEN_DEVICE_FUNC inline const MatrixType& matrix() const { return m_matrix; }
  /** \returns a writable expression of the transformation matrix */
  EIGEN_DEVICE_FUNC inline MatrixType& matrix() { return m_matrix; }

  /** \returns a read-only expression of the linear part of the transformation */
  EIGEN_DEVICE_FUNC inline ConstLinearPart linear() const { return ConstLinearPart(m_matrix, 0, 0); }
  /** \returns a writable expression of the linear part of the transformation */
  EIGEN_DEVICE_FUNC inline LinearPart linear() { return LinearPart(m_matrix, 0, 0); }

  /** \returns a read-only expression of the Dim x HDim affine part of the transformation */
  EIGEN_DEVICE_FUNC inline ConstAffinePart affine() const { return take_affine_part::run(m_matrix); }
  /** \returns a writable expression of the Dim x HDim affine part of the transformation */
  EIGEN_DEVICE_FUNC inline AffinePart affine() { return take_affine_part::run(m_matrix); }

  /** \returns a read-only expression of the translation vector of the transformation */
  EIGEN_DEVICE_FUNC inline ConstTranslationPart translation() const { return ConstTranslationPart(m_matrix, 0, Dim); }
  /** \returns a writable expression of the translation vector of the transformation */
  EIGEN_DEVICE_FUNC inline TranslationPart translation() { return TranslationPart(m_matrix, 0, Dim); }

  /** \returns an expression of the product between the transform \c *this and a matrix expression \a other.
   *
   * The right-hand-side \a other can be either:
   * \li an homogeneous vector of size Dim+1,
   * \li a set of homogeneous vectors of size Dim+1 x N,
   * \li a transformation matrix of size Dim+1 x Dim+1.
   *
   * Moreover, if \c *this represents an affine transformation (i.e., Mode!=Projective), then \a other can also be:
   * \li a point of size Dim (computes: \code this->linear() * other + this->translation()\endcode),
   * \li a set of N points as a Dim x N matrix (computes: \code (this->linear() * other).colwise() +
   * this->translation()\endcode),
   *
   * In all cases, the return type is a matrix or vector of same sizes as the right-hand-side \a other.
   *
   * If you want to interpret \a other as a linear or affine transformation, then first convert it to a Transform<>
   * type, or do your own cooking.
   *
   * Finally, if you want to apply Affine transformations to vectors, then explicitly apply the linear part only:
   * \code
   * Affine3f A;
   * Vector3f v1, v2;
   * v2 = A.linear() * v1;
   * \endcode
   *
   */
  // note: this function is defined here because some compilers cannot find the respective declaration
  template <typename OtherDerived>
  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const typename internal::transform_right_product_impl<Transform,
                                                                                              OtherDerived>::ResultType
  operator*(const MatrixBase<OtherDerived>& other) const {
    return internal::transform_right_product_impl<Transform, OtherDerived>::run(*this, other.derived());
  }

  /** \returns the product expression of a transformation matrix \a a times a transform \a b
   *
   * The left hand side \a other can be either:
   * \li a linear transformation matrix of size Dim x Dim,
   * \li an affine transformation matrix of size Dim x Dim+1,
   * \li a general transformation matrix of size Dim+1 x Dim+1.
   */
  template <typename OtherDerived>
  friend EIGEN_DEVICE_FUNC inline const typename internal::transform_left_product_impl<OtherDerived, Mode, Options,
                                                                                       Dim_, Dim_ + 1>::ResultType
  operator*(const MatrixBase<OtherDerived>& a, const Transform& b) {
    return internal::transform_left_product_impl<OtherDerived, Mode, Options, Dim, HDim>::run(a.derived(), b);
  }

  /** \returns The product expression of a transform \a a times a diagonal matrix \a b
   *
   * The rhs diagonal matrix is interpreted as an affine scaling transformation. The
   * product results in a Transform of the same type (mode) as the lhs only if the lhs
   * mode is no isometry. In that case, the returned transform is an affinity.
   */
  template <typename DiagonalDerived>
  EIGEN_DEVICE_FUNC inline const TransformTimeDiagonalReturnType operator*(
      const DiagonalBase<DiagonalDerived>& b) const {
    TransformTimeDiagonalReturnType res(*this);
    res.linearExt() *= b;
    return res;
  }

  /** \returns The product expression of a diagonal matrix \a a times a transform \a b
   *
   * The lhs diagonal matrix is interpreted as an affine scaling transformation. The
   * product results in a Transform of the same type (mode) as the lhs only if the lhs
   * mode is no isometry. In that case, the returned transform is an affinity.
   */
  template <typename DiagonalDerived>
  EIGEN_DEVICE_FUNC friend inline TransformTimeDiagonalReturnType operator*(const DiagonalBase<DiagonalDerived>& a,
                                                                            const Transform& b) {
    TransformTimeDiagonalReturnType res;
    res.linear().noalias() = a * b.linear();
    res.translation().noalias() = a * b.translation();
    if (EIGEN_CONST_CONDITIONAL(Mode != int(AffineCompact))) res.matrix().row(Dim) = b.matrix().row(Dim);
    return res;
  }

  template <typename OtherDerived>
  EIGEN_DEVICE_FUNC inline Transform& operator*=(const MatrixBase<OtherDerived>& other) {
    return *this = *this * other;
  }

  /** Concatenates two transformations */
  EIGEN_DEVICE_FUNC inline const Transform operator*(const Transform& other) const {
    return internal::transform_transform_product_impl<Transform, Transform>::run(*this, other);
  }

  /** Concatenates two different transformations */
  template <int OtherMode, int OtherOptions>
  EIGEN_DEVICE_FUNC inline
      typename internal::transform_transform_product_impl<Transform,
                                                          Transform<Scalar, Dim, OtherMode, OtherOptions> >::ResultType
      operator*(const Transform<Scalar, Dim, OtherMode, OtherOptions>& other) const {
    return internal::transform_transform_product_impl<Transform, Transform<Scalar, Dim, OtherMode, OtherOptions> >::run(
        *this, other);
  }

  /** \sa MatrixBase::setIdentity() */
  EIGEN_DEVICE_FUNC void setIdentity() { m_matrix.setIdentity(); }

  /**
   * \brief Returns an identity transformation.
   * \todo In the future this function should be returning a Transform expression.
   */
  EIGEN_DEVICE_FUNC static const Transform Identity() { return Transform(MatrixType::Identity()); }

  template <typename OtherDerived>
  EIGEN_DEVICE_FUNC inline Transform& scale(const MatrixBase<OtherDerived>& other);

  template <typename OtherDerived>
  EIGEN_DEVICE_FUNC inline Transform& prescale(const MatrixBase<OtherDerived>& other);

  EIGEN_DEVICE_FUNC inline Transform& scale(const Scalar& s);
  EIGEN_DEVICE_FUNC inline Transform& prescale(const Scalar& s);

  template <typename OtherDerived>
  EIGEN_DEVICE_FUNC inline Transform& translate(const MatrixBase<OtherDerived>& other);

  template <typename OtherDerived>
  EIGEN_DEVICE_FUNC inline Transform& pretranslate(const MatrixBase<OtherDerived>& other);

  template <typename RotationType>
  EIGEN_DEVICE_FUNC inline Transform& rotate(const RotationType& rotation);

  template <typename RotationType>
  EIGEN_DEVICE_FUNC inline Transform& prerotate(const RotationType& rotation);

  EIGEN_DEVICE_FUNC Transform& shear(const Scalar& sx, const Scalar& sy);
  EIGEN_DEVICE_FUNC Transform& preshear(const Scalar& sx, const Scalar& sy);

  EIGEN_DEVICE_FUNC inline Transform& operator=(const TranslationType& t);

  EIGEN_DEVICE_FUNC inline Transform& operator*=(const TranslationType& t) { return translate(t.vector()); }

  EIGEN_DEVICE_FUNC inline Transform operator*(const TranslationType& t) const;

  EIGEN_DEVICE_FUNC inline Transform& operator=(const UniformScaling<Scalar>& t);

  EIGEN_DEVICE_FUNC inline Transform& operator*=(const UniformScaling<Scalar>& s) { return scale(s.factor()); }

  EIGEN_DEVICE_FUNC inline TransformTimeDiagonalReturnType operator*(const UniformScaling<Scalar>& s) const {
    TransformTimeDiagonalReturnType res = *this;
    res.scale(s.factor());
    return res;
  }

  EIGEN_DEVICE_FUNC inline Transform& operator*=(const DiagonalMatrix<Scalar, Dim>& s) {
    linearExt() *= s;
    return *this;
  }

  template <typename Derived>
  EIGEN_DEVICE_FUNC inline Transform& operator=(const RotationBase<Derived, Dim>& r);
  template <typename Derived>
  EIGEN_DEVICE_FUNC inline Transform& operator*=(const RotationBase<Derived, Dim>& r) {
    return rotate(r.toRotationMatrix());
  }
  template <typename Derived>
  EIGEN_DEVICE_FUNC inline Transform operator*(const RotationBase<Derived, Dim>& r) const;

  using RotationReturnType = std::conditional_t<int(Mode) == Isometry, ConstLinearPart, const LinearMatrixType>;
  EIGEN_DEVICE_FUNC RotationReturnType rotation() const;

  template <typename RotationMatrixType, typename ScalingMatrixType>
  EIGEN_DEVICE_FUNC void computeRotationScaling(RotationMatrixType* rotation, ScalingMatrixType* scaling) const;
  template <typename ScalingMatrixType, typename RotationMatrixType>
  EIGEN_DEVICE_FUNC void computeScalingRotation(ScalingMatrixType* scaling, RotationMatrixType* rotation) const;

  template <typename PositionDerived, typename OrientationType, typename ScaleDerived>
  EIGEN_DEVICE_FUNC Transform& fromPositionOrientationScale(const MatrixBase<PositionDerived>& position,
                                                            const OrientationType& orientation,
                                                            const MatrixBase<ScaleDerived>& scale);

  EIGEN_DEVICE_FUNC inline Transform inverse(TransformTraits traits = (TransformTraits)Mode) const;

  /** \returns a const pointer to the column major internal matrix */
  EIGEN_DEVICE_FUNC constexpr const Scalar* data() const { return m_matrix.data(); }
  /** \returns a non-const pointer to the column major internal matrix */
  EIGEN_DEVICE_FUNC constexpr Scalar* data() { return m_matrix.data(); }

  /** \returns \c *this with scalar type casted to \a NewScalarType
   *
   * Note that if \a NewScalarType is equal to the current scalar type of \c *this
   * then this function smartly returns a const reference to \c *this.
   */
  template <typename NewScalarType>
  EIGEN_DEVICE_FUNC inline
      typename internal::cast_return_type<Transform, Transform<NewScalarType, Dim, Mode, Options> >::type
      cast() const {
    return typename internal::cast_return_type<Transform, Transform<NewScalarType, Dim, Mode, Options> >::type(*this);
  }

  /** Copy constructor with scalar type conversion */
  template <typename OtherScalarType>
  EIGEN_DEVICE_FUNC inline explicit Transform(const Transform<OtherScalarType, Dim, Mode, Options>& other) {
    check_template_params();
    m_matrix = other.matrix().template cast<Scalar>();
  }

  /** \returns \c true if \c *this is approximately equal to \a other, within the precision
   * determined by \a prec.
   *
   * \sa MatrixBase::isApprox() */
  EIGEN_DEVICE_FUNC bool isApprox(const Transform& other, const typename NumTraits<Scalar>::Real& prec =
                                                              NumTraits<Scalar>::dummy_precision()) const {
    return m_matrix.isApprox(other.m_matrix, prec);
  }

  /** Sets the last row to [0 ... 0 1]
   */
  EIGEN_DEVICE_FUNC void makeAffine() { internal::transform_make_affine<int(Mode)>::run(m_matrix); }

  /** \internal
   * \returns the Dim x Dim linear part if the transformation is affine,
   *          and the HDim x Dim part for projective transformations.
   */
  EIGEN_DEVICE_FUNC inline Block<MatrixType, int(Mode) == int(Projective) ? HDim : Dim, Dim> linearExt() {
    return m_matrix.template block < int(Mode) == int(Projective) ? HDim : Dim, Dim > (0, 0);
  }
  /** \internal
   * \returns the Dim x Dim linear part if the transformation is affine,
   *          and the HDim x Dim part for projective transformations.
   */
  EIGEN_DEVICE_FUNC inline const Block<MatrixType, int(Mode) == int(Projective) ? HDim : Dim, Dim> linearExt() const {
    return m_matrix.template block < int(Mode) == int(Projective) ? HDim : Dim, Dim > (0, 0);
  }

  /** \internal
   * \returns the translation part if the transformation is affine,
   *          and the last column for projective transformations.
   */
  EIGEN_DEVICE_FUNC inline Block<MatrixType, int(Mode) == int(Projective) ? HDim : Dim, 1> translationExt() {
    return m_matrix.template block < int(Mode) == int(Projective) ? HDim : Dim, 1 > (0, Dim);
  }
  /** \internal
   * \returns the translation part if the transformation is affine,
   *          and the last column for projective transformations.
   */
  EIGEN_DEVICE_FUNC inline const Block<MatrixType, int(Mode) == int(Projective) ? HDim : Dim, 1> translationExt()
      const {
    return m_matrix.template block < int(Mode) == int(Projective) ? HDim : Dim, 1 > (0, Dim);
  }

#ifdef EIGEN_TRANSFORM_PLUGIN
#include EIGEN_TRANSFORM_PLUGIN
#endif

 protected:
#ifndef EIGEN_PARSED_BY_DOXYGEN
  EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE void check_template_params() {
    EIGEN_STATIC_ASSERT((Options & (DontAlign | RowMajor)) == Options, INVALID_MATRIX_TEMPLATE_PARAMETERS)
  }
#endif
};

/** \ingroup Geometry_Module */
using Isometry2f = Transform<float, 2, Isometry>;
/** \ingroup Geometry_Module */
using Isometry3f = Transform<float, 3, Isometry>;
/** \ingroup Geometry_Module */
using Isometry2d = Transform<double, 2, Isometry>;
/** \ingroup Geometry_Module */
using Isometry3d = Transform<double, 3, Isometry>;

/** \ingroup Geometry_Module */
using Affine2f = Transform<float, 2, Affine>;
/** \ingroup Geometry_Module */
using Affine3f = Transform<float, 3, Affine>;
/** \ingroup Geometry_Module */
using Affine2d = Transform<double, 2, Affine>;
/** \ingroup Geometry_Module */
using Affine3d = Transform<double, 3, Affine>;

/** \ingroup Geometry_Module */
using AffineCompact2f = Transform<float, 2, AffineCompact>;
/** \ingroup Geometry_Module */
using AffineCompact3f = Transform<float, 3, AffineCompact>;
/** \ingroup Geometry_Module */
using AffineCompact2d = Transform<double, 2, AffineCompact>;
/** \ingroup Geometry_Module */
using AffineCompact3d = Transform<double, 3, AffineCompact>;

/** \ingroup Geometry_Module */
using Projective2f = Transform<float, 2, Projective>;
/** \ingroup Geometry_Module */
using Projective3f = Transform<float, 3, Projective>;
/** \ingroup Geometry_Module */
using Projective2d = Transform<double, 2, Projective>;
/** \ingroup Geometry_Module */
using Projective3d = Transform<double, 3, Projective>;

/**************************
*** Optional QT support ***
**************************/

#ifdef EIGEN_QT_SUPPORT

#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
/** Initializes \c *this from a QMatrix assuming the dimension is 2.
 *
 * This function is available only if the token EIGEN_QT_SUPPORT is defined.
 */
template <typename Scalar, int Dim, int Mode, int Options>
Transform<Scalar, Dim, Mode, Options>::Transform(const QMatrix& other) {
  check_template_params();
  *this = other;
}

/** Set \c *this from a QMatrix assuming the dimension is 2.
 *
 * This function is available only if the token EIGEN_QT_SUPPORT is defined.
 */
template <typename Scalar, int Dim, int Mode, int Options>
Transform<Scalar, Dim, Mode, Options>& Transform<Scalar, Dim, Mode, Options>::operator=(const QMatrix& other) {
  EIGEN_STATIC_ASSERT(Dim == 2, YOU_MADE_A_PROGRAMMING_MISTAKE)
  if (EIGEN_CONST_CONDITIONAL(Mode == int(AffineCompact)))
    m_matrix << other.m11(), other.m21(), other.dx(), other.m12(), other.m22(), other.dy();
  else
    m_matrix << other.m11(), other.m21(), other.dx(), other.m12(), other.m22(), other.dy(), 0, 0, 1;
  return *this;
}

/** \returns a QMatrix from \c *this assuming the dimension is 2.
 *
 * \warning this conversion might lose data if \c *this is not affine
 *
 * This function is available only if the token EIGEN_QT_SUPPORT is defined.
 */
template <typename Scalar, int Dim, int Mode, int Options>
QMatrix Transform<Scalar, Dim, Mode, Options>::toQMatrix(void) const {
  check_template_params();
  EIGEN_STATIC_ASSERT(Dim == 2, YOU_MADE_A_PROGRAMMING_MISTAKE)
  return QMatrix(m_matrix.coeff(0, 0), m_matrix.coeff(1, 0), m_matrix.coeff(0, 1), m_matrix.coeff(1, 1),
                 m_matrix.coeff(0, 2), m_matrix.coeff(1, 2));
}
#endif

/** Initializes \c *this from a QTransform assuming the dimension is 2.
 *
 * This function is available only if the token EIGEN_QT_SUPPORT is defined.
 */
template <typename Scalar, int Dim, int Mode, int Options>
Transform<Scalar, Dim, Mode, Options>::Transform(const QTransform& other) {
  check_template_params();
  *this = other;
}

/** Set \c *this from a QTransform assuming the dimension is 2.
 *
 * This function is available only if the token EIGEN_QT_SUPPORT is defined.
 */
template <typename Scalar, int Dim, int Mode, int Options>
Transform<Scalar, Dim, Mode, Options>& Transform<Scalar, Dim, Mode, Options>::operator=(const QTransform& other) {
  check_template_params();
  EIGEN_STATIC_ASSERT(Dim == 2, YOU_MADE_A_PROGRAMMING_MISTAKE)
  if (EIGEN_CONST_CONDITIONAL(Mode == int(AffineCompact)))
    m_matrix << other.m11(), other.m21(), other.dx(), other.m12(), other.m22(), other.dy();
  else
    m_matrix << other.m11(), other.m21(), other.dx(), other.m12(), other.m22(), other.dy(), other.m13(), other.m23(),
        other.m33();
  return *this;
}

/** \returns a QTransform from \c *this assuming the dimension is 2.
 *
 * This function is available only if the token EIGEN_QT_SUPPORT is defined.
 */
template <typename Scalar, int Dim, int Mode, int Options>
QTransform Transform<Scalar, Dim, Mode, Options>::toQTransform(void) const {
  EIGEN_STATIC_ASSERT(Dim == 2, YOU_MADE_A_PROGRAMMING_MISTAKE)
  if (EIGEN_CONST_CONDITIONAL(Mode == int(AffineCompact)))
    return QTransform(m_matrix.coeff(0, 0), m_matrix.coeff(1, 0), m_matrix.coeff(0, 1), m_matrix.coeff(1, 1),
                      m_matrix.coeff(0, 2), m_matrix.coeff(1, 2));
  else
    return QTransform(m_matrix.coeff(0, 0), m_matrix.coeff(1, 0), m_matrix.coeff(2, 0), m_matrix.coeff(0, 1),
                      m_matrix.coeff(1, 1), m_matrix.coeff(2, 1), m_matrix.coeff(0, 2), m_matrix.coeff(1, 2),
                      m_matrix.coeff(2, 2));
}
#endif

/*********************
*** Procedural API ***
*********************/

/** Applies on the right the non uniform scale transformation represented
 * by the vector \a other to \c *this and returns a reference to \c *this.
 * \sa prescale()
 */
template <typename Scalar, int Dim, int Mode, int Options>
template <typename OtherDerived>
EIGEN_DEVICE_FUNC Transform<Scalar, Dim, Mode, Options>& Transform<Scalar, Dim, Mode, Options>::scale(
    const MatrixBase<OtherDerived>& other) {
  EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(OtherDerived, int(Dim))
  EIGEN_STATIC_ASSERT(Mode != int(Isometry), THIS_METHOD_IS_ONLY_FOR_SPECIFIC_TRANSFORMATIONS)
  linearExt().noalias() = linearExt() * other.asDiagonal();
  return *this;
}

/** Applies on the right a uniform scale of a factor \a c to \c *this
 * and returns a reference to \c *this.
 * \sa prescale(Scalar)
 */
template <typename Scalar, int Dim, int Mode, int Options>
EIGEN_DEVICE_FUNC inline Transform<Scalar, Dim, Mode, Options>& Transform<Scalar, Dim, Mode, Options>::scale(
    const Scalar& s) {
  EIGEN_STATIC_ASSERT(Mode != int(Isometry), THIS_METHOD_IS_ONLY_FOR_SPECIFIC_TRANSFORMATIONS)
  linearExt() *= s;
  return *this;
}

/** Applies on the left the non uniform scale transformation represented
 * by the vector \a other to \c *this and returns a reference to \c *this.
 * \sa scale()
 */
template <typename Scalar, int Dim, int Mode, int Options>
template <typename OtherDerived>
EIGEN_DEVICE_FUNC Transform<Scalar, Dim, Mode, Options>& Transform<Scalar, Dim, Mode, Options>::prescale(
    const MatrixBase<OtherDerived>& other) {
  EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(OtherDerived, int(Dim))
  EIGEN_STATIC_ASSERT(Mode != int(Isometry), THIS_METHOD_IS_ONLY_FOR_SPECIFIC_TRANSFORMATIONS)
  affine().noalias() = other.asDiagonal() * affine();
  return *this;
}

/** Applies on the left a uniform scale of a factor \a c to \c *this
 * and returns a reference to \c *this.
 * \sa scale(Scalar)
 */
template <typename Scalar, int Dim, int Mode, int Options>
EIGEN_DEVICE_FUNC inline Transform<Scalar, Dim, Mode, Options>& Transform<Scalar, Dim, Mode, Options>::prescale(
    const Scalar& s) {
  EIGEN_STATIC_ASSERT(Mode != int(Isometry), THIS_METHOD_IS_ONLY_FOR_SPECIFIC_TRANSFORMATIONS)
  m_matrix.template topRows<Dim>() *= s;
  return *this;
}

/** Applies on the right the translation matrix represented by the vector \a other
 * to \c *this and returns a reference to \c *this.
 * \sa pretranslate()
 */
template <typename Scalar, int Dim, int Mode, int Options>
template <typename OtherDerived>
EIGEN_DEVICE_FUNC Transform<Scalar, Dim, Mode, Options>& Transform<Scalar, Dim, Mode, Options>::translate(
    const MatrixBase<OtherDerived>& other) {
  EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(OtherDerived, int(Dim))
  translationExt() += linearExt() * other;
  return *this;
}

/** Applies on the left the translation matrix represented by the vector \a other
 * to \c *this and returns a reference to \c *this.
 * \sa translate()
 */
template <typename Scalar, int Dim, int Mode, int Options>
template <typename OtherDerived>
EIGEN_DEVICE_FUNC Transform<Scalar, Dim, Mode, Options>& Transform<Scalar, Dim, Mode, Options>::pretranslate(
    const MatrixBase<OtherDerived>& other) {
  EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(OtherDerived, int(Dim))
  if (EIGEN_CONST_CONDITIONAL(int(Mode) == int(Projective)))
    affine() += other * m_matrix.row(Dim);
  else
    translation() += other;
  return *this;
}

/** Applies on the right the rotation represented by the rotation \a rotation
 * to \c *this and returns a reference to \c *this.
 *
 * The template parameter \a RotationType is the type of the rotation which
 * must be known by internal::toRotationMatrix<>.
 *
 * Natively supported types includes:
 *   - any scalar (2D),
 *   - a Dim x Dim matrix expression,
 *   - a Quaternion (3D),
 *   - a AngleAxis (3D)
 *
 * This mechanism is easily extendable to support user types such as Euler angles,
 * or a pair of Quaternion for 4D rotations.
 *
 * \sa rotate(Scalar), class Quaternion, class AngleAxis, prerotate(RotationType)
 */
template <typename Scalar, int Dim, int Mode, int Options>
template <typename RotationType>
EIGEN_DEVICE_FUNC Transform<Scalar, Dim, Mode, Options>& Transform<Scalar, Dim, Mode, Options>::rotate(
    const RotationType& rotation) {
  linearExt() *= internal::toRotationMatrix<Scalar, Dim>(rotation);
  return *this;
}

/** Applies on the left the rotation represented by the rotation \a rotation
 * to \c *this and returns a reference to \c *this.
 *
 * See rotate() for further details.
 *
 * \sa rotate()
 */
template <typename Scalar, int Dim, int Mode, int Options>
template <typename RotationType>
EIGEN_DEVICE_FUNC Transform<Scalar, Dim, Mode, Options>& Transform<Scalar, Dim, Mode, Options>::prerotate(
    const RotationType& rotation) {
  m_matrix.template block<Dim, HDim>(0, 0) =
      internal::toRotationMatrix<Scalar, Dim>(rotation) * m_matrix.template block<Dim, HDim>(0, 0);
  return *this;
}

/** Applies on the right the shear transformation represented
 * by the vector \a other to \c *this and returns a reference to \c *this.
 * \warning 2D only.
 * \sa preshear()
 */
template <typename Scalar, int Dim, int Mode, int Options>
EIGEN_DEVICE_FUNC Transform<Scalar, Dim, Mode, Options>& Transform<Scalar, Dim, Mode, Options>::shear(
    const Scalar& sx, const Scalar& sy) {
  EIGEN_STATIC_ASSERT(int(Dim) == 2, YOU_MADE_A_PROGRAMMING_MISTAKE)
  EIGEN_STATIC_ASSERT(Mode != int(Isometry), THIS_METHOD_IS_ONLY_FOR_SPECIFIC_TRANSFORMATIONS)
  VectorType tmp = linear().col(0) * sy + linear().col(1);
  linear() << linear().col(0) + linear().col(1) * sx, tmp;
  return *this;
}

/** Applies on the left the shear transformation represented
 * by the vector \a other to \c *this and returns a reference to \c *this.
 * \warning 2D only.
 * \sa shear()
 */
template <typename Scalar, int Dim, int Mode, int Options>
EIGEN_DEVICE_FUNC Transform<Scalar, Dim, Mode, Options>& Transform<Scalar, Dim, Mode, Options>::preshear(
    const Scalar& sx, const Scalar& sy) {
  EIGEN_STATIC_ASSERT(int(Dim) == 2, YOU_MADE_A_PROGRAMMING_MISTAKE)
  EIGEN_STATIC_ASSERT(Mode != int(Isometry), THIS_METHOD_IS_ONLY_FOR_SPECIFIC_TRANSFORMATIONS)
  m_matrix.template block<Dim, HDim>(0, 0) =
      LinearMatrixType({{1, sy}, {sx, 1}}) * m_matrix.template block<Dim, HDim>(0, 0);
  return *this;
}

/******************************************************
*** Scaling, Translation and Rotation compatibility ***
******************************************************/

template <typename Scalar, int Dim, int Mode, int Options>
EIGEN_DEVICE_FUNC inline Transform<Scalar, Dim, Mode, Options>& Transform<Scalar, Dim, Mode, Options>::operator=(
    const TranslationType& t) {
  linear().setIdentity();
  translation() = t.vector();
  makeAffine();
  return *this;
}

template <typename Scalar, int Dim, int Mode, int Options>
EIGEN_DEVICE_FUNC inline Transform<Scalar, Dim, Mode, Options> Transform<Scalar, Dim, Mode, Options>::operator*(
    const TranslationType& t) const {
  Transform res = *this;
  res.translate(t.vector());
  return res;
}

template <typename Scalar, int Dim, int Mode, int Options>
EIGEN_DEVICE_FUNC inline Transform<Scalar, Dim, Mode, Options>& Transform<Scalar, Dim, Mode, Options>::operator=(
    const UniformScaling<Scalar>& s) {
  m_matrix.setZero();
  linear().diagonal().fill(s.factor());
  makeAffine();
  return *this;
}

template <typename Scalar, int Dim, int Mode, int Options>
template <typename Derived>
EIGEN_DEVICE_FUNC inline Transform<Scalar, Dim, Mode, Options>& Transform<Scalar, Dim, Mode, Options>::operator=(
    const RotationBase<Derived, Dim>& r) {
  linear() = internal::toRotationMatrix<Scalar, Dim>(r);
  translation().setZero();
  makeAffine();
  return *this;
}

template <typename Scalar, int Dim, int Mode, int Options>
template <typename Derived>
EIGEN_DEVICE_FUNC inline Transform<Scalar, Dim, Mode, Options> Transform<Scalar, Dim, Mode, Options>::operator*(
    const RotationBase<Derived, Dim>& r) const {
  Transform res = *this;
  res.rotate(r.derived());
  return res;
}

/************************
*** Special functions ***
************************/

namespace internal {
template <int Mode>
struct transform_rotation_impl {
  template <typename TransformType>
  EIGEN_DEVICE_FUNC static inline const typename TransformType::LinearMatrixType run(const TransformType& t) {
    using LinearMatrixType = typename TransformType::LinearMatrixType;
    LinearMatrixType result;
    t.computeRotationScaling(&result, (LinearMatrixType*)0);
    return result;
  }
};
template <>
struct transform_rotation_impl<Isometry> {
  template <typename TransformType>
  EIGEN_DEVICE_FUNC static inline typename TransformType::ConstLinearPart run(const TransformType& t) {
    return t.linear();
  }
};
}  // namespace internal
/** \returns the rotation part of the transformation
 *
 * If Mode==Isometry, then this method is an alias for linear(),
 * otherwise it calls computeRotationScaling() to extract the rotation
 * through a SVD decomposition.
 *
 * \svd_module
 *
 * \sa computeRotationScaling(), computeScalingRotation(), class SVD
 */
template <typename Scalar, int Dim, int Mode, int Options>
EIGEN_DEVICE_FUNC typename Transform<Scalar, Dim, Mode, Options>::RotationReturnType
Transform<Scalar, Dim, Mode, Options>::rotation() const {
  return internal::transform_rotation_impl<Mode>::run(*this);
}

/** decomposes the linear part of the transformation as a product rotation x scaling, the scaling being
 * not necessarily positive.
 *
 * If either pointer is zero, the corresponding computation is skipped.
 *
 *
 *
 * \svd_module
 *
 * \sa computeScalingRotation(), rotation(), class SVD
 */
template <typename Scalar, int Dim, int Mode, int Options>
template <typename RotationMatrixType, typename ScalingMatrixType>
EIGEN_DEVICE_FUNC void Transform<Scalar, Dim, Mode, Options>::computeRotationScaling(RotationMatrixType* rotation,
                                                                                     ScalingMatrixType* scaling) const {
  // Note that JacobiSVD is faster than BDCSVD for small matrices.
  JacobiSVD<LinearMatrixType, ComputeFullU | ComputeFullV> svd(linear());

  Scalar x = (svd.matrixU() * svd.matrixV().adjoint()).determinant() < Scalar(0)
                 ? Scalar(-1)
                 : Scalar(1);  // so x has absolute value 1
  VectorType sv(svd.singularValues());
  sv.coeffRef(Dim - 1) *= x;
  if (scaling) (*scaling).noalias() = svd.matrixV() * sv.asDiagonal() * svd.matrixV().adjoint();
  if (rotation) {
    LinearMatrixType m(svd.matrixU());
    m.col(Dim - 1) *= x;
    (*rotation).noalias() = m * svd.matrixV().adjoint();
  }
}

/** decomposes the linear part of the transformation as a product scaling x rotation, the scaling being
 * not necessarily positive.
 *
 * If either pointer is zero, the corresponding computation is skipped.
 *
 *
 *
 * \svd_module
 *
 * \sa computeRotationScaling(), rotation(), class SVD
 */
template <typename Scalar, int Dim, int Mode, int Options>
template <typename ScalingMatrixType, typename RotationMatrixType>
EIGEN_DEVICE_FUNC void Transform<Scalar, Dim, Mode, Options>::computeScalingRotation(
    ScalingMatrixType* scaling, RotationMatrixType* rotation) const {
  // Note that JacobiSVD is faster than BDCSVD for small matrices.
  JacobiSVD<LinearMatrixType, ComputeFullU | ComputeFullV> svd(linear());

  Scalar x = (svd.matrixU() * svd.matrixV().adjoint()).determinant() < Scalar(0)
                 ? Scalar(-1)
                 : Scalar(1);  // so x has absolute value 1
  VectorType sv(svd.singularValues());
  sv.coeffRef(Dim - 1) *= x;
  if (scaling) *scaling = svd.matrixU() * sv.asDiagonal() * svd.matrixU().adjoint();
  if (rotation) {
    LinearMatrixType m(svd.matrixU());
    m.col(Dim - 1) *= x;
    *rotation = m * svd.matrixV().adjoint();
  }
}

/** Convenient method to set \c *this from a position, orientation and scale
 * of a 3D object.
 */
template <typename Scalar, int Dim, int Mode, int Options>
template <typename PositionDerived, typename OrientationType, typename ScaleDerived>
EIGEN_DEVICE_FUNC Transform<Scalar, Dim, Mode, Options>&
Transform<Scalar, Dim, Mode, Options>::fromPositionOrientationScale(const MatrixBase<PositionDerived>& position,
                                                                    const OrientationType& orientation,
                                                                    const MatrixBase<ScaleDerived>& scale) {
  linear() = internal::toRotationMatrix<Scalar, Dim>(orientation);
  linear() *= scale.asDiagonal();
  translation() = position;
  makeAffine();
  return *this;
}

namespace internal {

template <int Mode>
struct transform_make_affine {
  template <typename MatrixType>
  EIGEN_DEVICE_FUNC static void run(MatrixType& mat) {
    static const int Dim = MatrixType::ColsAtCompileTime - 1;
    mat.template block<1, Dim>(Dim, 0).setZero();
    mat.coeffRef(Dim, Dim) = typename MatrixType::Scalar(1);
  }
};

template <>
struct transform_make_affine<AffineCompact> {
  template <typename MatrixType>
  EIGEN_DEVICE_FUNC static void run(MatrixType&) {}
};

// Selector needed to avoid taking the inverse of a 3x4 matrix. Only a Projective transform can store a general
// inverse; for every other mode the type itself guarantees the transform is affine, so a Projective hint - which only
// asks that no extra structure be assumed - is honoured by the general affine inverse.
template <typename TransformType, int Mode = TransformType::Mode>
struct projective_transform_inverse {
  EIGEN_DEVICE_FUNC static inline void run(const TransformType& m, TransformType& res) { res = m.inverse(Affine); }
};

template <typename TransformType>
struct projective_transform_inverse<TransformType, Projective> {
  EIGEN_DEVICE_FUNC static inline void run(const TransformType& m, TransformType& res) {
    res.matrix() = m.matrix().inverse();
  }
};

}  // end namespace internal

/**
 *
 * \returns the inverse transformation according to some given knowledge
 * on \c *this.
 *
 * \param hint allows to optimize the inversion process when the transformation
 * is known to be not a general transformation (optional). The possible values are:
 *  - #Projective if the transformation is not necessarily affine, i.e., if the
 *    last row is not guaranteed to be [0 ... 0 1]
 *  - #Affine if the last row can be assumed to be [0 ... 0 1]
 *  - #Isometry if the transformation is only a concatenations of translations
 *    and rotations.
 *  The default is the template class parameter \c Mode.
 *
 * \warning unless \a traits is always set to NoShear or NoScaling, this function
 * requires the generic inverse method of MatrixBase defined in the LU module. If
 * you forget to include this module, then you will get hard to debug linking errors.
 *
 * \sa MatrixBase::inverse()
 */
template <typename Scalar, int Dim, int Mode, int Options>
EIGEN_DEVICE_FUNC Transform<Scalar, Dim, Mode, Options> Transform<Scalar, Dim, Mode, Options>::inverse(
    TransformTraits hint) const {
  Transform res;
  if (hint == Projective) {
    internal::projective_transform_inverse<Transform>::run(*this, res);
  } else {
    if (hint == Isometry) {
      res.matrix().template topLeftCorner<Dim, Dim>() = linear().transpose();
    } else if (hint & Affine) {
      res.matrix().template topLeftCorner<Dim, Dim>() = linear().inverse();
    } else {
      eigen_assert(false && "Invalid transform traits in Transform::Inverse");
    }
    // translation and remaining parts
    res.matrix().template topRightCorner<Dim, 1>().noalias() =
        -res.matrix().template topLeftCorner<Dim, Dim>() * translation();
    res.makeAffine();  // we do need this, because in the beginning res is uninitialized
  }
  return res;
}

namespace internal {

/*****************************************************
*** Specializations of take affine part            ***
*****************************************************/

template <typename TransformType>
struct transform_take_affine_part {
  using MatrixType = typename TransformType::MatrixType;
  using AffinePart = typename TransformType::AffinePart;
  using ConstAffinePart = typename TransformType::ConstAffinePart;
  static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE AffinePart run(MatrixType& m) {
    return m.template block<TransformType::Dim, TransformType::HDim>(0, 0);
  }
  static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE ConstAffinePart run(const MatrixType& m) {
    return m.template block<TransformType::Dim, TransformType::HDim>(0, 0);
  }
};

template <typename Scalar, int Dim, int Options>
struct transform_take_affine_part<Transform<Scalar, Dim, AffineCompact, Options> > {
  using MatrixType = typename Transform<Scalar, Dim, AffineCompact, Options>::MatrixType;
  static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE MatrixType& run(MatrixType& m) { return m; }
  static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const MatrixType& run(const MatrixType& m) { return m; }
};

/*****************************************************
*** Specializations of construct from matrix       ***
*****************************************************/

template <typename Other, int Mode, int Options, int Dim, int HDim>
struct transform_construct_from_matrix<Other, Mode, Options, Dim, HDim, Dim, Dim> {
  static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void run(
      Transform<typename Other::Scalar, Dim, Mode, Options>* transform, const Other& other) {
    transform->linear() = other;
    transform->translation().setZero();
    transform->makeAffine();
  }
};

template <typename Other, int Mode, int Options, int Dim, int HDim>
struct transform_construct_from_matrix<Other, Mode, Options, Dim, HDim, Dim, HDim> {
  static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void run(
      Transform<typename Other::Scalar, Dim, Mode, Options>* transform, const Other& other) {
    transform->affine() = other;
    transform->makeAffine();
  }
};

template <typename Other, int Mode, int Options, int Dim, int HDim>
struct transform_construct_from_matrix<Other, Mode, Options, Dim, HDim, HDim, HDim> {
  static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void run(
      Transform<typename Other::Scalar, Dim, Mode, Options>* transform, const Other& other) {
    transform->matrix() = other;
  }
};

template <typename Other, int Options, int Dim, int HDim>
struct transform_construct_from_matrix<Other, AffineCompact, Options, Dim, HDim, HDim, HDim> {
  static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void run(
      Transform<typename Other::Scalar, Dim, AffineCompact, Options>* transform, const Other& other) {
    transform->matrix() = other.template block<Dim, HDim>(0, 0);
  }
};

/**********************************************************
***   Specializations of operator* with rhs MatrixBase  ***
**********************************************************/

template <int LhsMode, int RhsMode>
struct transform_product_result {
  enum {
    Mode = (LhsMode == (int)Projective || RhsMode == (int)Projective)         ? Projective
           : (LhsMode == (int)Affine || RhsMode == (int)Affine)               ? Affine
           : (LhsMode == (int)AffineCompact || RhsMode == (int)AffineCompact) ? AffineCompact
           : (LhsMode == (int)Isometry || RhsMode == (int)Isometry)           ? Isometry
                                                                              : Projective
  };
};

template <typename TransformType, typename MatrixType, int RhsCols>
struct transform_right_product_impl<TransformType, MatrixType, 0, RhsCols> {
  using ResultType = typename MatrixType::PlainObject;

  static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE ResultType run(const TransformType& T, const MatrixType& other) {
    return T.matrix() * other;
  }
};

template <typename TransformType, typename MatrixType, int RhsCols>
struct transform_right_product_impl<TransformType, MatrixType, 1, RhsCols> {
  enum {
    Dim = TransformType::Dim,
    HDim = TransformType::HDim,
    OtherRows = MatrixType::RowsAtCompileTime,
    OtherCols = MatrixType::ColsAtCompileTime
  };

  using ResultType = typename MatrixType::PlainObject;

  static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE ResultType run(const TransformType& T, const MatrixType& other) {
    EIGEN_STATIC_ASSERT(OtherRows == HDim, YOU_MIXED_MATRICES_OF_DIFFERENT_SIZES);

    using TopLeftLhs = Block<ResultType, Dim, OtherCols, int(MatrixType::RowsAtCompileTime) == Dim>;

    ResultType res(other.rows(), other.cols());
    TopLeftLhs(res, 0, 0, Dim, other.cols()).noalias() = T.affine() * other;
    res.row(OtherRows - 1) = other.row(OtherRows - 1);

    return res;
  }
};

template <typename TransformType, typename MatrixType, int RhsCols>
struct transform_right_product_impl<TransformType, MatrixType, 2, RhsCols> {
  enum {
    Dim = TransformType::Dim,
    HDim = TransformType::HDim,
    OtherRows = MatrixType::RowsAtCompileTime,
    OtherCols = MatrixType::ColsAtCompileTime
  };

  using ResultType = typename MatrixType::PlainObject;

  static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE ResultType run(const TransformType& T, const MatrixType& other) {
    EIGEN_STATIC_ASSERT(OtherRows == Dim, YOU_MIXED_MATRICES_OF_DIFFERENT_SIZES);

    using TopLeftLhs = Block<ResultType, Dim, OtherCols, true>;
    ResultType res(
        Replicate<typename TransformType::ConstTranslationPart, 1, OtherCols>(T.translation(), 1, other.cols()));
    TopLeftLhs(res, 0, 0, Dim, other.cols()).noalias() += T.linear() * other;

    return res;
  }
};

template <typename TransformType, typename MatrixType>
struct transform_right_product_impl<TransformType, MatrixType, 2, 1>  // rhs is a vector of size Dim
{
  using TransformMatrix = typename TransformType::MatrixType;
  enum {
    Dim = TransformType::Dim,
    HDim = TransformType::HDim,
    OtherRows = MatrixType::RowsAtCompileTime,
    WorkingRows = plain_enum_min(TransformMatrix::RowsAtCompileTime, HDim)
  };

  using ResultType = typename MatrixType::PlainObject;

  static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE ResultType run(const TransformType& T, const MatrixType& other) {
    EIGEN_STATIC_ASSERT(OtherRows == Dim, YOU_MIXED_MATRICES_OF_DIFFERENT_SIZES);

    Matrix<typename ResultType::Scalar, Dim + 1, 1> rhs;
    rhs.template head<Dim>() = other;
    rhs[Dim] = typename ResultType::Scalar(1);
    Matrix<typename ResultType::Scalar, WorkingRows, 1> res(T.matrix() * rhs);
    return res.template head<Dim>();
  }
};

/**********************************************************
***   Specializations of operator* with lhs EigenBase   ***
**********************************************************/

// generic HDim x HDim matrix * T => Projective
template <typename Other, int Mode, int Options, int Dim, int HDim>
struct transform_left_product_impl<Other, Mode, Options, Dim, HDim, HDim, HDim> {
  using TransformType = Transform<typename Other::Scalar, Dim, Mode, Options>;
  using MatrixType = typename TransformType::MatrixType;
  using ResultType = Transform<typename Other::Scalar, Dim, Projective, Options>;
  static EIGEN_DEVICE_FUNC ResultType run(const Other& other, const TransformType& tr) {
    return ResultType(other * tr.matrix());
  }
};

// generic HDim x HDim matrix * AffineCompact => Projective
template <typename Other, int Options, int Dim, int HDim>
struct transform_left_product_impl<Other, AffineCompact, Options, Dim, HDim, HDim, HDim> {
  using TransformType = Transform<typename Other::Scalar, Dim, AffineCompact, Options>;
  using MatrixType = typename TransformType::MatrixType;
  using ResultType = Transform<typename Other::Scalar, Dim, Projective, Options>;
  static EIGEN_DEVICE_FUNC ResultType run(const Other& other, const TransformType& tr) {
    ResultType res;
    res.matrix().noalias() = other.template block<HDim, Dim>(0, 0) * tr.matrix();
    res.matrix().col(Dim) += other.col(Dim);
    return res;
  }
};

// affine matrix * T
template <typename Other, int Mode, int Options, int Dim, int HDim>
struct transform_left_product_impl<Other, Mode, Options, Dim, HDim, Dim, HDim> {
  using TransformType = Transform<typename Other::Scalar, Dim, Mode, Options>;
  using MatrixType = typename TransformType::MatrixType;
  using ResultType = TransformType;
  static EIGEN_DEVICE_FUNC ResultType run(const Other& other, const TransformType& tr) {
    ResultType res;
    res.affine().noalias() = other * tr.matrix();
    res.matrix().row(Dim) = tr.matrix().row(Dim);
    return res;
  }
};

// affine matrix * AffineCompact
template <typename Other, int Options, int Dim, int HDim>
struct transform_left_product_impl<Other, AffineCompact, Options, Dim, HDim, Dim, HDim> {
  using TransformType = Transform<typename Other::Scalar, Dim, AffineCompact, Options>;
  using MatrixType = typename TransformType::MatrixType;
  using ResultType = TransformType;
  static EIGEN_DEVICE_FUNC ResultType run(const Other& other, const TransformType& tr) {
    ResultType res;
    res.matrix().noalias() = other.template block<Dim, Dim>(0, 0) * tr.matrix();
    res.translation() += other.col(Dim);
    return res;
  }
};

// linear matrix * T
template <typename Other, int Mode, int Options, int Dim, int HDim>
struct transform_left_product_impl<Other, Mode, Options, Dim, HDim, Dim, Dim> {
  using TransformType = Transform<typename Other::Scalar, Dim, Mode, Options>;
  using MatrixType = typename TransformType::MatrixType;
  using ResultType = TransformType;
  static EIGEN_DEVICE_FUNC ResultType run(const Other& other, const TransformType& tr) {
    TransformType res;
    EIGEN_IF_CONSTEXPR (Mode != int(AffineCompact)) res.matrix().row(Dim) = tr.matrix().row(Dim);
    res.matrix().template topRows<Dim>().noalias() = other * tr.matrix().template topRows<Dim>();
    return res;
  }
};

/**********************************************************
*** Specializations of operator* with another Transform ***
**********************************************************/

template <typename Scalar, int Dim, int LhsMode, int LhsOptions, int RhsMode, int RhsOptions>
struct transform_transform_product_impl<Transform<Scalar, Dim, LhsMode, LhsOptions>,
                                        Transform<Scalar, Dim, RhsMode, RhsOptions>, false> {
  enum { ResultMode = transform_product_result<LhsMode, RhsMode>::Mode };
  using Lhs = Transform<Scalar, Dim, LhsMode, LhsOptions>;
  using Rhs = Transform<Scalar, Dim, RhsMode, RhsOptions>;
  using ResultType = Transform<Scalar, Dim, ResultMode, LhsOptions>;
  static EIGEN_DEVICE_FUNC ResultType run(const Lhs& lhs, const Rhs& rhs) {
    ResultType res;
    res.linear().noalias() = lhs.linear() * rhs.linear();
    res.translation() = lhs.linear() * rhs.translation() + lhs.translation();
    res.makeAffine();
    return res;
  }
};

template <typename Scalar, int Dim, int LhsMode, int LhsOptions, int RhsMode, int RhsOptions>
struct transform_transform_product_impl<Transform<Scalar, Dim, LhsMode, LhsOptions>,
                                        Transform<Scalar, Dim, RhsMode, RhsOptions>, true> {
  using Lhs = Transform<Scalar, Dim, LhsMode, LhsOptions>;
  using Rhs = Transform<Scalar, Dim, RhsMode, RhsOptions>;
  using ResultType = Transform<Scalar, Dim, Projective>;
  static EIGEN_DEVICE_FUNC ResultType run(const Lhs& lhs, const Rhs& rhs) {
    return ResultType(lhs.matrix() * rhs.matrix());
  }
};

template <typename Scalar, int Dim, int LhsOptions, int RhsOptions>
struct transform_transform_product_impl<Transform<Scalar, Dim, AffineCompact, LhsOptions>,
                                        Transform<Scalar, Dim, Projective, RhsOptions>, true> {
  using Lhs = Transform<Scalar, Dim, AffineCompact, LhsOptions>;
  using Rhs = Transform<Scalar, Dim, Projective, RhsOptions>;
  using ResultType = Transform<Scalar, Dim, Projective>;
  static EIGEN_DEVICE_FUNC ResultType run(const Lhs& lhs, const Rhs& rhs) {
    ResultType res;
    res.matrix().template topRows<Dim>() = lhs.matrix() * rhs.matrix();
    res.matrix().row(Dim) = rhs.matrix().row(Dim);
    return res;
  }
};

template <typename Scalar, int Dim, int LhsOptions, int RhsOptions>
struct transform_transform_product_impl<Transform<Scalar, Dim, Projective, LhsOptions>,
                                        Transform<Scalar, Dim, AffineCompact, RhsOptions>, true> {
  using Lhs = Transform<Scalar, Dim, Projective, LhsOptions>;
  using Rhs = Transform<Scalar, Dim, AffineCompact, RhsOptions>;
  using ResultType = Transform<Scalar, Dim, Projective>;
  static EIGEN_DEVICE_FUNC ResultType run(const Lhs& lhs, const Rhs& rhs) {
    ResultType res(lhs.matrix().template leftCols<Dim>() * rhs.matrix());
    res.matrix().col(Dim) += lhs.matrix().col(Dim);
    return res;
  }
};

}  // end namespace internal

}  // end namespace Eigen

#endif  // EIGEN_TRANSFORM_H
