From 7bd58ad0b6fe260b0b555ba75a798097500523b1 Mon Sep 17 00:00:00 2001 From: yoco Date: Sat, 18 Jan 2014 04:16:44 +0800 Subject: [PATCH 01/15] add Eigen/src/Core/Reshape.h --- Eigen/src/Core/Reshape.h | 419 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 419 insertions(+) create mode 100644 Eigen/src/Core/Reshape.h diff --git a/Eigen/src/Core/Reshape.h b/Eigen/src/Core/Reshape.h new file mode 100644 index 000000000..9d1a6765d --- /dev/null +++ b/Eigen/src/Core/Reshape.h @@ -0,0 +1,419 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2008 Gael Guennebaud +// Copyright (C) 2006-2010 Benoit Jacob +// +// 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_RESHAPE_H +#define EIGEN_RESHAPE_H + +namespace Eigen { + +/** \class Reshape + * \ingroup Core_Module + * + * \brief Expression of a fixed-size or dynamic-size reshape + * + * \param XprType the type of the expression in which we are taking a reshape + * \param ReshapeRows the number of rows of the reshape we are taking at compile time (optional) + * \param ReshapeCols the number of columns of the reshape we are taking at compile time (optional) + * \param InnerPanel is true, if the reshape maps to a set of rows of a row major matrix or + * to set of columns of a column major matrix (optional). The parameter allows to determine + * at compile time whether aligned access is possible on the reshape expression. + * + * This class represents an expression of either a fixed-size or dynamic-size reshape. It is the return + * type of DenseBase::reshape(Index,Index) and DenseBase::reshape() and + * most of the time this is the only way it is used. + * + * However, if you want to directly maniputate reshape expressions, + * for instance if you want to write a function returning such an expression, you + * will need to use this class. + * + * Here is an example illustrating the dynamic case: + * \include class_Reshape.cpp + * Output: \verbinclude class_Reshape.out + * + * \note Even though this expression has dynamic size, in the case where \a XprType + * has fixed size, this expression inherits a fixed maximal size which means that evaluating + * it does not cause a dynamic memory allocation. + * + * Here is an example illustrating the fixed-size case: + * \include class_FixedReshape.cpp + * Output: \verbinclude class_FixedReshape.out + * + * \sa DenseBase::reshape(Index,Index), DenseBase::reshape(), class VectorReshape + */ + +namespace internal { +template +struct traits > : traits +{ + typedef typename traits::Scalar Scalar; + typedef typename traits::StorageKind StorageKind; + typedef typename traits::XprKind XprKind; + typedef typename nested::type XprTypeNested; + typedef typename remove_reference::type _XprTypeNested; + enum{ + MatrixRows = traits::RowsAtCompileTime, + MatrixCols = traits::ColsAtCompileTime, + RowsAtCompileTime = MatrixRows == 0 ? 0 : ReshapeRows, + ColsAtCompileTime = MatrixCols == 0 ? 0 : ReshapeCols, + MaxRowsAtCompileTime = ReshapeRows==0 ? 0 + : RowsAtCompileTime != Dynamic ? int(RowsAtCompileTime) + : int(traits::MaxRowsAtCompileTime), + MaxColsAtCompileTime = ReshapeCols==0 ? 0 + : ColsAtCompileTime != Dynamic ? int(ColsAtCompileTime) + : int(traits::MaxColsAtCompileTime), + XprTypeIsRowMajor = (int(traits::Flags)&RowMajorBit) != 0, + IsRowMajor = (MaxRowsAtCompileTime==1&&MaxColsAtCompileTime!=1) ? 1 + : (MaxColsAtCompileTime==1&&MaxRowsAtCompileTime!=1) ? 0 + : XprTypeIsRowMajor, + HasSameStorageOrderAsXprType = (IsRowMajor == XprTypeIsRowMajor), + InnerSize = IsRowMajor ? int(ColsAtCompileTime) : int(RowsAtCompileTime), + InnerStrideAtCompileTime = HasSameStorageOrderAsXprType + ? int(inner_stride_at_compile_time::ret) + : int(outer_stride_at_compile_time::ret), + OuterStrideAtCompileTime = HasSameStorageOrderAsXprType + ? int(outer_stride_at_compile_time::ret) + : int(inner_stride_at_compile_time::ret), + MaskPacketAccessBit = (InnerSize == Dynamic || (InnerSize % packet_traits::size) == 0) + && (InnerStrideAtCompileTime == 1) + ? PacketAccessBit : 0, + MaskAlignedBit = (InnerPanel && (OuterStrideAtCompileTime!=Dynamic) && (((OuterStrideAtCompileTime * int(sizeof(Scalar))) % 16) == 0)) ? AlignedBit : 0, + FlagsLinearAccessBit = (RowsAtCompileTime == 1 || ColsAtCompileTime == 1) ? LinearAccessBit : 0, + FlagsLvalueBit = is_lvalue::value ? LvalueBit : 0, + FlagsRowMajorBit = IsRowMajor ? RowMajorBit : 0, + Flags0 = traits::Flags & ( (HereditaryBits & ~RowMajorBit) | + DirectAccessBit | + MaskPacketAccessBit | + MaskAlignedBit), + Flags = Flags0 | FlagsLinearAccessBit | FlagsLvalueBit | FlagsRowMajorBit + }; +}; + +template::ret> class ReshapeImpl_dense; + +} // end namespace internal + +template class ReshapeImpl; + +template class Reshape + : public ReshapeImpl::StorageKind> +{ + typedef ReshapeImpl::StorageKind> Impl; + public: + //typedef typename Impl::Base Base; + typedef Impl Base; + EIGEN_GENERIC_PUBLIC_INTERFACE(Reshape) + EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Reshape) + + /** Column or Row constructor + */ + EIGEN_DEVICE_FUNC + inline Reshape(XprType& xpr, Index i) : Impl(xpr,i) + { + eigen_assert( (i>=0) && ( + ((ReshapeRows==1) && (ReshapeCols==XprType::ColsAtCompileTime) && i +class ReshapeImpl + : public internal::ReshapeImpl_dense +{ + typedef internal::ReshapeImpl_dense Impl; + typedef typename XprType::Index Index; + public: + typedef Impl Base; + EIGEN_INHERIT_ASSIGNMENT_OPERATORS(ReshapeImpl) + EIGEN_DEVICE_FUNC inline ReshapeImpl(XprType& xpr) : Impl(xpr) {} + EIGEN_DEVICE_FUNC inline ReshapeImpl(XprType& xpr, Index reshapeRows, Index reshapeCols) + : Impl(xpr, reshapeRows, reshapeCols) {} +}; + +namespace internal { + +/** \internal Internal implementation of dense Reshapes in the general case. */ +template class ReshapeImpl_dense + : public internal::dense_xpr_base >::type +{ + typedef Reshape ReshapeType; + public: + + typedef typename internal::dense_xpr_base::type Base; + EIGEN_DENSE_PUBLIC_INTERFACE(ReshapeType) + EIGEN_INHERIT_ASSIGNMENT_OPERATORS(ReshapeImpl_dense) + + class InnerIterator; + + /** Column or Row constructor + */ + EIGEN_DEVICE_FUNC + inline ReshapeImpl_dense(XprType& xpr, Index i) + : m_xpr(xpr), + // It is a row if and only if ReshapeRows==1 and ReshapeCols==XprType::ColsAtCompileTime, + // and it is a column if and only if ReshapeRows==XprType::RowsAtCompileTime and ReshapeCols==1, + // all other cases are invalid. + // The case a 1x1 matrix seems ambiguous, but the result is the same anyway. + m_reshapeRows(ReshapeRows==1 ? 1 : xpr.rows()), + m_reshapeCols(ReshapeCols==1 ? 1 : xpr.cols()) + {} + + /** Fixed-size constructor + */ + EIGEN_DEVICE_FUNC + inline ReshapeImpl_dense(XprType& xpr) + : m_xpr(xpr), m_reshapeRows(ReshapeRows), m_reshapeCols(ReshapeCols) + {} + + /** Dynamic-size constructor + */ + EIGEN_DEVICE_FUNC + inline ReshapeImpl_dense(XprType& xpr, + Index reshapeRows, Index reshapeCols) + : m_xpr(xpr), m_reshapeRows(reshapeRows), m_reshapeCols(reshapeCols) + {} + + EIGEN_DEVICE_FUNC inline Index rows() const { return m_reshapeRows.value(); } + EIGEN_DEVICE_FUNC inline Index cols() const { return m_reshapeCols.value(); } + + inline std::pair index_remap(Index rowId, Index colId) const { + const Index nth_elem_idx = colId * m_reshapeRows.value() + rowId; + const Index actual_col = nth_elem_idx / m_xpr.rows(); + const Index actual_row = nth_elem_idx % m_xpr.rows(); + return {actual_row, actual_col}; + } + + EIGEN_DEVICE_FUNC + inline Scalar& coeffRef(Index rowId, Index colId) + { + EIGEN_STATIC_ASSERT_LVALUE(XprType) + const auto row_col = index_remap(rowId, colId); + return m_xpr.const_cast_derived().coeffRef(row_col.first, row_col.second); + } + + EIGEN_DEVICE_FUNC + inline const Scalar& coeffRef(Index rowId, Index colId) const + { + const auto row_col = index_remap(rowId, colId); + return m_xpr.derived().coeffRef(row_col.first, row_col.second); + } + + EIGEN_DEVICE_FUNC + EIGEN_STRONG_INLINE const CoeffReturnType coeff(Index rowId, Index colId) const + { + const auto row_col = index_remap(rowId, colId); + return m_xpr.coeff(row_col.first, row_col.second); + } + + EIGEN_DEVICE_FUNC + inline Scalar& coeffRef(Index index) + { + EIGEN_STATIC_ASSERT_LVALUE(XprType) + const auto row_col = index_remap((RowsAtCompileTime == 1 ? 0 : index) + (RowsAtCompileTime == 1 ? index : 0)); + return m_xpr.const_cast_derived().coeffRef(row_col.first, row_col.second); + + } + + EIGEN_DEVICE_FUNC + inline const Scalar& coeffRef(Index index) const + { + const auto row_col = index_remap((RowsAtCompileTime == 1 ? 0 : index) + (RowsAtCompileTime == 1 ? index : 0)); + return m_xpr.const_cast_derived().coeffRef(row_col.first, row_col.second); + } + + EIGEN_DEVICE_FUNC + inline const CoeffReturnType coeff(Index index) const + { + const auto row_col = index_remap((RowsAtCompileTime == 1 ? 0 : index) + (RowsAtCompileTime == 1 ? index : 0)); + return m_xpr.coeff(row_col.first, row_col.second); + } + + EIGEN_DEVICE_FUNC + template + inline PacketScalar packet(Index rowId, Index colId) const + { + const auto row_col = index_remap(rowId, colId); + return m_xpr.template packet(row_col.first, row_col.second); + + } + + template + inline void writePacket(Index rowId, Index colId, const PacketScalar& val) + { + const auto row_col = index_remap(rowId, colId); + m_xpr.const_cast_derived().template writePacket + (row_col.first, row_col.second, val); + } + + template + inline PacketScalar packet(Index index) const + { + const auto row_col = index_remap(RowsAtCompileTime == 1 ? 0 : index, + RowsAtCompileTime == 1 ? index : 0); + return m_xpr.template packet(row_col.first, row_col.second); + } + + template + inline void writePacket(Index index, const PacketScalar& val) + { + const auto row_col = index_remap(RowsAtCompileTime == 1 ? 0 : index, + RowsAtCompileTime == 1 ? index : 0); + return m_xpr.template packet(row_col.first, row_col.second, val); + } + + #ifdef EIGEN_PARSED_BY_DOXYGEN + /** \sa MapBase::data() */ + EIGEN_DEVICE_FUNC inline const Scalar* data() const; + EIGEN_DEVICE_FUNC inline Index innerStride() const; + EIGEN_DEVICE_FUNC inline Index outerStride() const; + #endif + + EIGEN_DEVICE_FUNC + const typename internal::remove_all::type& nestedExpression() const + { + return m_xpr; + } + + protected: + + const typename XprType::Nested m_xpr; + const internal::variable_if_dynamic m_reshapeRows; + const internal::variable_if_dynamic m_reshapeCols; +}; + +///** \internal Internal implementation of dense Reshapes in the direct access case.*/ +//template +//class ReshapeImpl_dense +// : public MapBase > +//{ +// typedef Reshape ReshapeType; +// public: +// +// typedef MapBase Base; +// EIGEN_DENSE_PUBLIC_INTERFACE(ReshapeType) +// EIGEN_INHERIT_ASSIGNMENT_OPERATORS(ReshapeImpl_dense) +// +// /** Column or Row constructor +// */ +// EIGEN_DEVICE_FUNC +// inline ReshapeImpl_dense(XprType& xpr, Index i) +// : Base(internal::const_cast_ptr(&xpr.coeffRef( +// (ReshapeRows==1) && (ReshapeCols==XprType::ColsAtCompileTime) ? i : 0, +// (ReshapeRows==XprType::RowsAtCompileTime) && (ReshapeCols==1) ? i : 0)), +// ReshapeRows==1 ? 1 : xpr.rows(), +// ReshapeCols==1 ? 1 : xpr.cols()), +// m_xpr(xpr) +// { +// init(); +// } +// +// /** Fixed-size constructor +// */ +// EIGEN_DEVICE_FUNC +// inline ReshapeImpl_dense(XprType& xpr) +// : Base(internal::const_cast_ptr(&xpr.coeffRef(0, 0))), m_xpr(xpr) +// { +// init(); +// } +// +// /** Dynamic-size constructor +// */ +// EIGEN_DEVICE_FUNC +// inline ReshapeImpl_dense(XprType& xpr, +// Index reshapeRows, Index reshapeCols) +// : Base(internal::const_cast_ptr(&xpr.coeffRef(0, 0)), reshapeRows, reshapeCols), +// m_xpr(xpr) +// { +// init(); +// } +// +// EIGEN_DEVICE_FUNC +// const typename internal::remove_all::type& nestedExpression() const +// { +// return m_xpr; +// } +// +// EIGEN_DEVICE_FUNC +// /** \sa MapBase::innerStride() */ +// inline Index innerStride() const +// { +// return internal::traits::HasSameStorageOrderAsXprType +// ? m_xpr.innerStride() +// : m_xpr.outerStride(); +// } +// +// EIGEN_DEVICE_FUNC +// /** \sa MapBase::outerStride() */ +// inline Index outerStride() const +// { +// return m_outerStride; +// } +// +// #ifndef __SUNPRO_CC +// // FIXME sunstudio is not friendly with the above friend... +// // META-FIXME there is no 'friend' keyword around here. Is this obsolete? +// protected: +// #endif +// +// #ifndef EIGEN_PARSED_BY_DOXYGEN +// /** \internal used by allowAligned() */ +// EIGEN_DEVICE_FUNC +// inline ReshapeImpl_dense(XprType& xpr, const Scalar* data, Index reshapeRows, Index reshapeCols) +// : Base(data, reshapeRows, reshapeCols), m_xpr(xpr) +// { +// init(); +// } +// #endif +// +// protected: +// EIGEN_DEVICE_FUNC +// void init() +// { +// m_outerStride = internal::traits::HasSameStorageOrderAsXprType +// ? m_xpr.outerStride() +// : m_xpr.innerStride(); +// } +// +// typename XprType::Nested m_xpr; +// Index m_outerStride; +//}; + +} // end namespace internal + +} // end namespace Eigen + +#endif // EIGEN_RESHAPE_H From fe2ad0647afbe920dae6de60b814d84d76c5f65d Mon Sep 17 00:00:00 2001 From: yoco Date: Sat, 18 Jan 2014 04:21:20 +0800 Subject: [PATCH 02/15] reshape now supported - add member function to plugin - add forward declaration - add documentation - add include --- Eigen/Core | 1 + Eigen/src/Core/util/ForwardDeclarations.h | 1 + Eigen/src/plugins/BlockMethods.h | 56 +++++++++++++++++++++++ 3 files changed, 58 insertions(+) diff --git a/Eigen/Core b/Eigen/Core index 468ae0c76..f1c952832 100644 --- a/Eigen/Core +++ b/Eigen/Core @@ -345,6 +345,7 @@ using std::ptrdiff_t; #include "src/Core/Stride.h" #include "src/Core/Map.h" #include "src/Core/Block.h" +#include "src/Core/Reshape.h" #include "src/Core/VectorBlock.h" #include "src/Core/Ref.h" #include "src/Core/Transpose.h" diff --git a/Eigen/src/Core/util/ForwardDeclarations.h b/Eigen/src/Core/util/ForwardDeclarations.h index 0a2144c69..a4f3435bb 100644 --- a/Eigen/src/Core/util/ForwardDeclarations.h +++ b/Eigen/src/Core/util/ForwardDeclarations.h @@ -79,6 +79,7 @@ template class ForceAlignedAccess; template class SwapWrapper; template class Block; +template class Reshape; template class VectorBlock; template class Transpose; diff --git a/Eigen/src/plugins/BlockMethods.h b/Eigen/src/plugins/BlockMethods.h index 9b7fdc4aa..d1da27766 100644 --- a/Eigen/src/plugins/BlockMethods.h +++ b/Eigen/src/plugins/BlockMethods.h @@ -993,3 +993,59 @@ inline typename ConstFixedSegmentReturnType::Type tail(Index n = N) const EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived) return typename ConstFixedSegmentReturnType::Type(derived(), size() - n); } + +/** \returns a dynamic-size expression of a reshape in *this. + * + * \param reshapeRows the number of rows in the reshape + * \param reshapeCols the number of columns in the reshape + * + * Example: \include MatrixBase_reshape_int_int.cpp + * Output: \verbinclude MatrixBase_reshape_int_int.out + * + * \note Even though the returned expression has dynamic size, in the case + * when it is applied to a fixed-size matrix, it inherits a fixed maximal size, + * which means that evaluating it does not cause a dynamic memory allocation. + * + * \sa class Reshape, reshape() + */ +EIGEN_DEVICE_FUNC +inline Reshape reshape(Index reshapeRows, Index reshapeCols) +{ + return Reshape(derived(), reshapeRows, reshapeCols); +} + +/** This is the const version of reshape(Index,Index). */ +EIGEN_DEVICE_FUNC +inline const Reshape reshape(Index reshapeRows, Index reshapeCols) const +{ + return Reshape(derived(), reshapeRows, reshapeCols); +} + +/** \returns a fixed-size expression of a reshape in *this. + * + * The template parameters \a ReshapeRows and \a ReshapeCols are the number of + * rows and columns in the reshape. + * + * Example: \include MatrixBase_reshape.cpp + * Output: \verbinclude MatrixBase_reshape.out + * + * \note since reshape is a templated member, the keyword template has to be used + * if the matrix type is also a template parameter: \code m.template reshape<3,3>(); \endcode + * + * \sa class Reshape, reshape(Index,Index) + */ +template +EIGEN_DEVICE_FUNC +inline Reshape reshape() +{ + return Reshape(derived()); +} + +/** This is the const version of reshape<>(Index, Index). */ +template +EIGEN_DEVICE_FUNC +inline const Reshape reshape() const +{ + return Reshape(derived()); +} + From 1e1d0c15b5b9bf5ca43e3020aec7aa596e3a167c Mon Sep 17 00:00:00 2001 From: yoco Date: Sat, 18 Jan 2014 04:43:29 +0800 Subject: [PATCH 03/15] add example code for Reshape class --- doc/examples/class_FixedReshape.cpp | 22 ++++++++++++++++++++++ doc/examples/class_Reshape.cpp | 23 +++++++++++++++++++++++ 2 files changed, 45 insertions(+) create mode 100644 doc/examples/class_FixedReshape.cpp create mode 100644 doc/examples/class_Reshape.cpp diff --git a/doc/examples/class_FixedReshape.cpp b/doc/examples/class_FixedReshape.cpp new file mode 100644 index 000000000..40156a123 --- /dev/null +++ b/doc/examples/class_FixedReshape.cpp @@ -0,0 +1,22 @@ +#include +#include +using namespace Eigen; +using namespace std; + +template +Eigen::Reshape +reshape_helper(MatrixBase& m) +{ + return Eigen::Reshape(m.derived()); +} + +int main(int, char**) +{ + MatrixXd m(2, 4); + m << 1, 2, 3, 4, + 5, 6, 7, 8; + MatrixXd n = reshape_helper(m); + cout << "matrix m is:" << endl << m << endl; + cout << "matrix n is:" << endl << n << endl; + return 0; +} diff --git a/doc/examples/class_Reshape.cpp b/doc/examples/class_Reshape.cpp new file mode 100644 index 000000000..b9abdc2d5 --- /dev/null +++ b/doc/examples/class_Reshape.cpp @@ -0,0 +1,23 @@ +#include +#include +using namespace std; +using namespace Eigen; + +template +const Reshape +reshape_helper(const MatrixBase& m, int rows, int cols) +{ + return Reshape(m.derived(), rows, cols); +} + +int main(int, char**) +{ + MatrixXd m(3, 4); + m << 1, 4, 7, 10, + 2, 5, 8, 11, + 3, 6, 9, 12; + cout << m << endl; + auto n = reshape_helper(m, 2, 6); + cout << "Matrix m is:" << endl << m << endl; + cout << "Matrix n is:" << endl << n << endl; +} From 9c832fad60b8122ef9ef59a61a68a9927a204607 Mon Sep 17 00:00:00 2001 From: yoco Date: Sat, 18 Jan 2014 04:53:46 +0800 Subject: [PATCH 04/15] add reshape() snippets --- doc/snippets/MatrixBase_reshape.cpp | 3 +++ doc/snippets/MatrixBase_reshape_int_int.cpp | 3 +++ 2 files changed, 6 insertions(+) create mode 100644 doc/snippets/MatrixBase_reshape.cpp create mode 100644 doc/snippets/MatrixBase_reshape_int_int.cpp diff --git a/doc/snippets/MatrixBase_reshape.cpp b/doc/snippets/MatrixBase_reshape.cpp new file mode 100644 index 000000000..549bd1007 --- /dev/null +++ b/doc/snippets/MatrixBase_reshape.cpp @@ -0,0 +1,3 @@ +Matrix4i m = Matrix4i::Random(); +cout << "Here is the matrix m:" << endl << m << endl; +cout << "Here is m.reshape<2,8>():" << endl << m.reshape<2,8>() << endl; diff --git a/doc/snippets/MatrixBase_reshape_int_int.cpp b/doc/snippets/MatrixBase_reshape_int_int.cpp new file mode 100644 index 000000000..1169cdb2d --- /dev/null +++ b/doc/snippets/MatrixBase_reshape_int_int.cpp @@ -0,0 +1,3 @@ +Matrix4i m = Matrix4i::Random(); +cout << "Here is the matrix m:" << endl << m << endl; +cout << "Here is m.reshape(2, 8):" << endl << m.reshape(2, 8) << endl; From 497a7b0ce1afd6d596ffe9520e5181f371ef6612 Mon Sep 17 00:00:00 2001 From: yoco Date: Sat, 18 Jan 2014 13:20:14 +0800 Subject: [PATCH 05/15] remove c++11, make c++03 compatible --- Eigen/src/Core/Reshape.h | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/Eigen/src/Core/Reshape.h b/Eigen/src/Core/Reshape.h index 9d1a6765d..896392798 100644 --- a/Eigen/src/Core/Reshape.h +++ b/Eigen/src/Core/Reshape.h @@ -207,32 +207,34 @@ template index_remap(Index rowId, Index colId) const { + typedef std::pair RowCol; + + inline RowCol index_remap(Index rowId, Index colId) const { const Index nth_elem_idx = colId * m_reshapeRows.value() + rowId; const Index actual_col = nth_elem_idx / m_xpr.rows(); const Index actual_row = nth_elem_idx % m_xpr.rows(); - return {actual_row, actual_col}; + return RowCol(actual_row, actual_col); } EIGEN_DEVICE_FUNC inline Scalar& coeffRef(Index rowId, Index colId) { EIGEN_STATIC_ASSERT_LVALUE(XprType) - const auto row_col = index_remap(rowId, colId); + const RowCol row_col = index_remap(rowId, colId); return m_xpr.const_cast_derived().coeffRef(row_col.first, row_col.second); } EIGEN_DEVICE_FUNC inline const Scalar& coeffRef(Index rowId, Index colId) const { - const auto row_col = index_remap(rowId, colId); + const RowCol row_col = index_remap(rowId, colId); return m_xpr.derived().coeffRef(row_col.first, row_col.second); } EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const CoeffReturnType coeff(Index rowId, Index colId) const { - const auto row_col = index_remap(rowId, colId); + const RowCol row_col = index_remap(rowId, colId); return m_xpr.coeff(row_col.first, row_col.second); } @@ -240,7 +242,7 @@ template inline PacketScalar packet(Index rowId, Index colId) const { - const auto row_col = index_remap(rowId, colId); + const RowCol row_col = index_remap(rowId, colId); return m_xpr.template packet(row_col.first, row_col.second); } @@ -274,7 +276,7 @@ template inline void writePacket(Index rowId, Index colId, const PacketScalar& val) { - const auto row_col = index_remap(rowId, colId); + const RowCol row_col = index_remap(rowId, colId); m_xpr.const_cast_derived().template writePacket (row_col.first, row_col.second, val); } @@ -282,7 +284,7 @@ template inline PacketScalar packet(Index index) const { - const auto row_col = index_remap(RowsAtCompileTime == 1 ? 0 : index, + const RowCol row_col = index_remap(RowsAtCompileTime == 1 ? 0 : index, RowsAtCompileTime == 1 ? index : 0); return m_xpr.template packet(row_col.first, row_col.second); } @@ -290,7 +292,7 @@ template inline void writePacket(Index index, const PacketScalar& val) { - const auto row_col = index_remap(RowsAtCompileTime == 1 ? 0 : index, + const RowCol row_col = index_remap(RowsAtCompileTime == 1 ? 0 : index, RowsAtCompileTime == 1 ? index : 0); return m_xpr.template packet(row_col.first, row_col.second, val); } @@ -317,7 +319,7 @@ template -//class ReshapeImpl_dense +//class ReshapeImpl_dense // : public MapBase > //{ // typedef Reshape ReshapeType; From 150796337ad50cc51a4975425b287f95a5368378 Mon Sep 17 00:00:00 2001 From: yoco Date: Sat, 18 Jan 2014 16:10:46 +0800 Subject: [PATCH 06/15] Add unit-test for reshape - add unittest for dynamic & fixed-size reshape - fix fixed-size reshape bugs bugs found while testing --- Eigen/src/Core/Reshape.h | 17 ++++++------ test/CMakeLists.txt | 1 + test/reshape.cpp | 58 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 68 insertions(+), 8 deletions(-) create mode 100644 test/reshape.cpp diff --git a/Eigen/src/Core/Reshape.h b/Eigen/src/Core/Reshape.h index 896392798..a773342ad 100644 --- a/Eigen/src/Core/Reshape.h +++ b/Eigen/src/Core/Reshape.h @@ -3,6 +3,7 @@ // // Copyright (C) 2008 Gael Guennebaud // Copyright (C) 2006-2010 Benoit Jacob +// Copyright (C) 2014 yoco // // 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 @@ -242,8 +243,8 @@ template(row_col.first, row_col.second); } @@ -293,7 +294,7 @@ template(row_col.first, row_col.second, val); } diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 3c32f4b21..238298d43 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -150,6 +150,7 @@ ei_add_test(exceptions) ei_add_test(redux) ei_add_test(visitor) ei_add_test(block) +ei_add_test(reshape) ei_add_test(corners) ei_add_test(product_small) ei_add_test(product_large) diff --git a/test/reshape.cpp b/test/reshape.cpp new file mode 100644 index 000000000..87ffc835b --- /dev/null +++ b/test/reshape.cpp @@ -0,0 +1,58 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2014 yoco +// +// 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/. + +#include "main.h" + +using Eigen::Map; +using Eigen::MatrixXi; + +void dynamic_reshape_all_size(int row, int col) { + // create matrix(row, col) and filled with 0, 1, 2, ... + Eigen::MatrixXi m(row, col); + for(int r = 0; r < row; ++r) + for(int c = 0; c < col; ++c) + m(r, c) = col * c + r; + + // for all possible shape + for(int new_r = 1; new_r <= row * col; ++new_r) { + // skip invalid shape + if(row * col % new_r != 0) + continue; + + // reshape and compare + int new_c = row * col / new_r; + VERIFY_IS_EQUAL(m.reshape(new_r, new_c), + Map(m.data(), new_r, new_c)); + } +} + +// just test a 4x4 matrix, enumerate all combination manually, +// so I don't have to do template-meta-programming here. +void static_reshape_all_size() { + // create matrix(row, col) and filled with 0, 1, 2, ... + int row = 4; + int col = 4; + Eigen::MatrixXi m(row, col); + for(int r = 0; r < row; ++r) + for(int c = 0; c < col; ++c) + m(r, c) = col * c + r; + + // reshape and compare + VERIFY_IS_EQUAL((m.reshape< 1, 16>()), Map(m.data(), 1, 16)); + VERIFY_IS_EQUAL((m.reshape< 2, 8>()), Map(m.data(), 2, 8)); + VERIFY_IS_EQUAL((m.reshape< 4, 4>()), Map(m.data(), 4, 4)); + VERIFY_IS_EQUAL((m.reshape< 8, 2>()), Map(m.data(), 8, 2)); + VERIFY_IS_EQUAL((m.reshape<16, 1>()), Map(m.data(), 16, 1)); +} + +void test_reshape() +{ + CALL_SUBTEST(dynamic_reshape_all_size(4, 4)); + CALL_SUBTEST(static_reshape_all_size()); +} From 24e1c0f2a16ccc99ef1dc6c9d0fc969fe351f680 Mon Sep 17 00:00:00 2001 From: yoco Date: Sat, 18 Jan 2014 23:27:53 +0800 Subject: [PATCH 07/15] add reshape test for const and static-size matrix --- test/reshape.cpp | 61 ++++++++++++++++++++++++++++-------------------- 1 file changed, 36 insertions(+), 25 deletions(-) diff --git a/test/reshape.cpp b/test/reshape.cpp index 87ffc835b..2aef066aa 100644 --- a/test/reshape.cpp +++ b/test/reshape.cpp @@ -12,14 +12,8 @@ using Eigen::Map; using Eigen::MatrixXi; -void dynamic_reshape_all_size(int row, int col) { - // create matrix(row, col) and filled with 0, 1, 2, ... - Eigen::MatrixXi m(row, col); - for(int r = 0; r < row; ++r) - for(int c = 0; c < col; ++c) - m(r, c) = col * c + r; - - // for all possible shape +template +void dynamic_reshape_all_size(MatType m, int row, int col) { for(int new_r = 1; new_r <= row * col; ++new_r) { // skip invalid shape if(row * col % new_r != 0) @@ -34,25 +28,42 @@ void dynamic_reshape_all_size(int row, int col) { // just test a 4x4 matrix, enumerate all combination manually, // so I don't have to do template-meta-programming here. -void static_reshape_all_size() { - // create matrix(row, col) and filled with 0, 1, 2, ... - int row = 4; - int col = 4; - Eigen::MatrixXi m(row, col); - for(int r = 0; r < row; ++r) - for(int c = 0; c < col; ++c) - m(r, c) = col * c + r; - - // reshape and compare - VERIFY_IS_EQUAL((m.reshape< 1, 16>()), Map(m.data(), 1, 16)); - VERIFY_IS_EQUAL((m.reshape< 2, 8>()), Map(m.data(), 2, 8)); - VERIFY_IS_EQUAL((m.reshape< 4, 4>()), Map(m.data(), 4, 4)); - VERIFY_IS_EQUAL((m.reshape< 8, 2>()), Map(m.data(), 8, 2)); - VERIFY_IS_EQUAL((m.reshape<16, 1>()), Map(m.data(), 16, 1)); +template +void static_reshape_all_size(MatType m) { + VERIFY_IS_EQUAL((m.template reshape< 1, 16>()), Map(m.data(), 1, 16)); + VERIFY_IS_EQUAL((m.template reshape< 2, 8>()), Map(m.data(), 2, 8)); + VERIFY_IS_EQUAL((m.template reshape< 4, 4>()), Map(m.data(), 4, 4)); + VERIFY_IS_EQUAL((m.template reshape< 8, 2>()), Map(m.data(), 8, 2)); + VERIFY_IS_EQUAL((m.template reshape<16, 1>()), Map(m.data(), 16, 1)); } void test_reshape() { - CALL_SUBTEST(dynamic_reshape_all_size(4, 4)); - CALL_SUBTEST(static_reshape_all_size()); + // create matrix(row, col) and filled with 0, 1, 2, ... + // for all possible shape + int row = 4; + int col = 4; + Eigen::MatrixXi mx(row, col); + Eigen::Matrix4i m4(row, col); + + for(int r = 0; r < row; ++r) { + for(int c = 0; c < col; ++c) { + mx(r, c) = col * c + r; + m4(r, c) = col * c + r; + } + } + + // test dynamic-size matrix + CALL_SUBTEST(dynamic_reshape_all_size(mx, 4, 4)); + CALL_SUBTEST(static_reshape_all_size(mx)); + // test static-size matrix + CALL_SUBTEST(dynamic_reshape_all_size(m4, 4, 4)); + CALL_SUBTEST(static_reshape_all_size(m4)); + + // test dynamic-size const matrix + CALL_SUBTEST(dynamic_reshape_all_size(static_cast(mx), 4, 4)); + CALL_SUBTEST(static_reshape_all_size(static_cast(mx))); + // test static-size const matrix + CALL_SUBTEST(dynamic_reshape_all_size(static_cast(m4), 4, 4)); + CALL_SUBTEST(static_reshape_all_size(static_cast(m4))); } From 342c8e532149025fd8263090e291d248f1705cb2 Mon Sep 17 00:00:00 2001 From: yoco Date: Mon, 20 Jan 2014 00:15:19 +0800 Subject: [PATCH 08/15] Fix Reshape DirectAccessBit bug --- Eigen/src/Core/Reshape.h | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Eigen/src/Core/Reshape.h b/Eigen/src/Core/Reshape.h index a773342ad..1397673e5 100644 --- a/Eigen/src/Core/Reshape.h +++ b/Eigen/src/Core/Reshape.h @@ -88,8 +88,13 @@ struct traits > : traits< FlagsLinearAccessBit = (RowsAtCompileTime == 1 || ColsAtCompileTime == 1) ? LinearAccessBit : 0, FlagsLvalueBit = is_lvalue::value ? LvalueBit : 0, FlagsRowMajorBit = IsRowMajor ? RowMajorBit : 0, + IsSameShapeAtCompileTime = RowsAtCompileTime == ReshapeRows + && ColsAtCompileTime == ReshapeCols + && RowsAtCompileTime != Dynamic + && ColsAtCompileTime != Dynamic, + MaskDirectAccessBit = IsSameShapeAtCompileTime ? DirectAccessBit : 0, Flags0 = traits::Flags & ( (HereditaryBits & ~RowMajorBit) | - DirectAccessBit | + MaskDirectAccessBit | MaskPacketAccessBit | MaskAlignedBit), Flags = Flags0 | FlagsLinearAccessBit | FlagsLvalueBit | FlagsRowMajorBit From 03723abda059a1a7f44907a543df248cf7e46104 Mon Sep 17 00:00:00 2001 From: yoco Date: Mon, 20 Jan 2014 00:22:16 +0800 Subject: [PATCH 09/15] Remove useless reshape row/col ctor --- Eigen/src/Core/Reshape.h | 23 ----------------------- 1 file changed, 23 deletions(-) diff --git a/Eigen/src/Core/Reshape.h b/Eigen/src/Core/Reshape.h index 1397673e5..3d741010b 100644 --- a/Eigen/src/Core/Reshape.h +++ b/Eigen/src/Core/Reshape.h @@ -117,16 +117,6 @@ template cl typedef Impl Base; EIGEN_GENERIC_PUBLIC_INTERFACE(Reshape) EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Reshape) - - /** Column or Row constructor - */ - EIGEN_DEVICE_FUNC - inline Reshape(XprType& xpr, Index i) : Impl(xpr,i) - { - eigen_assert( (i>=0) && ( - ((ReshapeRows==1) && (ReshapeCols==XprType::ColsAtCompileTime) && i Date: Mon, 20 Jan 2014 01:43:28 +0800 Subject: [PATCH 10/15] Remove reshape InnerPanel, add test, fix bug --- Eigen/src/Core/Reshape.h | 44 +++++++++++------------ Eigen/src/Core/util/ForwardDeclarations.h | 2 +- test/reshape.cpp | 2 ++ 3 files changed, 24 insertions(+), 24 deletions(-) diff --git a/Eigen/src/Core/Reshape.h b/Eigen/src/Core/Reshape.h index 3d741010b..3e0b91c39 100644 --- a/Eigen/src/Core/Reshape.h +++ b/Eigen/src/Core/Reshape.h @@ -22,9 +22,6 @@ namespace Eigen { * \param XprType the type of the expression in which we are taking a reshape * \param ReshapeRows the number of rows of the reshape we are taking at compile time (optional) * \param ReshapeCols the number of columns of the reshape we are taking at compile time (optional) - * \param InnerPanel is true, if the reshape maps to a set of rows of a row major matrix or - * to set of columns of a column major matrix (optional). The parameter allows to determine - * at compile time whether aligned access is possible on the reshape expression. * * This class represents an expression of either a fixed-size or dynamic-size reshape. It is the return * type of DenseBase::reshape(Index,Index) and DenseBase::reshape() and @@ -50,8 +47,8 @@ namespace Eigen { */ namespace internal { -template -struct traits > : traits +template +struct traits > : traits { typedef typename traits::Scalar Scalar; typedef typename traits::StorageKind StorageKind; @@ -84,7 +81,7 @@ struct traits > : traits< MaskPacketAccessBit = (InnerSize == Dynamic || (InnerSize % packet_traits::size) == 0) && (InnerStrideAtCompileTime == 1) ? PacketAccessBit : 0, - MaskAlignedBit = (InnerPanel && (OuterStrideAtCompileTime!=Dynamic) && (((OuterStrideAtCompileTime * int(sizeof(Scalar))) % 16) == 0)) ? AlignedBit : 0, + MaskAlignedBit = ((OuterStrideAtCompileTime!=Dynamic) && (((OuterStrideAtCompileTime * int(sizeof(Scalar))) % 16) == 0)) ? AlignedBit : 0, FlagsLinearAccessBit = (RowsAtCompileTime == 1 || ColsAtCompileTime == 1) ? LinearAccessBit : 0, FlagsLvalueBit = is_lvalue::value ? LvalueBit : 0, FlagsRowMajorBit = IsRowMajor ? RowMajorBit : 0, @@ -92,7 +89,8 @@ struct traits > : traits< && ColsAtCompileTime == ReshapeCols && RowsAtCompileTime != Dynamic && ColsAtCompileTime != Dynamic, - MaskDirectAccessBit = IsSameShapeAtCompileTime ? DirectAccessBit : 0, + MaskDirectAccessBit = (IsSameShapeAtCompileTime ? DirectAccessBit : 0) + && DirectAccessBit, Flags0 = traits::Flags & ( (HereditaryBits & ~RowMajorBit) | MaskDirectAccessBit | MaskPacketAccessBit | @@ -101,17 +99,17 @@ struct traits > : traits< }; }; -template::ret> class ReshapeImpl_dense; } // end namespace internal -template class ReshapeImpl; +template class ReshapeImpl; -template class Reshape - : public ReshapeImpl::StorageKind> +template class Reshape + : public ReshapeImpl::StorageKind> { - typedef ReshapeImpl::StorageKind> Impl; + typedef ReshapeImpl::StorageKind> Impl; public: //typedef typename Impl::Base Base; typedef Impl Base; @@ -143,11 +141,11 @@ template cl // The generic default implementation for dense reshape simplu forward to the internal::ReshapeImpl_dense // that must be specialized for direct and non-direct access... -template -class ReshapeImpl - : public internal::ReshapeImpl_dense +template +class ReshapeImpl + : public internal::ReshapeImpl_dense { - typedef internal::ReshapeImpl_dense Impl; + typedef internal::ReshapeImpl_dense Impl; typedef typename XprType::Index Index; public: typedef Impl Base; @@ -160,10 +158,10 @@ class ReshapeImpl namespace internal { /** \internal Internal implementation of dense Reshapes in the general case. */ -template class ReshapeImpl_dense - : public internal::dense_xpr_base >::type +template class ReshapeImpl_dense + : public internal::dense_xpr_base >::type { - typedef Reshape ReshapeType; + typedef Reshape ReshapeType; public: typedef typename internal::dense_xpr_base::type Base; @@ -301,11 +299,11 @@ template -//class ReshapeImpl_dense -// : public MapBase > +//template +//class ReshapeImpl_dense +// : public MapBase > //{ -// typedef Reshape ReshapeType; +// typedef Reshape ReshapeType; // public: // // typedef MapBase Base; diff --git a/Eigen/src/Core/util/ForwardDeclarations.h b/Eigen/src/Core/util/ForwardDeclarations.h index a4f3435bb..f85b3b32b 100644 --- a/Eigen/src/Core/util/ForwardDeclarations.h +++ b/Eigen/src/Core/util/ForwardDeclarations.h @@ -79,7 +79,7 @@ template class ForceAlignedAccess; template class SwapWrapper; template class Block; -template class Reshape; +template class Reshape; template class VectorBlock; template class Transpose; diff --git a/test/reshape.cpp b/test/reshape.cpp index 2aef066aa..053ece14d 100644 --- a/test/reshape.cpp +++ b/test/reshape.cpp @@ -53,6 +53,8 @@ void test_reshape() } } + mx.reshape(8, 2).leftCols(2); + // test dynamic-size matrix CALL_SUBTEST(dynamic_reshape_all_size(mx, 4, 4)); CALL_SUBTEST(static_reshape_all_size(mx)); From 009047db2781bb5108b6297ca743dc78ac7401b8 Mon Sep 17 00:00:00 2001 From: yoco Date: Tue, 4 Feb 2014 02:21:41 +0800 Subject: [PATCH 11/15] Fix Reshape traits flag calculate bug --- Eigen/src/Core/Reshape.h | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/Eigen/src/Core/Reshape.h b/Eigen/src/Core/Reshape.h index 3e0b91c39..967849185 100644 --- a/Eigen/src/Core/Reshape.h +++ b/Eigen/src/Core/Reshape.h @@ -12,7 +12,7 @@ #ifndef EIGEN_RESHAPE_H #define EIGEN_RESHAPE_H -namespace Eigen { +namespace Eigen { /** \class Reshape * \ingroup Core_Module @@ -89,19 +89,17 @@ struct traits > : traits && ColsAtCompileTime == ReshapeCols && RowsAtCompileTime != Dynamic && ColsAtCompileTime != Dynamic, - MaskDirectAccessBit = (IsSameShapeAtCompileTime ? DirectAccessBit : 0) - && DirectAccessBit, Flags0 = traits::Flags & ( (HereditaryBits & ~RowMajorBit) | - MaskDirectAccessBit | + DirectAccessBit | MaskPacketAccessBit | MaskAlignedBit), - Flags = Flags0 | FlagsLinearAccessBit | FlagsLvalueBit | FlagsRowMajorBit + Flags = (Flags0 | FlagsLinearAccessBit | FlagsLvalueBit | FlagsRowMajorBit) }; }; template::ret> class ReshapeImpl_dense; - + } // end namespace internal template class ReshapeImpl; @@ -138,7 +136,7 @@ template class Reshape eigen_assert(reshapeRows * reshapeCols == xpr.rows() * xpr.cols()); } }; - + // The generic default implementation for dense reshape simplu forward to the internal::ReshapeImpl_dense // that must be specialized for direct and non-direct access... template @@ -287,10 +285,10 @@ template::type& nestedExpression() const - { - return m_xpr; + { + return m_xpr; } - + protected: const typename XprType::Nested m_xpr; From 515bbf8bb207ed5e43615c96a7a5ef92f8b3d84c Mon Sep 17 00:00:00 2001 From: yoco Date: Tue, 4 Feb 2014 02:50:23 +0800 Subject: [PATCH 12/15] Improve reshape test case - simplify test code - add reshape chain --- test/reshape.cpp | 82 ++++++++++++++++++++++-------------------------- 1 file changed, 38 insertions(+), 44 deletions(-) diff --git a/test/reshape.cpp b/test/reshape.cpp index 053ece14d..eeab155f3 100644 --- a/test/reshape.cpp +++ b/test/reshape.cpp @@ -12,60 +12,54 @@ using Eigen::Map; using Eigen::MatrixXi; -template -void dynamic_reshape_all_size(MatType m, int row, int col) { - for(int new_r = 1; new_r <= row * col; ++new_r) { - // skip invalid shape - if(row * col % new_r != 0) - continue; - - // reshape and compare - int new_c = row * col / new_r; - VERIFY_IS_EQUAL(m.reshape(new_r, new_c), - Map(m.data(), new_r, new_c)); - } -} - // just test a 4x4 matrix, enumerate all combination manually, // so I don't have to do template-meta-programming here. template -void static_reshape_all_size(MatType m) { - VERIFY_IS_EQUAL((m.template reshape< 1, 16>()), Map(m.data(), 1, 16)); - VERIFY_IS_EQUAL((m.template reshape< 2, 8>()), Map(m.data(), 2, 8)); - VERIFY_IS_EQUAL((m.template reshape< 4, 4>()), Map(m.data(), 4, 4)); - VERIFY_IS_EQUAL((m.template reshape< 8, 2>()), Map(m.data(), 8, 2)); - VERIFY_IS_EQUAL((m.template reshape<16, 1>()), Map(m.data(), 16, 1)); +void reshape_all_size(MatType m) { + typedef Eigen::Map MapMat; + // dynamic + VERIFY_IS_EQUAL((m.template reshape( 1, 16)), MapMat(m.eval().data(), 1, 16)); + VERIFY_IS_EQUAL((m.template reshape( 2, 8)), MapMat(m.eval().data(), 2, 8)); + VERIFY_IS_EQUAL((m.template reshape( 4, 4)), MapMat(m.eval().data(), 4, 4)); + VERIFY_IS_EQUAL((m.template reshape( 8, 2)), MapMat(m.eval().data(), 8, 2)); + VERIFY_IS_EQUAL((m.template reshape(16, 1)), MapMat(m.eval().data(), 16, 1)); + + // static + VERIFY_IS_EQUAL((m.template reshape< 1, 16>()), MapMat(m.eval().data(), 1, 16)); + VERIFY_IS_EQUAL((m.template reshape< 2, 8>()), MapMat(m.eval().data(), 2, 8)); + VERIFY_IS_EQUAL((m.template reshape< 4, 4>()), MapMat(m.eval().data(), 4, 4)); + VERIFY_IS_EQUAL((m.template reshape< 8, 2>()), MapMat(m.eval().data(), 8, 2)); + VERIFY_IS_EQUAL((m.template reshape<16, 1>()), MapMat(m.eval().data(), 16, 1)); + + // reshape chain + VERIFY_IS_EQUAL( + (m + .template reshape( 1, 16) + .template reshape< 2, 8>() + .template reshape(16, 1) + .template reshape< 8, 2>() + .template reshape( 2, 8) + .template reshape< 1, 16>() + .template reshape( 4, 4) + .template reshape<16, 1>() + .template reshape( 8, 2) + .template reshape< 4, 4>() + ), + MapMat(m.eval().data(), 4, 4) + ); } void test_reshape() { - // create matrix(row, col) and filled with 0, 1, 2, ... - // for all possible shape - int row = 4; - int col = 4; - Eigen::MatrixXi mx(row, col); - Eigen::Matrix4i m4(row, col); - - for(int r = 0; r < row; ++r) { - for(int c = 0; c < col; ++c) { - mx(r, c) = col * c + r; - m4(r, c) = col * c + r; - } - } - - mx.reshape(8, 2).leftCols(2); + Eigen::MatrixXi mx = Eigen::MatrixXi::Random(4, 4); + Eigen::Matrix4i m4 = Eigen::Matrix4i::Random(4, 4); // test dynamic-size matrix - CALL_SUBTEST(dynamic_reshape_all_size(mx, 4, 4)); - CALL_SUBTEST(static_reshape_all_size(mx)); + CALL_SUBTEST(reshape_all_size(mx)); // test static-size matrix - CALL_SUBTEST(dynamic_reshape_all_size(m4, 4, 4)); - CALL_SUBTEST(static_reshape_all_size(m4)); - + CALL_SUBTEST(reshape_all_size(m4)); // test dynamic-size const matrix - CALL_SUBTEST(dynamic_reshape_all_size(static_cast(mx), 4, 4)); - CALL_SUBTEST(static_reshape_all_size(static_cast(mx))); + CALL_SUBTEST(reshape_all_size(static_cast(mx))); // test static-size const matrix - CALL_SUBTEST(dynamic_reshape_all_size(static_cast(m4), 4, 4)); - CALL_SUBTEST(static_reshape_all_size(static_cast(m4))); + CALL_SUBTEST(reshape_all_size(static_cast(m4))); } From f8ad87f226ded488a153a3b978881a369362e3f4 Mon Sep 17 00:00:00 2001 From: yoco Date: Tue, 4 Feb 2014 05:19:56 +0800 Subject: [PATCH 13/15] Reshape always non-directly-access --- Eigen/src/Core/Reshape.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Eigen/src/Core/Reshape.h b/Eigen/src/Core/Reshape.h index 967849185..9666e6b9c 100644 --- a/Eigen/src/Core/Reshape.h +++ b/Eigen/src/Core/Reshape.h @@ -90,7 +90,7 @@ struct traits > : traits && RowsAtCompileTime != Dynamic && ColsAtCompileTime != Dynamic, Flags0 = traits::Flags & ( (HereditaryBits & ~RowMajorBit) | - DirectAccessBit | + (traits::Flags & ~DirectAccessBit) | MaskPacketAccessBit | MaskAlignedBit), Flags = (Flags0 | FlagsLinearAccessBit | FlagsLvalueBit | FlagsRowMajorBit) From b64a09acc109489f0b14c20de11493c26cc74d92 Mon Sep 17 00:00:00 2001 From: yoco Date: Tue, 4 Feb 2014 05:54:50 +0800 Subject: [PATCH 14/15] fix reshape's Max[Row/Col]AtCompileTime --- Eigen/src/Core/Reshape.h | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/Eigen/src/Core/Reshape.h b/Eigen/src/Core/Reshape.h index 9666e6b9c..e82136bd4 100644 --- a/Eigen/src/Core/Reshape.h +++ b/Eigen/src/Core/Reshape.h @@ -61,11 +61,9 @@ struct traits > : traits RowsAtCompileTime = MatrixRows == 0 ? 0 : ReshapeRows, ColsAtCompileTime = MatrixCols == 0 ? 0 : ReshapeCols, MaxRowsAtCompileTime = ReshapeRows==0 ? 0 - : RowsAtCompileTime != Dynamic ? int(RowsAtCompileTime) - : int(traits::MaxRowsAtCompileTime), + : int(RowsAtCompileTime), MaxColsAtCompileTime = ReshapeCols==0 ? 0 - : ColsAtCompileTime != Dynamic ? int(ColsAtCompileTime) - : int(traits::MaxColsAtCompileTime), + : int(ColsAtCompileTime), XprTypeIsRowMajor = (int(traits::Flags)&RowMajorBit) != 0, IsRowMajor = (MaxRowsAtCompileTime==1&&MaxColsAtCompileTime!=1) ? 1 : (MaxColsAtCompileTime==1&&MaxRowsAtCompileTime!=1) ? 0 From 15f273b63c1089df68129076de4f93cbd38aae5b Mon Sep 17 00:00:00 2001 From: yoco Date: Mon, 10 Feb 2014 22:49:13 +0800 Subject: [PATCH 15/15] fix reshape flag and test case --- Eigen/src/Core/Reshape.h | 27 ++++++++++----------------- test/reshape.cpp | 22 +++++++++++----------- 2 files changed, 21 insertions(+), 28 deletions(-) diff --git a/Eigen/src/Core/Reshape.h b/Eigen/src/Core/Reshape.h index e82136bd4..e4a71312c 100644 --- a/Eigen/src/Core/Reshape.h +++ b/Eigen/src/Core/Reshape.h @@ -53,20 +53,16 @@ struct traits > : traits typedef typename traits::Scalar Scalar; typedef typename traits::StorageKind StorageKind; typedef typename traits::XprKind XprKind; - typedef typename nested::type XprTypeNested; - typedef typename remove_reference::type _XprTypeNested; enum{ MatrixRows = traits::RowsAtCompileTime, MatrixCols = traits::ColsAtCompileTime, - RowsAtCompileTime = MatrixRows == 0 ? 0 : ReshapeRows, - ColsAtCompileTime = MatrixCols == 0 ? 0 : ReshapeCols, - MaxRowsAtCompileTime = ReshapeRows==0 ? 0 - : int(RowsAtCompileTime), - MaxColsAtCompileTime = ReshapeCols==0 ? 0 - : int(ColsAtCompileTime), - XprTypeIsRowMajor = (int(traits::Flags)&RowMajorBit) != 0, - IsRowMajor = (MaxRowsAtCompileTime==1&&MaxColsAtCompileTime!=1) ? 1 - : (MaxColsAtCompileTime==1&&MaxRowsAtCompileTime!=1) ? 0 + RowsAtCompileTime = ReshapeRows, + ColsAtCompileTime = ReshapeCols, + MaxRowsAtCompileTime = ReshapeRows, + MaxColsAtCompileTime = ReshapeCols, + XprTypeIsRowMajor = (int(traits::Flags) & RowMajorBit) != 0, + IsRowMajor = (RowsAtCompileTime == 1 && ColsAtCompileTime != 1) ? 1 + : (ColsAtCompileTime == 1 && RowsAtCompileTime != 1) ? 0 : XprTypeIsRowMajor, HasSameStorageOrderAsXprType = (IsRowMajor == XprTypeIsRowMajor), InnerSize = IsRowMajor ? int(ColsAtCompileTime) : int(RowsAtCompileTime), @@ -83,14 +79,11 @@ struct traits > : traits FlagsLinearAccessBit = (RowsAtCompileTime == 1 || ColsAtCompileTime == 1) ? LinearAccessBit : 0, FlagsLvalueBit = is_lvalue::value ? LvalueBit : 0, FlagsRowMajorBit = IsRowMajor ? RowMajorBit : 0, - IsSameShapeAtCompileTime = RowsAtCompileTime == ReshapeRows - && ColsAtCompileTime == ReshapeCols - && RowsAtCompileTime != Dynamic - && ColsAtCompileTime != Dynamic, Flags0 = traits::Flags & ( (HereditaryBits & ~RowMajorBit) | - (traits::Flags & ~DirectAccessBit) | MaskPacketAccessBit | - MaskAlignedBit), + MaskAlignedBit) + & ~DirectAccessBit, + Flags = (Flags0 | FlagsLinearAccessBit | FlagsLvalueBit | FlagsRowMajorBit) }; }; diff --git a/test/reshape.cpp b/test/reshape.cpp index eeab155f3..0298a2fe4 100644 --- a/test/reshape.cpp +++ b/test/reshape.cpp @@ -18,18 +18,18 @@ template void reshape_all_size(MatType m) { typedef Eigen::Map MapMat; // dynamic - VERIFY_IS_EQUAL((m.template reshape( 1, 16)), MapMat(m.eval().data(), 1, 16)); - VERIFY_IS_EQUAL((m.template reshape( 2, 8)), MapMat(m.eval().data(), 2, 8)); - VERIFY_IS_EQUAL((m.template reshape( 4, 4)), MapMat(m.eval().data(), 4, 4)); - VERIFY_IS_EQUAL((m.template reshape( 8, 2)), MapMat(m.eval().data(), 8, 2)); - VERIFY_IS_EQUAL((m.template reshape(16, 1)), MapMat(m.eval().data(), 16, 1)); + VERIFY_IS_EQUAL((m.template reshape( 1, 16)), MapMat(m.data(), 1, 16)); + VERIFY_IS_EQUAL((m.template reshape( 2, 8)), MapMat(m.data(), 2, 8)); + VERIFY_IS_EQUAL((m.template reshape( 4, 4)), MapMat(m.data(), 4, 4)); + VERIFY_IS_EQUAL((m.template reshape( 8, 2)), MapMat(m.data(), 8, 2)); + VERIFY_IS_EQUAL((m.template reshape(16, 1)), MapMat(m.data(), 16, 1)); // static - VERIFY_IS_EQUAL((m.template reshape< 1, 16>()), MapMat(m.eval().data(), 1, 16)); - VERIFY_IS_EQUAL((m.template reshape< 2, 8>()), MapMat(m.eval().data(), 2, 8)); - VERIFY_IS_EQUAL((m.template reshape< 4, 4>()), MapMat(m.eval().data(), 4, 4)); - VERIFY_IS_EQUAL((m.template reshape< 8, 2>()), MapMat(m.eval().data(), 8, 2)); - VERIFY_IS_EQUAL((m.template reshape<16, 1>()), MapMat(m.eval().data(), 16, 1)); + VERIFY_IS_EQUAL((m.template reshape< 1, 16>()), MapMat(m.data(), 1, 16)); + VERIFY_IS_EQUAL((m.template reshape< 2, 8>()), MapMat(m.data(), 2, 8)); + VERIFY_IS_EQUAL((m.template reshape< 4, 4>()), MapMat(m.data(), 4, 4)); + VERIFY_IS_EQUAL((m.template reshape< 8, 2>()), MapMat(m.data(), 8, 2)); + VERIFY_IS_EQUAL((m.template reshape<16, 1>()), MapMat(m.data(), 16, 1)); // reshape chain VERIFY_IS_EQUAL( @@ -45,7 +45,7 @@ void reshape_all_size(MatType m) { .template reshape( 8, 2) .template reshape< 4, 4>() ), - MapMat(m.eval().data(), 4, 4) + MapMat(m.data(), 4, 4) ); }