00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #ifndef EIGEN_TRANSPOSE_H
00027 #define EIGEN_TRANSPOSE_H
00028
00029 namespace Eigen {
00030
00045 namespace internal {
00046 template<typename MatrixType>
00047 struct traits<Transpose<MatrixType> > : traits<MatrixType>
00048 {
00049 typedef typename MatrixType::Scalar Scalar;
00050 typedef typename nested<MatrixType>::type MatrixTypeNested;
00051 typedef typename remove_reference<MatrixTypeNested>::type MatrixTypeNestedPlain;
00052 typedef typename traits<MatrixType>::StorageKind StorageKind;
00053 typedef typename traits<MatrixType>::XprKind XprKind;
00054 enum {
00055 RowsAtCompileTime = MatrixType::ColsAtCompileTime,
00056 ColsAtCompileTime = MatrixType::RowsAtCompileTime,
00057 MaxRowsAtCompileTime = MatrixType::MaxColsAtCompileTime,
00058 MaxColsAtCompileTime = MatrixType::MaxRowsAtCompileTime,
00059 FlagsLvalueBit = is_lvalue<MatrixType>::value ? LvalueBit : 0,
00060 Flags0 = MatrixTypeNestedPlain::Flags & ~(LvalueBit | NestByRefBit),
00061 Flags1 = Flags0 | FlagsLvalueBit,
00062 Flags = Flags1 ^ RowMajorBit,
00063 CoeffReadCost = MatrixTypeNestedPlain::CoeffReadCost,
00064 InnerStrideAtCompileTime = inner_stride_at_compile_time<MatrixType>::ret,
00065 OuterStrideAtCompileTime = outer_stride_at_compile_time<MatrixType>::ret
00066 };
00067 };
00068 }
00069
00070 template<typename MatrixType, typename StorageKind> class TransposeImpl;
00071
00072 template<typename MatrixType> class Transpose
00073 : public TransposeImpl<MatrixType,typename internal::traits<MatrixType>::StorageKind>
00074 {
00075 public:
00076
00077 typedef typename TransposeImpl<MatrixType,typename internal::traits<MatrixType>::StorageKind>::Base Base;
00078 EIGEN_GENERIC_PUBLIC_INTERFACE(Transpose)
00079
00080 inline Transpose(MatrixType& matrix) : m_matrix(matrix) {}
00081
00082 EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Transpose)
00083
00084 inline Index rows() const { return m_matrix.cols(); }
00085 inline Index cols() const { return m_matrix.rows(); }
00086
00088 const typename internal::remove_all<typename MatrixType::Nested>::type&
00089 nestedExpression() const { return m_matrix; }
00090
00092 typename internal::remove_all<typename MatrixType::Nested>::type&
00093 nestedExpression() { return m_matrix.const_cast_derived(); }
00094
00095 protected:
00096 typename MatrixType::Nested m_matrix;
00097 };
00098
00099 namespace internal {
00100
00101 template<typename MatrixType, bool HasDirectAccess = has_direct_access<MatrixType>::ret>
00102 struct TransposeImpl_base
00103 {
00104 typedef typename dense_xpr_base<Transpose<MatrixType> >::type type;
00105 };
00106
00107 template<typename MatrixType>
00108 struct TransposeImpl_base<MatrixType, false>
00109 {
00110 typedef typename dense_xpr_base<Transpose<MatrixType> >::type type;
00111 };
00112
00113 }
00114
00115 template<typename MatrixType> class TransposeImpl<MatrixType,Dense>
00116 : public internal::TransposeImpl_base<MatrixType>::type
00117 {
00118 public:
00119
00120 typedef typename internal::TransposeImpl_base<MatrixType>::type Base;
00121 EIGEN_DENSE_PUBLIC_INTERFACE(Transpose<MatrixType>)
00122
00123 inline Index innerStride() const { return derived().nestedExpression().innerStride(); }
00124 inline Index outerStride() const { return derived().nestedExpression().outerStride(); }
00125
00126 typedef typename internal::conditional<
00127 internal::is_lvalue<MatrixType>::value,
00128 Scalar,
00129 const Scalar
00130 >::type ScalarWithConstIfNotLvalue;
00131
00132 inline ScalarWithConstIfNotLvalue* data() { return derived().nestedExpression().data(); }
00133 inline const Scalar* data() const { return derived().nestedExpression().data(); }
00134
00135 inline ScalarWithConstIfNotLvalue& coeffRef(Index row, Index col)
00136 {
00137 EIGEN_STATIC_ASSERT_LVALUE(MatrixType)
00138 return derived().nestedExpression().const_cast_derived().coeffRef(col, row);
00139 }
00140
00141 inline ScalarWithConstIfNotLvalue& coeffRef(Index index)
00142 {
00143 EIGEN_STATIC_ASSERT_LVALUE(MatrixType)
00144 return derived().nestedExpression().const_cast_derived().coeffRef(index);
00145 }
00146
00147 inline const Scalar& coeffRef(Index row, Index col) const
00148 {
00149 return derived().nestedExpression().coeffRef(col, row);
00150 }
00151
00152 inline const Scalar& coeffRef(Index index) const
00153 {
00154 return derived().nestedExpression().coeffRef(index);
00155 }
00156
00157 inline CoeffReturnType coeff(Index row, Index col) const
00158 {
00159 return derived().nestedExpression().coeff(col, row);
00160 }
00161
00162 inline CoeffReturnType coeff(Index index) const
00163 {
00164 return derived().nestedExpression().coeff(index);
00165 }
00166
00167 template<int LoadMode>
00168 inline const PacketScalar packet(Index row, Index col) const
00169 {
00170 return derived().nestedExpression().template packet<LoadMode>(col, row);
00171 }
00172
00173 template<int LoadMode>
00174 inline void writePacket(Index row, Index col, const PacketScalar& x)
00175 {
00176 derived().nestedExpression().const_cast_derived().template writePacket<LoadMode>(col, row, x);
00177 }
00178
00179 template<int LoadMode>
00180 inline const PacketScalar packet(Index index) const
00181 {
00182 return derived().nestedExpression().template packet<LoadMode>(index);
00183 }
00184
00185 template<int LoadMode>
00186 inline void writePacket(Index index, const PacketScalar& x)
00187 {
00188 derived().nestedExpression().const_cast_derived().template writePacket<LoadMode>(index, x);
00189 }
00190 };
00191
00211 template<typename Derived>
00212 inline Transpose<Derived>
00213 DenseBase<Derived>::transpose()
00214 {
00215 return derived();
00216 }
00217
00223 template<typename Derived>
00224 inline const typename DenseBase<Derived>::ConstTransposeReturnType
00225 DenseBase<Derived>::transpose() const
00226 {
00227 return ConstTransposeReturnType(derived());
00228 }
00229
00249 template<typename Derived>
00250 inline const typename MatrixBase<Derived>::AdjointReturnType
00251 MatrixBase<Derived>::adjoint() const
00252 {
00253 return this->transpose();
00254
00255 }
00256
00257
00258
00259
00260
00261 namespace internal {
00262
00263 template<typename MatrixType,
00264 bool IsSquare = (MatrixType::RowsAtCompileTime == MatrixType::ColsAtCompileTime) && MatrixType::RowsAtCompileTime!=Dynamic>
00265 struct inplace_transpose_selector;
00266
00267 template<typename MatrixType>
00268 struct inplace_transpose_selector<MatrixType,true> {
00269 static void run(MatrixType& m) {
00270 m.template triangularView<StrictlyUpper>().swap(m.transpose());
00271 }
00272 };
00273
00274 template<typename MatrixType>
00275 struct inplace_transpose_selector<MatrixType,false> {
00276 static void run(MatrixType& m) {
00277 if (m.rows()==m.cols())
00278 m.template triangularView<StrictlyUpper>().swap(m.transpose());
00279 else
00280 m = m.transpose().eval();
00281 }
00282 };
00283
00284 }
00285
00304 template<typename Derived>
00305 inline void DenseBase<Derived>::transposeInPlace()
00306 {
00307 internal::inplace_transpose_selector<Derived>::run(derived());
00308 }
00309
00310
00311
00312
00313
00332 template<typename Derived>
00333 inline void MatrixBase<Derived>::adjointInPlace()
00334 {
00335 derived() = adjoint().eval();
00336 }
00337
00338 #ifndef EIGEN_NO_DEBUG
00339
00340
00341
00342 namespace internal {
00343
00344 template<typename BinOp,typename NestedXpr,typename Rhs>
00345 struct blas_traits<SelfCwiseBinaryOp<BinOp,NestedXpr,Rhs> >
00346 : blas_traits<NestedXpr>
00347 {
00348 typedef SelfCwiseBinaryOp<BinOp,NestedXpr,Rhs> XprType;
00349 static inline const XprType extract(const XprType& x) { return x; }
00350 };
00351
00352 template<bool DestIsTransposed, typename OtherDerived>
00353 struct check_transpose_aliasing_compile_time_selector
00354 {
00355 enum { ret = bool(blas_traits<OtherDerived>::IsTransposed) != DestIsTransposed };
00356 };
00357
00358 template<bool DestIsTransposed, typename BinOp, typename DerivedA, typename DerivedB>
00359 struct check_transpose_aliasing_compile_time_selector<DestIsTransposed,CwiseBinaryOp<BinOp,DerivedA,DerivedB> >
00360 {
00361 enum { ret = bool(blas_traits<DerivedA>::IsTransposed) != DestIsTransposed
00362 || bool(blas_traits<DerivedB>::IsTransposed) != DestIsTransposed
00363 };
00364 };
00365
00366 template<typename Scalar, bool DestIsTransposed, typename OtherDerived>
00367 struct check_transpose_aliasing_run_time_selector
00368 {
00369 static bool run(const Scalar* dest, const OtherDerived& src)
00370 {
00371 return (bool(blas_traits<OtherDerived>::IsTransposed) != DestIsTransposed) && (dest!=0 && dest==(Scalar*)extract_data(src));
00372 }
00373 };
00374
00375 template<typename Scalar, bool DestIsTransposed, typename BinOp, typename DerivedA, typename DerivedB>
00376 struct check_transpose_aliasing_run_time_selector<Scalar,DestIsTransposed,CwiseBinaryOp<BinOp,DerivedA,DerivedB> >
00377 {
00378 static bool run(const Scalar* dest, const CwiseBinaryOp<BinOp,DerivedA,DerivedB>& src)
00379 {
00380 return ((blas_traits<DerivedA>::IsTransposed != DestIsTransposed) && (dest!=0 && dest==(Scalar*)extract_data(src.lhs())))
00381 || ((blas_traits<DerivedB>::IsTransposed != DestIsTransposed) && (dest!=0 && dest==(Scalar*)extract_data(src.rhs())));
00382 }
00383 };
00384
00385
00386
00387
00388
00389
00390
00391 template<typename Derived, typename OtherDerived,
00392 bool MightHaveTransposeAliasing
00393 = check_transpose_aliasing_compile_time_selector
00394 <blas_traits<Derived>::IsTransposed,OtherDerived>::ret
00395 >
00396 struct checkTransposeAliasing_impl
00397 {
00398 static void run(const Derived& dst, const OtherDerived& other)
00399 {
00400 eigen_assert((!check_transpose_aliasing_run_time_selector
00401 <typename Derived::Scalar,blas_traits<Derived>::IsTransposed,OtherDerived>
00402 ::run(extract_data(dst), other))
00403 && "aliasing detected during tranposition, use transposeInPlace() "
00404 "or evaluate the rhs into a temporary using .eval()");
00405
00406 }
00407 };
00408
00409 template<typename Derived, typename OtherDerived>
00410 struct checkTransposeAliasing_impl<Derived, OtherDerived, false>
00411 {
00412 static void run(const Derived&, const OtherDerived&)
00413 {
00414 }
00415 };
00416
00417 }
00418
00419 template<typename Derived>
00420 template<typename OtherDerived>
00421 void DenseBase<Derived>::checkTransposeAliasing(const OtherDerived& other) const
00422 {
00423 internal::checkTransposeAliasing_impl<Derived, OtherDerived>::run(derived(), other);
00424 }
00425 #endif
00426
00427 }
00428
00429 #endif // EIGEN_TRANSPOSE_H