// 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 LhsScalar, typename RhsScalar, typename BinaryOp, typename TargetScalar, typename = void>
struct has_matching_binary_op_traits : std::false_type {};

template <typename LhsScalar, typename RhsScalar, typename BinaryOp, typename TargetScalar>
struct has_matching_binary_op_traits<LhsScalar, RhsScalar, BinaryOp, TargetScalar,
                                     void_t<typename ScalarBinaryOpTraits<LhsScalar, RhsScalar, BinaryOp>::ReturnType>>
    : std::integral_constant<
          bool, std::is_convertible<typename ScalarBinaryOpTraits<LhsScalar, RhsScalar, BinaryOp>::ReturnType,
                                    TargetScalar>::value ||
                    std::is_assignable<TargetScalar&,
                                       typename ScalarBinaryOpTraits<LhsScalar, RhsScalar, BinaryOp>::ReturnType>::value> {};

template <typename TargetScalar, typename Derived, typename LhsScalar, typename RhsScalar, typename BinaryOp,
          typename = void>
struct transform_convert_arg {
  EIGEN_DEVICE_FUNC static auto run(const MatrixBase<Derived>& mat) { return mat.template cast<TargetScalar>(); }
};

template <typename TargetScalar, typename Derived, typename LhsScalar, typename RhsScalar, typename BinaryOp>
struct transform_convert_arg<
    TargetScalar, Derived, LhsScalar, RhsScalar, BinaryOp,
    std::enable_if_t<std::is_same<typename Derived::Scalar, TargetScalar>::value ||
                     has_matching_binary_op_traits<LhsScalar, RhsScalar, BinaryOp, TargetScalar>::value>> {
  EIGEN_DEVICE_FUNC static const Derived& run(const MatrixBase<Derived>& mat) { return mat.derived(); }
};

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() = 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() = 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() *
      internal::transform_convert_arg<Scalar, OtherDerived, Scalar, typename OtherDerived::Scalar,
                                      internal::fast_mult_op<Scalar, typename OtherDerived::Scalar>>::run(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() +=
        internal::transform_convert_arg<Scalar, OtherDerived, typename OtherDerived::Scalar, Scalar,
                                        internal::fast_mult_op<typename OtherDerived::Scalar, Scalar>>::run(other) *
        m_matrix.row(Dim);
  else
    translation() +=
        internal::transform_convert_arg<Scalar, OtherDerived, Scalar, typename OtherDerived::Scalar,
                                        internal::scalar_sum_op<Scalar, typename OtherDerived::Scalar>>::run(other);
  return *this;
}

namespace internal {

template <typename TransformType, typename RotationType, typename Enable = void>
struct transform_rotate_impl {
  EIGEN_DEVICE_FUNC static inline void run(TransformType& t, const RotationType& rotation) {
    t.linearExt() *= internal::toRotationMatrix<typename TransformType::Scalar, TransformType::Dim>(rotation);
  }
};

template <typename TransformType, typename Derived>
struct transform_rotate_impl<TransformType, Derived,
                             std::enable_if_t<std::is_base_of<MatrixBase<Derived>, Derived>::value>> {
  EIGEN_DEVICE_FUNC static inline void run(TransformType& t, const Derived& rotation) {
    using Scalar = typename TransformType::Scalar;
    t.linearExt() *= internal::transform_convert_arg<
        Scalar, Derived, Scalar, typename Derived::Scalar,
        internal::fast_mult_op<Scalar, typename Derived::Scalar>>::run(rotation);
  }
};

template <typename TransformType, typename Derived>
struct transform_rotate_impl<
    TransformType, Derived,
    std::enable_if_t<std::is_base_of<RotationBase<Derived, TransformType::Dim>, Derived>::value>> {
  EIGEN_DEVICE_FUNC static inline void run(TransformType& t, const Derived& rotation) {
    t.rotate(rotation.toRotationMatrix());
  }
};

template <typename TransformType, typename OtherScalar>
struct transform_rotate_impl<TransformType, OtherScalar, std::enable_if_t<std::is_scalar<OtherScalar>::value>> {
  EIGEN_DEVICE_FUNC static inline void run(TransformType& t, const OtherScalar& rotation) {
    EIGEN_STATIC_ASSERT(TransformType::Dim == 2, YOU_MADE_A_PROGRAMMING_MISTAKE)
    t.rotate(Rotation2D<OtherScalar>(rotation).toRotationMatrix());
  }
};

template <typename TransformType, typename RotationType, typename Enable = void>
struct transform_prerotate_impl {
  EIGEN_DEVICE_FUNC static inline void run(TransformType& t, const RotationType& rotation) {
    t.matrix().template block<TransformType::Dim, TransformType::HDim>(0, 0) =
        internal::toRotationMatrix<typename TransformType::Scalar, TransformType::Dim>(rotation) *
        t.matrix().template block<TransformType::Dim, TransformType::HDim>(0, 0);
  }
};

template <typename TransformType, typename Derived>
struct transform_prerotate_impl<TransformType, Derived,
                                std::enable_if_t<std::is_base_of<MatrixBase<Derived>, Derived>::value>> {
  EIGEN_DEVICE_FUNC static inline void run(TransformType& t, const Derived& rotation) {
    using Scalar = typename TransformType::Scalar;
    t.matrix().template block<TransformType::Dim, TransformType::HDim>(0, 0) =
        internal::transform_convert_arg<
            Scalar, Derived, typename Derived::Scalar, Scalar,
            internal::fast_mult_op<typename Derived::Scalar, Scalar>>::run(rotation) *
        t.matrix().template block<TransformType::Dim, TransformType::HDim>(0, 0);
  }
};

template <typename TransformType, typename Derived>
struct transform_prerotate_impl<
    TransformType, Derived,
    std::enable_if_t<std::is_base_of<RotationBase<Derived, TransformType::Dim>, Derived>::value>> {
  EIGEN_DEVICE_FUNC static inline void run(TransformType& t, const Derived& rotation) {
    t.prerotate(rotation.toRotationMatrix());
  }
};

template <typename TransformType, typename OtherScalar>
struct transform_prerotate_impl<TransformType, OtherScalar, std::enable_if_t<std::is_scalar<OtherScalar>::value>> {
  EIGEN_DEVICE_FUNC static inline void run(TransformType& t, const OtherScalar& rotation) {
    EIGEN_STATIC_ASSERT(TransformType::Dim == 2, YOU_MADE_A_PROGRAMMING_MISTAKE)
    t.prerotate(Rotation2D<OtherScalar>(rotation).toRotationMatrix());
  }
};

}  // end namespace internal

/** 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) {
  internal::transform_rotate_impl<Transform, RotationType>::run(*this, 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) {
  internal::transform_prerotate_impl<Transform, RotationType>::run(*this, rotation);
  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().noalias() = 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>().noalias() = 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
