00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #ifndef EIGEN_TRANSPOSITIONS_H
00026 #define EIGEN_TRANSPOSITIONS_H
00027
00057 namespace internal {
00058 template<typename TranspositionType, typename MatrixType, int Side, bool Transposed=false> struct transposition_matrix_product_retval;
00059 }
00060
00061 template<typename Derived>
00062 class TranspositionsBase
00063 {
00064 typedef internal::traits<Derived> Traits;
00065
00066 public:
00067
00068 typedef typename Traits::IndicesType IndicesType;
00069 typedef typename IndicesType::Scalar Index;
00070
00071 Derived& derived() { return *static_cast<Derived*>(this); }
00072 const Derived& derived() const { return *static_cast<const Derived*>(this); }
00073
00075 template<typename OtherDerived>
00076 Derived& operator=(const TranspositionsBase<OtherDerived>& other)
00077 {
00078 indices() = other.indices();
00079 return derived();
00080 }
00081
00082 #ifndef EIGEN_PARSED_BY_DOXYGEN
00083
00086 Derived& operator=(const TranspositionsBase& other)
00087 {
00088 indices() = other.indices();
00089 return derived();
00090 }
00091 #endif
00092
00094 inline Index size() const { return indices().size(); }
00095
00097 inline const Index& coeff(Index i) const { return indices().coeff(i); }
00099 inline Index& coeffRef(Index i) { return indices().coeffRef(i); }
00101 inline const Index& operator()(Index i) const { return indices()(i); }
00103 inline Index& operator()(Index i) { return indices()(i); }
00105 inline const Index& operator[](Index i) const { return indices()(i); }
00107 inline Index& operator[](Index i) { return indices()(i); }
00108
00110 const IndicesType& indices() const { return derived().indices(); }
00112 IndicesType& indices() { return derived().indices(); }
00113
00115 inline void resize(int size)
00116 {
00117 indices().resize(size);
00118 }
00119
00121 void setIdentity()
00122 {
00123 for(int i = 0; i < indices().size(); ++i)
00124 coeffRef(i) = i;
00125 }
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00149 inline Transpose<TranspositionsBase> inverse() const
00150 { return Transpose<TranspositionsBase>(derived()); }
00151
00153 inline Transpose<TranspositionsBase> transpose() const
00154 { return Transpose<TranspositionsBase>(derived()); }
00155
00156 protected:
00157 };
00158
00159 namespace internal {
00160 template<int SizeAtCompileTime, int MaxSizeAtCompileTime, typename IndexType>
00161 struct traits<Transpositions<SizeAtCompileTime,MaxSizeAtCompileTime,IndexType> >
00162 {
00163 typedef IndexType Index;
00164 typedef Matrix<Index, SizeAtCompileTime, 1, 0, MaxSizeAtCompileTime, 1> IndicesType;
00165 };
00166 }
00167
00168 template<int SizeAtCompileTime, int MaxSizeAtCompileTime, typename IndexType>
00169 class Transpositions : public TranspositionsBase<Transpositions<SizeAtCompileTime,MaxSizeAtCompileTime,IndexType> >
00170 {
00171 typedef internal::traits<Transpositions> Traits;
00172 public:
00173
00174 typedef TranspositionsBase<Transpositions> Base;
00175 typedef typename Traits::IndicesType IndicesType;
00176 typedef typename IndicesType::Scalar Index;
00177
00178 inline Transpositions() {}
00179
00181 template<typename OtherDerived>
00182 inline Transpositions(const TranspositionsBase<OtherDerived>& other)
00183 : m_indices(other.indices()) {}
00184
00185 #ifndef EIGEN_PARSED_BY_DOXYGEN
00186
00188 inline Transpositions(const Transpositions& other) : m_indices(other.indices()) {}
00189 #endif
00190
00192 template<typename Other>
00193 explicit inline Transpositions(const MatrixBase<Other>& indices) : m_indices(indices)
00194 {}
00195
00197 template<typename OtherDerived>
00198 Transpositions& operator=(const TranspositionsBase<OtherDerived>& other)
00199 {
00200 return Base::operator=(other);
00201 }
00202
00203 #ifndef EIGEN_PARSED_BY_DOXYGEN
00204
00207 Transpositions& operator=(const Transpositions& other)
00208 {
00209 m_indices = other.m_indices;
00210 return *this;
00211 }
00212 #endif
00213
00216 inline Transpositions(Index size) : m_indices(size)
00217 {}
00218
00220 const IndicesType& indices() const { return m_indices; }
00222 IndicesType& indices() { return m_indices; }
00223
00224 protected:
00225
00226 IndicesType m_indices;
00227 };
00228
00229
00230 namespace internal {
00231 template<int SizeAtCompileTime, int MaxSizeAtCompileTime, typename IndexType, int _PacketAccess>
00232 struct traits<Map<Transpositions<SizeAtCompileTime,MaxSizeAtCompileTime,IndexType>,_PacketAccess> >
00233 {
00234 typedef IndexType Index;
00235 typedef Map<const Matrix<Index,SizeAtCompileTime,1,0,MaxSizeAtCompileTime,1>, _PacketAccess> IndicesType;
00236 };
00237 }
00238
00239 template<int SizeAtCompileTime, int MaxSizeAtCompileTime, typename IndexType, int PacketAccess>
00240 class Map<Transpositions<SizeAtCompileTime,MaxSizeAtCompileTime,IndexType>,PacketAccess>
00241 : public TranspositionsBase<Map<Transpositions<SizeAtCompileTime,MaxSizeAtCompileTime,IndexType>,PacketAccess> >
00242 {
00243 typedef internal::traits<Map> Traits;
00244 public:
00245
00246 typedef TranspositionsBase<Map> Base;
00247 typedef typename Traits::IndicesType IndicesType;
00248 typedef typename IndicesType::Scalar Index;
00249
00250 inline Map(const Index* indices)
00251 : m_indices(indices)
00252 {}
00253
00254 inline Map(const Index* indices, Index size)
00255 : m_indices(indices,size)
00256 {}
00257
00259 template<typename OtherDerived>
00260 Map& operator=(const TranspositionsBase<OtherDerived>& other)
00261 {
00262 return Base::operator=(other);
00263 }
00264
00265 #ifndef EIGEN_PARSED_BY_DOXYGEN
00266
00269 Map& operator=(const Map& other)
00270 {
00271 m_indices = other.m_indices;
00272 return *this;
00273 }
00274 #endif
00275
00277 const IndicesType& indices() const { return m_indices; }
00278
00280 IndicesType& indices() { return m_indices; }
00281
00282 protected:
00283
00284 IndicesType m_indices;
00285 };
00286
00287 namespace internal {
00288 template<typename _IndicesType>
00289 struct traits<TranspositionsWrapper<_IndicesType> >
00290 {
00291 typedef typename _IndicesType::Scalar Index;
00292 typedef _IndicesType IndicesType;
00293 };
00294 }
00295
00296 template<typename _IndicesType>
00297 class TranspositionsWrapper
00298 : public TranspositionsBase<TranspositionsWrapper<_IndicesType> >
00299 {
00300 typedef internal::traits<TranspositionsWrapper> Traits;
00301 public:
00302
00303 typedef TranspositionsBase<TranspositionsWrapper> Base;
00304 typedef typename Traits::IndicesType IndicesType;
00305 typedef typename IndicesType::Scalar Index;
00306
00307 inline TranspositionsWrapper(IndicesType& indices)
00308 : m_indices(indices)
00309 {}
00310
00312 template<typename OtherDerived>
00313 TranspositionsWrapper& operator=(const TranspositionsBase<OtherDerived>& other)
00314 {
00315 return Base::operator=(other);
00316 }
00317
00318 #ifndef EIGEN_PARSED_BY_DOXYGEN
00319
00322 TranspositionsWrapper& operator=(const TranspositionsWrapper& other)
00323 {
00324 m_indices = other.m_indices;
00325 return *this;
00326 }
00327 #endif
00328
00330 const IndicesType& indices() const { return m_indices; }
00331
00333 IndicesType& indices() { return m_indices; }
00334
00335 protected:
00336
00337 const typename IndicesType::Nested m_indices;
00338 };
00339
00342 template<typename Derived, typename TranspositionsDerived>
00343 inline const internal::transposition_matrix_product_retval<TranspositionsDerived, Derived, OnTheRight>
00344 operator*(const MatrixBase<Derived>& matrix,
00345 const TranspositionsBase<TranspositionsDerived> &transpositions)
00346 {
00347 return internal::transposition_matrix_product_retval
00348 <TranspositionsDerived, Derived, OnTheRight>
00349 (transpositions.derived(), matrix.derived());
00350 }
00351
00354 template<typename Derived, typename TranspositionDerived>
00355 inline const internal::transposition_matrix_product_retval
00356 <TranspositionDerived, Derived, OnTheLeft>
00357 operator*(const TranspositionsBase<TranspositionDerived> &transpositions,
00358 const MatrixBase<Derived>& matrix)
00359 {
00360 return internal::transposition_matrix_product_retval
00361 <TranspositionDerived, Derived, OnTheLeft>
00362 (transpositions.derived(), matrix.derived());
00363 }
00364
00365 namespace internal {
00366
00367 template<typename TranspositionType, typename MatrixType, int Side, bool Transposed>
00368 struct traits<transposition_matrix_product_retval<TranspositionType, MatrixType, Side, Transposed> >
00369 {
00370 typedef typename MatrixType::PlainObject ReturnType;
00371 };
00372
00373 template<typename TranspositionType, typename MatrixType, int Side, bool Transposed>
00374 struct transposition_matrix_product_retval
00375 : public ReturnByValue<transposition_matrix_product_retval<TranspositionType, MatrixType, Side, Transposed> >
00376 {
00377 typedef typename remove_all<typename MatrixType::Nested>::type MatrixTypeNestedCleaned;
00378 typedef typename TranspositionType::Index Index;
00379
00380 transposition_matrix_product_retval(const TranspositionType& tr, const MatrixType& matrix)
00381 : m_transpositions(tr), m_matrix(matrix)
00382 {}
00383
00384 inline int rows() const { return m_matrix.rows(); }
00385 inline int cols() const { return m_matrix.cols(); }
00386
00387 template<typename Dest> inline void evalTo(Dest& dst) const
00388 {
00389 const int size = m_transpositions.size();
00390 Index j = 0;
00391
00392 if(!(is_same<MatrixTypeNestedCleaned,Dest>::value && extract_data(dst) == extract_data(m_matrix)))
00393 dst = m_matrix;
00394
00395 for(int k=(Transposed?size-1:0) ; Transposed?k>=0:k<size ; Transposed?--k:++k)
00396 if((j=m_transpositions.coeff(k))!=k)
00397 {
00398 if(Side==OnTheLeft)
00399 dst.row(k).swap(dst.row(j));
00400 else if(Side==OnTheRight)
00401 dst.col(k).swap(dst.col(j));
00402 }
00403 }
00404
00405 protected:
00406 const TranspositionType& m_transpositions;
00407 const typename MatrixType::Nested m_matrix;
00408 };
00409
00410 }
00411
00412
00413
00414 template<typename TranspositionsDerived>
00415 class Transpose<TranspositionsBase<TranspositionsDerived> >
00416 {
00417 typedef TranspositionsDerived TranspositionType;
00418 typedef typename TranspositionType::IndicesType IndicesType;
00419 public:
00420
00421 Transpose(const TranspositionType& t) : m_transpositions(t) {}
00422
00423 inline int size() const { return m_transpositions.size(); }
00424
00427 template<typename Derived> friend
00428 inline const internal::transposition_matrix_product_retval<TranspositionType, Derived, OnTheRight, true>
00429 operator*(const MatrixBase<Derived>& matrix, const Transpose& trt)
00430 {
00431 return internal::transposition_matrix_product_retval<TranspositionType, Derived, OnTheRight, true>(trt.m_transpositions, matrix.derived());
00432 }
00433
00436 template<typename Derived>
00437 inline const internal::transposition_matrix_product_retval<TranspositionType, Derived, OnTheLeft, true>
00438 operator*(const MatrixBase<Derived>& matrix) const
00439 {
00440 return internal::transposition_matrix_product_retval<TranspositionType, Derived, OnTheLeft, true>(m_transpositions, matrix.derived());
00441 }
00442
00443 protected:
00444 const TranspositionType& m_transpositions;
00445 };
00446
00447 #endif // EIGEN_TRANSPOSITIONS_H