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