diff options
author | Benoit Jacob <jacob.benoit.1@gmail.com> | 2010-02-18 20:42:38 -0500 |
---|---|---|
committer | Benoit Jacob <jacob.benoit.1@gmail.com> | 2010-02-18 20:42:38 -0500 |
commit | b73e22905dd1544830b41463576d112c53fc66d9 (patch) | |
tree | d5832987f01195981df53d634e379721fed6b29c /Eigen/src/Core/MapBase.h | |
parent | 39d9f0275b8c9ef515b04f7b0e51f701edabbcad (diff) |
miserable half-working state, commiting to a fork just in case, just to perfect
my day, my hard disk would die.
Will write a more detailed commit message once it's working.
Diffstat (limited to 'Eigen/src/Core/MapBase.h')
-rw-r--r-- | Eigen/src/Core/MapBase.h | 94 |
1 files changed, 55 insertions, 39 deletions
diff --git a/Eigen/src/Core/MapBase.h b/Eigen/src/Core/MapBase.h index a922d8bb0..6bac2ed4c 100644 --- a/Eigen/src/Core/MapBase.h +++ b/Eigen/src/Core/MapBase.h @@ -1,7 +1,7 @@ // This file is part of Eigen, a lightweight C++ template library // for linear algebra. // -// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com> +// Copyright (C) 2007-2010 Benoit Jacob <jacob.benoit.1@gmail.com> // Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr> // // Eigen is free software; you can redistribute it and/or @@ -37,12 +37,12 @@ template<typename Derived, typename Base> class MapBase { public: -// typedef MatrixBase<Derived> Base; enum { IsRowMajor = (int(ei_traits<Derived>::Flags) & RowMajorBit) ? 1 : 0, RowsAtCompileTime = ei_traits<Derived>::RowsAtCompileTime, ColsAtCompileTime = ei_traits<Derived>::ColsAtCompileTime, - SizeAtCompileTime = Base::SizeAtCompileTime + SizeAtCompileTime = Base::SizeAtCompileTime, + InnerStrideAtCompileTime = ei_traits<Derived>::InnerStrideAtCompileTime }; typedef typename ei_traits<Derived>::Scalar Scalar; @@ -52,90 +52,104 @@ template<typename Derived, typename Base> class MapBase inline int rows() const { return m_rows.value(); } inline int cols() const { return m_cols.value(); } - /** Returns the leading dimension (for matrices) or the increment (for vectors) to be used with data(). + /** \returns the pointer increment between two consecutive elements. * - * More precisely: - * - for a column major matrix it returns the number of elements between two successive columns - * - for a row major matrix it returns the number of elements between two successive rows - * - for a vector it returns the number of elements between two successive coefficients - * This function has to be used together with the MapBase::data() function. + * \note For vectors, the storage order is ignored. For matrices (non-vectors), we're looking + * at the increment between two consecutive elements within a slice in the inner direction. * - * \sa MapBase::data() */ - inline int stride() const { return derived().stride(); } + * \sa outerStride(), data(), rowStride(), colStride() + */ + inline int innerStride() const { return derived().innerStride(); } + + /** \returns the pointer increment between two consecutive inner slices (for example, between two consecutive columns + * in a column-major matrix). + * + * \note For vectors, the storage order is ignored, there is only one inner slice, and so this method returns 1. + * For matrices (non-vectors), the notion of inner slice depends on the storage order. + * + * \sa innerStride(), data(), rowStride(), colStride() + */ + inline int outerStride() const { return derived().outerStride(); } + + /** \returns the pointer increment between two consecutive rows. + * + * \sa data(), innerStride(), outerStride(), colStride() + */ + inline int rowStride() const + { + return (RowsAtCompileTime==1 || IsRowMajor) ? outerStride() : innerStride(); + } + + /** \returns the pointer increment between two consecutive columns. + * + * \sa data(), innerStride(), outerStride(), rowStride() + */ + inline int colStride() const + { + return (RowsAtCompileTime==1 || IsRowMajor) ? innerStride() : outerStride(); + } /** Returns a pointer to the first coefficient of the matrix or vector. - * This function has to be used together with the stride() function. * - * \sa MapBase::stride() */ + * \note When addressing this data, make sure to honor the strides returned by innerStride() and outerStride(). + * + * \sa innerStride(), outerStride() + */ inline const Scalar* data() const { return m_data; } inline const Scalar& coeff(int row, int col) const { - if(IsRowMajor) - return m_data[col + row * stride()]; - else // column-major - return m_data[row + col * stride()]; + return m_data[col * colStride() + row * rowStride()]; } inline Scalar& coeffRef(int row, int col) { - if(IsRowMajor) - return const_cast<Scalar*>(m_data)[col + row * stride()]; - else // column-major - return const_cast<Scalar*>(m_data)[row + col * stride()]; + return const_cast<Scalar*>(m_data)[col * colStride() + row * rowStride()]; } inline const Scalar& coeff(int index) const { ei_assert(Derived::IsVectorAtCompileTime || (ei_traits<Derived>::Flags & LinearAccessBit)); - if ( ((RowsAtCompileTime == 1) == IsRowMajor) || !int(Derived::IsVectorAtCompileTime) ) - return m_data[index]; - else - return m_data[index*stride()]; + return m_data[index * innerStride()]; } inline Scalar& coeffRef(int index) { ei_assert(Derived::IsVectorAtCompileTime || (ei_traits<Derived>::Flags & LinearAccessBit)); - if ( ((RowsAtCompileTime == 1) == IsRowMajor) || !int(Derived::IsVectorAtCompileTime) ) - return const_cast<Scalar*>(m_data)[index]; - else - return const_cast<Scalar*>(m_data)[index*stride()]; + return const_cast<Scalar*>(m_data)[index * innerStride()]; } template<int LoadMode> inline PacketScalar packet(int row, int col) const { return ei_ploadt<Scalar, LoadMode> - (m_data + (IsRowMajor ? col + row * stride() - : row + col * stride())); + (m_data + (col * colStride() + row * rowStride())); } template<int LoadMode> inline PacketScalar packet(int index) const { - return ei_ploadt<Scalar, LoadMode>(m_data + index); + return ei_ploadt<Scalar, LoadMode>(m_data + index * innerStride()); } template<int StoreMode> inline void writePacket(int row, int col, const PacketScalar& x) { ei_pstoret<Scalar, PacketScalar, StoreMode> - (const_cast<Scalar*>(m_data) + (IsRowMajor ? col + row * stride() - : row + col * stride()), x); + (const_cast<Scalar*>(m_data) + (col * colStride() + row * rowStride()), x); } template<int StoreMode> inline void writePacket(int index, const PacketScalar& x) { ei_pstoret<Scalar, PacketScalar, StoreMode> - (const_cast<Scalar*>(m_data) + index, x); + (const_cast<Scalar*>(m_data) + index * innerStride(), x); } inline MapBase(const Scalar* data) : m_data(data), m_rows(RowsAtCompileTime), m_cols(ColsAtCompileTime) { EIGEN_STATIC_ASSERT_FIXED_SIZE(Derived) - checkDataAlignment(); + checkSanity(); } inline MapBase(const Scalar* data, int size) @@ -146,7 +160,7 @@ template<typename Derived, typename Base> class MapBase EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived) ei_assert(size >= 0); ei_assert(data == 0 || SizeAtCompileTime == Dynamic || SizeAtCompileTime == size); - checkDataAlignment(); + checkSanity(); } inline MapBase(const Scalar* data, int rows, int cols) @@ -155,7 +169,7 @@ template<typename Derived, typename Base> class MapBase ei_assert( (data == 0) || ( rows >= 0 && (RowsAtCompileTime == Dynamic || RowsAtCompileTime == rows) && cols >= 0 && (ColsAtCompileTime == Dynamic || ColsAtCompileTime == cols))); - checkDataAlignment(); + checkSanity(); } Derived& operator=(const MapBase& other) @@ -167,10 +181,12 @@ template<typename Derived, typename Base> class MapBase protected: - void checkDataAlignment() const + void checkSanity() const { ei_assert( ((!(ei_traits<Derived>::Flags&AlignedBit)) || ((size_t(m_data)&0xf)==0)) && "data is not aligned"); + ei_assert( ((!(ei_traits<Derived>::Flags&PacketAccessBit)) + || (innerStride()==1)) && "packet access incompatible with inner stride greater than 1"); } const Scalar* EIGEN_RESTRICT m_data; |