// 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/.
// SPDX-License-Identifier: 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:
  using Base = RotationBase<Derived, 3>;

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

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

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

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

  /** \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);

  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 <typename OtherDerived>
  EIGEN_DEVICE_FUNC Derived& setFromScaledAxis(const MatrixBase<OtherDerived>& scaled_axis);

  EIGEN_DEVICE_FUNC inline Vector3 toScaledAxis() const;

  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<std::is_same<Scalar, NewScalarType>::value, const Derived&> cast() const {
    return derived();
  }

  template <typename NewScalarType>
  EIGEN_DEVICE_FUNC inline std::enable_if_t<!std::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_> > {
  using PlainObject = Quaternion<Scalar_, Options_>;
  using Scalar = Scalar_;
  using Coefficients = Matrix<Scalar_, 4, 1, Options_>;
  enum { Alignment = internal::traits<Coefficients>::Alignment, Flags = LvalueBit };
};
}  // namespace internal

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

  using Scalar = Scalar_;

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

  using Coefficients = typename internal::traits<Quaternion>::Coefficients;
  using AngleAxisType = typename Base::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);

  template <typename Derived>
  EIGEN_DEVICE_FUNC static Quaternion FromScaledAxis(const MatrixBase<Derived>& scaled_axis);

  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 */
using Quaternionf = Quaternion<float>;
/** \ingroup Geometry_Module
 * double precision quaternion type */
using Quaterniond = Quaternion<double>;

/***************************************************************************
 * 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> > {
  using Coefficients = Map<Matrix<Scalar_, 4, 1>, Options_>;
};
}  // 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> > {
  using Coefficients = Map<const Matrix<Scalar_, 4, 1>, Options_>;
  using TraitsBase = traits<Quaternion<Scalar_, (int(Options_) & Aligned) == Aligned ? AutoAlign : DontAlign>>;
  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:
  using Base = QuaternionBase<Map<const Quaternion<Scalar_>, Options_>>;

  using Scalar = Scalar_;
  using Coefficients = typename internal::traits<Map>::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:
  using Base = QuaternionBase<Map<Quaternion<Scalar_>, Options_>>;

  using Scalar = Scalar_;
  using Coefficients = typename internal::traits<Map>::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 */
using QuaternionMapf = Map<Quaternion<float>, 0>;
/** \ingroup Geometry_Module
 * Map an unaligned array of double precision scalars as a quaternion */
using QuaternionMapd = Map<Quaternion<double>, 0>;
/** \ingroup Geometry_Module
 * Map a 16-byte aligned array of single precision scalars as a quaternion */
using QuaternionMapAlignedf = Map<Quaternion<float>, Aligned>;
/** \ingroup Geometry_Module
 * Map a 16-byte aligned array of double precision scalars as a quaternion */
using QuaternionMapAlignedd = Map<Quaternion<double>, Aligned>;

/***************************************************************************
 * 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(
      (std::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:
 *   - Quaternion:    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(
      (std::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 {
  // Keep this inline: forcing an out-of-line call is much more expensive than returning Matrix3 by value.
  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
  // => any axis perpendicular to v0 will do for a ~180 degree rotation.
  if (c < Scalar(-1) + NumTraits<Scalar>::dummy_precision()) {
    c = numext::maxi(c, Scalar(-1));
    Vector3 axis = v0.unitOrthogonal();

    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();
}

/** Sets \c *this to the unit quaternion representing the rotation by `||scaled_axis||` radians
 * around the axis `scaled_axis / ||scaled_axis||`. This is the SO(3) exponential map.
 *
 * The closed form \f$ q = (\cos(\theta/2),\;(\sin(\theta/2)/\theta)\,v),\;\theta=\|v\| \f$ is
 * evaluated directly for every non-zero input; the limit value (the identity quaternion) is
 * substituted only at the bit-exact zero input. No Taylor expansion and no scalar-type-
 * dependent threshold are involved, and the result is accurate to a few ULPs across the
 * full range of finite inputs.
 *
 * \sa toScaledAxis(), Quaternion::FromScaledAxis()
 */
template <class Derived>
template <typename OtherDerived>
EIGEN_DEVICE_FUNC inline Derived& QuaternionBase<Derived>::setFromScaledAxis(
    const MatrixBase<OtherDerived>& scaled_axis) {
  EIGEN_USING_STD(sin)
  EIGEN_USING_STD(cos)
  EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(OtherDerived, 3)

  // Materialise the input once so the caller's expression (e.g. omega*dt) is not
  // recomputed by the norm and the subsequent assignment to vec().
  const Vector3 v = scaled_axis;

  // Fast path with stableNorm() fallback when norm() returns a suspiciously small
  // value (below epsilon, where squaredNorm() may have underflowed); same idiom
  // as AngleAxis::operator=(QuaternionBase).
  Scalar angle = v.norm();
  if (angle < NumTraits<Scalar>::epsilon()) angle = v.stableNorm();
  if (numext::is_exactly_zero(angle)) {
    this->w() = Scalar(1);
    this->vec().setZero();
    return derived();
  }

  const Scalar half_angle = Scalar(0.5) * angle;
  this->w() = cos(half_angle);
  this->vec() = (sin(half_angle) / angle) * v;
  return derived();
}

/** \returns the rotation vector (axis scaled by the rotation angle in `[0, pi]`)
 * corresponding to \c *this. This is the SO(3) logarithmic map and the inverse of
 * setFromScaledAxis().
 *
 * The closed form \f$ v = (2\,\mathrm{atan2}(\|q_v\|,\,q_w)/\|q_v\|)\, q_v \f$ is evaluated
 * directly for every quaternion with non-zero imaginary part; the limit value (the zero
 * vector) is substituted only at the bit-exact zero imaginary part. The IEEE corner case
 * `w == -0.0` is handled by passing \c |w| to \c atan2 and recovering the sign separately,
 * mirroring AngleAxis::operator=(QuaternionBase). The result is accurate to a few ULPs.
 *
 * \pre \c *this is approximately a unit quaternion.
 * \sa setFromScaledAxis(), Quaternion::FromScaledAxis()
 */
template <class Derived>
EIGEN_DEVICE_FUNC inline typename QuaternionBase<Derived>::Vector3 QuaternionBase<Derived>::toScaledAxis() const {
  EIGEN_USING_STD(atan2)
  eigen_assert(internal::isApprox(this->squaredNorm(), Scalar(1), Scalar(8) * NumTraits<Scalar>::dummy_precision()) &&
               "QuaternionBase::toScaledAxis(): the quaternion must be approximately a unit quaternion");

  // Fast path with stableNorm() fallback; same idiom as AngleAxis::operator=(QuaternionBase).
  Scalar sin_half_angle = this->vec().norm();
  if (sin_half_angle < NumTraits<Scalar>::epsilon()) sin_half_angle = this->vec().stableNorm();
  if (numext::is_exactly_zero(sin_half_angle)) return Vector3::Zero();

  // |w| in atan2 prevents -0.0 from flipping the sign; recover it via the comparison below
  // (false for both +0.0 and -0.0).
  // Cannot overflow: for unit q, atan2(s, |c|) is O(s) as s -> 0, so k stays in [2, pi].
  Scalar k = Scalar(2) * atan2(sin_half_angle, numext::abs(this->w())) / sin_half_angle;
  if (this->w() < Scalar(0)) k = -k;
  return k * this->vec();
}

/** \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 a unit quaternion representing the rotation by `||scaled_axis||` radians around
 * the axis `scaled_axis / ||scaled_axis||`. The natural building block for SO(3)-aware
 * integration of a body angular velocity \a omega over a small interval \a dt:
 * \code Quaterniond q_next = q_curr * Quaterniond::FromScaledAxis(omega * dt); \endcode
 * \sa setFromScaledAxis(), toScaledAxis()
 */
template <typename Scalar, int Options>
template <typename Derived>
EIGEN_DEVICE_FUNC Quaternion<Scalar, Options> Quaternion<Scalar, Options>::FromScaledAxis(
    const MatrixBase<Derived>& scaled_axis) {
  Quaternion quat;
  quat.setFromScaledAxis(scaled_axis);
  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: consider renaming to multiplicativeInverse() and renaming conjugate() to 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 Quaternion::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) {
    // Near-parallel quaternions: use lerp to avoid division by ~zero sinTheta.
    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> {
  using Scalar = typename Other::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(numext::maxi(t + Scalar(1.0), Scalar(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;

      // Guard against slightly negative argument from non-orthogonal matrices.
      t = sqrt(numext::maxi(mat.coeff(i, i) - mat.coeff(j, j) - mat.coeff(k, k) + Scalar(1.0), Scalar(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> {
  using Scalar = typename Other::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
