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
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057 namespace internal {
00058 template<typename TranspositionType, typename MatrixType, int Side, bool Transposed=false> struct transposition_matrix_product_retval;
00059 }
00060
00061 template<int SizeAtCompileTime, int MaxSizeAtCompileTime>
00062 class Transpositions
00063 {
00064 public:
00065
00066 typedef Matrix<DenseIndex, SizeAtCompileTime, 1, 0, MaxSizeAtCompileTime, 1> IndicesType;
00067 typedef typename IndicesType::Index Index;
00068
00069 inline Transpositions() {}
00070
00071
00072 template<int OtherSize, int OtherMaxSize>
00073 inline Transpositions(const Transpositions<OtherSize, OtherMaxSize>& other)
00074 : m_indices(other.indices()) {}
00075
00076 #ifndef EIGEN_PARSED_BY_DOXYGEN
00077
00078
00079 inline Transpositions(const Transpositions& other) : m_indices(other.indices()) {}
00080 #endif
00081
00082
00083 template<typename Other>
00084 explicit inline Transpositions(const MatrixBase<Other>& indices) : m_indices(indices)
00085 {}
00086
00087
00088 template<int OtherSize, int OtherMaxSize>
00089 Transpositions& operator=(const Transpositions<OtherSize, OtherMaxSize>& other)
00090 {
00091 m_indices = other.indices();
00092 return *this;
00093 }
00094
00095 #ifndef EIGEN_PARSED_BY_DOXYGEN
00096
00097
00098
00099 Transpositions& operator=(const Transpositions& other)
00100 {
00101 m_indices = other.m_indices;
00102 return *this;
00103 }
00104 #endif
00105
00106
00107
00108 inline Transpositions(Index size) : m_indices(size)
00109 {}
00110
00111
00112 inline Index size() const { return m_indices.size(); }
00113
00114
00115 inline const Index& coeff(Index i) const { return m_indices.coeff(i); }
00116
00117 inline Index& coeffRef(Index i) { return m_indices.coeffRef(i); }
00118
00119 inline const Index& operator()(Index i) const { return m_indices(i); }
00120
00121 inline Index& operator()(Index i) { return m_indices(i); }
00122
00123 inline const Index& operator[](Index i) const { return m_indices(i); }
00124
00125 inline Index& operator[](Index i) { return m_indices(i); }
00126
00127
00128 const IndicesType& indices() const { return m_indices; }
00129
00130 IndicesType& indices() { return m_indices; }
00131
00132
00133 inline void resize(int size)
00134 {
00135 m_indices.resize(size);
00136 }
00137
00138
00139 void setIdentity()
00140 {
00141 for(int i = 0; i < m_indices.size(); ++i)
00142 m_indices.coeffRef(i) = i;
00143 }
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167 inline Transpose<Transpositions> inverse() const
00168 { return *this; }
00169
00170
00171 inline Transpose<Transpositions> transpose() const
00172 { return *this; }
00173
00174 #ifndef EIGEN_PARSED_BY_DOXYGEN
00175 template<int OtherSize, int OtherMaxSize>
00176 Transpositions(const Transpose<Transpositions<OtherSize,OtherMaxSize> >& other)
00177 : m_indices(other.size())
00178 {
00179 Index n = size();
00180 Index j = size-1;
00181 for(Index i=0; i<n;++i,--j)
00182 m_indices.coeffRef(j) = other.nestedTranspositions().indices().coeff(i);
00183 }
00184 #endif
00185
00186 protected:
00187
00188 IndicesType m_indices;
00189 };
00190
00191
00192
00193 template<typename Derived, int SizeAtCompileTime, int MaxSizeAtCompileTime>
00194 inline const internal::transposition_matrix_product_retval<Transpositions<SizeAtCompileTime, MaxSizeAtCompileTime>, Derived, OnTheRight>
00195 operator*(const MatrixBase<Derived>& matrix,
00196 const Transpositions<SizeAtCompileTime, MaxSizeAtCompileTime> &transpositions)
00197 {
00198 return internal::transposition_matrix_product_retval
00199 <Transpositions<SizeAtCompileTime, MaxSizeAtCompileTime>, Derived, OnTheRight>
00200 (transpositions, matrix.derived());
00201 }
00202
00203
00204
00205 template<typename Derived, int SizeAtCompileTime, int MaxSizeAtCompileTime>
00206 inline const internal::transposition_matrix_product_retval
00207 <Transpositions<SizeAtCompileTime, MaxSizeAtCompileTime>, Derived, OnTheLeft>
00208 operator*(const Transpositions<SizeAtCompileTime, MaxSizeAtCompileTime> &transpositions,
00209 const MatrixBase<Derived>& matrix)
00210 {
00211 return internal::transposition_matrix_product_retval
00212 <Transpositions<SizeAtCompileTime, MaxSizeAtCompileTime>, Derived, OnTheLeft>
00213 (transpositions, matrix.derived());
00214 }
00215
00216 namespace internal {
00217
00218 template<typename TranspositionType, typename MatrixType, int Side, bool Transposed>
00219 struct traits<transposition_matrix_product_retval<TranspositionType, MatrixType, Side, Transposed> >
00220 {
00221 typedef typename MatrixType::PlainObject ReturnType;
00222 };
00223
00224 template<typename TranspositionType, typename MatrixType, int Side, bool Transposed>
00225 struct transposition_matrix_product_retval
00226 : public ReturnByValue<transposition_matrix_product_retval<TranspositionType, MatrixType, Side, Transposed> >
00227 {
00228 typedef typename remove_all<typename MatrixType::Nested>::type MatrixTypeNestedCleaned;
00229 typedef typename TranspositionType::Index Index;
00230
00231 transposition_matrix_product_retval(const TranspositionType& tr, const MatrixType& matrix)
00232 : m_transpositions(tr), m_matrix(matrix)
00233 {}
00234
00235 inline int rows() const { return m_matrix.rows(); }
00236 inline int cols() const { return m_matrix.cols(); }
00237
00238 template<typename Dest> inline void evalTo(Dest& dst) const
00239 {
00240 const int size = m_transpositions.size();
00241 Index j = 0;
00242
00243 if(!(is_same<MatrixTypeNestedCleaned,Dest>::value && extract_data(dst) == extract_data(m_matrix)))
00244 dst = m_matrix;
00245
00246 for(int k=(Transposed?size-1:0) ; Transposed?k>=0:k<size ; Transposed?--k:++k)
00247 if((j=m_transpositions.coeff(k))!=k)
00248 {
00249 if(Side==OnTheLeft)
00250 dst.row(k).swap(dst.row(j));
00251 else if(Side==OnTheRight)
00252 dst.col(k).swap(dst.col(j));
00253 }
00254 }
00255
00256 protected:
00257 const TranspositionType& m_transpositions;
00258 const typename MatrixType::Nested m_matrix;
00259 };
00260
00261 }
00262
00263
00264
00265 template<int SizeAtCompileTime, int MaxSizeAtCompileTime>
00266 class Transpose<Transpositions<SizeAtCompileTime, MaxSizeAtCompileTime> >
00267 {
00268 typedef Transpositions<SizeAtCompileTime, MaxSizeAtCompileTime> TranspositionType;
00269 typedef typename TranspositionType::IndicesType IndicesType;
00270 public:
00271
00272 Transpose(const TranspositionType& t) : m_transpositions(t) {}
00273
00274 inline int size() const { return m_transpositions.size(); }
00275
00276
00277
00278 template<typename Derived> friend
00279 inline const internal::transposition_matrix_product_retval<TranspositionType, Derived, OnTheRight, true>
00280 operator*(const MatrixBase<Derived>& matrix, const Transpose& trt)
00281 {
00282 return internal::transposition_matrix_product_retval<TranspositionType, Derived, OnTheRight, true>(trt.m_transpositions, matrix.derived());
00283 }
00284
00285
00286
00287 template<typename Derived>
00288 inline const internal::transposition_matrix_product_retval<TranspositionType, Derived, OnTheLeft, true>
00289 operator*(const MatrixBase<Derived>& matrix) const
00290 {
00291 return internal::transposition_matrix_product_retval<TranspositionType, Derived, OnTheLeft, true>(m_transpositions, matrix.derived());
00292 }
00293
00294 const TranspositionType& nestedTranspositions() const { return m_transpositions; }
00295
00296 protected:
00297 const TranspositionType& m_transpositions;
00298 };
00299
00300 #endif // EIGEN_TRANSPOSITIONS_H