Eigen  3.3.3
Transpositions.h
00001 // This file is part of Eigen, a lightweight C++ template library
00002 // for linear algebra.
00003 //
00004 // Copyright (C) 2010-2011 Gael Guennebaud <gael.guennebaud@inria.fr>
00005 //
00006 // This Source Code Form is subject to the terms of the Mozilla
00007 // Public License v. 2.0. If a copy of the MPL was not distributed
00008 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
00009 
00010 #ifndef EIGEN_TRANSPOSITIONS_H
00011 #define EIGEN_TRANSPOSITIONS_H
00012 
00013 namespace Eigen { 
00014 
00015 template<typename Derived>
00016 class TranspositionsBase
00017 {
00018     typedef internal::traits<Derived> Traits;
00019     
00020   public:
00021 
00022     typedef typename Traits::IndicesType IndicesType;
00023     typedef typename IndicesType::Scalar StorageIndex;
00024     typedef Eigen::Index Index; 
00025 
00026     Derived& derived() { return *static_cast<Derived*>(this); }
00027     const Derived& derived() const { return *static_cast<const Derived*>(this); }
00028 
00030     template<typename OtherDerived>
00031     Derived& operator=(const TranspositionsBase<OtherDerived>& other)
00032     {
00033       indices() = other.indices();
00034       return derived();
00035     }
00036     
00037     #ifndef EIGEN_PARSED_BY_DOXYGEN
00038 
00041     Derived& operator=(const TranspositionsBase& other)
00042     {
00043       indices() = other.indices();
00044       return derived();
00045     }
00046     #endif
00047 
00049     Index size() const { return indices().size(); }
00051     Index rows() const { return indices().size(); }
00053     Index cols() const { return indices().size(); }
00054 
00056     inline const StorageIndex& coeff(Index i) const { return indices().coeff(i); }
00058     inline StorageIndex& coeffRef(Index i) { return indices().coeffRef(i); }
00060     inline const StorageIndex& operator()(Index i) const { return indices()(i); }
00062     inline StorageIndex& operator()(Index i) { return indices()(i); }
00064     inline const StorageIndex& operator[](Index i) const { return indices()(i); }
00066     inline StorageIndex& operator[](Index i) { return indices()(i); }
00067 
00069     const IndicesType& indices() const { return derived().indices(); }
00071     IndicesType& indices() { return derived().indices(); }
00072 
00074     inline void resize(Index newSize)
00075     {
00076       indices().resize(newSize);
00077     }
00078 
00080     void setIdentity()
00081     {
00082       for(StorageIndex i = 0; i < indices().size(); ++i)
00083         coeffRef(i) = i;
00084     }
00085 
00086     // FIXME: do we want such methods ?
00087     // might be usefull when the target matrix expression is complex, e.g.:
00088     // object.matrix().block(..,..,..,..) = trans * object.matrix().block(..,..,..,..);
00089     /*
00090     template<typename MatrixType>
00091     void applyForwardToRows(MatrixType& mat) const
00092     {
00093       for(Index k=0 ; k<size() ; ++k)
00094         if(m_indices(k)!=k)
00095           mat.row(k).swap(mat.row(m_indices(k)));
00096     }
00097 
00098     template<typename MatrixType>
00099     void applyBackwardToRows(MatrixType& mat) const
00100     {
00101       for(Index k=size()-1 ; k>=0 ; --k)
00102         if(m_indices(k)!=k)
00103           mat.row(k).swap(mat.row(m_indices(k)));
00104     }
00105     */
00106 
00108     inline Transpose<TranspositionsBase> inverse() const
00109     { return Transpose<TranspositionsBase>(derived()); }
00110 
00112     inline Transpose<TranspositionsBase> transpose() const
00113     { return Transpose<TranspositionsBase>(derived()); }
00114 
00115   protected:
00116 };
00117 
00118 namespace internal {
00119 template<int SizeAtCompileTime, int MaxSizeAtCompileTime, typename _StorageIndex>
00120 struct traits<Transpositions<SizeAtCompileTime,MaxSizeAtCompileTime,_StorageIndex> >
00121  : traits<PermutationMatrix<SizeAtCompileTime,MaxSizeAtCompileTime,_StorageIndex> >
00122 {
00123   typedef Matrix<_StorageIndex, SizeAtCompileTime, 1, 0, MaxSizeAtCompileTime, 1> IndicesType;
00124   typedef TranspositionsStorage StorageKind;
00125 };
00126 }
00127 
00157 template<int SizeAtCompileTime, int MaxSizeAtCompileTime, typename _StorageIndex>
00158 class Transpositions : public TranspositionsBase<Transpositions<SizeAtCompileTime,MaxSizeAtCompileTime,_StorageIndex> >
00159 {
00160     typedef internal::traits<Transpositions> Traits;
00161   public:
00162 
00163     typedef TranspositionsBase<Transpositions> Base;
00164     typedef typename Traits::IndicesType IndicesType;
00165     typedef typename IndicesType::Scalar StorageIndex;
00166 
00167     inline Transpositions() {}
00168 
00170     template<typename OtherDerived>
00171     inline Transpositions(const TranspositionsBase<OtherDerived>& other)
00172       : m_indices(other.indices()) {}
00173 
00174     #ifndef EIGEN_PARSED_BY_DOXYGEN
00175 
00177     inline Transpositions(const Transpositions& other) : m_indices(other.indices()) {}
00178     #endif
00179 
00181     template<typename Other>
00182     explicit inline Transpositions(const MatrixBase<Other>& indices) : m_indices(indices)
00183     {}
00184 
00186     template<typename OtherDerived>
00187     Transpositions& operator=(const TranspositionsBase<OtherDerived>& other)
00188     {
00189       return Base::operator=(other);
00190     }
00191 
00192     #ifndef EIGEN_PARSED_BY_DOXYGEN
00193 
00196     Transpositions& operator=(const Transpositions& other)
00197     {
00198       m_indices = other.m_indices;
00199       return *this;
00200     }
00201     #endif
00202 
00205     inline Transpositions(Index size) : m_indices(size)
00206     {}
00207 
00209     const IndicesType& indices() const { return m_indices; }
00211     IndicesType& indices() { return m_indices; }
00212 
00213   protected:
00214 
00215     IndicesType m_indices;
00216 };
00217 
00218 
00219 namespace internal {
00220 template<int SizeAtCompileTime, int MaxSizeAtCompileTime, typename _StorageIndex, int _PacketAccess>
00221 struct traits<Map<Transpositions<SizeAtCompileTime,MaxSizeAtCompileTime,_StorageIndex>,_PacketAccess> >
00222  : traits<PermutationMatrix<SizeAtCompileTime,MaxSizeAtCompileTime,_StorageIndex> >
00223 {
00224   typedef Map<const Matrix<_StorageIndex,SizeAtCompileTime,1,0,MaxSizeAtCompileTime,1>, _PacketAccess> IndicesType;
00225   typedef _StorageIndex StorageIndex;
00226   typedef TranspositionsStorage StorageKind;
00227 };
00228 }
00229 
00230 template<int SizeAtCompileTime, int MaxSizeAtCompileTime, typename _StorageIndex, int PacketAccess>
00231 class Map<Transpositions<SizeAtCompileTime,MaxSizeAtCompileTime,_StorageIndex>,PacketAccess>
00232  : public TranspositionsBase<Map<Transpositions<SizeAtCompileTime,MaxSizeAtCompileTime,_StorageIndex>,PacketAccess> >
00233 {
00234     typedef internal::traits<Map> Traits;
00235   public:
00236 
00237     typedef TranspositionsBase<Map> Base;
00238     typedef typename Traits::IndicesType IndicesType;
00239     typedef typename IndicesType::Scalar StorageIndex;
00240 
00241     explicit inline Map(const StorageIndex* indicesPtr)
00242       : m_indices(indicesPtr)
00243     {}
00244 
00245     inline Map(const StorageIndex* indicesPtr, Index size)
00246       : m_indices(indicesPtr,size)
00247     {}
00248 
00250     template<typename OtherDerived>
00251     Map& operator=(const TranspositionsBase<OtherDerived>& other)
00252     {
00253       return Base::operator=(other);
00254     }
00255 
00256     #ifndef EIGEN_PARSED_BY_DOXYGEN
00257 
00260     Map& operator=(const Map& other)
00261     {
00262       m_indices = other.m_indices;
00263       return *this;
00264     }
00265     #endif
00266 
00268     const IndicesType& indices() const { return m_indices; }
00269     
00271     IndicesType& indices() { return m_indices; }
00272 
00273   protected:
00274 
00275     IndicesType m_indices;
00276 };
00277 
00278 namespace internal {
00279 template<typename _IndicesType>
00280 struct traits<TranspositionsWrapper<_IndicesType> >
00281  : traits<PermutationWrapper<_IndicesType> >
00282 {
00283   typedef TranspositionsStorage StorageKind;
00284 };
00285 }
00286 
00287 template<typename _IndicesType>
00288 class TranspositionsWrapper
00289  : public TranspositionsBase<TranspositionsWrapper<_IndicesType> >
00290 {
00291     typedef internal::traits<TranspositionsWrapper> Traits;
00292   public:
00293 
00294     typedef TranspositionsBase<TranspositionsWrapper> Base;
00295     typedef typename Traits::IndicesType IndicesType;
00296     typedef typename IndicesType::Scalar StorageIndex;
00297 
00298     explicit inline TranspositionsWrapper(IndicesType& indices)
00299       : m_indices(indices)
00300     {}
00301 
00303     template<typename OtherDerived>
00304     TranspositionsWrapper& operator=(const TranspositionsBase<OtherDerived>& other)
00305     {
00306       return Base::operator=(other);
00307     }
00308 
00309     #ifndef EIGEN_PARSED_BY_DOXYGEN
00310 
00313     TranspositionsWrapper& operator=(const TranspositionsWrapper& other)
00314     {
00315       m_indices = other.m_indices;
00316       return *this;
00317     }
00318     #endif
00319 
00321     const IndicesType& indices() const { return m_indices; }
00322 
00324     IndicesType& indices() { return m_indices; }
00325 
00326   protected:
00327 
00328     typename IndicesType::Nested m_indices;
00329 };
00330 
00331 
00332 
00335 template<typename MatrixDerived, typename TranspositionsDerived>
00336 EIGEN_DEVICE_FUNC
00337 const Product<MatrixDerived, TranspositionsDerived, AliasFreeProduct>
00338 operator*(const MatrixBase<MatrixDerived> &matrix,
00339           const TranspositionsBase<TranspositionsDerived>& transpositions)
00340 {
00341   return Product<MatrixDerived, TranspositionsDerived, AliasFreeProduct>
00342             (matrix.derived(), transpositions.derived());
00343 }
00344 
00347 template<typename TranspositionsDerived, typename MatrixDerived>
00348 EIGEN_DEVICE_FUNC
00349 const Product<TranspositionsDerived, MatrixDerived, AliasFreeProduct>
00350 operator*(const TranspositionsBase<TranspositionsDerived> &transpositions,
00351           const MatrixBase<MatrixDerived>& matrix)
00352 {
00353   return Product<TranspositionsDerived, MatrixDerived, AliasFreeProduct>
00354             (transpositions.derived(), matrix.derived());
00355 }
00356 
00357 // Template partial specialization for transposed/inverse transpositions
00358 
00359 namespace internal {
00360 
00361 template<typename Derived>
00362 struct traits<Transpose<TranspositionsBase<Derived> > >
00363  : traits<Derived>
00364 {};
00365 
00366 } // end namespace internal
00367 
00368 template<typename TranspositionsDerived>
00369 class Transpose<TranspositionsBase<TranspositionsDerived> >
00370 {
00371     typedef TranspositionsDerived TranspositionType;
00372     typedef typename TranspositionType::IndicesType IndicesType;
00373   public:
00374 
00375     explicit Transpose(const TranspositionType& t) : m_transpositions(t) {}
00376 
00377     Index size() const { return m_transpositions.size(); }
00378     Index rows() const { return m_transpositions.size(); }
00379     Index cols() const { return m_transpositions.size(); }
00380 
00383     template<typename OtherDerived> friend
00384     const Product<OtherDerived, Transpose, AliasFreeProduct>
00385     operator*(const MatrixBase<OtherDerived>& matrix, const Transpose& trt)
00386     {
00387       return Product<OtherDerived, Transpose, AliasFreeProduct>(matrix.derived(), trt.derived());
00388     }
00389 
00392     template<typename OtherDerived>
00393     const Product<Transpose, OtherDerived, AliasFreeProduct>
00394     operator*(const MatrixBase<OtherDerived>& matrix) const
00395     {
00396       return Product<Transpose, OtherDerived, AliasFreeProduct>(*this, matrix.derived());
00397     }
00398     
00399     const TranspositionType& nestedExpression() const { return m_transpositions; }
00400 
00401   protected:
00402     const TranspositionType& m_transpositions;
00403 };
00404 
00405 } // end namespace Eigen
00406 
00407 #endif // EIGEN_TRANSPOSITIONS_H
 All Classes Functions Variables Typedefs Enumerations Enumerator Friends