aboutsummaryrefslogtreecommitdiffhomepage
path: root/Eigen/src/Core/MapBase.h
diff options
context:
space:
mode:
authorGravatar Benoit Jacob <jacob.benoit.1@gmail.com>2010-02-18 20:42:38 -0500
committerGravatar Benoit Jacob <jacob.benoit.1@gmail.com>2010-02-18 20:42:38 -0500
commitb73e22905dd1544830b41463576d112c53fc66d9 (patch)
treed5832987f01195981df53d634e379721fed6b29c /Eigen/src/Core/MapBase.h
parent39d9f0275b8c9ef515b04f7b0e51f701edabbcad (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.h94
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;