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
00028 namespace Eigen {
00029
00059 namespace internal {
00060 template<typename TranspositionType, typename MatrixType, int Side, bool Transposed=false> struct transposition_matrix_product_retval;
00061 }
00062
00063 template<typename Derived>
00064 class TranspositionsBase
00065 {
00066 typedef internal::traits<Derived> Traits;
00067
00068 public:
00069
00070 typedef typename Traits::IndicesType IndicesType;
00071 typedef typename IndicesType::Scalar Index;
00072
00073 Derived& derived() { return *static_cast<Derived*>(this); }
00074 const Derived& derived() const { return *static_cast<const Derived*>(this); }
00075
00077 template<typename OtherDerived>
00078 Derived& operator=(const TranspositionsBase<OtherDerived>& other)
00079 {
00080 indices() = other.indices();
00081 return derived();
00082 }
00083
00084 #ifndef EIGEN_PARSED_BY_DOXYGEN
00085
00088 Derived& operator=(const TranspositionsBase& other)
00089 {
00090 indices() = other.indices();
00091 return derived();
00092 }
00093 #endif
00094
00096 inline Index size() const { return indices().size(); }
00097
00099 inline const Index& coeff(Index i) const { return indices().coeff(i); }
00101 inline Index& coeffRef(Index i) { return indices().coeffRef(i); }
00103 inline const Index& operator()(Index i) const { return indices()(i); }
00105 inline Index& operator()(Index i) { return indices()(i); }
00107 inline const Index& operator[](Index i) const { return indices()(i); }
00109 inline Index& operator[](Index i) { return indices()(i); }
00110
00112 const IndicesType& indices() const { return derived().indices(); }
00114 IndicesType& indices() { return derived().indices(); }
00115
00117 inline void resize(int size)
00118 {
00119 indices().resize(size);
00120 }
00121
00123 void setIdentity()
00124 {
00125 for(int i = 0; i < indices().size(); ++i)
00126 coeffRef(i) = i;
00127 }
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00151 inline Transpose<TranspositionsBase> inverse() const
00152 { return Transpose<TranspositionsBase>(derived()); }
00153
00155 inline Transpose<TranspositionsBase> transpose() const
00156 { return Transpose<TranspositionsBase>(derived()); }
00157
00158 protected:
00159 };
00160
00161 namespace internal {
00162 template<int SizeAtCompileTime, int MaxSizeAtCompileTime, typename IndexType>
00163 struct traits<Transpositions<SizeAtCompileTime,MaxSizeAtCompileTime,IndexType> >
00164 {
00165 typedef IndexType Index;
00166 typedef Matrix<Index, SizeAtCompileTime, 1, 0, MaxSizeAtCompileTime, 1> IndicesType;
00167 };
00168 }
00169
00170 template<int SizeAtCompileTime, int MaxSizeAtCompileTime, typename IndexType>
00171 class Transpositions : public TranspositionsBase<Transpositions<SizeAtCompileTime,MaxSizeAtCompileTime,IndexType> >
00172 {
00173 typedef internal::traits<Transpositions> Traits;
00174 public:
00175
00176 typedef TranspositionsBase<Transpositions> Base;
00177 typedef typename Traits::IndicesType IndicesType;
00178 typedef typename IndicesType::Scalar Index;
00179
00180 inline Transpositions() {}
00181
00183 template<typename OtherDerived>
00184 inline Transpositions(const TranspositionsBase<OtherDerived>& other)
00185 : m_indices(other.indices()) {}
00186
00187 #ifndef EIGEN_PARSED_BY_DOXYGEN
00188
00190 inline Transpositions(const Transpositions& other) : m_indices(other.indices()) {}
00191 #endif
00192
00194 template<typename Other>
00195 explicit inline Transpositions(const MatrixBase<Other>& indices) : m_indices(indices)
00196 {}
00197
00199 template<typename OtherDerived>
00200 Transpositions& operator=(const TranspositionsBase<OtherDerived>& other)
00201 {
00202 return Base::operator=(other);
00203 }
00204
00205 #ifndef EIGEN_PARSED_BY_DOXYGEN
00206
00209 Transpositions& operator=(const Transpositions& other)
00210 {
00211 m_indices = other.m_indices;
00212 return *this;
00213 }
00214 #endif
00215
00218 inline Transpositions(Index size) : m_indices(size)
00219 {}
00220
00222 const IndicesType& indices() const { return m_indices; }
00224 IndicesType& indices() { return m_indices; }
00225
00226 protected:
00227
00228 IndicesType m_indices;
00229 };
00230
00231
00232 namespace internal {
00233 template<int SizeAtCompileTime, int MaxSizeAtCompileTime, typename IndexType, int _PacketAccess>
00234 struct traits<Map<Transpositions<SizeAtCompileTime,MaxSizeAtCompileTime,IndexType>,_PacketAccess> >
00235 {
00236 typedef IndexType Index;
00237 typedef Map<const Matrix<Index,SizeAtCompileTime,1,0,MaxSizeAtCompileTime,1>, _PacketAccess> IndicesType;
00238 };
00239 }
00240
00241 template<int SizeAtCompileTime, int MaxSizeAtCompileTime, typename IndexType, int PacketAccess>
00242 class Map<Transpositions<SizeAtCompileTime,MaxSizeAtCompileTime,IndexType>,PacketAccess>
00243 : public TranspositionsBase<Map<Transpositions<SizeAtCompileTime,MaxSizeAtCompileTime,IndexType>,PacketAccess> >
00244 {
00245 typedef internal::traits<Map> Traits;
00246 public:
00247
00248 typedef TranspositionsBase<Map> Base;
00249 typedef typename Traits::IndicesType IndicesType;
00250 typedef typename IndicesType::Scalar Index;
00251
00252 inline Map(const Index* indices)
00253 : m_indices(indices)
00254 {}
00255
00256 inline Map(const Index* indices, Index size)
00257 : m_indices(indices,size)
00258 {}
00259
00261 template<typename OtherDerived>
00262 Map& operator=(const TranspositionsBase<OtherDerived>& other)
00263 {
00264 return Base::operator=(other);
00265 }
00266
00267 #ifndef EIGEN_PARSED_BY_DOXYGEN
00268
00271 Map& operator=(const Map& other)
00272 {
00273 m_indices = other.m_indices;
00274 return *this;
00275 }
00276 #endif
00277
00279 const IndicesType& indices() const { return m_indices; }
00280
00282 IndicesType& indices() { return m_indices; }
00283
00284 protected:
00285
00286 IndicesType m_indices;
00287 };
00288
00289 namespace internal {
00290 template<typename _IndicesType>
00291 struct traits<TranspositionsWrapper<_IndicesType> >
00292 {
00293 typedef typename _IndicesType::Scalar Index;
00294 typedef _IndicesType IndicesType;
00295 };
00296 }
00297
00298 template<typename _IndicesType>
00299 class TranspositionsWrapper
00300 : public TranspositionsBase<TranspositionsWrapper<_IndicesType> >
00301 {
00302 typedef internal::traits<TranspositionsWrapper> Traits;
00303 public:
00304
00305 typedef TranspositionsBase<TranspositionsWrapper> Base;
00306 typedef typename Traits::IndicesType IndicesType;
00307 typedef typename IndicesType::Scalar Index;
00308
00309 inline TranspositionsWrapper(IndicesType& indices)
00310 : m_indices(indices)
00311 {}
00312
00314 template<typename OtherDerived>
00315 TranspositionsWrapper& operator=(const TranspositionsBase<OtherDerived>& other)
00316 {
00317 return Base::operator=(other);
00318 }
00319
00320 #ifndef EIGEN_PARSED_BY_DOXYGEN
00321
00324 TranspositionsWrapper& operator=(const TranspositionsWrapper& other)
00325 {
00326 m_indices = other.m_indices;
00327 return *this;
00328 }
00329 #endif
00330
00332 const IndicesType& indices() const { return m_indices; }
00333
00335 IndicesType& indices() { return m_indices; }
00336
00337 protected:
00338
00339 const typename IndicesType::Nested m_indices;
00340 };
00341
00344 template<typename Derived, typename TranspositionsDerived>
00345 inline const internal::transposition_matrix_product_retval<TranspositionsDerived, Derived, OnTheRight>
00346 operator*(const MatrixBase<Derived>& matrix,
00347 const TranspositionsBase<TranspositionsDerived> &transpositions)
00348 {
00349 return internal::transposition_matrix_product_retval
00350 <TranspositionsDerived, Derived, OnTheRight>
00351 (transpositions.derived(), matrix.derived());
00352 }
00353
00356 template<typename Derived, typename TranspositionDerived>
00357 inline const internal::transposition_matrix_product_retval
00358 <TranspositionDerived, Derived, OnTheLeft>
00359 operator*(const TranspositionsBase<TranspositionDerived> &transpositions,
00360 const MatrixBase<Derived>& matrix)
00361 {
00362 return internal::transposition_matrix_product_retval
00363 <TranspositionDerived, Derived, OnTheLeft>
00364 (transpositions.derived(), matrix.derived());
00365 }
00366
00367 namespace internal {
00368
00369 template<typename TranspositionType, typename MatrixType, int Side, bool Transposed>
00370 struct traits<transposition_matrix_product_retval<TranspositionType, MatrixType, Side, Transposed> >
00371 {
00372 typedef typename MatrixType::PlainObject ReturnType;
00373 };
00374
00375 template<typename TranspositionType, typename MatrixType, int Side, bool Transposed>
00376 struct transposition_matrix_product_retval
00377 : public ReturnByValue<transposition_matrix_product_retval<TranspositionType, MatrixType, Side, Transposed> >
00378 {
00379 typedef typename remove_all<typename MatrixType::Nested>::type MatrixTypeNestedCleaned;
00380 typedef typename TranspositionType::Index Index;
00381
00382 transposition_matrix_product_retval(const TranspositionType& tr, const MatrixType& matrix)
00383 : m_transpositions(tr), m_matrix(matrix)
00384 {}
00385
00386 inline int rows() const { return m_matrix.rows(); }
00387 inline int cols() const { return m_matrix.cols(); }
00388
00389 template<typename Dest> inline void evalTo(Dest& dst) const
00390 {
00391 const int size = m_transpositions.size();
00392 Index j = 0;
00393
00394 if(!(is_same<MatrixTypeNestedCleaned,Dest>::value && extract_data(dst) == extract_data(m_matrix)))
00395 dst = m_matrix;
00396
00397 for(int k=(Transposed?size-1:0) ; Transposed?k>=0:k<size ; Transposed?--k:++k)
00398 if((j=m_transpositions.coeff(k))!=k)
00399 {
00400 if(Side==OnTheLeft)
00401 dst.row(k).swap(dst.row(j));
00402 else if(Side==OnTheRight)
00403 dst.col(k).swap(dst.col(j));
00404 }
00405 }
00406
00407 protected:
00408 const TranspositionType& m_transpositions;
00409 typename MatrixType::Nested m_matrix;
00410 };
00411
00412 }
00413
00414
00415
00416 template<typename TranspositionsDerived>
00417 class Transpose<TranspositionsBase<TranspositionsDerived> >
00418 {
00419 typedef TranspositionsDerived TranspositionType;
00420 typedef typename TranspositionType::IndicesType IndicesType;
00421 public:
00422
00423 Transpose(const TranspositionType& t) : m_transpositions(t) {}
00424
00425 inline int size() const { return m_transpositions.size(); }
00426
00429 template<typename Derived> friend
00430 inline const internal::transposition_matrix_product_retval<TranspositionType, Derived, OnTheRight, true>
00431 operator*(const MatrixBase<Derived>& matrix, const Transpose& trt)
00432 {
00433 return internal::transposition_matrix_product_retval<TranspositionType, Derived, OnTheRight, true>(trt.m_transpositions, matrix.derived());
00434 }
00435
00438 template<typename Derived>
00439 inline const internal::transposition_matrix_product_retval<TranspositionType, Derived, OnTheLeft, true>
00440 operator*(const MatrixBase<Derived>& matrix) const
00441 {
00442 return internal::transposition_matrix_product_retval<TranspositionType, Derived, OnTheLeft, true>(m_transpositions, matrix.derived());
00443 }
00444
00445 protected:
00446 const TranspositionType& m_transpositions;
00447 };
00448
00449 }
00450
00451 #endif // EIGEN_TRANSPOSITIONS_H