Merge of itasc branch. Project files, scons and cmake should be working. Makefile...
[blender.git] / extern / Eigen2 / Eigen / src / Core / Transpose.h
1 // This file is part of Eigen, a lightweight C++ template library
2 // for linear algebra. Eigen itself is part of the KDE project.
3 //
4 // Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
5 //
6 // Eigen is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 3 of the License, or (at your option) any later version.
10 //
11 // Alternatively, you can redistribute it and/or
12 // modify it under the terms of the GNU General Public License as
13 // published by the Free Software Foundation; either version 2 of
14 // the License, or (at your option) any later version.
15 //
16 // Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
17 // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
18 // FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
19 // GNU General Public License for more details.
20 //
21 // You should have received a copy of the GNU Lesser General Public
22 // License and a copy of the GNU General Public License along with
23 // Eigen. If not, see <http://www.gnu.org/licenses/>.
24
25 #ifndef EIGEN_TRANSPOSE_H
26 #define EIGEN_TRANSPOSE_H
27
28 /** \class Transpose
29   *
30   * \brief Expression of the transpose of a matrix
31   *
32   * \param MatrixType the type of the object of which we are taking the transpose
33   *
34   * This class represents an expression of the transpose of a matrix.
35   * It is the return type of MatrixBase::transpose() and MatrixBase::adjoint()
36   * and most of the time this is the only way it is used.
37   *
38   * \sa MatrixBase::transpose(), MatrixBase::adjoint()
39   */
40 template<typename MatrixType>
41 struct ei_traits<Transpose<MatrixType> >
42 {
43   typedef typename MatrixType::Scalar Scalar;
44   typedef typename ei_nested<MatrixType>::type MatrixTypeNested;
45   typedef typename ei_unref<MatrixTypeNested>::type _MatrixTypeNested;
46   enum {
47     RowsAtCompileTime = MatrixType::ColsAtCompileTime,
48     ColsAtCompileTime = MatrixType::RowsAtCompileTime,
49     MaxRowsAtCompileTime = MatrixType::MaxColsAtCompileTime,
50     MaxColsAtCompileTime = MatrixType::MaxRowsAtCompileTime,
51     Flags = ((int(_MatrixTypeNested::Flags) ^ RowMajorBit)
52           & ~(LowerTriangularBit | UpperTriangularBit))
53           | (int(_MatrixTypeNested::Flags)&UpperTriangularBit ? LowerTriangularBit : 0)
54           | (int(_MatrixTypeNested::Flags)&LowerTriangularBit ? UpperTriangularBit : 0),
55     CoeffReadCost = _MatrixTypeNested::CoeffReadCost
56   };
57 };
58
59 template<typename MatrixType> class Transpose
60   : public MatrixBase<Transpose<MatrixType> >
61 {
62   public:
63
64     EIGEN_GENERIC_PUBLIC_INTERFACE(Transpose)
65
66     inline Transpose(const MatrixType& matrix) : m_matrix(matrix) {}
67
68     EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Transpose)
69
70     inline int rows() const { return m_matrix.cols(); }
71     inline int cols() const { return m_matrix.rows(); }
72     inline int nonZeros() const { return m_matrix.nonZeros(); }
73     inline int stride(void) const { return m_matrix.stride(); }
74
75     inline Scalar& coeffRef(int row, int col)
76     {
77       return m_matrix.const_cast_derived().coeffRef(col, row);
78     }
79
80     inline const Scalar coeff(int row, int col) const
81     {
82       return m_matrix.coeff(col, row);
83     }
84
85     inline const Scalar coeff(int index) const
86     {
87       return m_matrix.coeff(index);
88     }
89
90     inline Scalar& coeffRef(int index)
91     {
92       return m_matrix.const_cast_derived().coeffRef(index);
93     }
94
95     template<int LoadMode>
96     inline const PacketScalar packet(int row, int col) const
97     {
98       return m_matrix.template packet<LoadMode>(col, row);
99     }
100
101     template<int LoadMode>
102     inline void writePacket(int row, int col, const PacketScalar& x)
103     {
104       m_matrix.const_cast_derived().template writePacket<LoadMode>(col, row, x);
105     }
106
107     template<int LoadMode>
108     inline const PacketScalar packet(int index) const
109     {
110       return m_matrix.template packet<LoadMode>(index);
111     }
112
113     template<int LoadMode>
114     inline void writePacket(int index, const PacketScalar& x)
115     {
116       m_matrix.const_cast_derived().template writePacket<LoadMode>(index, x);
117     }
118
119   protected:
120     const typename MatrixType::Nested m_matrix;
121 };
122
123 /** \returns an expression of the transpose of *this.
124   *
125   * Example: \include MatrixBase_transpose.cpp
126   * Output: \verbinclude MatrixBase_transpose.out
127   *
128   * \warning If you want to replace a matrix by its own transpose, do \b NOT do this:
129   * \code
130   * m = m.transpose(); // bug!!! caused by aliasing effect
131   * \endcode
132   * Instead, use the transposeInPlace() method:
133   * \code
134   * m.transposeInPlace();
135   * \endcode
136   * which gives Eigen good opportunities for optimization, or alternatively you can also do:
137   * \code
138   * m = m.transpose().eval();
139   * \endcode
140   *
141   * \sa transposeInPlace(), adjoint() */
142 template<typename Derived>
143 inline Transpose<Derived>
144 MatrixBase<Derived>::transpose()
145 {
146   return derived();
147 }
148
149 /** This is the const version of transpose().
150   *
151   * Make sure you read the warning for transpose() !
152   *
153   * \sa transposeInPlace(), adjoint() */
154 template<typename Derived>
155 inline const Transpose<Derived>
156 MatrixBase<Derived>::transpose() const
157 {
158   return derived();
159 }
160
161 /** \returns an expression of the adjoint (i.e. conjugate transpose) of *this.
162   *
163   * Example: \include MatrixBase_adjoint.cpp
164   * Output: \verbinclude MatrixBase_adjoint.out
165   *
166   * \warning If you want to replace a matrix by its own adjoint, do \b NOT do this:
167   * \code
168   * m = m.adjoint(); // bug!!! caused by aliasing effect
169   * \endcode
170   * Instead, do:
171   * \code
172   * m = m.adjoint().eval();
173   * \endcode
174   *
175   * \sa transpose(), conjugate(), class Transpose, class ei_scalar_conjugate_op */
176 template<typename Derived>
177 inline const typename MatrixBase<Derived>::AdjointReturnType
178 MatrixBase<Derived>::adjoint() const
179 {
180   return conjugate().nestByValue();
181 }
182
183 /***************************************************************************
184 * "in place" transpose implementation
185 ***************************************************************************/
186
187 template<typename MatrixType,
188   bool IsSquare = (MatrixType::RowsAtCompileTime == MatrixType::ColsAtCompileTime) && MatrixType::RowsAtCompileTime!=Dynamic>
189 struct ei_inplace_transpose_selector;
190
191 template<typename MatrixType>
192 struct ei_inplace_transpose_selector<MatrixType,true> { // square matrix
193   static void run(MatrixType& m) {
194     m.template part<StrictlyUpperTriangular>().swap(m.transpose());
195   }
196 };
197
198 template<typename MatrixType>
199 struct ei_inplace_transpose_selector<MatrixType,false> { // non square matrix
200   static void run(MatrixType& m) {
201     if (m.rows()==m.cols())
202       m.template part<StrictlyUpperTriangular>().swap(m.transpose());
203     else
204       m = m.transpose().eval();
205   }
206 };
207
208 /** This is the "in place" version of transpose: it transposes \c *this.
209   *
210   * In most cases it is probably better to simply use the transposed expression
211   * of a matrix. However, when transposing the matrix data itself is really needed,
212   * then this "in-place" version is probably the right choice because it provides
213   * the following additional features:
214   *  - less error prone: doing the same operation with .transpose() requires special care:
215   *    \code m = m.transpose().eval(); \endcode
216   *  - no temporary object is created (currently only for squared matrices)
217   *  - it allows future optimizations (cache friendliness, etc.)
218   *
219   * \note if the matrix is not square, then \c *this must be a resizable matrix.
220   *
221   * \sa transpose(), adjoint() */
222 template<typename Derived>
223 inline void MatrixBase<Derived>::transposeInPlace()
224 {
225   ei_inplace_transpose_selector<Derived>::run(derived());
226 }
227
228 #endif // EIGEN_TRANSPOSE_H