diff options
author | Gael Guennebaud <g.gael@free.fr> | 2008-10-29 15:24:08 +0000 |
---|---|---|
committer | Gael Guennebaud <g.gael@free.fr> | 2008-10-29 15:24:08 +0000 |
commit | ebe14aae7d39fb16d173d8db68e0ea439c4f87fc (patch) | |
tree | 79d6a94c70cc0a15e6f854a3dc7fe7607a8f8c79 /Eigen | |
parent | 48137e28d8abe8464ffbc422333e26b91cd8e3b0 (diff) |
add transposeInPlace (not optimized yet for rectangular matrix)
Diffstat (limited to 'Eigen')
-rw-r--r-- | Eigen/src/Core/MatrixBase.h | 1 | ||||
-rw-r--r-- | Eigen/src/Core/Part.h | 18 | ||||
-rw-r--r-- | Eigen/src/Core/Transpose.h | 45 |
3 files changed, 58 insertions, 6 deletions
diff --git a/Eigen/src/Core/MatrixBase.h b/Eigen/src/Core/MatrixBase.h index 496684198..a9fe26555 100644 --- a/Eigen/src/Core/MatrixBase.h +++ b/Eigen/src/Core/MatrixBase.h @@ -337,6 +337,7 @@ template<typename Derived> class MatrixBase Transpose<Derived> transpose(); const Transpose<Derived> transpose() const; + void transposeInPlace(); const AdjointReturnType adjoint() const; diff --git a/Eigen/src/Core/Part.h b/Eigen/src/Core/Part.h index aed771210..2a17a7f71 100644 --- a/Eigen/src/Core/Part.h +++ b/Eigen/src/Core/Part.h @@ -119,6 +119,12 @@ template<typename MatrixType, unsigned int Mode> class Part const Block<Part, RowsAtCompileTime, 1> col(int i) { return Base::col(i); } const Block<Part, RowsAtCompileTime, 1> col(int i) const { return Base::col(i); } + template<typename OtherDerived/*, int OtherMode*/> + void swap(const MatrixBase<OtherDerived>& other) + { + Part<SwapWrapper<MatrixType>,Mode>(SwapWrapper<MatrixType>(const_cast<MatrixType&>(m_matrix))).lazyAssign(other.derived()); + } + protected: const typename MatrixType::Nested m_matrix; @@ -184,7 +190,7 @@ struct ei_part_assignment_impl || (Mode == Lower && row >= col) || (Mode == StrictlyUpper && row < col) || (Mode == StrictlyLower && row > col)) - dst.coeffRef(row, col) = src.coeff(row, col); + dst.copyCoeff(row, col, src); } } }; @@ -195,7 +201,7 @@ struct ei_part_assignment_impl<Derived1, Derived2, Mode, 1> inline static void run(Derived1 &dst, const Derived2 &src) { if(!(Mode & ZeroDiagBit)) - dst.coeffRef(0, 0) = src.coeff(0, 0); + dst.copyCoeff(0, 0, src); } }; @@ -213,7 +219,7 @@ struct ei_part_assignment_impl<Derived1, Derived2, Upper, Dynamic> { for(int j = 0; j < dst.cols(); j++) for(int i = 0; i <= j; i++) - dst.coeffRef(i, j) = src.coeff(i, j); + dst.copyCoeff(i, j, src); } }; @@ -224,7 +230,7 @@ struct ei_part_assignment_impl<Derived1, Derived2, Lower, Dynamic> { for(int j = 0; j < dst.cols(); j++) for(int i = j; i < dst.rows(); i++) - dst.coeffRef(i, j) = src.coeff(i, j); + dst.copyCoeff(i, j, src); } }; @@ -235,7 +241,7 @@ struct ei_part_assignment_impl<Derived1, Derived2, StrictlyUpper, Dynamic> { for(int j = 0; j < dst.cols(); j++) for(int i = 0; i < j; i++) - dst.coeffRef(i, j) = src.coeff(i, j); + dst.copyCoeff(i, j, src); } }; template<typename Derived1, typename Derived2> @@ -245,7 +251,7 @@ struct ei_part_assignment_impl<Derived1, Derived2, StrictlyLower, Dynamic> { for(int j = 0; j < dst.cols(); j++) for(int i = j+1; i < dst.rows(); i++) - dst.coeffRef(i, j) = src.coeff(i, j); + dst.copyCoeff(i, j, src); } }; template<typename Derived1, typename Derived2> diff --git a/Eigen/src/Core/Transpose.h b/Eigen/src/Core/Transpose.h index dba19f025..30d274e75 100644 --- a/Eigen/src/Core/Transpose.h +++ b/Eigen/src/Core/Transpose.h @@ -156,4 +156,49 @@ MatrixBase<Derived>::adjoint() const return conjugate().nestByValue(); } +/*************************************************************************** +* "in place" transpose implementation +***************************************************************************/ + +template<typename MatrixType, + bool IsSquare = (MatrixType::RowsAtCompileTime == MatrixType::ColsAtCompileTime) && MatrixType::RowsAtCompileTime!=Dynamic> +struct ei_inplace_transpose_selector; + +template<typename MatrixType> +struct ei_inplace_transpose_selector<MatrixType,true> { // square matrix + static void run(MatrixType& m) { + m.template part<StrictlyUpper>().swap(m.transpose()); + } +}; + +template<typename MatrixType> +struct ei_inplace_transpose_selector<MatrixType,false> { // non square matrix + static void run(MatrixType& m) { + if (m.rows()==m.cols()) + m.template part<StrictlyUpper>().swap(m.transpose()); + else + m.set(m.transpose().eval()); + } +}; + +/** This is the "in place" version of transpose: it transposes \c *this. + * + * In most cases it is probably better to simply use the transposed expression + * of a matrix. However, when transposing the matrix data itself is really needed, + * then this "in-place" version is probably the right choice because it provides + * the following additional features: + * - less error prone: doing the same operation with .transpose() requires special care: + * \code m.set(m.transpose().eval()); \endcode + * - no temporary object is created (currently only for squared matrices) + * - it allows future optimizations (cache friendliness, etc.) + * + * \note if the matrix is not square, then \c *this must be a resizable matrix. + * + * \sa transpose(), adjoint() */ +template<typename Derived> +inline void MatrixBase<Derived>::transposeInPlace() +{ + ei_inplace_transpose_selector<Derived>::run(derived()); +} + #endif // EIGEN_TRANSPOSE_H |