Re: [eigen] Mapping array of scalars into quaternions

[ Thread Index | Date Index | More lists.tuxfamily.org/eigen Archives ]


Hi,

Also, it would help to read some rationalizations:
* why the EIGEN_STRONG_INLINE in front of cross product? Did you
benchmark an improvement here?

I remove this part, I have to inspect this more closely.

I update the documentation, and add the test. I also had to modify the EIGEN_INHERIT_ASSIGNEMENT_OPERATORS macro to use only operator= and to handle icc with visual studio.

The changeset :
* add Map<Quaternion> test based on Map from test/map.cpp
* replace implicit constructor AngleAxis(QuaternionBase&) by an explicit one, it seems ambiguous for the compiler * remove explicit constructor with conversion type quaternion(Quaternion&): conflict between constructor.
* modify EIGEN_INHERIT_ASSIGNEMENT_OPERATORS to suit Quaternion class

--
Mathieu Gautier
# HG changeset patch
# User Mathieu Gautier <mathieu.gautier@xxxxxx>
# Date 1258017912 -3600
# Node ID b35de8b1454a3b50911de9567401f4b138be178e
# Parent  4d3f3bb9a2f1e8fc5b58c0d555a2345f54543362
* add Map<Quaternion> test based on Map from test/map.cpp
* replace implicit constructor AngleAxis(QuaternionBase&) by an explicit one, it seems ambiguous for the compiler
* remove explicit constructor with conversion type quaternion(Quaternion&): conflict between constructor.
* modify EIGEN_INHERIT_ASSIGNEMENT_OPERATORS to suit Quaternion class

N.B : with ms visual c++ (at least vs 2008), while using icc compiler, both __INTEL_COMPILER and _MSC_VER macro are defined.

diff -r 4d3f3bb9a2f1 -r b35de8b1454a Eigen/src/Core/util/Macros.h
--- a/Eigen/src/Core/util/Macros.h	Wed Nov 11 21:25:21 2009 -0500
+++ b/Eigen/src/Core/util/Macros.h	Thu Nov 12 10:25:12 2009 +0100
@@ -261,25 +261,25 @@
   #define EIGEN_REF_TO_TEMPORARY const &
 #endif
 
-#ifdef _MSC_VER
+#if defined(_MSC_VER) && (!defined(__INTEL_COMPILER))
+#define EIGEN_INHERIT_ASSIGNMENT_EQUAL_OPERATOR(Derived) \
+using Base::operator =;
+#else
+#define EIGEN_INHERIT_ASSIGNMENT_EQUAL_OPERATOR(Derived) \
+using Base::operator =; \
+EIGEN_STRONG_INLINE Derived& operator=(const Derived& other) \
+{ \
+  Base::operator=(other); \
+  return *this; \
+}
+#endif
+
 #define EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Derived) \
-using Base::operator =; \
-using Base::operator +=; \
-using Base::operator -=; \
-using Base::operator *=; \
-using Base::operator /=;
-#else
-#define EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Derived) \
-using Base::operator =; \
 using Base::operator +=; \
 using Base::operator -=; \
 using Base::operator *=; \
 using Base::operator /=; \
-EIGEN_STRONG_INLINE Derived& operator=(const Derived& other) \
-{ \
-  return Base::operator=(other); \
-}
-#endif
+EIGEN_INHERIT_ASSIGNMENT_EQUAL_OPERATOR(Derived)
 
 #define _EIGEN_GENERIC_PUBLIC_INTERFACE(Derived, BaseClass) \
 typedef BaseClass Base; \
diff -r 4d3f3bb9a2f1 -r b35de8b1454a Eigen/src/Geometry/AngleAxis.h
--- a/Eigen/src/Geometry/AngleAxis.h	Wed Nov 11 21:25:21 2009 -0500
+++ b/Eigen/src/Geometry/AngleAxis.h	Thu Nov 12 10:25:12 2009 +0100
@@ -89,7 +89,7 @@
   template<typename Derived>
   inline AngleAxis(Scalar angle, const MatrixBase<Derived>& axis) : m_axis(axis), m_angle(angle) {}
   /** Constructs and initialize the angle-axis rotation from a quaternion \a q. */
-  inline AngleAxis(const QuaternionType& q) { *this = q; }
+  template<typename QuatDerived> inline explicit AngleAxis(const QuaternionBase<QuatDerived>& q) { *this = q; }
   /** Constructs and initialize the angle-axis rotation from a 3x3 rotation matrix. */
   template<typename Derived>
   inline explicit AngleAxis(const MatrixBase<Derived>& m) { *this = m; }
@@ -116,7 +116,8 @@
   AngleAxis inverse() const
   { return AngleAxis(-m_angle, m_axis); }
 
-  AngleAxis& operator=(const QuaternionType& q);
+  template<class QuatDerived>
+  AngleAxis& operator=(const QuaternionBase<QuatDerived>& q);
   template<typename Derived>
   AngleAxis& operator=(const MatrixBase<Derived>& m);
 
@@ -160,7 +161,8 @@
   * The axis is normalized.
   */
 template<typename Scalar>
-AngleAxis<Scalar>& AngleAxis<Scalar>::operator=(const QuaternionType& q)
+template<typename QuatDerived>
+AngleAxis<Scalar>& AngleAxis<Scalar>::operator=(const QuaternionBase<QuatDerived>& q)
 {
   Scalar n2 = q.vec().squaredNorm();
   if (n2 < precision<Scalar>()*precision<Scalar>())
diff -r 4d3f3bb9a2f1 -r b35de8b1454a Eigen/src/Geometry/Quaternion.h
--- a/Eigen/src/Geometry/Quaternion.h	Wed Nov 11 21:25:21 2009 -0500
+++ b/Eigen/src/Geometry/Quaternion.h	Thu Nov 12 10:25:12 2009 +0100
@@ -88,7 +88,8 @@
   /** \returns a vector expression of the coefficients (x,y,z,w) */
   inline typename ei_traits<Derived>::Coefficients& coeffs() { return derived().coeffs(); }
 
-  template<class OtherDerived> Derived& operator=(const QuaternionBase<OtherDerived>& other);
+  EIGEN_STRONG_INLINE QuaternionBase<Derived>& operator=(const QuaternionBase<Derived>& other);
+  template<class OtherDerived> 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
@@ -140,8 +141,8 @@
   template<typename Derived1, typename Derived2>
   Derived& setFromTwoVectors(const MatrixBase<Derived1>& a, const MatrixBase<Derived2>& b);
 
-  template<class OtherDerived> inline Quaternion<Scalar> operator* (const QuaternionBase<OtherDerived>& q) const;
-  template<class OtherDerived> inline Derived& operator*= (const QuaternionBase<OtherDerived>& q);
+  template<class OtherDerived> EIGEN_STRONG_INLINE Quaternion<Scalar> operator* (const QuaternionBase<OtherDerived>& q) const;
+  template<class OtherDerived> EIGEN_STRONG_INLINE Derived& operator*= (const QuaternionBase<OtherDerived>& q);
 
   Quaternion<Scalar> inverse() const;
   Quaternion<Scalar> conjugate() const;
@@ -156,7 +157,7 @@
   bool isApprox(const QuaternionBase<OtherDerived>& other, RealScalar prec = precision<Scalar>()) const
   { return coeffs().isApprox(other.coeffs(), prec); }
 
-  Vector3 _transformVector(Vector3 v) const;
+  EIGEN_STRONG_INLINE Vector3 _transformVector(Vector3 v) const;
 
   /** \returns \c *this with scalar type casted to \a NewScalarType
     *
@@ -164,7 +165,7 @@
     * then this function smartly returns a const reference to \c *this.
     */
   template<typename NewScalarType>
-  inline typename ei_cast_return_type<Derived,Quaternion<NewScalarType> >::type cast() const
+  EIGEN_STRONG_INLINE typename ei_cast_return_type<Derived,Quaternion<NewScalarType> >::type cast() const
   {
     return typename ei_cast_return_type<Derived,Quaternion<NewScalarType> >::type(
       coeffs().template cast<NewScalarType>());
@@ -211,8 +212,9 @@
 class Quaternion : public QuaternionBase<Quaternion<_Scalar> >{
   typedef QuaternionBase<Quaternion<_Scalar> > Base;
 public:
-  using Base::operator=;
-
+  EIGEN_INHERIT_ASSIGNMENT_EQUAL_OPERATOR(Quaternion<Scalar>)
+  using Base::operator*=;
+  
   typedef _Scalar Scalar;
 
   typedef typename ei_traits<Quaternion<Scalar> >::Coefficients Coefficients;
@@ -236,7 +238,7 @@
   inline Quaternion(const Scalar* data) : m_coeffs(data) {}
 
   /** Copy constructor */
-//  template<class Derived> inline Quaternion(const QuaternionBase<Derived>& other) { m_coeffs = other.coeffs(); } [XXX] redundant with 703
+  template<class Derived> EIGEN_STRONG_INLINE Quaternion(const QuaternionBase<Derived>& other) { this->Base::operator=(other); }
 
   /** Constructs and initializes a quaternion from the angle-axis \a aa */
   explicit inline Quaternion(const AngleAxisType& aa) { *this = aa; }
@@ -248,10 +250,9 @@
   template<typename Derived>
   explicit inline Quaternion(const MatrixBase<Derived>& other) { *this = other; }
 
-  /** Copy constructor with scalar type conversion */
-  template<typename Derived>
-  inline explicit Quaternion(const QuaternionBase<Derived>& other)
-  { m_coeffs = other.coeffs().template cast<Scalar>(); }
+/*  template<typename Derived>
+  inline explicit Quaternion(const QuaternionBase<Derived>& other) [XXXX]
+  { m_coeffs = other.coeffs().template cast<Scalar>(); } */
 
   inline Coefficients& coeffs() { return m_coeffs;}
   inline const Coefficients& coeffs() const { return m_coeffs;}
@@ -289,7 +290,7 @@
 ei_traits<Quaternion<_Scalar> >
 {
   typedef _Scalar Scalar;
-  typedef Map<Matrix<_Scalar,4,1> > Coefficients;
+  typedef Map<Matrix<_Scalar,4,1>, _PacketAccess> Coefficients;
   enum {
     PacketAccess = _PacketAccess
   };
@@ -300,10 +301,13 @@
   : public QuaternionBase<Map<Quaternion<_Scalar>, PacketAccess> >,
     ei_no_assignment_operator
 {
+    typedef QuaternionBase<Map<Quaternion<_Scalar>, PacketAccess> > Base;
   public:
+    using Base::operator=;
+    using Base::operator*=;
 
     typedef _Scalar Scalar;
-    typedef typename ei_traits<Map>::Coefficients Coefficients;
+    typedef typename ei_traits<Map<Quaternion<Scalar>, PacketAccess> >::Coefficients Coefficients;
 
     /** Constructs a Mapped Quaternion object from the pointer \a coeffs
       *
@@ -311,7 +315,7 @@
       * \code *coeffs == {x, y, z, w} \endcode
       *
       * If the template paramter PacketAccess is set to Aligned, then the pointer coeffs must be aligned. */
-    inline Map(const Scalar* coeffs) : m_coeffs(coeffs) {}
+    EIGEN_STRONG_INLINE Map(const Scalar* coeffs) : m_coeffs(coeffs) {}
 
     inline Coefficients& coeffs() { return m_coeffs;}
     inline const Coefficients& coeffs() const { return m_coeffs;}
@@ -320,8 +324,8 @@
     Coefficients m_coeffs;
 };
 
-typedef Map<Quaternion<double> >          QuaternionMapd;
-typedef Map<Quaternion<float> >           QuaternionMapf;
+typedef Map<Quaternion<double>, 0>          QuaternionMapd;
+typedef Map<Quaternion<float>, 0>           QuaternionMapf;
 typedef Map<Quaternion<double>, Aligned>  QuaternionMapAlignedd;
 typedef Map<Quaternion<float>, Aligned>   QuaternionMapAlignedf;
 
@@ -333,7 +337,7 @@
 // This product can be specialized for a given architecture via the Arch template argument.
 template<int Arch, class Derived1, class Derived2, typename Scalar, int PacketAccess> struct ei_quat_product
 {
-  inline static Quaternion<Scalar> run(const QuaternionBase<Derived1>& a, const QuaternionBase<Derived2>& b){
+  EIGEN_STRONG_INLINE static 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(),
@@ -347,7 +351,7 @@
 /** \returns the concatenation of two rotations as a quaternion-quaternion product */
 template <class Derived>
 template <class OtherDerived>
-inline Quaternion<typename ei_traits<Derived>::Scalar>
+EIGEN_STRONG_INLINE Quaternion<typename ei_traits<Derived>::Scalar>
 QuaternionBase<Derived>::operator* (const QuaternionBase<OtherDerived>& other) const
 {
   EIGEN_STATIC_ASSERT((ei_is_same_type<typename Derived::Scalar, typename OtherDerived::Scalar>::ret),
@@ -360,7 +364,7 @@
 /** \sa operator*(Quaternion) */
 template <class Derived>
 template <class OtherDerived>
-inline Derived& QuaternionBase<Derived>::operator*= (const QuaternionBase<OtherDerived>& other)
+EIGEN_STRONG_INLINE Derived& QuaternionBase<Derived>::operator*= (const QuaternionBase<OtherDerived>& other)
 {
   return (derived() = derived() * other.derived());
 }
@@ -373,7 +377,7 @@
   *   - Via a Matrix3: 24 + 15n
   */
 template <class Derived>
-inline typename QuaternionBase<Derived>::Vector3
+EIGEN_STRONG_INLINE typename QuaternionBase<Derived>::Vector3
 QuaternionBase<Derived>::_transformVector(Vector3 v) const
 {
     // Note that this algorithm comes from the optimization by hand
@@ -386,8 +390,15 @@
 }
 
 template<class Derived>
+EIGEN_STRONG_INLINE QuaternionBase<Derived>& QuaternionBase<Derived>::operator=(const QuaternionBase<Derived>& other)
+{
+  coeffs() = other.coeffs();
+  return derived();
+}
+
+template<class Derived>
 template<class OtherDerived>
-inline Derived& QuaternionBase<Derived>::operator=(const QuaternionBase<OtherDerived>& other)
+EIGEN_STRONG_INLINE Derived& QuaternionBase<Derived>::operator=(const QuaternionBase<OtherDerived>& other)
 {
   coeffs() = other.coeffs();
   return derived();
@@ -396,7 +407,7 @@
 /** Set \c *this from an angle-axis \a aa and returns a reference to \c *this
   */
 template<class Derived>
-inline Derived& QuaternionBase<Derived>::operator=(const AngleAxisType& aa)
+EIGEN_STRONG_INLINE Derived& QuaternionBase<Derived>::operator=(const AngleAxisType& aa)
 {
   Scalar ha = Scalar(0.5)*aa.angle(); // Scalar(0.5) to suppress precision loss warnings
   this->w() = ei_cos(ha);
diff -r 4d3f3bb9a2f1 -r b35de8b1454a Eigen/src/Geometry/RotationBase.h
--- a/Eigen/src/Geometry/RotationBase.h	Wed Nov 11 21:25:21 2009 -0500
+++ b/Eigen/src/Geometry/RotationBase.h	Thu Nov 12 10:25:12 2009 +0100
@@ -73,7 +73,7 @@
       *  - a vector of size Dim
       */
     template<typename OtherDerived>
-    inline typename ei_rotation_base_generic_product_selector<Derived,OtherDerived,OtherDerived::IsVectorAtCompileTime>::ReturnType
+    EIGEN_STRONG_INLINE typename ei_rotation_base_generic_product_selector<Derived,OtherDerived,OtherDerived::IsVectorAtCompileTime>::ReturnType
     operator*(const AnyMatrixBase<OtherDerived>& e) const
     { return ei_rotation_base_generic_product_selector<Derived,OtherDerived>::run(derived(), e.derived()); }
 
@@ -107,7 +107,7 @@
 {
   enum { Dim = RotationDerived::Dim };
   typedef Matrix<typename RotationDerived::Scalar,Dim,1> ReturnType;
-  inline static ReturnType run(const RotationDerived& r, const OtherVectorType& v)
+  EIGEN_STRONG_INLINE static ReturnType run(const RotationDerived& r, const OtherVectorType& v)
   {
     return r._transformVector(v);
   }
diff -r 4d3f3bb9a2f1 -r b35de8b1454a test/geo_quaternion.cpp
--- a/test/geo_quaternion.cpp	Wed Nov 11 21:25:21 2009 -0500
+++ b/test/geo_quaternion.cpp	Thu Nov 12 10:25:12 2009 +0100
@@ -84,7 +84,7 @@
 
 
   // angle-axis conversion
-  AngleAxisx aa = q1;
+  AngleAxisx aa = AngleAxisx(q1);
   VERIFY_IS_APPROX(q1 * v1, Quaternionx(aa) * v1);
   VERIFY_IS_NOT_APPROX(q1 * v1, Quaternionx(AngleAxisx(aa.angle()*2,aa.axis())) * v1);
 
@@ -110,10 +110,39 @@
   VERIFY_IS_APPROX(q1d.template cast<Scalar>(),q1);
 }
 
+template<typename Scalar> void mapQuaternion(void){
+  typedef Map<Quaternion<Scalar>, Aligned> MQuaternionA;
+  typedef Map<Quaternion<Scalar> > MQuaternionUA;
+  typedef Quaternion<Scalar> Quaternionx;
+
+  Scalar* array1 = ei_aligned_new<Scalar>(4);
+  Scalar* array2 = ei_aligned_new<Scalar>(4);
+  Scalar* array3 = new Scalar[4+1];
+  Scalar* array3unaligned = size_t(array3)%16 == 0 ? array3+1 : array3;
+
+  MQuaternionA(array1).coeffs().setRandom();
+  (MQuaternionA(array2)) = MQuaternionA(array1);
+  (MQuaternionUA(array3unaligned)) = MQuaternionA(array1);
+
+  Quaternionx q1 = MQuaternionA(array1);
+  Quaternionx q2 = MQuaternionA(array2);
+  Quaternionx q3 = MQuaternionUA(array3unaligned);
+
+  VERIFY_IS_APPROX(q1.coeffs(), q2.coeffs());
+  VERIFY_IS_APPROX(q1.coeffs(), q3.coeffs());
+  VERIFY_RAISES_ASSERT((MQuaternionA(array3unaligned)));
+
+  ei_aligned_delete(array1, 4);
+  ei_aligned_delete(array2, 4);
+  delete[] array3;
+}
+
 void test_geo_quaternion()
 {
   for(int i = 0; i < g_repeat; i++) {
     CALL_SUBTEST_1( quaternion<float>() );
     CALL_SUBTEST_2( quaternion<double>() );
+    CALL_SUBTEST( mapQuaternion<float>() );
+    CALL_SUBTEST( mapQuaternion<double>() );
   }
 }
diff -r 4d3f3bb9a2f1 -r b35de8b1454a test/geo_transformations.cpp
--- a/test/geo_transformations.cpp	Wed Nov 11 21:25:21 2009 -0500
+++ b/test/geo_transformations.cpp	Thu Nov 12 10:25:12 2009 +0100
@@ -81,7 +81,7 @@
     * (AngleAxisx(Scalar(0.3), Vector3(0,0,1)).toRotationMatrix() * v1)));
 
   // angle-axis conversion
-  AngleAxisx aa = q1;
+  AngleAxisx aa = AngleAxisx(q1);
   VERIFY_IS_APPROX(q1 * v1, Quaternionx(aa) * v1);
   VERIFY_IS_NOT_APPROX(q1 * v1, Quaternionx(AngleAxisx(aa.angle()*2,aa.axis())) * v1);
 
# HG changeset patch
# User Mathieu Gautier <mathieu.gautier@xxxxxx>
# Date 1258022263 -3600
# Node ID 1ac03648bac2135b6408eff00cead1c55a592ad6
# Parent  b35de8b1454a3b50911de9567401f4b138be178e
* build with gcc
* some doc

diff -r b35de8b1454a -r 1ac03648bac2 Eigen/src/Geometry/Quaternion.h
--- a/Eigen/src/Geometry/Quaternion.h	Thu Nov 12 10:25:12 2009 +0100
+++ b/Eigen/src/Geometry/Quaternion.h	Thu Nov 12 11:37:43 2009 +0100
@@ -136,17 +136,26 @@
 
   template<class OtherDerived> inline Scalar angularDistance(const QuaternionBase<OtherDerived>& other) const;
 
+	/** \returns an equivalent 3x3 rotation matrix */
   Matrix3 toRotationMatrix() const;
 
+	/** \returns the quaternion which transform \a a into \a b through a rotation */
   template<typename Derived1, typename Derived2>
   Derived& setFromTwoVectors(const MatrixBase<Derived1>& a, const MatrixBase<Derived2>& b);
 
   template<class OtherDerived> EIGEN_STRONG_INLINE Quaternion<Scalar> operator* (const QuaternionBase<OtherDerived>& q) const;
   template<class OtherDerived> EIGEN_STRONG_INLINE Derived& operator*= (const QuaternionBase<OtherDerived>& q);
 
+	/** \returns the quaternion describing the inverse rotation */
   Quaternion<Scalar> inverse() const;
+
+	/** \returns the conjugated quaternion */
   Quaternion<Scalar> conjugate() const;
 
+	/** \returns an interpolation for a constant motion between \a other and \c *this 
+		* \a t in [0;1]
+		* see http://en.wikipedia.org/wiki/Slerp		
+	*/
   template<class OtherDerived> Quaternion<Scalar> slerp(Scalar t, const QuaternionBase<OtherDerived>& other) const;
 
   /** \returns \c true if \c *this is approximately equal to \a other, within the precision
@@ -157,6 +166,7 @@
   bool isApprox(const QuaternionBase<OtherDerived>& other, RealScalar prec = precision<Scalar>()) const
   { return coeffs().isApprox(other.coeffs(), prec); }
 
+	/** return the result vector of \a v through the rotation*/
   EIGEN_STRONG_INLINE Vector3 _transformVector(Vector3 v) const;
 
   /** \returns \c *this with scalar type casted to \a NewScalarType
@@ -211,11 +221,11 @@
 template<typename _Scalar>
 class Quaternion : public QuaternionBase<Quaternion<_Scalar> >{
   typedef QuaternionBase<Quaternion<_Scalar> > Base;
-public:
+public: 
+  typedef _Scalar Scalar;
+
   EIGEN_INHERIT_ASSIGNMENT_EQUAL_OPERATOR(Quaternion<Scalar>)
   using Base::operator*=;
-  
-  typedef _Scalar Scalar;
 
   typedef typename ei_traits<Quaternion<Scalar> >::Coefficients Coefficients;
   typedef typename Base::AngleAxisType AngleAxisType;
@@ -233,8 +243,7 @@
   inline Quaternion(Scalar w, Scalar x, Scalar y, Scalar z)
   { coeffs() << x, y, z, w; }
 
-  /** Constructs and initialize a quaternion from the array data
-    * This constructor is also used to map an array */
+  /** Constructs and initialize a quaternion from the array data */
   inline Quaternion(const Scalar* data) : m_coeffs(data) {}
 
   /** Copy constructor */
@@ -250,10 +259,6 @@
   template<typename Derived>
   explicit inline Quaternion(const MatrixBase<Derived>& other) { *this = other; }
 
-/*  template<typename Derived>
-  inline explicit Quaternion(const QuaternionBase<Derived>& other) [XXXX]
-  { m_coeffs = other.coeffs().template cast<Scalar>(); } */
-
   inline Coefficients& coeffs() { return m_coeffs;}
   inline const Coefficients& coeffs() const { return m_coeffs;}
 
@@ -298,15 +303,21 @@
 
 template<typename _Scalar, int PacketAccess>
 class Map<Quaternion<_Scalar>, PacketAccess >
-  : public QuaternionBase<Map<Quaternion<_Scalar>, PacketAccess> >,
-    ei_no_assignment_operator
+  : public QuaternionBase<Map<Quaternion<_Scalar>, PacketAccess> >
 {
+	public:
+    typedef _Scalar Scalar;
+		typedef Map<Quaternion<Scalar>, PacketAccess > MapQuat;
+		
+	private:
+ 		Map<Quaternion<Scalar>, PacketAccess >();
+ 		Map<Quaternion<Scalar>, PacketAccess >(const Map<Quaternion<Scalar>, PacketAccess>&);
+
     typedef QuaternionBase<Map<Quaternion<_Scalar>, PacketAccess> > Base;
   public:
-    using Base::operator=;
+  	EIGEN_INHERIT_ASSIGNMENT_EQUAL_OPERATOR(MapQuat)
     using Base::operator*=;
 
-    typedef _Scalar Scalar;
     typedef typename ei_traits<Map<Quaternion<Scalar>, PacketAccess> >::Coefficients Coefficients;
 
     /** Constructs a Mapped Quaternion object from the pointer \a coeffs
@@ -324,10 +335,18 @@
     Coefficients m_coeffs;
 };
 
-typedef Map<Quaternion<double>, 0>          QuaternionMapd;
-typedef Map<Quaternion<float>, 0>           QuaternionMapf;
+/** \ingroup Geometry_Module
+  * Map an unaligned array of single precision scalar as a quaternion */
+typedef Map<Quaternion<float>, 0>         QuaternionMapf;
+/** \ingroup Geometry_Module
+  * Map an unaligned array of double precision scalar as a quaternion */
+typedef Map<Quaternion<double>, 0>        QuaternionMapd;
+/** \ingroup Geometry_Module
+  * Map a 16-bits aligned array of double precision scalars as a quaternion */
+typedef Map<Quaternion<float>, Aligned>   QuaternionMapAlignedf;
+/** \ingroup Geometry_Module
+  * Map a 16-bits aligned array of double precision scalars as a quaternion */
 typedef Map<Quaternion<double>, Aligned>  QuaternionMapAlignedd;
-typedef Map<Quaternion<float>, Aligned>   QuaternionMapAlignedf;
 
 /***************************************************************************
 * Implementation of QuaternionBase methods


Mail converted by MHonArc 2.6.19+ http://listengine.tuxfamily.org/