Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: MPC_current_control HydraulicControlBoard_SW AHRS Test_ekf ... more
src/Core/Transpositions.h@0:13a5d365ba16, 2016-10-13 (annotated)
- Committer:
- ykuroda
- Date:
- Thu Oct 13 04:07:23 2016 +0000
- Revision:
- 0:13a5d365ba16
First commint, Eigne Matrix Class Library
Who changed what in which revision?
| User | Revision | Line number | New contents of line |
|---|---|---|---|
| ykuroda | 0:13a5d365ba16 | 1 | // This file is part of Eigen, a lightweight C++ template library |
| ykuroda | 0:13a5d365ba16 | 2 | // for linear algebra. |
| ykuroda | 0:13a5d365ba16 | 3 | // |
| ykuroda | 0:13a5d365ba16 | 4 | // Copyright (C) 2010-2011 Gael Guennebaud <gael.guennebaud@inria.fr> |
| ykuroda | 0:13a5d365ba16 | 5 | // |
| ykuroda | 0:13a5d365ba16 | 6 | // This Source Code Form is subject to the terms of the Mozilla |
| ykuroda | 0:13a5d365ba16 | 7 | // Public License v. 2.0. If a copy of the MPL was not distributed |
| ykuroda | 0:13a5d365ba16 | 8 | // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. |
| ykuroda | 0:13a5d365ba16 | 9 | |
| ykuroda | 0:13a5d365ba16 | 10 | #ifndef EIGEN_TRANSPOSITIONS_H |
| ykuroda | 0:13a5d365ba16 | 11 | #define EIGEN_TRANSPOSITIONS_H |
| ykuroda | 0:13a5d365ba16 | 12 | |
| ykuroda | 0:13a5d365ba16 | 13 | namespace Eigen { |
| ykuroda | 0:13a5d365ba16 | 14 | |
| ykuroda | 0:13a5d365ba16 | 15 | /** \class Transpositions |
| ykuroda | 0:13a5d365ba16 | 16 | * \ingroup Core_Module |
| ykuroda | 0:13a5d365ba16 | 17 | * |
| ykuroda | 0:13a5d365ba16 | 18 | * \brief Represents a sequence of transpositions (row/column interchange) |
| ykuroda | 0:13a5d365ba16 | 19 | * |
| ykuroda | 0:13a5d365ba16 | 20 | * \param SizeAtCompileTime the number of transpositions, or Dynamic |
| ykuroda | 0:13a5d365ba16 | 21 | * \param MaxSizeAtCompileTime the maximum number of transpositions, or Dynamic. This optional parameter defaults to SizeAtCompileTime. Most of the time, you should not have to specify it. |
| ykuroda | 0:13a5d365ba16 | 22 | * |
| ykuroda | 0:13a5d365ba16 | 23 | * This class represents a permutation transformation as a sequence of \em n transpositions |
| ykuroda | 0:13a5d365ba16 | 24 | * \f$[T_{n-1} \ldots T_{i} \ldots T_{0}]\f$. It is internally stored as a vector of integers \c indices. |
| ykuroda | 0:13a5d365ba16 | 25 | * Each transposition \f$ T_{i} \f$ applied on the left of a matrix (\f$ T_{i} M\f$) interchanges |
| ykuroda | 0:13a5d365ba16 | 26 | * the rows \c i and \c indices[i] of the matrix \c M. |
| ykuroda | 0:13a5d365ba16 | 27 | * A transposition applied on the right (e.g., \f$ M T_{i}\f$) yields a column interchange. |
| ykuroda | 0:13a5d365ba16 | 28 | * |
| ykuroda | 0:13a5d365ba16 | 29 | * Compared to the class PermutationMatrix, such a sequence of transpositions is what is |
| ykuroda | 0:13a5d365ba16 | 30 | * computed during a decomposition with pivoting, and it is faster when applying the permutation in-place. |
| ykuroda | 0:13a5d365ba16 | 31 | * |
| ykuroda | 0:13a5d365ba16 | 32 | * To apply a sequence of transpositions to a matrix, simply use the operator * as in the following example: |
| ykuroda | 0:13a5d365ba16 | 33 | * \code |
| ykuroda | 0:13a5d365ba16 | 34 | * Transpositions tr; |
| ykuroda | 0:13a5d365ba16 | 35 | * MatrixXf mat; |
| ykuroda | 0:13a5d365ba16 | 36 | * mat = tr * mat; |
| ykuroda | 0:13a5d365ba16 | 37 | * \endcode |
| ykuroda | 0:13a5d365ba16 | 38 | * In this example, we detect that the matrix appears on both side, and so the transpositions |
| ykuroda | 0:13a5d365ba16 | 39 | * are applied in-place without any temporary or extra copy. |
| ykuroda | 0:13a5d365ba16 | 40 | * |
| ykuroda | 0:13a5d365ba16 | 41 | * \sa class PermutationMatrix |
| ykuroda | 0:13a5d365ba16 | 42 | */ |
| ykuroda | 0:13a5d365ba16 | 43 | |
| ykuroda | 0:13a5d365ba16 | 44 | namespace internal { |
| ykuroda | 0:13a5d365ba16 | 45 | template<typename TranspositionType, typename MatrixType, int Side, bool Transposed=false> struct transposition_matrix_product_retval; |
| ykuroda | 0:13a5d365ba16 | 46 | } |
| ykuroda | 0:13a5d365ba16 | 47 | |
| ykuroda | 0:13a5d365ba16 | 48 | template<typename Derived> |
| ykuroda | 0:13a5d365ba16 | 49 | class TranspositionsBase |
| ykuroda | 0:13a5d365ba16 | 50 | { |
| ykuroda | 0:13a5d365ba16 | 51 | typedef internal::traits<Derived> Traits; |
| ykuroda | 0:13a5d365ba16 | 52 | |
| ykuroda | 0:13a5d365ba16 | 53 | public: |
| ykuroda | 0:13a5d365ba16 | 54 | |
| ykuroda | 0:13a5d365ba16 | 55 | typedef typename Traits::IndicesType IndicesType; |
| ykuroda | 0:13a5d365ba16 | 56 | typedef typename IndicesType::Scalar Index; |
| ykuroda | 0:13a5d365ba16 | 57 | |
| ykuroda | 0:13a5d365ba16 | 58 | Derived& derived() { return *static_cast<Derived*>(this); } |
| ykuroda | 0:13a5d365ba16 | 59 | const Derived& derived() const { return *static_cast<const Derived*>(this); } |
| ykuroda | 0:13a5d365ba16 | 60 | |
| ykuroda | 0:13a5d365ba16 | 61 | /** Copies the \a other transpositions into \c *this */ |
| ykuroda | 0:13a5d365ba16 | 62 | template<typename OtherDerived> |
| ykuroda | 0:13a5d365ba16 | 63 | Derived& operator=(const TranspositionsBase<OtherDerived>& other) |
| ykuroda | 0:13a5d365ba16 | 64 | { |
| ykuroda | 0:13a5d365ba16 | 65 | indices() = other.indices(); |
| ykuroda | 0:13a5d365ba16 | 66 | return derived(); |
| ykuroda | 0:13a5d365ba16 | 67 | } |
| ykuroda | 0:13a5d365ba16 | 68 | |
| ykuroda | 0:13a5d365ba16 | 69 | #ifndef EIGEN_PARSED_BY_DOXYGEN |
| ykuroda | 0:13a5d365ba16 | 70 | /** This is a special case of the templated operator=. Its purpose is to |
| ykuroda | 0:13a5d365ba16 | 71 | * prevent a default operator= from hiding the templated operator=. |
| ykuroda | 0:13a5d365ba16 | 72 | */ |
| ykuroda | 0:13a5d365ba16 | 73 | Derived& operator=(const TranspositionsBase& other) |
| ykuroda | 0:13a5d365ba16 | 74 | { |
| ykuroda | 0:13a5d365ba16 | 75 | indices() = other.indices(); |
| ykuroda | 0:13a5d365ba16 | 76 | return derived(); |
| ykuroda | 0:13a5d365ba16 | 77 | } |
| ykuroda | 0:13a5d365ba16 | 78 | #endif |
| ykuroda | 0:13a5d365ba16 | 79 | |
| ykuroda | 0:13a5d365ba16 | 80 | /** \returns the number of transpositions */ |
| ykuroda | 0:13a5d365ba16 | 81 | inline Index size() const { return indices().size(); } |
| ykuroda | 0:13a5d365ba16 | 82 | |
| ykuroda | 0:13a5d365ba16 | 83 | /** Direct access to the underlying index vector */ |
| ykuroda | 0:13a5d365ba16 | 84 | inline const Index& coeff(Index i) const { return indices().coeff(i); } |
| ykuroda | 0:13a5d365ba16 | 85 | /** Direct access to the underlying index vector */ |
| ykuroda | 0:13a5d365ba16 | 86 | inline Index& coeffRef(Index i) { return indices().coeffRef(i); } |
| ykuroda | 0:13a5d365ba16 | 87 | /** Direct access to the underlying index vector */ |
| ykuroda | 0:13a5d365ba16 | 88 | inline const Index& operator()(Index i) const { return indices()(i); } |
| ykuroda | 0:13a5d365ba16 | 89 | /** Direct access to the underlying index vector */ |
| ykuroda | 0:13a5d365ba16 | 90 | inline Index& operator()(Index i) { return indices()(i); } |
| ykuroda | 0:13a5d365ba16 | 91 | /** Direct access to the underlying index vector */ |
| ykuroda | 0:13a5d365ba16 | 92 | inline const Index& operator[](Index i) const { return indices()(i); } |
| ykuroda | 0:13a5d365ba16 | 93 | /** Direct access to the underlying index vector */ |
| ykuroda | 0:13a5d365ba16 | 94 | inline Index& operator[](Index i) { return indices()(i); } |
| ykuroda | 0:13a5d365ba16 | 95 | |
| ykuroda | 0:13a5d365ba16 | 96 | /** const version of indices(). */ |
| ykuroda | 0:13a5d365ba16 | 97 | const IndicesType& indices() const { return derived().indices(); } |
| ykuroda | 0:13a5d365ba16 | 98 | /** \returns a reference to the stored array representing the transpositions. */ |
| ykuroda | 0:13a5d365ba16 | 99 | IndicesType& indices() { return derived().indices(); } |
| ykuroda | 0:13a5d365ba16 | 100 | |
| ykuroda | 0:13a5d365ba16 | 101 | /** Resizes to given size. */ |
| ykuroda | 0:13a5d365ba16 | 102 | inline void resize(int newSize) |
| ykuroda | 0:13a5d365ba16 | 103 | { |
| ykuroda | 0:13a5d365ba16 | 104 | indices().resize(newSize); |
| ykuroda | 0:13a5d365ba16 | 105 | } |
| ykuroda | 0:13a5d365ba16 | 106 | |
| ykuroda | 0:13a5d365ba16 | 107 | /** Sets \c *this to represents an identity transformation */ |
| ykuroda | 0:13a5d365ba16 | 108 | void setIdentity() |
| ykuroda | 0:13a5d365ba16 | 109 | { |
| ykuroda | 0:13a5d365ba16 | 110 | for(int i = 0; i < indices().size(); ++i) |
| ykuroda | 0:13a5d365ba16 | 111 | coeffRef(i) = i; |
| ykuroda | 0:13a5d365ba16 | 112 | } |
| ykuroda | 0:13a5d365ba16 | 113 | |
| ykuroda | 0:13a5d365ba16 | 114 | // FIXME: do we want such methods ? |
| ykuroda | 0:13a5d365ba16 | 115 | // might be usefull when the target matrix expression is complex, e.g.: |
| ykuroda | 0:13a5d365ba16 | 116 | // object.matrix().block(..,..,..,..) = trans * object.matrix().block(..,..,..,..); |
| ykuroda | 0:13a5d365ba16 | 117 | /* |
| ykuroda | 0:13a5d365ba16 | 118 | template<typename MatrixType> |
| ykuroda | 0:13a5d365ba16 | 119 | void applyForwardToRows(MatrixType& mat) const |
| ykuroda | 0:13a5d365ba16 | 120 | { |
| ykuroda | 0:13a5d365ba16 | 121 | for(Index k=0 ; k<size() ; ++k) |
| ykuroda | 0:13a5d365ba16 | 122 | if(m_indices(k)!=k) |
| ykuroda | 0:13a5d365ba16 | 123 | mat.row(k).swap(mat.row(m_indices(k))); |
| ykuroda | 0:13a5d365ba16 | 124 | } |
| ykuroda | 0:13a5d365ba16 | 125 | |
| ykuroda | 0:13a5d365ba16 | 126 | template<typename MatrixType> |
| ykuroda | 0:13a5d365ba16 | 127 | void applyBackwardToRows(MatrixType& mat) const |
| ykuroda | 0:13a5d365ba16 | 128 | { |
| ykuroda | 0:13a5d365ba16 | 129 | for(Index k=size()-1 ; k>=0 ; --k) |
| ykuroda | 0:13a5d365ba16 | 130 | if(m_indices(k)!=k) |
| ykuroda | 0:13a5d365ba16 | 131 | mat.row(k).swap(mat.row(m_indices(k))); |
| ykuroda | 0:13a5d365ba16 | 132 | } |
| ykuroda | 0:13a5d365ba16 | 133 | */ |
| ykuroda | 0:13a5d365ba16 | 134 | |
| ykuroda | 0:13a5d365ba16 | 135 | /** \returns the inverse transformation */ |
| ykuroda | 0:13a5d365ba16 | 136 | inline Transpose<TranspositionsBase> inverse() const |
| ykuroda | 0:13a5d365ba16 | 137 | { return Transpose<TranspositionsBase>(derived()); } |
| ykuroda | 0:13a5d365ba16 | 138 | |
| ykuroda | 0:13a5d365ba16 | 139 | /** \returns the tranpose transformation */ |
| ykuroda | 0:13a5d365ba16 | 140 | inline Transpose<TranspositionsBase> transpose() const |
| ykuroda | 0:13a5d365ba16 | 141 | { return Transpose<TranspositionsBase>(derived()); } |
| ykuroda | 0:13a5d365ba16 | 142 | |
| ykuroda | 0:13a5d365ba16 | 143 | protected: |
| ykuroda | 0:13a5d365ba16 | 144 | }; |
| ykuroda | 0:13a5d365ba16 | 145 | |
| ykuroda | 0:13a5d365ba16 | 146 | namespace internal { |
| ykuroda | 0:13a5d365ba16 | 147 | template<int SizeAtCompileTime, int MaxSizeAtCompileTime, typename IndexType> |
| ykuroda | 0:13a5d365ba16 | 148 | struct traits<Transpositions<SizeAtCompileTime,MaxSizeAtCompileTime,IndexType> > |
| ykuroda | 0:13a5d365ba16 | 149 | { |
| ykuroda | 0:13a5d365ba16 | 150 | typedef IndexType Index; |
| ykuroda | 0:13a5d365ba16 | 151 | typedef Matrix<Index, SizeAtCompileTime, 1, 0, MaxSizeAtCompileTime, 1> IndicesType; |
| ykuroda | 0:13a5d365ba16 | 152 | }; |
| ykuroda | 0:13a5d365ba16 | 153 | } |
| ykuroda | 0:13a5d365ba16 | 154 | |
| ykuroda | 0:13a5d365ba16 | 155 | template<int SizeAtCompileTime, int MaxSizeAtCompileTime, typename IndexType> |
| ykuroda | 0:13a5d365ba16 | 156 | class Transpositions : public TranspositionsBase<Transpositions<SizeAtCompileTime,MaxSizeAtCompileTime,IndexType> > |
| ykuroda | 0:13a5d365ba16 | 157 | { |
| ykuroda | 0:13a5d365ba16 | 158 | typedef internal::traits<Transpositions> Traits; |
| ykuroda | 0:13a5d365ba16 | 159 | public: |
| ykuroda | 0:13a5d365ba16 | 160 | |
| ykuroda | 0:13a5d365ba16 | 161 | typedef TranspositionsBase<Transpositions> Base; |
| ykuroda | 0:13a5d365ba16 | 162 | typedef typename Traits::IndicesType IndicesType; |
| ykuroda | 0:13a5d365ba16 | 163 | typedef typename IndicesType::Scalar Index; |
| ykuroda | 0:13a5d365ba16 | 164 | |
| ykuroda | 0:13a5d365ba16 | 165 | inline Transpositions() {} |
| ykuroda | 0:13a5d365ba16 | 166 | |
| ykuroda | 0:13a5d365ba16 | 167 | /** Copy constructor. */ |
| ykuroda | 0:13a5d365ba16 | 168 | template<typename OtherDerived> |
| ykuroda | 0:13a5d365ba16 | 169 | inline Transpositions(const TranspositionsBase<OtherDerived>& other) |
| ykuroda | 0:13a5d365ba16 | 170 | : m_indices(other.indices()) {} |
| ykuroda | 0:13a5d365ba16 | 171 | |
| ykuroda | 0:13a5d365ba16 | 172 | #ifndef EIGEN_PARSED_BY_DOXYGEN |
| ykuroda | 0:13a5d365ba16 | 173 | /** Standard copy constructor. Defined only to prevent a default copy constructor |
| ykuroda | 0:13a5d365ba16 | 174 | * from hiding the other templated constructor */ |
| ykuroda | 0:13a5d365ba16 | 175 | inline Transpositions(const Transpositions& other) : m_indices(other.indices()) {} |
| ykuroda | 0:13a5d365ba16 | 176 | #endif |
| ykuroda | 0:13a5d365ba16 | 177 | |
| ykuroda | 0:13a5d365ba16 | 178 | /** Generic constructor from expression of the transposition indices. */ |
| ykuroda | 0:13a5d365ba16 | 179 | template<typename Other> |
| ykuroda | 0:13a5d365ba16 | 180 | explicit inline Transpositions(const MatrixBase<Other>& a_indices) : m_indices(a_indices) |
| ykuroda | 0:13a5d365ba16 | 181 | {} |
| ykuroda | 0:13a5d365ba16 | 182 | |
| ykuroda | 0:13a5d365ba16 | 183 | /** Copies the \a other transpositions into \c *this */ |
| ykuroda | 0:13a5d365ba16 | 184 | template<typename OtherDerived> |
| ykuroda | 0:13a5d365ba16 | 185 | Transpositions& operator=(const TranspositionsBase<OtherDerived>& other) |
| ykuroda | 0:13a5d365ba16 | 186 | { |
| ykuroda | 0:13a5d365ba16 | 187 | return Base::operator=(other); |
| ykuroda | 0:13a5d365ba16 | 188 | } |
| ykuroda | 0:13a5d365ba16 | 189 | |
| ykuroda | 0:13a5d365ba16 | 190 | #ifndef EIGEN_PARSED_BY_DOXYGEN |
| ykuroda | 0:13a5d365ba16 | 191 | /** This is a special case of the templated operator=. Its purpose is to |
| ykuroda | 0:13a5d365ba16 | 192 | * prevent a default operator= from hiding the templated operator=. |
| ykuroda | 0:13a5d365ba16 | 193 | */ |
| ykuroda | 0:13a5d365ba16 | 194 | Transpositions& operator=(const Transpositions& other) |
| ykuroda | 0:13a5d365ba16 | 195 | { |
| ykuroda | 0:13a5d365ba16 | 196 | m_indices = other.m_indices; |
| ykuroda | 0:13a5d365ba16 | 197 | return *this; |
| ykuroda | 0:13a5d365ba16 | 198 | } |
| ykuroda | 0:13a5d365ba16 | 199 | #endif |
| ykuroda | 0:13a5d365ba16 | 200 | |
| ykuroda | 0:13a5d365ba16 | 201 | /** Constructs an uninitialized permutation matrix of given size. |
| ykuroda | 0:13a5d365ba16 | 202 | */ |
| ykuroda | 0:13a5d365ba16 | 203 | inline Transpositions(Index size) : m_indices(size) |
| ykuroda | 0:13a5d365ba16 | 204 | {} |
| ykuroda | 0:13a5d365ba16 | 205 | |
| ykuroda | 0:13a5d365ba16 | 206 | /** const version of indices(). */ |
| ykuroda | 0:13a5d365ba16 | 207 | const IndicesType& indices() const { return m_indices; } |
| ykuroda | 0:13a5d365ba16 | 208 | /** \returns a reference to the stored array representing the transpositions. */ |
| ykuroda | 0:13a5d365ba16 | 209 | IndicesType& indices() { return m_indices; } |
| ykuroda | 0:13a5d365ba16 | 210 | |
| ykuroda | 0:13a5d365ba16 | 211 | protected: |
| ykuroda | 0:13a5d365ba16 | 212 | |
| ykuroda | 0:13a5d365ba16 | 213 | IndicesType m_indices; |
| ykuroda | 0:13a5d365ba16 | 214 | }; |
| ykuroda | 0:13a5d365ba16 | 215 | |
| ykuroda | 0:13a5d365ba16 | 216 | |
| ykuroda | 0:13a5d365ba16 | 217 | namespace internal { |
| ykuroda | 0:13a5d365ba16 | 218 | template<int SizeAtCompileTime, int MaxSizeAtCompileTime, typename IndexType, int _PacketAccess> |
| ykuroda | 0:13a5d365ba16 | 219 | struct traits<Map<Transpositions<SizeAtCompileTime,MaxSizeAtCompileTime,IndexType>,_PacketAccess> > |
| ykuroda | 0:13a5d365ba16 | 220 | { |
| ykuroda | 0:13a5d365ba16 | 221 | typedef IndexType Index; |
| ykuroda | 0:13a5d365ba16 | 222 | typedef Map<const Matrix<Index,SizeAtCompileTime,1,0,MaxSizeAtCompileTime,1>, _PacketAccess> IndicesType; |
| ykuroda | 0:13a5d365ba16 | 223 | }; |
| ykuroda | 0:13a5d365ba16 | 224 | } |
| ykuroda | 0:13a5d365ba16 | 225 | |
| ykuroda | 0:13a5d365ba16 | 226 | template<int SizeAtCompileTime, int MaxSizeAtCompileTime, typename IndexType, int PacketAccess> |
| ykuroda | 0:13a5d365ba16 | 227 | class Map<Transpositions<SizeAtCompileTime,MaxSizeAtCompileTime,IndexType>,PacketAccess> |
| ykuroda | 0:13a5d365ba16 | 228 | : public TranspositionsBase<Map<Transpositions<SizeAtCompileTime,MaxSizeAtCompileTime,IndexType>,PacketAccess> > |
| ykuroda | 0:13a5d365ba16 | 229 | { |
| ykuroda | 0:13a5d365ba16 | 230 | typedef internal::traits<Map> Traits; |
| ykuroda | 0:13a5d365ba16 | 231 | public: |
| ykuroda | 0:13a5d365ba16 | 232 | |
| ykuroda | 0:13a5d365ba16 | 233 | typedef TranspositionsBase<Map> Base; |
| ykuroda | 0:13a5d365ba16 | 234 | typedef typename Traits::IndicesType IndicesType; |
| ykuroda | 0:13a5d365ba16 | 235 | typedef typename IndicesType::Scalar Index; |
| ykuroda | 0:13a5d365ba16 | 236 | |
| ykuroda | 0:13a5d365ba16 | 237 | inline Map(const Index* indicesPtr) |
| ykuroda | 0:13a5d365ba16 | 238 | : m_indices(indicesPtr) |
| ykuroda | 0:13a5d365ba16 | 239 | {} |
| ykuroda | 0:13a5d365ba16 | 240 | |
| ykuroda | 0:13a5d365ba16 | 241 | inline Map(const Index* indicesPtr, Index size) |
| ykuroda | 0:13a5d365ba16 | 242 | : m_indices(indicesPtr,size) |
| ykuroda | 0:13a5d365ba16 | 243 | {} |
| ykuroda | 0:13a5d365ba16 | 244 | |
| ykuroda | 0:13a5d365ba16 | 245 | /** Copies the \a other transpositions into \c *this */ |
| ykuroda | 0:13a5d365ba16 | 246 | template<typename OtherDerived> |
| ykuroda | 0:13a5d365ba16 | 247 | Map& operator=(const TranspositionsBase<OtherDerived>& other) |
| ykuroda | 0:13a5d365ba16 | 248 | { |
| ykuroda | 0:13a5d365ba16 | 249 | return Base::operator=(other); |
| ykuroda | 0:13a5d365ba16 | 250 | } |
| ykuroda | 0:13a5d365ba16 | 251 | |
| ykuroda | 0:13a5d365ba16 | 252 | #ifndef EIGEN_PARSED_BY_DOXYGEN |
| ykuroda | 0:13a5d365ba16 | 253 | /** This is a special case of the templated operator=. Its purpose is to |
| ykuroda | 0:13a5d365ba16 | 254 | * prevent a default operator= from hiding the templated operator=. |
| ykuroda | 0:13a5d365ba16 | 255 | */ |
| ykuroda | 0:13a5d365ba16 | 256 | Map& operator=(const Map& other) |
| ykuroda | 0:13a5d365ba16 | 257 | { |
| ykuroda | 0:13a5d365ba16 | 258 | m_indices = other.m_indices; |
| ykuroda | 0:13a5d365ba16 | 259 | return *this; |
| ykuroda | 0:13a5d365ba16 | 260 | } |
| ykuroda | 0:13a5d365ba16 | 261 | #endif |
| ykuroda | 0:13a5d365ba16 | 262 | |
| ykuroda | 0:13a5d365ba16 | 263 | /** const version of indices(). */ |
| ykuroda | 0:13a5d365ba16 | 264 | const IndicesType& indices() const { return m_indices; } |
| ykuroda | 0:13a5d365ba16 | 265 | |
| ykuroda | 0:13a5d365ba16 | 266 | /** \returns a reference to the stored array representing the transpositions. */ |
| ykuroda | 0:13a5d365ba16 | 267 | IndicesType& indices() { return m_indices; } |
| ykuroda | 0:13a5d365ba16 | 268 | |
| ykuroda | 0:13a5d365ba16 | 269 | protected: |
| ykuroda | 0:13a5d365ba16 | 270 | |
| ykuroda | 0:13a5d365ba16 | 271 | IndicesType m_indices; |
| ykuroda | 0:13a5d365ba16 | 272 | }; |
| ykuroda | 0:13a5d365ba16 | 273 | |
| ykuroda | 0:13a5d365ba16 | 274 | namespace internal { |
| ykuroda | 0:13a5d365ba16 | 275 | template<typename _IndicesType> |
| ykuroda | 0:13a5d365ba16 | 276 | struct traits<TranspositionsWrapper<_IndicesType> > |
| ykuroda | 0:13a5d365ba16 | 277 | { |
| ykuroda | 0:13a5d365ba16 | 278 | typedef typename _IndicesType::Scalar Index; |
| ykuroda | 0:13a5d365ba16 | 279 | typedef _IndicesType IndicesType; |
| ykuroda | 0:13a5d365ba16 | 280 | }; |
| ykuroda | 0:13a5d365ba16 | 281 | } |
| ykuroda | 0:13a5d365ba16 | 282 | |
| ykuroda | 0:13a5d365ba16 | 283 | template<typename _IndicesType> |
| ykuroda | 0:13a5d365ba16 | 284 | class TranspositionsWrapper |
| ykuroda | 0:13a5d365ba16 | 285 | : public TranspositionsBase<TranspositionsWrapper<_IndicesType> > |
| ykuroda | 0:13a5d365ba16 | 286 | { |
| ykuroda | 0:13a5d365ba16 | 287 | typedef internal::traits<TranspositionsWrapper> Traits; |
| ykuroda | 0:13a5d365ba16 | 288 | public: |
| ykuroda | 0:13a5d365ba16 | 289 | |
| ykuroda | 0:13a5d365ba16 | 290 | typedef TranspositionsBase<TranspositionsWrapper> Base; |
| ykuroda | 0:13a5d365ba16 | 291 | typedef typename Traits::IndicesType IndicesType; |
| ykuroda | 0:13a5d365ba16 | 292 | typedef typename IndicesType::Scalar Index; |
| ykuroda | 0:13a5d365ba16 | 293 | |
| ykuroda | 0:13a5d365ba16 | 294 | inline TranspositionsWrapper(IndicesType& a_indices) |
| ykuroda | 0:13a5d365ba16 | 295 | : m_indices(a_indices) |
| ykuroda | 0:13a5d365ba16 | 296 | {} |
| ykuroda | 0:13a5d365ba16 | 297 | |
| ykuroda | 0:13a5d365ba16 | 298 | /** Copies the \a other transpositions into \c *this */ |
| ykuroda | 0:13a5d365ba16 | 299 | template<typename OtherDerived> |
| ykuroda | 0:13a5d365ba16 | 300 | TranspositionsWrapper& operator=(const TranspositionsBase<OtherDerived>& other) |
| ykuroda | 0:13a5d365ba16 | 301 | { |
| ykuroda | 0:13a5d365ba16 | 302 | return Base::operator=(other); |
| ykuroda | 0:13a5d365ba16 | 303 | } |
| ykuroda | 0:13a5d365ba16 | 304 | |
| ykuroda | 0:13a5d365ba16 | 305 | #ifndef EIGEN_PARSED_BY_DOXYGEN |
| ykuroda | 0:13a5d365ba16 | 306 | /** This is a special case of the templated operator=. Its purpose is to |
| ykuroda | 0:13a5d365ba16 | 307 | * prevent a default operator= from hiding the templated operator=. |
| ykuroda | 0:13a5d365ba16 | 308 | */ |
| ykuroda | 0:13a5d365ba16 | 309 | TranspositionsWrapper& operator=(const TranspositionsWrapper& other) |
| ykuroda | 0:13a5d365ba16 | 310 | { |
| ykuroda | 0:13a5d365ba16 | 311 | m_indices = other.m_indices; |
| ykuroda | 0:13a5d365ba16 | 312 | return *this; |
| ykuroda | 0:13a5d365ba16 | 313 | } |
| ykuroda | 0:13a5d365ba16 | 314 | #endif |
| ykuroda | 0:13a5d365ba16 | 315 | |
| ykuroda | 0:13a5d365ba16 | 316 | /** const version of indices(). */ |
| ykuroda | 0:13a5d365ba16 | 317 | const IndicesType& indices() const { return m_indices; } |
| ykuroda | 0:13a5d365ba16 | 318 | |
| ykuroda | 0:13a5d365ba16 | 319 | /** \returns a reference to the stored array representing the transpositions. */ |
| ykuroda | 0:13a5d365ba16 | 320 | IndicesType& indices() { return m_indices; } |
| ykuroda | 0:13a5d365ba16 | 321 | |
| ykuroda | 0:13a5d365ba16 | 322 | protected: |
| ykuroda | 0:13a5d365ba16 | 323 | |
| ykuroda | 0:13a5d365ba16 | 324 | const typename IndicesType::Nested m_indices; |
| ykuroda | 0:13a5d365ba16 | 325 | }; |
| ykuroda | 0:13a5d365ba16 | 326 | |
| ykuroda | 0:13a5d365ba16 | 327 | /** \returns the \a matrix with the \a transpositions applied to the columns. |
| ykuroda | 0:13a5d365ba16 | 328 | */ |
| ykuroda | 0:13a5d365ba16 | 329 | template<typename Derived, typename TranspositionsDerived> |
| ykuroda | 0:13a5d365ba16 | 330 | inline const internal::transposition_matrix_product_retval<TranspositionsDerived, Derived, OnTheRight> |
| ykuroda | 0:13a5d365ba16 | 331 | operator*(const MatrixBase<Derived>& matrix, |
| ykuroda | 0:13a5d365ba16 | 332 | const TranspositionsBase<TranspositionsDerived> &transpositions) |
| ykuroda | 0:13a5d365ba16 | 333 | { |
| ykuroda | 0:13a5d365ba16 | 334 | return internal::transposition_matrix_product_retval |
| ykuroda | 0:13a5d365ba16 | 335 | <TranspositionsDerived, Derived, OnTheRight> |
| ykuroda | 0:13a5d365ba16 | 336 | (transpositions.derived(), matrix.derived()); |
| ykuroda | 0:13a5d365ba16 | 337 | } |
| ykuroda | 0:13a5d365ba16 | 338 | |
| ykuroda | 0:13a5d365ba16 | 339 | /** \returns the \a matrix with the \a transpositions applied to the rows. |
| ykuroda | 0:13a5d365ba16 | 340 | */ |
| ykuroda | 0:13a5d365ba16 | 341 | template<typename Derived, typename TranspositionDerived> |
| ykuroda | 0:13a5d365ba16 | 342 | inline const internal::transposition_matrix_product_retval |
| ykuroda | 0:13a5d365ba16 | 343 | <TranspositionDerived, Derived, OnTheLeft> |
| ykuroda | 0:13a5d365ba16 | 344 | operator*(const TranspositionsBase<TranspositionDerived> &transpositions, |
| ykuroda | 0:13a5d365ba16 | 345 | const MatrixBase<Derived>& matrix) |
| ykuroda | 0:13a5d365ba16 | 346 | { |
| ykuroda | 0:13a5d365ba16 | 347 | return internal::transposition_matrix_product_retval |
| ykuroda | 0:13a5d365ba16 | 348 | <TranspositionDerived, Derived, OnTheLeft> |
| ykuroda | 0:13a5d365ba16 | 349 | (transpositions.derived(), matrix.derived()); |
| ykuroda | 0:13a5d365ba16 | 350 | } |
| ykuroda | 0:13a5d365ba16 | 351 | |
| ykuroda | 0:13a5d365ba16 | 352 | namespace internal { |
| ykuroda | 0:13a5d365ba16 | 353 | |
| ykuroda | 0:13a5d365ba16 | 354 | template<typename TranspositionType, typename MatrixType, int Side, bool Transposed> |
| ykuroda | 0:13a5d365ba16 | 355 | struct traits<transposition_matrix_product_retval<TranspositionType, MatrixType, Side, Transposed> > |
| ykuroda | 0:13a5d365ba16 | 356 | { |
| ykuroda | 0:13a5d365ba16 | 357 | typedef typename MatrixType::PlainObject ReturnType; |
| ykuroda | 0:13a5d365ba16 | 358 | }; |
| ykuroda | 0:13a5d365ba16 | 359 | |
| ykuroda | 0:13a5d365ba16 | 360 | template<typename TranspositionType, typename MatrixType, int Side, bool Transposed> |
| ykuroda | 0:13a5d365ba16 | 361 | struct transposition_matrix_product_retval |
| ykuroda | 0:13a5d365ba16 | 362 | : public ReturnByValue<transposition_matrix_product_retval<TranspositionType, MatrixType, Side, Transposed> > |
| ykuroda | 0:13a5d365ba16 | 363 | { |
| ykuroda | 0:13a5d365ba16 | 364 | typedef typename remove_all<typename MatrixType::Nested>::type MatrixTypeNestedCleaned; |
| ykuroda | 0:13a5d365ba16 | 365 | typedef typename TranspositionType::Index Index; |
| ykuroda | 0:13a5d365ba16 | 366 | |
| ykuroda | 0:13a5d365ba16 | 367 | transposition_matrix_product_retval(const TranspositionType& tr, const MatrixType& matrix) |
| ykuroda | 0:13a5d365ba16 | 368 | : m_transpositions(tr), m_matrix(matrix) |
| ykuroda | 0:13a5d365ba16 | 369 | {} |
| ykuroda | 0:13a5d365ba16 | 370 | |
| ykuroda | 0:13a5d365ba16 | 371 | inline int rows() const { return m_matrix.rows(); } |
| ykuroda | 0:13a5d365ba16 | 372 | inline int cols() const { return m_matrix.cols(); } |
| ykuroda | 0:13a5d365ba16 | 373 | |
| ykuroda | 0:13a5d365ba16 | 374 | template<typename Dest> inline void evalTo(Dest& dst) const |
| ykuroda | 0:13a5d365ba16 | 375 | { |
| ykuroda | 0:13a5d365ba16 | 376 | const int size = m_transpositions.size(); |
| ykuroda | 0:13a5d365ba16 | 377 | Index j = 0; |
| ykuroda | 0:13a5d365ba16 | 378 | |
| ykuroda | 0:13a5d365ba16 | 379 | if(!(is_same<MatrixTypeNestedCleaned,Dest>::value && extract_data(dst) == extract_data(m_matrix))) |
| ykuroda | 0:13a5d365ba16 | 380 | dst = m_matrix; |
| ykuroda | 0:13a5d365ba16 | 381 | |
| ykuroda | 0:13a5d365ba16 | 382 | for(int k=(Transposed?size-1:0) ; Transposed?k>=0:k<size ; Transposed?--k:++k) |
| ykuroda | 0:13a5d365ba16 | 383 | if((j=m_transpositions.coeff(k))!=k) |
| ykuroda | 0:13a5d365ba16 | 384 | { |
| ykuroda | 0:13a5d365ba16 | 385 | if(Side==OnTheLeft) |
| ykuroda | 0:13a5d365ba16 | 386 | dst.row(k).swap(dst.row(j)); |
| ykuroda | 0:13a5d365ba16 | 387 | else if(Side==OnTheRight) |
| ykuroda | 0:13a5d365ba16 | 388 | dst.col(k).swap(dst.col(j)); |
| ykuroda | 0:13a5d365ba16 | 389 | } |
| ykuroda | 0:13a5d365ba16 | 390 | } |
| ykuroda | 0:13a5d365ba16 | 391 | |
| ykuroda | 0:13a5d365ba16 | 392 | protected: |
| ykuroda | 0:13a5d365ba16 | 393 | const TranspositionType& m_transpositions; |
| ykuroda | 0:13a5d365ba16 | 394 | typename MatrixType::Nested m_matrix; |
| ykuroda | 0:13a5d365ba16 | 395 | }; |
| ykuroda | 0:13a5d365ba16 | 396 | |
| ykuroda | 0:13a5d365ba16 | 397 | } // end namespace internal |
| ykuroda | 0:13a5d365ba16 | 398 | |
| ykuroda | 0:13a5d365ba16 | 399 | /* Template partial specialization for transposed/inverse transpositions */ |
| ykuroda | 0:13a5d365ba16 | 400 | |
| ykuroda | 0:13a5d365ba16 | 401 | template<typename TranspositionsDerived> |
| ykuroda | 0:13a5d365ba16 | 402 | class Transpose<TranspositionsBase<TranspositionsDerived> > |
| ykuroda | 0:13a5d365ba16 | 403 | { |
| ykuroda | 0:13a5d365ba16 | 404 | typedef TranspositionsDerived TranspositionType; |
| ykuroda | 0:13a5d365ba16 | 405 | typedef typename TranspositionType::IndicesType IndicesType; |
| ykuroda | 0:13a5d365ba16 | 406 | public: |
| ykuroda | 0:13a5d365ba16 | 407 | |
| ykuroda | 0:13a5d365ba16 | 408 | Transpose(const TranspositionType& t) : m_transpositions(t) {} |
| ykuroda | 0:13a5d365ba16 | 409 | |
| ykuroda | 0:13a5d365ba16 | 410 | inline int size() const { return m_transpositions.size(); } |
| ykuroda | 0:13a5d365ba16 | 411 | |
| ykuroda | 0:13a5d365ba16 | 412 | /** \returns the \a matrix with the inverse transpositions applied to the columns. |
| ykuroda | 0:13a5d365ba16 | 413 | */ |
| ykuroda | 0:13a5d365ba16 | 414 | template<typename Derived> friend |
| ykuroda | 0:13a5d365ba16 | 415 | inline const internal::transposition_matrix_product_retval<TranspositionType, Derived, OnTheRight, true> |
| ykuroda | 0:13a5d365ba16 | 416 | operator*(const MatrixBase<Derived>& matrix, const Transpose& trt) |
| ykuroda | 0:13a5d365ba16 | 417 | { |
| ykuroda | 0:13a5d365ba16 | 418 | return internal::transposition_matrix_product_retval<TranspositionType, Derived, OnTheRight, true>(trt.m_transpositions, matrix.derived()); |
| ykuroda | 0:13a5d365ba16 | 419 | } |
| ykuroda | 0:13a5d365ba16 | 420 | |
| ykuroda | 0:13a5d365ba16 | 421 | /** \returns the \a matrix with the inverse transpositions applied to the rows. |
| ykuroda | 0:13a5d365ba16 | 422 | */ |
| ykuroda | 0:13a5d365ba16 | 423 | template<typename Derived> |
| ykuroda | 0:13a5d365ba16 | 424 | inline const internal::transposition_matrix_product_retval<TranspositionType, Derived, OnTheLeft, true> |
| ykuroda | 0:13a5d365ba16 | 425 | operator*(const MatrixBase<Derived>& matrix) const |
| ykuroda | 0:13a5d365ba16 | 426 | { |
| ykuroda | 0:13a5d365ba16 | 427 | return internal::transposition_matrix_product_retval<TranspositionType, Derived, OnTheLeft, true>(m_transpositions, matrix.derived()); |
| ykuroda | 0:13a5d365ba16 | 428 | } |
| ykuroda | 0:13a5d365ba16 | 429 | |
| ykuroda | 0:13a5d365ba16 | 430 | protected: |
| ykuroda | 0:13a5d365ba16 | 431 | const TranspositionType& m_transpositions; |
| ykuroda | 0:13a5d365ba16 | 432 | }; |
| ykuroda | 0:13a5d365ba16 | 433 | |
| ykuroda | 0:13a5d365ba16 | 434 | } // end namespace Eigen |
| ykuroda | 0:13a5d365ba16 | 435 | |
| ykuroda | 0:13a5d365ba16 | 436 | #endif // EIGEN_TRANSPOSITIONS_H |