Eigne Matrix Class Library

Dependents:   MPC_current_control HydraulicControlBoard_SW AHRS Test_ekf ... more

Committer:
jsoh91
Date:
Tue Sep 24 00:18:23 2019 +0000
Revision:
1:3b8049da21b8
Parent:
0:13a5d365ba16
ignore and revise some of error parts

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