aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Gael Guennebaud <g.gael@free.fr>2008-10-29 15:24:08 +0000
committerGravatar Gael Guennebaud <g.gael@free.fr>2008-10-29 15:24:08 +0000
commitebe14aae7d39fb16d173d8db68e0ea439c4f87fc (patch)
tree79d6a94c70cc0a15e6f854a3dc7fe7607a8f8c79
parent48137e28d8abe8464ffbc422333e26b91cd8e3b0 (diff)
add transposeInPlace (not optimized yet for rectangular matrix)
-rw-r--r--Eigen/src/Core/MatrixBase.h1
-rw-r--r--Eigen/src/Core/Part.h18
-rw-r--r--Eigen/src/Core/Transpose.h45
-rw-r--r--test/adjoint.cpp8
4 files changed, 66 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
diff --git a/test/adjoint.cpp b/test/adjoint.cpp
index 9a50e076e..18256a124 100644
--- a/test/adjoint.cpp
+++ b/test/adjoint.cpp
@@ -90,6 +90,14 @@ template<typename MatrixType> void adjoint(const MatrixType& m)
// normalized() in order to produce a consistent result.
VERIFY_IS_APPROX(VectorType::Random(rows).normalized().norm(), RealScalar(1));
}
+
+ // check inplace transpose
+ m3 = m1;
+ m3.transposeInPlace();
+ VERIFY_IS_APPROX(m3,m1.transpose());
+ m3.transposeInPlace();
+ VERIFY_IS_APPROX(m3,m1);
+
}
void test_adjoint()