// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2008-2010 Gael Guennebaud <gael.guennebaud@inria.fr>
// Copyright (C) 2009 Mathieu Gautier <mathieu.gautier@cea.fr>
//
// 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/.

#ifndef EIGEN_QUATERNION_H
#define EIGEN_QUATERNION_H
// IWYU pragma: private
#include "./InternalHeaderCheck.h"

namespace Eigen {

/***************************************************************************
 * Definition of QuaternionBase<Derived>
 * The implementation is at the end of the file
 ***************************************************************************/

namespace internal {
template <typename Other, int OtherRows = Other::RowsAtCompileTime, int OtherCols = Other::ColsAtCompileTime>
struct quaternionbase_assign_impl;
}

/** \geometry_module \ingroup Geometry_Module
 * \class QuaternionBase
 * \brief Base class for quaternion expressions
 * \tparam Derived derived type (CRTP)
 * \sa class Quaternion
 */
template <class Derived>
class QuaternionBase : public RotationBase<Derived, 3> {
 public:
  typedef RotationBase<Derived, 3> Base;

  using Base::operator*;
  using Base::derived;

  typedef typename internal::traits<Derived>::Scalar Scalar;
  typedef typename NumTraits<Scalar>::Real RealScalar;
  typedef typename internal::traits<Derived>::Coefficients Coefficients;
  typedef typename Coefficients::CoeffReturnType CoeffReturnType;
  typedef std::conditional_t<bool(internal::traits<Derived>::Flags& LvalueBit), Scalar&, CoeffReturnType>
      NonConstCoeffReturnType;

  enum { Flags = Eigen::internal::traits<Derived>::Flags };

  // typedef typename Matrix<Scalar,4,1> Coefficients;
  /** the type of a 3D vector */
  typedef Matrix<Scalar, 3, 1> Vector3;
  /** the equivalent rotation matrix type */
  typedef Matrix<Scalar, 3, 3> Matrix3;
  /** the equivalent angle-axis type */
  typedef AngleAxis<Scalar> AngleAxisType;

  /** \returns the \c x coefficient */
  EIGEN_DEVICE_FUNC constexpr CoeffReturnType x() const { return this->derived().coeffs().coeff(0); }
  /** \returns the \c y coefficient */
  EIGEN_DEVICE_FUNC constexpr CoeffReturnType y() const { return this->derived().coeffs().coeff(1); }
  /** \returns the \c z coefficient */
  EIGEN_DEVICE_FUNC constexpr CoeffReturnType z() const { return this->derived().coeffs().coeff(2); }
  /** \returns the \c w coefficient */
  EIGEN_DEVICE_FUNC constexpr CoeffReturnType w() const { return this->derived().coeffs().coeff(3); }

  /** \returns a reference to the \c x coefficient (if Derived is a non-const lvalue) */
  EIGEN_DEVICE_FUNC constexpr NonConstCoeffReturnType x() { return this->derived().coeffs().x(); }
  /** \returns a reference to the \c y coefficient (if Derived is a non-const lvalue) */
  EIGEN_DEVICE_FUNC constexpr NonConstCoeffReturnType y() { return this->derived().coeffs().y(); }
  /** \returns a reference to the \c z coefficient (if Derived is a non-const lvalue) */
  EIGEN_DEVICE_FUNC constexpr NonConstCoeffReturnType z() { return this->derived().coeffs().z(); }
  /** \returns a reference to the \c w coefficient (if Derived is a non-const lvalue) */
  EIGEN_DEVICE_FUNC constexpr NonConstCoeffReturnType w() { return this->derived().coeffs().w(); }

  /** \returns a read-only vector expression of the imaginary part (x,y,z) */
  EIGEN_DEVICE_FUNC inline const VectorBlock<const Coefficients, 3> vec() const { return coeffs().template head<3>(); }

  /** \returns a vector expression of the imaginary part (x,y,z) */
  EIGEN_DEVICE_FUNC inline VectorBlock<Coefficients, 3> vec() { return coeffs().template head<3>(); }

  /** \returns a read-only vector expression of the coefficients (x,y,z,w) */
  EIGEN_DEVICE_FUNC inline const typename internal::traits<Derived>::Coefficients& coeffs() const {
    return derived().coeffs();
  }

  /** \returns a vector containing the coefficients, rearranged into the order [\c w, \c x, \c y, \c z].
   *
   * This is the order expected by the \code Quaternion(const Scalar& w, const Scalar& x, const Scalar& y, const Scalar&
   * z) \endcode constructor, but not the order of the internal vector representation. Therefore, it returns a newly
   * constructed vector.
   *
   * \sa QuaternionBase::coeffsScalarLast()
   * */
  EIGEN_DEVICE_FUNC inline typename internal::traits<Derived>::Coefficients coeffsScalarFirst() const {
    return derived().coeffsScalarFirst();
  }

  /** \returns a vector containing the coefficients in their original order [\c x, \c y, \c z, \c w].
   *
   * This is equivalent to \code coeffs() \endcode, but returns a newly constructed vector for uniformity with \code
   * coeffsScalarFirst() \endcode.
   *
   * \sa QuaternionBase::coeffsScalarFirst()
   * */
  EIGEN_DEVICE_FUNC inline typename internal::traits<Derived>::Coefficients coeffsScalarLast() const {
    return derived().coeffsScalarLast();
  }

  /** \returns a vector expression of the coefficients (x,y,z,w) */
  EIGEN_DEVICE_FUNC inline typename internal::traits<Derived>::Coefficients& coeffs() { return derived().coeffs(); }

  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE QuaternionBase<Derived>& operator=(const QuaternionBase<Derived>& other);
  template <class OtherDerived>
  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived& operator=(const QuaternionBase<OtherDerived>& other);

  // disabled this copy operator as it is giving very strange compilation errors when compiling
  // test_stdvector with GCC 4.4.2. This looks like a GCC bug though, so feel free to re-enable it if it's
  // useful; however notice that we already have the templated operator= above and e.g. in MatrixBase
  // we didn't have to add, in addition to templated operator=, such a non-templated copy operator.
  //  Derived& operator=(const QuaternionBase& other)
  //  { return operator=<Derived>(other); }

  EIGEN_DEVICE_FUNC Derived& operator=(const AngleAxisType& aa);
  template <class OtherDerived>
  EIGEN_DEVICE_FUNC Derived& operator=(const MatrixBase<OtherDerived>& m);

  /** \returns a quaternion representing an identity rotation
   * \sa MatrixBase::Identity()
   */
  EIGEN_DEVICE_FUNC static inline Quaternion<Scalar> Identity() {
    return Quaternion<Scalar>(Scalar(1), Scalar(0), Scalar(0), Scalar(0));
  }

  /** \sa QuaternionBase::Identity(), MatrixBase::setIdentity()
   */
  EIGEN_DEVICE_FUNC inline QuaternionBase& setIdentity() {
    coeffs() << Scalar(0), Scalar(0), Scalar(0), Scalar(1);
    return *this;
  }

  /** \returns the squared norm of the quaternion's coefficients
   * \sa QuaternionBase::norm(), MatrixBase::squaredNorm()
   */
  EIGEN_DEVICE_FUNC inline Scalar squaredNorm() const { return coeffs().squaredNorm(); }

  /** \returns the norm of the quaternion's coefficients
   * \sa QuaternionBase::squaredNorm(), MatrixBase::norm()
   */
  EIGEN_DEVICE_FUNC inline Scalar norm() const { return coeffs().norm(); }

  /** Normalizes the quaternion \c *this
   * \sa normalized(), MatrixBase::normalize() */
  EIGEN_DEVICE_FUNC inline void normalize() { coeffs().normalize(); }
  /** \returns a normalized copy of \c *this
   * \sa normalize(), MatrixBase::normalized() */
  EIGEN_DEVICE_FUNC inline Quaternion<Scalar> normalized() const { return Quaternion<Scalar>(coeffs().normalized()); }

  /** \returns the dot product of \c *this and \a other
   * Geometrically speaking, the dot product of two unit quaternions
   * corresponds to the cosine of half the angle between the two rotations.
   * \sa angularDistance()
   */
  template <class OtherDerived>
  EIGEN_DEVICE_FUNC inline Scalar dot(const QuaternionBase<OtherDerived>& other) const {
    return coeffs().dot(other.coeffs());
  }

  template <class OtherDerived>
  EIGEN_DEVICE_FUNC Scalar angularDistance(const QuaternionBase<OtherDerived>& other) const;

  /** \returns an equivalent 3x3 rotation matrix */
  EIGEN_DEVICE_FUNC inline Matrix3 toRotationMatrix() const;

  /** \returns the quaternion which transform \a a into \a b through a rotation */
  template <typename Derived1, typename Derived2>
  EIGEN_DEVICE_FUNC Derived& setFromTwoVectors(const MatrixBase<Derived1>& a, const MatrixBase<Derived2>& b);

  template <class OtherDerived>
  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Quaternion<Scalar> operator*(const QuaternionBase<OtherDerived>& q) const;
  template <class OtherDerived>
  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived& operator*=(const QuaternionBase<OtherDerived>& q);

  /** \returns the quaternion describing the inverse rotation */
  EIGEN_DEVICE_FUNC Quaternion<Scalar> inverse() const;

  /** \returns the conjugated quaternion */
  EIGEN_DEVICE_FUNC Quaternion<Scalar> conjugate() const;

  template <class OtherDerived>
  EIGEN_DEVICE_FUNC Quaternion<Scalar> slerp(const Scalar& t, const QuaternionBase<OtherDerived>& other) const;

  /** \returns true if each coefficients of \c *this and \a other are all exactly equal.
   * \warning When using floating point scalar values you probably should rather use a
   *          fuzzy comparison such as isApprox()
   * \sa isApprox(), operator!= */
  template <class OtherDerived>
  EIGEN_DEVICE_FUNC inline bool operator==(const QuaternionBase<OtherDerived>& other) const {
    return coeffs() == other.coeffs();
  }

  /** \returns true if at least one pair of coefficients of \c *this and \a other are not exactly equal to each other.
   * \warning When using floating point scalar values you probably should rather use a
   *          fuzzy comparison such as isApprox()
   * \sa isApprox(), operator== */
  template <class OtherDerived>
  EIGEN_DEVICE_FUNC inline bool operator!=(const QuaternionBase<OtherDerived>& other) const {
    return coeffs() != other.coeffs();
  }

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

  /** return the result vector of \a v through the rotation*/
  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Vector3 _transformVector(const Vector3& v) const;

#ifdef EIGEN_PARSED_BY_DOXYGEN
  /** \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<Derived, Quaternion<NewScalarType> >::type cast() const;

#else

  template <typename NewScalarType>
  EIGEN_DEVICE_FUNC inline std::enable_if_t<internal::is_same<Scalar, NewScalarType>::value, const Derived&> cast()
      const {
    return derived();
  }

  template <typename NewScalarType>
  EIGEN_DEVICE_FUNC inline std::enable_if_t<!internal::is_same<Scalar, NewScalarType>::value,
                                            Quaternion<NewScalarType> >
  cast() const {
    return Quaternion<NewScalarType>(coeffs().template cast<NewScalarType>());
  }
#endif

#ifndef EIGEN_NO_IO
  friend std::ostream& operator<<(std::ostream& s, const QuaternionBase<Derived>& q) {
    s << q.x() << "i + " << q.y() << "j + " << q.z() << "k"
      << " + " << q.w();
    return s;
  }
#endif

#ifdef EIGEN_QUATERNIONBASE_PLUGIN
#include EIGEN_QUATERNIONBASE_PLUGIN
#endif
 protected:
  EIGEN_DEFAULT_COPY_CONSTRUCTOR(QuaternionBase)
  EIGEN_DEFAULT_EMPTY_CONSTRUCTOR_AND_DESTRUCTOR(QuaternionBase)
};

/***************************************************************************
 * Definition/implementation of Quaternion<Scalar>
 ***************************************************************************/

/** \geometry_module \ingroup Geometry_Module
 *
 * \class Quaternion
 *
 * \brief The quaternion class used to represent 3D orientations and rotations
 *
 * \tparam Scalar_ the scalar type, i.e., the type of the coefficients
 * \tparam Options_ controls the memory alignment of the coefficients. Can be \# AutoAlign or \# DontAlign. Default is
 * AutoAlign.
 *
 * This class represents a quaternion \f$ w+xi+yj+zk \f$ that is a convenient representation of
 * orientations and rotations of objects in three dimensions. Compared to other representations
 * like Euler angles or 3x3 matrices, quaternions offer the following advantages:
 * \li \b compact storage (4 scalars)
 * \li \b efficient to compose (28 flops),
 * \li \b stable spherical interpolation
 *
 * The following two typedefs are provided for convenience:
 * \li \c Quaternionf for \c float
 * \li \c Quaterniond for \c double
 *
 * \warning Operations interpreting the quaternion as rotation have undefined behavior if the quaternion is not
 * normalized.
 *
 * \sa  class AngleAxis, class Transform
 */

namespace internal {
template <typename Scalar_, int Options_>
struct traits<Quaternion<Scalar_, Options_> > {
  typedef Quaternion<Scalar_, Options_> PlainObject;
  typedef Scalar_ Scalar;
  typedef Matrix<Scalar_, 4, 1, Options_> Coefficients;
  enum { Alignment = internal::traits<Coefficients>::Alignment, Flags = LvalueBit };
};
}  // namespace internal

template <typename Scalar_, int Options_>
class Quaternion : public QuaternionBase<Quaternion<Scalar_, Options_> > {
 public:
  typedef QuaternionBase<Quaternion<Scalar_, Options_> > Base;
  enum { NeedsAlignment = internal::traits<Quaternion>::Alignment > 0 };

  typedef Scalar_ Scalar;

  EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Quaternion)
  using Base::operator*=;

  typedef typename internal::traits<Quaternion>::Coefficients Coefficients;
  typedef typename Base::AngleAxisType AngleAxisType;

  /** Default constructor leaving the quaternion uninitialized. */
  EIGEN_DEVICE_FUNC inline Quaternion() {}

  /** Constructs and initializes the quaternion \f$ w+xi+yj+zk \f$ from
   * its four coefficients \a w, \a x, \a y and \a z.
   *
   * \warning Note the order of the arguments: the real \a w coefficient first,
   * while internally the coefficients are stored in the following order:
   * [\c x, \c y, \c z, \c w]
   */
  EIGEN_DEVICE_FUNC inline Quaternion(const Scalar& w, const Scalar& x, const Scalar& y, const Scalar& z)
      : m_coeffs(x, y, z, w) {}

  /** Constructs and initializes a quaternion from its real part as a scalar,
   *  and its imaginary part as a 3-vector [\c x, \c y, \c z]
   */
  template <typename Derived>
  EIGEN_DEVICE_FUNC inline Quaternion(const Scalar& w, const Eigen::MatrixBase<Derived>& vec)
      : m_coeffs(vec.x(), vec.y(), vec.z(), w) {
    EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(Derived, 3);
  }

  /** Constructs and initialize a quaternion from the array data */
  EIGEN_DEVICE_FUNC explicit inline Quaternion(const Scalar* data) : m_coeffs(data) {}

  /** Copy constructor */
  template <class Derived>
  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Quaternion(const QuaternionBase<Derived>& other) {
    this->Base::operator=(other);
  }

  /** Constructs and initializes a quaternion from the angle-axis \a aa */
  EIGEN_DEVICE_FUNC explicit inline Quaternion(const AngleAxisType& aa) { *this = aa; }

  /** Constructs and initializes a quaternion from either:
   *  - a rotation matrix expression,
   *  - a 4D vector expression representing quaternion coefficients in the order [\c x, \c y, \c z, \c w].
   */
  template <typename Derived>
  EIGEN_DEVICE_FUNC explicit inline Quaternion(const MatrixBase<Derived>& other) {
    *this = other;
  }

  /** Explicit copy constructor with scalar conversion */
  template <typename OtherScalar, int OtherOptions>
  EIGEN_DEVICE_FUNC explicit inline Quaternion(const Quaternion<OtherScalar, OtherOptions>& other) {
    m_coeffs = other.coeffs().template cast<Scalar>();
  }

  // We define a copy constructor, which means we don't get an implicit move constructor or assignment operator.
  /** Default move constructor */
  EIGEN_DEVICE_FUNC inline Quaternion(Quaternion&& other) noexcept(std::is_nothrow_move_constructible<Scalar>::value)
      : m_coeffs(std::move(other.coeffs())) {}

  /** Default move assignment operator */
  EIGEN_DEVICE_FUNC Quaternion& operator=(Quaternion&& other) noexcept(std::is_nothrow_move_assignable<Scalar>::value) {
    m_coeffs = std::move(other.coeffs());
    return *this;
  }

  EIGEN_DEVICE_FUNC static Quaternion UnitRandom();

  EIGEN_DEVICE_FUNC static Quaternion FromCoeffsScalarLast(const Scalar& x, const Scalar& y, const Scalar& z,
                                                           const Scalar& w);

  EIGEN_DEVICE_FUNC static Quaternion FromCoeffsScalarFirst(const Scalar& w, const Scalar& x, const Scalar& y,
                                                            const Scalar& z);

  template <typename Derived1, typename Derived2>
  EIGEN_DEVICE_FUNC static Quaternion FromTwoVectors(const MatrixBase<Derived1>& a, const MatrixBase<Derived2>& b);

  EIGEN_DEVICE_FUNC inline Coefficients& coeffs() { return m_coeffs; }
  EIGEN_DEVICE_FUNC inline const Coefficients& coeffs() const { return m_coeffs; }

  EIGEN_DEVICE_FUNC inline Coefficients coeffsScalarLast() const { return m_coeffs; }

  EIGEN_DEVICE_FUNC inline Coefficients coeffsScalarFirst() const {
    return {m_coeffs.w(), m_coeffs.x(), m_coeffs.y(), m_coeffs.z()};
  }
  EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF(bool(NeedsAlignment))

#ifdef EIGEN_QUATERNION_PLUGIN
#include EIGEN_QUATERNION_PLUGIN
#endif

 protected:
  Coefficients m_coeffs;

#ifndef EIGEN_PARSED_BY_DOXYGEN
  EIGEN_STATIC_ASSERT((Options_ & DontAlign) == Options_, INVALID_MATRIX_TEMPLATE_PARAMETERS)
#endif
};

/** \ingroup Geometry_Module
 * single precision quaternion type */
typedef Quaternion<float> Quaternionf;
/** \ingroup Geometry_Module
 * double precision quaternion type */
typedef Quaternion<double> Quaterniond;

/***************************************************************************
 * Specialization of Map<Quaternion<Scalar>>
 ***************************************************************************/

namespace internal {
template <typename Scalar_, int Options_>
struct traits<Map<Quaternion<Scalar_>, Options_> >
    : traits<Quaternion<Scalar_, (int(Options_) & Aligned) == Aligned ? AutoAlign : DontAlign> > {
  typedef Map<Matrix<Scalar_, 4, 1>, Options_> Coefficients;
};
}  // namespace internal

namespace internal {
template <typename Scalar_, int Options_>
struct traits<Map<const Quaternion<Scalar_>, Options_> >
    : traits<Quaternion<Scalar_, (int(Options_) & Aligned) == Aligned ? AutoAlign : DontAlign> > {
  typedef Map<const Matrix<Scalar_, 4, 1>, Options_> Coefficients;
  typedef traits<Quaternion<Scalar_, (int(Options_) & Aligned) == Aligned ? AutoAlign : DontAlign> > TraitsBase;
  enum { Flags = TraitsBase::Flags & ~LvalueBit };
};
}  // namespace internal

/** \ingroup Geometry_Module
 * \brief Quaternion expression mapping a constant memory buffer
 *
 * \tparam Scalar_ the type of the Quaternion coefficients
 * \tparam Options_ see class Map
 *
 * This is a specialization of class Map for Quaternion. This class allows to view
 * a 4 scalar memory buffer as an Eigen's Quaternion object.
 *
 * \sa class Map, class Quaternion, class QuaternionBase
 */
template <typename Scalar_, int Options_>
class Map<const Quaternion<Scalar_>, Options_> : public QuaternionBase<Map<const Quaternion<Scalar_>, Options_> > {
 public:
  typedef QuaternionBase<Map<const Quaternion<Scalar_>, Options_> > Base;

  typedef Scalar_ Scalar;
  typedef typename internal::traits<Map>::Coefficients Coefficients;
  EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Map)
  using Base::operator*=;

  /** Constructs a Mapped Quaternion object from the pointer \a coeffs
   *
   * The pointer \a coeffs must reference the four coefficients of Quaternion in the following order:
   * \code *coeffs == {x, y, z, w} \endcode
   *
   * If the template parameter Options_ is set to #Aligned, then the pointer coeffs must be aligned. */
  EIGEN_DEVICE_FUNC explicit EIGEN_STRONG_INLINE Map(const Scalar* coeffs) : m_coeffs(coeffs) {}

  EIGEN_DEVICE_FUNC inline const Coefficients& coeffs() const { return m_coeffs; }

  EIGEN_DEVICE_FUNC inline Coefficients coeffsScalarLast() const { return m_coeffs; }

  EIGEN_DEVICE_FUNC inline Coefficients coeffsScalarFirst() const {
    return {m_coeffs.w(), m_coeffs.x(), m_coeffs.y(), m_coeffs.z()};
  }

 protected:
  const Coefficients m_coeffs;
};

/** \ingroup Geometry_Module
 * \brief Expression of a quaternion from a memory buffer
 *
 * \tparam Scalar_ the type of the Quaternion coefficients
 * \tparam Options_ see class Map
 *
 * This is a specialization of class Map for Quaternion. This class allows to view
 * a 4 scalar memory buffer as an Eigen's  Quaternion object.
 *
 * \sa class Map, class Quaternion, class QuaternionBase
 */
template <typename Scalar_, int Options_>
class Map<Quaternion<Scalar_>, Options_> : public QuaternionBase<Map<Quaternion<Scalar_>, Options_> > {
 public:
  typedef QuaternionBase<Map<Quaternion<Scalar_>, Options_> > Base;

  typedef Scalar_ Scalar;
  typedef typename internal::traits<Map>::Coefficients Coefficients;
  EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Map)
  using Base::operator*=;

  /** Constructs a Mapped Quaternion object from the pointer \a coeffs
   *
   * The pointer \a coeffs must reference the four coefficients of Quaternion in the following order:
   * \code *coeffs == {x, y, z, w} \endcode
   *
   * If the template parameter Options_ is set to #Aligned, then the pointer coeffs must be aligned. */
  EIGEN_DEVICE_FUNC explicit EIGEN_STRONG_INLINE Map(Scalar* coeffs) : m_coeffs(coeffs) {}

  EIGEN_DEVICE_FUNC inline Coefficients& coeffs() { return m_coeffs; }
  EIGEN_DEVICE_FUNC inline const Coefficients& coeffs() const { return m_coeffs; }

  EIGEN_DEVICE_FUNC inline Coefficients coeffsScalarLast() const { return m_coeffs; }

  EIGEN_DEVICE_FUNC inline Coefficients coeffsScalarFirst() const {
    return {m_coeffs.w(), m_coeffs.x(), m_coeffs.y(), m_coeffs.z()};
  }

 protected:
  Coefficients m_coeffs;
};

/** \ingroup Geometry_Module
 * Map an unaligned array of single precision scalars as a quaternion */
typedef Map<Quaternion<float>, 0> QuaternionMapf;
/** \ingroup Geometry_Module
 * Map an unaligned array of double precision scalars as a quaternion */
typedef Map<Quaternion<double>, 0> QuaternionMapd;
/** \ingroup Geometry_Module
 * Map a 16-byte aligned array of single precision scalars as a quaternion */
typedef Map<Quaternion<float>, Aligned> QuaternionMapAlignedf;
/** \ingroup Geometry_Module
 * Map a 16-byte aligned array of double precision scalars as a quaternion */
typedef Map<Quaternion<double>, Aligned> QuaternionMapAlignedd;

/***************************************************************************
 * Implementation of QuaternionBase methods
 ***************************************************************************/

// Generic Quaternion * Quaternion product
// This product can be specialized for a given architecture via the Arch template argument.
namespace internal {
template <int Arch, class Derived1, class Derived2, typename Scalar>
struct quat_product {
  EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE Quaternion<Scalar> run(const QuaternionBase<Derived1>& a,
                                                                      const QuaternionBase<Derived2>& b) {
    return Quaternion<Scalar>(a.w() * b.w() - a.x() * b.x() - a.y() * b.y() - a.z() * b.z(),
                              a.w() * b.x() + a.x() * b.w() + a.y() * b.z() - a.z() * b.y(),
                              a.w() * b.y() + a.y() * b.w() + a.z() * b.x() - a.x() * b.z(),
                              a.w() * b.z() + a.z() * b.w() + a.x() * b.y() - a.y() * b.x());
  }
};
}  // namespace internal

/** \returns the concatenation of two rotations as a quaternion-quaternion product */
template <class Derived>
template <class OtherDerived>
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Quaternion<typename internal::traits<Derived>::Scalar>
QuaternionBase<Derived>::operator*(const QuaternionBase<OtherDerived>& other) const {
  EIGEN_STATIC_ASSERT(
      (internal::is_same<typename Derived::Scalar, typename OtherDerived::Scalar>::value),
      YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY)
  return internal::quat_product<Architecture::Target, Derived, OtherDerived,
                                typename internal::traits<Derived>::Scalar>::run(*this, other);
}

/** \sa operator*(Quaternion) */
template <class Derived>
template <class OtherDerived>
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived& QuaternionBase<Derived>::operator*=(
    const QuaternionBase<OtherDerived>& other) {
  derived() = derived() * other.derived();
  return derived();
}

/** Rotation of a vector by a quaternion.
 * \remarks If the quaternion is used to rotate several points (>1)
 * then it is much more efficient to first convert it to a 3x3 Matrix.
 * Comparison of the operation cost for n transformations:
 *   - Quaternion2:    30n
 *   - Via a Matrix3: 24 + 15n
 */
template <class Derived>
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE typename QuaternionBase<Derived>::Vector3
QuaternionBase<Derived>::_transformVector(const Vector3& v) const {
  // Note that this algorithm comes from the optimization by hand
  // of the conversion to a Matrix followed by a Matrix/Vector product.
  // It appears to be much faster than the common algorithm found
  // in the literature (30 versus 39 flops). It also requires two
  // Vector3 as temporaries.
  Vector3 uv = this->vec().cross(v);
  uv += uv;
  return v + this->w() * uv + this->vec().cross(uv);
}

template <class Derived>
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE QuaternionBase<Derived>& QuaternionBase<Derived>::operator=(
    const QuaternionBase<Derived>& other) {
  coeffs() = other.coeffs();
  return derived();
}

template <class Derived>
template <class OtherDerived>
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived& QuaternionBase<Derived>::operator=(
    const QuaternionBase<OtherDerived>& other) {
  coeffs() = other.coeffs();
  return derived();
}

/** Set \c *this from an angle-axis \a aa and returns a reference to \c *this
 */
template <class Derived>
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived& QuaternionBase<Derived>::operator=(const AngleAxisType& aa) {
  EIGEN_USING_STD(cos)
  EIGEN_USING_STD(sin)
  Scalar ha = Scalar(0.5) * aa.angle();  // Scalar(0.5) to suppress precision loss warnings
  this->w() = cos(ha);
  this->vec() = sin(ha) * aa.axis();
  return derived();
}

/** Set \c *this from the expression \a xpr:
 *   - if \a xpr is a 4x1 vector, then \a xpr is assumed to be a quaternion
 *   - if \a xpr is a 3x3 matrix, then \a xpr is assumed to be rotation matrix
 *     and \a xpr is converted to a quaternion
 */

template <class Derived>
template <class MatrixDerived>
EIGEN_DEVICE_FUNC inline Derived& QuaternionBase<Derived>::operator=(const MatrixBase<MatrixDerived>& xpr) {
  EIGEN_STATIC_ASSERT(
      (internal::is_same<typename Derived::Scalar, typename MatrixDerived::Scalar>::value),
      YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY)
  internal::quaternionbase_assign_impl<MatrixDerived>::run(*this, xpr.derived());
  return derived();
}

/** Convert the quaternion to a 3x3 rotation matrix. The quaternion is required to
 * be normalized, otherwise the result is undefined.
 */
template <class Derived>
EIGEN_DEVICE_FUNC inline typename QuaternionBase<Derived>::Matrix3 QuaternionBase<Derived>::toRotationMatrix(
    void) const {
  // NOTE if inlined, then gcc 4.2 and 4.4 get rid of the temporary (not gcc 4.3 !!)
  // if not inlined then the cost of the return by value is huge ~ +35%,
  // however, not inlining this function is an order of magnitude slower, so
  // it has to be inlined, and so the return by value is not an issue
  Matrix3 res;

  const Scalar tx = Scalar(2) * this->x();
  const Scalar ty = Scalar(2) * this->y();
  const Scalar tz = Scalar(2) * this->z();
  const Scalar twx = tx * this->w();
  const Scalar twy = ty * this->w();
  const Scalar twz = tz * this->w();
  const Scalar txx = tx * this->x();
  const Scalar txy = ty * this->x();
  const Scalar txz = tz * this->x();
  const Scalar tyy = ty * this->y();
  const Scalar tyz = tz * this->y();
  const Scalar tzz = tz * this->z();

  res.coeffRef(0, 0) = Scalar(1) - (tyy + tzz);
  res.coeffRef(0, 1) = txy - twz;
  res.coeffRef(0, 2) = txz + twy;
  res.coeffRef(1, 0) = txy + twz;
  res.coeffRef(1, 1) = Scalar(1) - (txx + tzz);
  res.coeffRef(1, 2) = tyz - twx;
  res.coeffRef(2, 0) = txz - twy;
  res.coeffRef(2, 1) = tyz + twx;
  res.coeffRef(2, 2) = Scalar(1) - (txx + tyy);

  return res;
}

/** Sets \c *this to be a quaternion representing a rotation between
 * the two arbitrary vectors \a a and \a b. In other words, the built
 * rotation represent a rotation sending the line of direction \a a
 * to the line of direction \a b, both lines passing through the origin.
 *
 * \returns a reference to \c *this.
 *
 * Note that the two input vectors do \b not have to be normalized, and
 * do not need to have the same norm.
 */
template <class Derived>
template <typename Derived1, typename Derived2>
EIGEN_DEVICE_FUNC inline Derived& QuaternionBase<Derived>::setFromTwoVectors(const MatrixBase<Derived1>& a,
                                                                             const MatrixBase<Derived2>& b) {
  EIGEN_USING_STD(sqrt)
  Vector3 v0 = a.normalized();
  Vector3 v1 = b.normalized();
  Scalar c = v1.dot(v0);

  // if dot == -1, vectors are nearly opposites
  // => accurately compute the rotation axis by computing the
  //    intersection of the two planes. This is done by solving:
  //       x^T v0 = 0
  //       x^T v1 = 0
  //    under the constraint:
  //       ||x|| = 1
  //    which yields a singular value problem
  if (c < Scalar(-1) + NumTraits<Scalar>::dummy_precision()) {
    c = numext::maxi(c, Scalar(-1));
    Matrix<Scalar, 2, 3> m;
    m << v0.transpose(), v1.transpose();
    JacobiSVD<Matrix<Scalar, 2, 3>, ComputeFullV> svd(m);
    Vector3 axis = svd.matrixV().col(2);

    Scalar w2 = (Scalar(1) + c) * Scalar(0.5);
    this->w() = sqrt(w2);
    this->vec() = axis * sqrt(Scalar(1) - w2);
    return derived();
  }
  Vector3 axis = v0.cross(v1);
  Scalar s = sqrt((Scalar(1) + c) * Scalar(2));
  Scalar invs = Scalar(1) / s;
  this->vec() = axis * invs;
  this->w() = s * Scalar(0.5);

  return derived();
}

/** \returns a random unit quaternion following a uniform distribution law on SO(3)
 *
 * \note The implementation is based on http://planning.cs.uiuc.edu/node198.html
 */
template <typename Scalar, int Options>
EIGEN_DEVICE_FUNC Quaternion<Scalar, Options> Quaternion<Scalar, Options>::UnitRandom() {
  EIGEN_USING_STD(sqrt)
  EIGEN_USING_STD(sin)
  EIGEN_USING_STD(cos)
  const Scalar u1 = internal::random<Scalar>(0, 1), u2 = internal::random<Scalar>(0, 2 * EIGEN_PI),
               u3 = internal::random<Scalar>(0, 2 * EIGEN_PI);
  const Scalar a = sqrt(Scalar(1) - u1), b = sqrt(u1);
  return Quaternion(a * sin(u2), a * cos(u2), b * sin(u3), b * cos(u3));
}

/** Constructs a quaternion from its coefficients in the order [\c x, \c y, \c z, \c w], i.e. vector part [\c x, \c y,
 * \c z] first, scalar part \a w LAST.
 *
 * This factory accepts the parameters in the same order as the underlying coefficient vector. Consider using this
 * factory function to make the parameter ordering explicit.
 */
template <typename Scalar, int Options>
EIGEN_DEVICE_FUNC Quaternion<Scalar, Options> Quaternion<Scalar, Options>::FromCoeffsScalarLast(const Scalar& x,
                                                                                                const Scalar& y,
                                                                                                const Scalar& z,
                                                                                                const Scalar& w) {
  return Quaternion(w, x, y, z);
}

/** Constructs a quaternion from its coefficients in the order [\c w, \c x, \c y, \c z], i.e. scalar part \a w FIRST,
 * vector part [\c x, \c y, \c z] last.
 *
 * This factory accepts the parameters in the same order as the constructor \code Quaternion(const Scalar& w, const
 * Scalar& x, const Scalar& y, const Scalar& z) \endcode. Consider using this factory function to make the parameter
 * ordering explicit.
 */
template <typename Scalar, int Options>
EIGEN_DEVICE_FUNC Quaternion<Scalar, Options> Quaternion<Scalar, Options>::FromCoeffsScalarFirst(const Scalar& w,
                                                                                                 const Scalar& x,
                                                                                                 const Scalar& y,
                                                                                                 const Scalar& z) {
  return Quaternion(w, x, y, z);
}

/** Returns a quaternion representing a rotation between
 * the two arbitrary vectors \a a and \a b. In other words, the built
 * rotation represent a rotation sending the line of direction \a a
 * to the line of direction \a b, both lines passing through the origin.
 *
 * \returns resulting quaternion
 *
 * Note that the two input vectors do \b not have to be normalized, and
 * do not need to have the same norm.
 */
template <typename Scalar, int Options>
template <typename Derived1, typename Derived2>
EIGEN_DEVICE_FUNC Quaternion<Scalar, Options> Quaternion<Scalar, Options>::FromTwoVectors(
    const MatrixBase<Derived1>& a, const MatrixBase<Derived2>& b) {
  Quaternion quat;
  quat.setFromTwoVectors(a, b);
  return quat;
}

/** \returns the multiplicative inverse of \c *this
 * Note that in most cases, i.e., if you simply want the opposite rotation,
 * and/or the quaternion is normalized, then it is enough to use the conjugate.
 *
 * \sa QuaternionBase::conjugate()
 */
template <class Derived>
EIGEN_DEVICE_FUNC inline Quaternion<typename internal::traits<Derived>::Scalar> QuaternionBase<Derived>::inverse()
    const {
  // FIXME should this function be called multiplicativeInverse and conjugate() be called inverse() or opposite()  ??
  Scalar n2 = this->squaredNorm();
  if (n2 > Scalar(0))
    return Quaternion<Scalar>(conjugate().coeffs() / n2);
  else {
    // return an invalid result to flag the error
    return Quaternion<Scalar>(Coefficients::Zero());
  }
}

// Generic conjugate of a Quaternion
namespace internal {
template <int Arch, class Derived, typename Scalar>
struct quat_conj {
  EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE Quaternion<Scalar> run(const QuaternionBase<Derived>& q) {
    return Quaternion<Scalar>(q.w(), -q.x(), -q.y(), -q.z());
  }
};
}  // namespace internal

/** \returns the conjugate of the \c *this which is equal to the multiplicative inverse
 * if the quaternion is normalized.
 * The conjugate of a quaternion represents the opposite rotation.
 *
 * \sa Quaternion2::inverse()
 */
template <class Derived>
EIGEN_DEVICE_FUNC inline Quaternion<typename internal::traits<Derived>::Scalar> QuaternionBase<Derived>::conjugate()
    const {
  return internal::quat_conj<Architecture::Target, Derived, typename internal::traits<Derived>::Scalar>::run(*this);
}

/** \returns the angle (in radian) between two rotations
 * \sa dot()
 */
template <class Derived>
template <class OtherDerived>
EIGEN_DEVICE_FUNC inline typename internal::traits<Derived>::Scalar QuaternionBase<Derived>::angularDistance(
    const QuaternionBase<OtherDerived>& other) const {
  EIGEN_USING_STD(atan2)
  Quaternion<Scalar> d = (*this) * other.conjugate();
  return Scalar(2) * atan2(d.vec().norm(), numext::abs(d.w()));
}

/** \returns the spherical linear interpolation between the two quaternions
 * \c *this and \a other at the parameter \a t in [0;1].
 *
 * This represents an interpolation for a constant motion between \c *this and \a other,
 * see also http://en.wikipedia.org/wiki/Slerp.
 */
template <class Derived>
template <class OtherDerived>
EIGEN_DEVICE_FUNC Quaternion<typename internal::traits<Derived>::Scalar> QuaternionBase<Derived>::slerp(
    const Scalar& t, const QuaternionBase<OtherDerived>& other) const {
  EIGEN_USING_STD(acos)
  EIGEN_USING_STD(sin)
  const Scalar one = Scalar(1) - NumTraits<Scalar>::epsilon();
  Scalar d = this->dot(other);
  Scalar absD = numext::abs(d);

  Scalar scale0;
  Scalar scale1;

  if (absD >= one) {
    scale0 = Scalar(1) - t;
    scale1 = t;
  } else {
    // theta is the angle between the 2 quaternions
    Scalar theta = acos(absD);
    Scalar sinTheta = numext::sqrt(Scalar(1) - absD * absD);

    scale0 = sin((Scalar(1) - t) * theta) / sinTheta;
    scale1 = sin((t * theta)) / sinTheta;
  }
  if (d < Scalar(0)) scale1 = -scale1;

  return Quaternion<Scalar>(scale0 * coeffs() + scale1 * other.coeffs());
}

namespace internal {

// set from a rotation matrix
template <typename Other>
struct quaternionbase_assign_impl<Other, 3, 3> {
  typedef typename Other::Scalar Scalar;
  template <class Derived>
  EIGEN_DEVICE_FUNC static inline void run(QuaternionBase<Derived>& q, const Other& a_mat) {
    const typename internal::nested_eval<Other, 2>::type mat(a_mat);
    EIGEN_USING_STD(sqrt)
    // This algorithm comes from  "Quaternion Calculus and Fast Animation",
    // Ken Shoemake, 1987 SIGGRAPH course notes
    Scalar t = mat.trace();
    if (t > Scalar(0)) {
      t = sqrt(t + Scalar(1.0));
      q.w() = Scalar(0.5) * t;
      t = Scalar(0.5) / t;
      q.x() = (mat.coeff(2, 1) - mat.coeff(1, 2)) * t;
      q.y() = (mat.coeff(0, 2) - mat.coeff(2, 0)) * t;
      q.z() = (mat.coeff(1, 0) - mat.coeff(0, 1)) * t;
    } else {
      Index i = 0;
      if (mat.coeff(1, 1) > mat.coeff(0, 0)) i = 1;
      if (mat.coeff(2, 2) > mat.coeff(i, i)) i = 2;
      Index j = (i + 1) % 3;
      Index k = (j + 1) % 3;

      t = sqrt(mat.coeff(i, i) - mat.coeff(j, j) - mat.coeff(k, k) + Scalar(1.0));
      q.coeffs().coeffRef(i) = Scalar(0.5) * t;
      t = Scalar(0.5) / t;
      q.w() = (mat.coeff(k, j) - mat.coeff(j, k)) * t;
      q.coeffs().coeffRef(j) = (mat.coeff(j, i) + mat.coeff(i, j)) * t;
      q.coeffs().coeffRef(k) = (mat.coeff(k, i) + mat.coeff(i, k)) * t;
    }
  }
};

// set from a vector of coefficients assumed to be a quaternion
template <typename Other>
struct quaternionbase_assign_impl<Other, 4, 1> {
  typedef typename Other::Scalar Scalar;
  template <class Derived>
  EIGEN_DEVICE_FUNC static inline void run(QuaternionBase<Derived>& q, const Other& vec) {
    q.coeffs() = vec;
  }
};

}  // end namespace internal

}  // end namespace Eigen

#endif  // EIGEN_QUATERNION_H
