- Added maximization features, with corresponding plugins. Added painting feature...
[mldemos:mldemos.git] / _3rdParty / Eigen / src / Core / Transpose.h
1 // This file is part of Eigen, a lightweight C++ template library
2 // for linear algebra.
3 //
4 // Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
5 // Copyright (C) 2009-2010 Gael Guennebaud <gael.guennebaud@inria.fr>
6 //
7 // Eigen is free software; you can redistribute it and/or
8 // modify it under the terms of the GNU Lesser General Public
9 // License as published by the Free Software Foundation; either
10 // version 3 of the License, or (at your option) any later version.
11 //
12 // Alternatively, you can redistribute it and/or
13 // modify it under the terms of the GNU General Public License as
14 // published by the Free Software Foundation; either version 2 of
15 // the License, or (at your option) any later version.
16 //
17 // Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
18 // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
19 // FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
20 // GNU General Public License for more details.
21 //
22 // You should have received a copy of the GNU Lesser General Public
23 // License and a copy of the GNU General Public License along with
24 // Eigen. If not, see <http://www.gnu.org/licenses/>.
25
26 #ifndef EIGEN_TRANSPOSE_H
27 #define EIGEN_TRANSPOSE_H
28
29 /** \class Transpose
30   * \ingroup Core_Module
31   *
32   * \brief Expression of the transpose of a matrix
33   *
34   * \param MatrixType the type of the object of which we are taking the transpose
35   *
36   * This class represents an expression of the transpose of a matrix.
37   * It is the return type of MatrixBase::transpose() and MatrixBase::adjoint()
38   * and most of the time this is the only way it is used.
39   *
40   * \sa MatrixBase::transpose(), MatrixBase::adjoint()
41   */
42
43 namespace internal {
44 template<typename MatrixType>
45 struct traits<Transpose<MatrixType> > : traits<MatrixType>
46 {
47   typedef typename MatrixType::Scalar Scalar;
48   typedef typename nested<MatrixType>::type MatrixTypeNested;
49   typedef typename remove_reference<MatrixTypeNested>::type MatrixTypeNestedPlain;
50   typedef typename traits<MatrixType>::StorageKind StorageKind;
51   typedef typename traits<MatrixType>::XprKind XprKind;
52   enum {
53     RowsAtCompileTime = MatrixType::ColsAtCompileTime,
54     ColsAtCompileTime = MatrixType::RowsAtCompileTime,
55     MaxRowsAtCompileTime = MatrixType::MaxColsAtCompileTime,
56     MaxColsAtCompileTime = MatrixType::MaxRowsAtCompileTime,
57     FlagsLvalueBit = is_lvalue<MatrixType>::value ? LvalueBit : 0,
58     Flags0 = MatrixTypeNestedPlain::Flags & ~(LvalueBit | NestByRefBit),
59     Flags1 = Flags0 | FlagsLvalueBit,
60     Flags = Flags1 ^ RowMajorBit,
61     CoeffReadCost = MatrixTypeNestedPlain::CoeffReadCost,
62     InnerStrideAtCompileTime = inner_stride_at_compile_time<MatrixType>::ret,
63     OuterStrideAtCompileTime = outer_stride_at_compile_time<MatrixType>::ret
64   };
65 };
66 }
67
68 template<typename MatrixType, typename StorageKind> class TransposeImpl;
69
70 template<typename MatrixType> class Transpose
71   : public TransposeImpl<MatrixType,typename internal::traits<MatrixType>::StorageKind>
72 {
73   public:
74
75     typedef typename TransposeImpl<MatrixType,typename internal::traits<MatrixType>::StorageKind>::Base Base;
76     EIGEN_GENERIC_PUBLIC_INTERFACE(Transpose)
77
78     inline Transpose(MatrixType& matrix) : m_matrix(matrix) {}
79
80     EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Transpose)
81
82     inline Index rows() const { return m_matrix.cols(); }
83     inline Index cols() const { return m_matrix.rows(); }
84
85     /** \returns the nested expression */
86     const typename internal::remove_all<typename MatrixType::Nested>::type&
87     nestedExpression() const { return m_matrix; }
88
89     /** \returns the nested expression */
90     typename internal::remove_all<typename MatrixType::Nested>::type&
91     nestedExpression() { return m_matrix.const_cast_derived(); }
92
93   protected:
94     const typename MatrixType::Nested m_matrix;
95 };
96
97 namespace internal {
98
99 template<typename MatrixType, bool HasDirectAccess = has_direct_access<MatrixType>::ret>
100 struct TransposeImpl_base
101 {
102   typedef typename dense_xpr_base<Transpose<MatrixType> >::type type;
103 };
104
105 template<typename MatrixType>
106 struct TransposeImpl_base<MatrixType, false>
107 {
108   typedef typename dense_xpr_base<Transpose<MatrixType> >::type type;
109 };
110
111 } // end namespace internal
112
113 template<typename MatrixType> class TransposeImpl<MatrixType,Dense>
114   : public internal::TransposeImpl_base<MatrixType>::type
115 {
116   public:
117
118     typedef typename internal::TransposeImpl_base<MatrixType>::type Base;
119     EIGEN_DENSE_PUBLIC_INTERFACE(Transpose<MatrixType>)
120
121     inline Index innerStride() const { return derived().nestedExpression().innerStride(); }
122     inline Index outerStride() const { return derived().nestedExpression().outerStride(); }
123
124     typedef typename internal::conditional<
125                        internal::is_lvalue<MatrixType>::value,
126                        Scalar,
127                        const Scalar
128                      >::type ScalarWithConstIfNotLvalue;
129
130     inline ScalarWithConstIfNotLvalue* data() { return derived().nestedExpression().data(); }
131     inline const Scalar* data() const { return derived().nestedExpression().data(); }
132
133     inline ScalarWithConstIfNotLvalue& coeffRef(Index row, Index col)
134     {
135       EIGEN_STATIC_ASSERT_LVALUE(MatrixType)
136       return derived().nestedExpression().const_cast_derived().coeffRef(col, row);
137     }
138
139     inline ScalarWithConstIfNotLvalue& coeffRef(Index index)
140     {
141       EIGEN_STATIC_ASSERT_LVALUE(MatrixType)
142       return derived().nestedExpression().const_cast_derived().coeffRef(index);
143     }
144
145     inline const Scalar& coeffRef(Index row, Index col) const
146     {
147       return derived().nestedExpression().coeffRef(col, row);
148     }
149
150     inline const Scalar& coeffRef(Index index) const
151     {
152       return derived().nestedExpression().coeffRef(index);
153     }
154
155     inline const CoeffReturnType coeff(Index row, Index col) const
156     {
157       return derived().nestedExpression().coeff(col, row);
158     }
159
160     inline const CoeffReturnType coeff(Index index) const
161     {
162       return derived().nestedExpression().coeff(index);
163     }
164
165     template<int LoadMode>
166     inline const PacketScalar packet(Index row, Index col) const
167     {
168       return derived().nestedExpression().template packet<LoadMode>(col, row);
169     }
170
171     template<int LoadMode>
172     inline void writePacket(Index row, Index col, const PacketScalar& x)
173     {
174       derived().nestedExpression().const_cast_derived().template writePacket<LoadMode>(col, row, x);
175     }
176
177     template<int LoadMode>
178     inline const PacketScalar packet(Index index) const
179     {
180       return derived().nestedExpression().template packet<LoadMode>(index);
181     }
182
183     template<int LoadMode>
184     inline void writePacket(Index index, const PacketScalar& x)
185     {
186       derived().nestedExpression().const_cast_derived().template writePacket<LoadMode>(index, x);
187     }
188 };
189
190 /** \returns an expression of the transpose of *this.
191   *
192   * Example: \include MatrixBase_transpose.cpp
193   * Output: \verbinclude MatrixBase_transpose.out
194   *
195   * \warning If you want to replace a matrix by its own transpose, do \b NOT do this:
196   * \code
197   * m = m.transpose(); // bug!!! caused by aliasing effect
198   * \endcode
199   * Instead, use the transposeInPlace() method:
200   * \code
201   * m.transposeInPlace();
202   * \endcode
203   * which gives Eigen good opportunities for optimization, or alternatively you can also do:
204   * \code
205   * m = m.transpose().eval();
206   * \endcode
207   *
208   * \sa transposeInPlace(), adjoint() */
209 template<typename Derived>
210 inline Transpose<Derived>
211 DenseBase<Derived>::transpose()
212 {
213   return derived();
214 }
215
216 /** This is the const version of transpose().
217   *
218   * Make sure you read the warning for transpose() !
219   *
220   * \sa transposeInPlace(), adjoint() */
221 template<typename Derived>
222 inline const typename DenseBase<Derived>::ConstTransposeReturnType
223 DenseBase<Derived>::transpose() const
224 {
225   return ConstTransposeReturnType(derived());
226 }
227
228 /** \returns an expression of the adjoint (i.e. conjugate transpose) of *this.
229   *
230   * Example: \include MatrixBase_adjoint.cpp
231   * Output: \verbinclude MatrixBase_adjoint.out
232   *
233   * \warning If you want to replace a matrix by its own adjoint, do \b NOT do this:
234   * \code
235   * m = m.adjoint(); // bug!!! caused by aliasing effect
236   * \endcode
237   * Instead, use the adjointInPlace() method:
238   * \code
239   * m.adjointInPlace();
240   * \endcode
241   * which gives Eigen good opportunities for optimization, or alternatively you can also do:
242   * \code
243   * m = m.adjoint().eval();
244   * \endcode
245   *
246   * \sa adjointInPlace(), transpose(), conjugate(), class Transpose, class internal::scalar_conjugate_op */
247 template<typename Derived>
248 inline const typename MatrixBase<Derived>::AdjointReturnType
249 MatrixBase<Derived>::adjoint() const
250 {
251   return this->transpose(); // in the complex case, the .conjugate() is be implicit here
252                             // due to implicit conversion to return type
253 }
254
255 /***************************************************************************
256 * "in place" transpose implementation
257 ***************************************************************************/
258
259 namespace internal {
260
261 template<typename MatrixType,
262   bool IsSquare = (MatrixType::RowsAtCompileTime == MatrixType::ColsAtCompileTime) && MatrixType::RowsAtCompileTime!=Dynamic>
263 struct inplace_transpose_selector;
264
265 template<typename MatrixType>
266 struct inplace_transpose_selector<MatrixType,true> { // square matrix
267   static void run(MatrixType& m) {
268     m.template triangularView<StrictlyUpper>().swap(m.transpose());
269   }
270 };
271
272 template<typename MatrixType>
273 struct inplace_transpose_selector<MatrixType,false> { // non square matrix
274   static void run(MatrixType& m) {
275     if (m.rows()==m.cols())
276       m.template triangularView<StrictlyUpper>().swap(m.transpose());
277     else
278       m = m.transpose().eval();
279   }
280 };
281
282 } // end namespace internal
283
284 /** This is the "in place" version of transpose(): it replaces \c *this by its own transpose.
285   * Thus, doing
286   * \code
287   * m.transposeInPlace();
288   * \endcode
289   * has the same effect on m as doing
290   * \code
291   * m = m.transpose().eval();
292   * \endcode
293   * and is faster and also safer because in the latter line of code, forgetting the eval() results
294   * in a bug caused by aliasing.
295   *
296   * Notice however that this method is only useful if you want to replace a matrix by its own transpose.
297   * If you just need the transpose of a matrix, use transpose().
298   *
299   * \note if the matrix is not square, then \c *this must be a resizable matrix.
300   *
301   * \sa transpose(), adjoint(), adjointInPlace() */
302 template<typename Derived>
303 inline void DenseBase<Derived>::transposeInPlace()
304 {
305   internal::inplace_transpose_selector<Derived>::run(derived());
306 }
307
308 /***************************************************************************
309 * "in place" adjoint implementation
310 ***************************************************************************/
311
312 /** This is the "in place" version of adjoint(): it replaces \c *this by its own transpose.
313   * Thus, doing
314   * \code
315   * m.adjointInPlace();
316   * \endcode
317   * has the same effect on m as doing
318   * \code
319   * m = m.adjoint().eval();
320   * \endcode
321   * and is faster and also safer because in the latter line of code, forgetting the eval() results
322   * in a bug caused by aliasing.
323   *
324   * Notice however that this method is only useful if you want to replace a matrix by its own adjoint.
325   * If you just need the adjoint of a matrix, use adjoint().
326   *
327   * \note if the matrix is not square, then \c *this must be a resizable matrix.
328   *
329   * \sa transpose(), adjoint(), transposeInPlace() */
330 template<typename Derived>
331 inline void MatrixBase<Derived>::adjointInPlace()
332 {
333   derived() = adjoint().eval();
334 }
335
336 #ifndef EIGEN_NO_DEBUG
337
338 // The following is to detect aliasing problems in most common cases.
339
340 namespace internal {
341
342 template<typename BinOp,typename NestedXpr,typename Rhs>
343 struct blas_traits<SelfCwiseBinaryOp<BinOp,NestedXpr,Rhs> >
344  : blas_traits<NestedXpr>
345 {
346   typedef SelfCwiseBinaryOp<BinOp,NestedXpr,Rhs> XprType;
347   static inline const XprType extract(const XprType& x) { return x; }
348 };
349
350 template<bool DestIsTransposed, typename OtherDerived>
351 struct check_transpose_aliasing_compile_time_selector
352 {
353   enum { ret = blas_traits<OtherDerived>::IsTransposed != DestIsTransposed
354   };
355 };
356
357 template<bool DestIsTransposed, typename BinOp, typename DerivedA, typename DerivedB>
358 struct check_transpose_aliasing_compile_time_selector<DestIsTransposed,CwiseBinaryOp<BinOp,DerivedA,DerivedB> >
359 {
360   enum { ret =    blas_traits<DerivedA>::IsTransposed != DestIsTransposed
361                || blas_traits<DerivedB>::IsTransposed != DestIsTransposed
362   };
363 };
364
365 template<typename Scalar, bool DestIsTransposed, typename OtherDerived>
366 struct check_transpose_aliasing_run_time_selector
367 {
368   static bool run(const Scalar* dest, const OtherDerived& src)
369   {
370     return (blas_traits<OtherDerived>::IsTransposed != DestIsTransposed) && (dest!=0 && dest==(Scalar*)extract_data(src));
371   }
372 };
373
374 template<typename Scalar, bool DestIsTransposed, typename BinOp, typename DerivedA, typename DerivedB>
375 struct check_transpose_aliasing_run_time_selector<Scalar,DestIsTransposed,CwiseBinaryOp<BinOp,DerivedA,DerivedB> >
376 {
377   static bool run(const Scalar* dest, const CwiseBinaryOp<BinOp,DerivedA,DerivedB>& src)
378   {
379     return ((blas_traits<DerivedA>::IsTransposed != DestIsTransposed) && (dest!=0 && dest==(Scalar*)extract_data(src.lhs())))
380         || ((blas_traits<DerivedB>::IsTransposed != DestIsTransposed) && (dest!=0 && dest==(Scalar*)extract_data(src.rhs())));
381   }
382 };
383
384 // the following selector, checkTransposeAliasing_impl, based on MightHaveTransposeAliasing,
385 // is because when the condition controlling the assert is known at compile time, ICC emits a warning.
386 // This is actually a good warning: in expressions that don't have any transposing, the condition is
387 // known at compile time to be false, and using that, we can avoid generating the code of the assert again
388 // and again for all these expressions that don't need it.
389
390 template<typename Derived, typename OtherDerived,
391          bool MightHaveTransposeAliasing
392                  = check_transpose_aliasing_compile_time_selector
393                      <blas_traits<Derived>::IsTransposed,OtherDerived>::ret
394         >
395 struct checkTransposeAliasing_impl
396 {
397     static void run(const Derived& dst, const OtherDerived& other)
398     {
399         eigen_assert((!check_transpose_aliasing_run_time_selector
400                       <typename Derived::Scalar,blas_traits<Derived>::IsTransposed,OtherDerived>
401                       ::run(extract_data(dst), other))
402           && "aliasing detected during tranposition, use transposeInPlace() "
403              "or evaluate the rhs into a temporary using .eval()");
404
405     }
406 };
407
408 template<typename Derived, typename OtherDerived>
409 struct checkTransposeAliasing_impl<Derived, OtherDerived, false>
410 {
411     static void run(const Derived&, const OtherDerived&)
412     {
413     }
414 };
415
416 } // end namespace internal
417
418 template<typename Derived>
419 template<typename OtherDerived>
420 void DenseBase<Derived>::checkTransposeAliasing(const OtherDerived& other) const
421 {
422     internal::checkTransposeAliasing_impl<Derived, OtherDerived>::run(derived(), other);
423 }
424 #endif
425
426 #endif // EIGEN_TRANSPOSE_H