diff options
author | Gael Guennebaud <g.gael@free.fr> | 2011-01-26 16:33:23 +0100 |
---|---|---|
committer | Gael Guennebaud <g.gael@free.fr> | 2011-01-26 16:33:23 +0100 |
commit | 15ef62ca43c2e08c1e2fefb751b994441e019376 (patch) | |
tree | 85b8e86cedb33e44f259275a814ec983d802b855 /Eigen/src/Core/Transpositions.h | |
parent | 84448b058c1611a0eae45212007d02a0c5457f5c (diff) |
extend PermutationMatrix and Transpositions to support arbitrary interger types and to support the Map/Wrapper model via base and derived classes
Diffstat (limited to 'Eigen/src/Core/Transpositions.h')
-rw-r--r-- | Eigen/src/Core/Transpositions.h | 295 |
1 files changed, 222 insertions, 73 deletions
diff --git a/Eigen/src/Core/Transpositions.h b/Eigen/src/Core/Transpositions.h index 9735b4eea..928ccb02b 100644 --- a/Eigen/src/Core/Transpositions.h +++ b/Eigen/src/Core/Transpositions.h @@ -1,7 +1,7 @@ // This file is part of Eigen, a lightweight C++ template library // for linear algebra. // -// Copyright (C) 2010 Gael Guennebaud <gael.guennebaud@inria.fr> +// Copyright (C) 2010-2011 Gael Guennebaud <gael.guennebaud@inria.fr> // // Eigen is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -58,88 +58,72 @@ namespace internal { template<typename TranspositionType, typename MatrixType, int Side, bool Transposed=false> struct transposition_matrix_product_retval; } -template<int SizeAtCompileTime, int MaxSizeAtCompileTime> -class Transpositions +template<typename Derived> +class TranspositionsBase { + typedef internal::traits<Derived> Traits; + public: - typedef Matrix<DenseIndex, SizeAtCompileTime, 1, 0, MaxSizeAtCompileTime, 1> IndicesType; - typedef typename IndicesType::Index Index; + typedef typename Traits::IndicesType IndicesType; + typedef typename IndicesType::Scalar Index; - inline Transpositions() {} + Derived& derived() { return *static_cast<Derived*>(this); } + const Derived& derived() const { return *static_cast<const Derived*>(this); } - /** Copy constructor. */ - template<int OtherSize, int OtherMaxSize> - inline Transpositions(const Transpositions<OtherSize, OtherMaxSize>& other) - : m_indices(other.indices()) {} - - #ifndef EIGEN_PARSED_BY_DOXYGEN - /** Standard copy constructor. Defined only to prevent a default copy constructor - * from hiding the other templated constructor */ - inline Transpositions(const Transpositions& other) : m_indices(other.indices()) {} - #endif - - /** Generic constructor from expression of the transposition indices. */ - template<typename Other> - explicit inline Transpositions(const MatrixBase<Other>& indices) : m_indices(indices) - {} + inline TranspositionsBase() {} /** Copies the \a other transpositions into \c *this */ - template<int OtherSize, int OtherMaxSize> - Transpositions& operator=(const Transpositions<OtherSize, OtherMaxSize>& other) + template<typename OtherDerived> + Derived& operator=(const TranspositionsBase<OtherDerived>& other) { - m_indices = other.indices(); - return *this; + indices() = other.indices(); + return derived(); } #ifndef EIGEN_PARSED_BY_DOXYGEN /** This is a special case of the templated operator=. Its purpose is to * prevent a default operator= from hiding the templated operator=. */ - Transpositions& operator=(const Transpositions& other) + Derived& operator=(const TranspositionsBase& other) { - m_indices = other.m_indices; - return *this; + indices() = other.indices(); + return derived(); } #endif - /** Constructs an uninitialized permutation matrix of given size. - */ - inline Transpositions(Index size) : m_indices(size) - {} - /** \returns the number of transpositions */ - inline Index size() const { return m_indices.size(); } + inline Index size() const { return indices().size(); } /** Direct access to the underlying index vector */ - inline const Index& coeff(Index i) const { return m_indices.coeff(i); } + inline const Index& coeff(Index i) const { return indices().coeff(i); } /** Direct access to the underlying index vector */ - inline Index& coeffRef(Index i) { return m_indices.coeffRef(i); } + inline Index& coeffRef(Index i) { return indices().coeffRef(i); } /** Direct access to the underlying index vector */ - inline const Index& operator()(Index i) const { return m_indices(i); } + inline const Index& operator()(Index i) const { return indices()(i); } /** Direct access to the underlying index vector */ - inline Index& operator()(Index i) { return m_indices(i); } + inline Index& operator()(Index i) { return indices()(i); } /** Direct access to the underlying index vector */ - inline const Index& operator[](Index i) const { return m_indices(i); } + inline const Index& operator[](Index i) const { return indices()(i); } /** Direct access to the underlying index vector */ - inline Index& operator[](Index i) { return m_indices(i); } + inline Index& operator[](Index i) { return indices()(i); } /** const version of indices(). */ - const IndicesType& indices() const { return m_indices; } + const IndicesType& indices() const { return derived().indices(); } /** \returns a reference to the stored array representing the transpositions. */ - IndicesType& indices() { return m_indices; } + IndicesType& indices() { return derived().indices(); } /** Resizes to given size. */ inline void resize(int size) { - m_indices.resize(size); + indices().resize(size); } /** Sets \c *this to represents an identity transformation */ void setIdentity() { - for(int i = 0; i < m_indices.size(); ++i) - m_indices.coeffRef(i) = i; + for(int i = 0; i < indices().size(); ++i) + coeffRef(i) = i; } // FIXME: do we want such methods ? @@ -164,53 +148,220 @@ class Transpositions */ /** \returns the inverse transformation */ - inline Transpose<Transpositions> inverse() const - { return *this; } + inline Transpose<TranspositionsBase> inverse() const + { return Transpose<TranspositionsBase>(derived()); } /** \returns the tranpose transformation */ - inline Transpose<Transpositions> transpose() const - { return *this; } + inline Transpose<TranspositionsBase> transpose() const + { return Transpose<TranspositionsBase>(derived()); } -#ifndef EIGEN_PARSED_BY_DOXYGEN - template<int OtherSize, int OtherMaxSize> - Transpositions(const Transpose<Transpositions<OtherSize,OtherMaxSize> >& other) - : m_indices(other.size()) + protected: +}; + +namespace internal { +template<int SizeAtCompileTime, int MaxSizeAtCompileTime, typename IndexType> +struct traits<Transpositions<SizeAtCompileTime,MaxSizeAtCompileTime,IndexType> > +{ + typedef IndexType Index; + typedef Matrix<Index, SizeAtCompileTime, 1, 0, MaxSizeAtCompileTime, 1> IndicesType; +}; +} + +template<int SizeAtCompileTime, int MaxSizeAtCompileTime, typename IndexType> +class Transpositions : public TranspositionsBase<Transpositions<SizeAtCompileTime,MaxSizeAtCompileTime,IndexType> > +{ + typedef internal::traits<Transpositions> Traits; + public: + + typedef TranspositionsBase<Transpositions> Base; + typedef typename Traits::IndicesType IndicesType; + typedef typename IndicesType::Scalar Index; + + inline Transpositions() {} + + /** Copy constructor. */ + template<typename OtherDerived> + inline Transpositions(const TranspositionsBase<OtherDerived>& other) + : m_indices(other.indices()) {} + + #ifndef EIGEN_PARSED_BY_DOXYGEN + /** Standard copy constructor. Defined only to prevent a default copy constructor + * from hiding the other templated constructor */ + inline Transpositions(const Transpositions& other) : m_indices(other.indices()) {} + #endif + + /** Generic constructor from expression of the transposition indices. */ + template<typename Other> + explicit inline Transpositions(const MatrixBase<Other>& indices) : m_indices(indices) + {} + + /** Copies the \a other transpositions into \c *this */ + template<typename OtherDerived> + Transpositions& operator=(const TranspositionsBase<OtherDerived>& other) { - Index n = size(); - Index j = size-1; - for(Index i=0; i<n;++i,--j) - m_indices.coeffRef(j) = other.nestedTranspositions().indices().coeff(i); + return Base::operator=(other); } -#endif + + #ifndef EIGEN_PARSED_BY_DOXYGEN + /** This is a special case of the templated operator=. Its purpose is to + * prevent a default operator= from hiding the templated operator=. + */ + Transpositions& operator=(const Transpositions& other) + { + m_indices = other.m_indices; + return *this; + } + #endif + + /** Constructs an uninitialized permutation matrix of given size. + */ + inline Transpositions(Index size) : m_indices(size) + {} + + /** const version of indices(). */ + const IndicesType& indices() const { return m_indices; } + /** \returns a reference to the stored array representing the transpositions. */ + IndicesType& indices() { return m_indices; } protected: IndicesType m_indices; }; + +namespace internal { +template<int SizeAtCompileTime, int MaxSizeAtCompileTime, typename IndexType, int _PacketAccess> +struct traits<Map<Transpositions<SizeAtCompileTime,MaxSizeAtCompileTime,IndexType>,_PacketAccess> > +{ + typedef IndexType Index; + typedef Map<const Matrix<Index,SizeAtCompileTime,1,0,MaxSizeAtCompileTime,1>, _PacketAccess> IndicesType; +}; +} + +template<int SizeAtCompileTime, int MaxSizeAtCompileTime, typename IndexType, int PacketAccess> +class Map<Transpositions<SizeAtCompileTime,MaxSizeAtCompileTime,IndexType>,PacketAccess> + : public TranspositionsBase<Map<Transpositions<SizeAtCompileTime,MaxSizeAtCompileTime,IndexType>,PacketAccess> > +{ + typedef internal::traits<Map> Traits; + public: + + typedef TranspositionsBase<Map> Base; + typedef typename Traits::IndicesType IndicesType; + typedef typename IndicesType::Scalar Index; + + inline Map(const Index* indices) + : m_indices(indices) + {} + + inline Map(const Index* indices, Index size) + : m_indices(indices,size) + {} + + /** Copies the \a other transpositions into \c *this */ + template<typename OtherDerived> + Map& operator=(const TranspositionsBase<OtherDerived>& other) + { + return Base::operator=(other); + } + + #ifndef EIGEN_PARSED_BY_DOXYGEN + /** This is a special case of the templated operator=. Its purpose is to + * prevent a default operator= from hiding the templated operator=. + */ + Map& operator=(const Map& other) + { + m_indices = other.m_indices; + return *this; + } + #endif + + /** const version of indices(). */ + const IndicesType& indices() const { return m_indices; } + + /** \returns a reference to the stored array representing the transpositions. */ + IndicesType& indices() { return m_indices; } + + protected: + + IndicesType m_indices; +}; + +namespace internal { +template<typename _IndicesType> +struct traits<TranspositionsWrapper<_IndicesType> > +{ + typedef typename _IndicesType::Scalar Index; + typedef _IndicesType IndicesType; +}; +} + +template<typename _IndicesType> +class TranspositionsWrapper + : public TranspositionsBase<TranspositionsWrapper<_IndicesType> > +{ + typedef internal::traits<TranspositionsWrapper> Traits; + public: + + typedef TranspositionsBase<TranspositionsWrapper> Base; + typedef typename Traits::IndicesType IndicesType; + typedef typename IndicesType::Scalar Index; + + inline TranspositionsWrapper(IndicesType& indices) + : m_indices(indices) + {} + + /** Copies the \a other transpositions into \c *this */ + template<typename OtherDerived> + TranspositionsWrapper& operator=(const TranspositionsBase<OtherDerived>& other) + { + return Base::operator=(other); + } + + #ifndef EIGEN_PARSED_BY_DOXYGEN + /** This is a special case of the templated operator=. Its purpose is to + * prevent a default operator= from hiding the templated operator=. + */ + TranspositionsWrapper& operator=(const TranspositionsWrapper& other) + { + m_indices = other.m_indices; + return *this; + } + #endif + + /** const version of indices(). */ + const IndicesType& indices() const { return m_indices; } + + /** \returns a reference to the stored array representing the transpositions. */ + IndicesType& indices() { return m_indices; } + + protected: + + const typename IndicesType::Nested m_indices; +}; + /** \returns the \a matrix with the \a transpositions applied to the columns. */ -template<typename Derived, int SizeAtCompileTime, int MaxSizeAtCompileTime> -inline const internal::transposition_matrix_product_retval<Transpositions<SizeAtCompileTime, MaxSizeAtCompileTime>, Derived, OnTheRight> +template<typename Derived, typename TranspositionsDerived> +inline const internal::transposition_matrix_product_retval<TranspositionsDerived, Derived, OnTheRight> operator*(const MatrixBase<Derived>& matrix, - const Transpositions<SizeAtCompileTime, MaxSizeAtCompileTime> &transpositions) + const TranspositionsBase<TranspositionsDerived> &transpositions) { return internal::transposition_matrix_product_retval - <Transpositions<SizeAtCompileTime, MaxSizeAtCompileTime>, Derived, OnTheRight> - (transpositions, matrix.derived()); + <TranspositionsDerived, Derived, OnTheRight> + (transpositions.derived(), matrix.derived()); } /** \returns the \a matrix with the \a transpositions applied to the rows. */ -template<typename Derived, int SizeAtCompileTime, int MaxSizeAtCompileTime> +template<typename Derived, typename TranspositionDerived> inline const internal::transposition_matrix_product_retval - <Transpositions<SizeAtCompileTime, MaxSizeAtCompileTime>, Derived, OnTheLeft> -operator*(const Transpositions<SizeAtCompileTime, MaxSizeAtCompileTime> &transpositions, + <TranspositionDerived, Derived, OnTheLeft> +operator*(const TranspositionsBase<TranspositionDerived> &transpositions, const MatrixBase<Derived>& matrix) { return internal::transposition_matrix_product_retval - <Transpositions<SizeAtCompileTime, MaxSizeAtCompileTime>, Derived, OnTheLeft> - (transpositions, matrix.derived()); + <TranspositionDerived, Derived, OnTheLeft> + (transpositions.derived(), matrix.derived()); } namespace internal { @@ -262,10 +413,10 @@ struct transposition_matrix_product_retval /* Template partial specialization for transposed/inverse transpositions */ -template<int SizeAtCompileTime, int MaxSizeAtCompileTime> -class Transpose<Transpositions<SizeAtCompileTime, MaxSizeAtCompileTime> > +template<typename TranspositionsDerived> +class Transpose<TranspositionsBase<TranspositionsDerived> > { - typedef Transpositions<SizeAtCompileTime, MaxSizeAtCompileTime> TranspositionType; + typedef TranspositionsDerived TranspositionType; typedef typename TranspositionType::IndicesType IndicesType; public: @@ -291,8 +442,6 @@ class Transpose<Transpositions<SizeAtCompileTime, MaxSizeAtCompileTime> > return internal::transposition_matrix_product_retval<TranspositionType, Derived, OnTheLeft, true>(m_transpositions, matrix.derived()); } - const TranspositionType& nestedTranspositions() const { return m_transpositions; } - protected: const TranspositionType& m_transpositions; }; |