diff options
-rw-r--r-- | Eigen/src/Core/ArithmeticSequence.h | 84 | ||||
-rw-r--r-- | Eigen/src/Core/util/IntegralConstant.h | 2 | ||||
-rw-r--r-- | test/indexed_view.cpp | 22 |
3 files changed, 96 insertions, 12 deletions
diff --git a/Eigen/src/Core/ArithmeticSequence.h b/Eigen/src/Core/ArithmeticSequence.h index 2ad4c0906..0f9c72e2e 100644 --- a/Eigen/src/Core/ArithmeticSequence.h +++ b/Eigen/src/Core/ArithmeticSequence.h @@ -12,10 +12,69 @@ namespace Eigen { +namespace internal { + +#if !EIGEN_HAS_CXX11 +template<typename T> struct aseq_negate {}; + +template<> struct aseq_negate<Index> { + typedef Index type; +}; + +template<int N> struct aseq_negate<fix_t<N> > { + typedef fix_t<-N> type; +}; + +// Compilation error in the following case: +template<> struct aseq_negate<fix_t<DynamicIndex> > {}; + +template<typename FirstType,typename SizeType, + bool FirstIsSymbolic=Symbolic::is_symbolic<FirstType>::value, + bool SizeIsSymbolic =Symbolic::is_symbolic<SizeType>::value> +struct aseq_reverse_first_type { + typedef Index type; +}; + +template<typename FirstType,typename SizeType> +struct aseq_reverse_first_type<FirstType,SizeType,true,true> { + typedef Symbolic::AddExpr<FirstType, + Symbolic::ProductExpr<Symbolic::AddExpr<SizeType,Symbolic::ValueExpr>, + Symbolic::ValueExpr> + > type; +}; + +template<typename FirstType,typename SizeType> +struct aseq_reverse_first_type<FirstType,SizeType,true,false> { + typedef Symbolic::AddExpr<FirstType,Symbolic::ValueExpr> type; +}; + +template<typename FirstType,typename SizeType> +struct aseq_reverse_first_type<FirstType,SizeType,false,true> { + typedef Symbolic::AddExpr<Symbolic::ProductExpr<Symbolic::AddExpr<SizeType,Symbolic::ValueExpr>,Symbolic::ValueExpr>, + Symbolic::ValueExpr> type; +}; +#endif + +// Helper to cleanup the type of the increment: +template<typename T> struct cleanup_seq_incr { + typedef typename cleanup_index_type<T,DynamicIndex>::type type; +}; + +} + //-------------------------------------------------------------------------------- // seq(first,last,incr) and seqN(first,size,incr) //-------------------------------------------------------------------------------- +template<typename FirstType=Index,typename SizeType=Index,typename IncrType=internal::fix_t<1> > +class ArithmeticSequence; + +template<typename FirstType,typename SizeType,typename IncrType> +ArithmeticSequence<typename internal::cleanup_index_type<FirstType>::type, + typename internal::cleanup_index_type<SizeType>::type, + typename internal::cleanup_seq_incr<IncrType>::type > +seqN(FirstType first, SizeType size, IncrType incr); + /** \class ArithmeticSequence * \ingroup Core_Module * @@ -35,10 +94,9 @@ namespace Eigen { * * \sa Eigen::seq, Eigen::seqN, DenseBase::operator()(const RowIndices&, const ColIndices&), class IndexedView */ -template<typename FirstType=Index,typename SizeType=Index,typename IncrType=internal::fix_t<1> > +template<typename FirstType,typename SizeType,typename IncrType> class ArithmeticSequence { - public: ArithmeticSequence(FirstType first, SizeType size) : m_first(first), m_size(size) {} ArithmeticSequence(FirstType first, SizeType size, IncrType incr) : m_first(first), m_size(size), m_incr(incr) {} @@ -65,17 +123,25 @@ protected: FirstType m_first; SizeType m_size; IncrType m_incr; -}; -namespace internal { +public: -// Helper to cleanup the type of the increment: -template<typename T> struct cleanup_seq_incr { - typedef typename cleanup_index_type<T,DynamicIndex>::type type; +#if EIGEN_HAS_CXX11 + auto reverse() const -> decltype(Eigen::seqN(m_first+(m_size-1)*Index(m_incr),m_size,-m_incr)) { + return seqN(m_first+(m_size-1)*Index(m_incr),m_size,-m_incr); + } +#else +protected: + typedef typename internal::aseq_negate<IncrType>::type ReverseIncrType; + typedef typename internal::aseq_reverse_first_type<FirstType,SizeType>::type ReverseFirstType; +public: + ArithmeticSequence<ReverseFirstType,SizeType,ReverseIncrType> + reverse() const { + return seqN(m_first+(m_size-1)*Index(m_incr),m_size,-m_incr); + } +#endif }; -} - /** \returns an ArithmeticSequence starting at \a first, of length \a size, and increment \a incr * * \sa seqN(FirstType,SizeType), seq(FirstType,LastType,IncrType) */ diff --git a/Eigen/src/Core/util/IntegralConstant.h b/Eigen/src/Core/util/IntegralConstant.h index 2402baeec..354aa8c4c 100644 --- a/Eigen/src/Core/util/IntegralConstant.h +++ b/Eigen/src/Core/util/IntegralConstant.h @@ -27,6 +27,8 @@ template<int N> struct fix_t { eigen_internal_assert(int(other)==N); } + fix_t<-N> operator-() const { return fix_t<-N>(); } + #if EIGEN_HAS_CXX14 // Needed in C++14 to allow fix<N>(): fix_t operator() () const { return *this; } diff --git a/test/indexed_view.cpp b/test/indexed_view.cpp index 47c454976..f8b3838a4 100644 --- a/test/indexed_view.cpp +++ b/test/indexed_view.cpp @@ -58,7 +58,13 @@ template<typename T1,typename T2> typename internal::enable_if<internal::is_same<T1,T2>::value,bool>::type is_same_seq_type(const T1& a, const T2& b) { - return a.size() == b.size() && a.first()==b.first() && Index(a.incrObject())==Index(b.incrObject()); + bool ok = a.first()==b.first() && a.size() == b.size() && Index(a.incrObject())==Index(b.incrObject());; + if(!ok) + { + std::cerr << "seqN(" << a.first() << ", " << a.size() << ", " << Index(a.incrObject()) << ") != "; + std::cerr << "seqN(" << b.first() << ", " << b.size() << ", " << Index(b.incrObject()) << ")\n"; + } + return ok; } #define VERIFY_EQ_INT(A,B) VERIFY_IS_APPROX(int(A),int(B)) @@ -187,7 +193,6 @@ void check_indexed_view() VERIFY( is_same_seq_type( seqN(2,fix<Dynamic>(5),3), seqN(2,5,fix<DynamicIndex>(3)) ) ); VERIFY( is_same_seq_type( seqN(2,fix<5>(5),fix<-2>), seqN(2,fix<5>,fix<-2>()) ) ); - VERIFY( (A(seqN(2,fix<5>), 5)).RowsAtCompileTime == 5); VERIFY( (A(4, all)).ColsAtCompileTime == Dynamic); VERIFY( (A(4, all)).RowsAtCompileTime == 1); @@ -201,6 +206,8 @@ void check_indexed_view() VERIFY_EQ_INT( (A(eii, eii)).InnerStrideAtCompileTime, 0); VERIFY_EQ_INT( (A(eii, eii)).OuterStrideAtCompileTime, 0); + VERIFY_IS_APPROX( A(seq(n-1,2,-2), seqN(n-1-6,3,-1)), A(seq(last,2,fix<-2>), seqN(last-6,3,fix<-1>)) ); + VERIFY_IS_APPROX( A(seq(n-1,2,-2), seqN(n-1-6,4)), A(seq(last,2,-2), seqN(last-6,4)) ); VERIFY_IS_APPROX( A(seq(n-1-6,n-1-2), seqN(n-1-6,4)), A(seq(last-6,last-2), seqN(6+last-6-6,4)) ); VERIFY_IS_APPROX( A(seq((n-1)/2,(n)/2+3), seqN(2,4)), A(seq(last/2,(last+1)/2+3), seqN(last+2-last,4)) ); @@ -218,7 +225,6 @@ void check_indexed_view() VERIFY_IS_APPROX( a(a.size()-2), a(last-1) ); VERIFY_IS_APPROX( a(a.size()/2), a((last+1)/2) ); - // Check fall-back to Block { VERIFY( is_same_eq(A.col(0), A(all,0)) ); @@ -251,6 +257,16 @@ void check_indexed_view() A1(seq(6,3,-1),range25) = A2; VERIFY_IS_APPROX( A1.block(3,2,4,4), A2 ); + // check reverse + { + VERIFY( is_same_seq_type( seq(3,7).reverse(), seqN(7,5,fix<-1>) ) ); + VERIFY( is_same_seq_type( seq(7,3,fix<-2>).reverse(), seqN(3,3,fix<2>) ) ); + VERIFY_IS_APPROX( a(seqN(2,last/2).reverse()), a(seqN(2+(last/2-1)*1,last/2,fix<-1>)) ); + VERIFY_IS_APPROX( a(seqN(last/2,fix<4>).reverse()),a(seqN(last/2,fix<4>)).reverse() ); + VERIFY_IS_APPROX( A(seq(last-5,last-1,2).reverse(), seqN(last-3,3,fix<-2>).reverse()), + A(seq(last-5,last-1,2), seqN(last-3,3,fix<-2>)).reverse() ); + } + #if EIGEN_HAS_CXX11 VERIFY( (A(all, std::array<int,4>{{1,3,2,4}})).ColsAtCompileTime == 4); |