Jaesung Oh / Eigen

Dependents:   MPC_current_control HydraulicControlBoard_SW AHRS Test_ekf ... more

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?

UserRevisionLine numberNew 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