aboutsummaryrefslogtreecommitdiffhomepage
path: root/Eigen/src/Core/Reverse.h
diff options
context:
space:
mode:
authorGravatar Gael Guennebaud <g.gael@free.fr>2015-03-31 21:35:53 +0200
committerGravatar Gael Guennebaud <g.gael@free.fr>2015-03-31 21:35:53 +0200
commit8313fb7df7f5f116834b412d6a6f5aff8862a173 (patch)
tree7d2ade8fe6b1b1fe49006ac8eab9e768ff75432e /Eigen/src/Core/Reverse.h
parentdfb674a25ead137118eebf0230c4c8a4c81db5d0 (diff)
Add row/column-wise reverseInPlace feature.
Diffstat (limited to 'Eigen/src/Core/Reverse.h')
-rw-r--r--Eigen/src/Core/Reverse.h52
1 files changed, 49 insertions, 3 deletions
diff --git a/Eigen/src/Core/Reverse.h b/Eigen/src/Core/Reverse.h
index b3fba9704..5237fbf1c 100644
--- a/Eigen/src/Core/Reverse.h
+++ b/Eigen/src/Core/Reverse.h
@@ -200,13 +200,13 @@ DenseBase<Derived>::reverse() const
* In most cases it is probably better to simply use the reversed expression
* of a matrix. However, when reversing the matrix data itself is really needed,
* then this "in-place" version is probably the right choice because it provides
- * the following additional features:
+ * the following additional benefits:
* - less error prone: doing the same operation with .reverse() requires special care:
* \code m = m.reverse().eval(); \endcode
- * - this API allows to avoid creating a temporary (the current implementation creates a temporary, but that could be avoided using swap)
+ * - this API enables reverse operations without the need for a temporary
* - it allows future optimizations (cache friendliness, etc.)
*
- * \sa reverse() */
+ * \sa VectorwiseOp::reverseInPlace(), reverse() */
template<typename Derived>
inline void DenseBase<Derived>::reverseInPlace()
{
@@ -232,6 +232,52 @@ inline void DenseBase<Derived>::reverseInPlace()
}
}
+namespace internal {
+
+template<int Direction>
+struct vectorwise_reverse_inplace_impl;
+
+template<>
+struct vectorwise_reverse_inplace_impl<Vertical>
+{
+ template<typename ExpressionType>
+ static void run(ExpressionType &xpr)
+ {
+ Index half = xpr.rows()/2;
+ xpr.topRows(half).swap(xpr.bottomRows(half).colwise().reverse());
+ }
+};
+
+template<>
+struct vectorwise_reverse_inplace_impl<Horizontal>
+{
+ template<typename ExpressionType>
+ static void run(ExpressionType &xpr)
+ {
+ Index half = xpr.cols()/2;
+ xpr.leftCols(half).swap(xpr.rightCols(half).rowwise().reverse());
+ }
+};
+
+} // end namespace internal
+
+/** This is the "in place" version of VectorwiseOp::reverse: it reverses each column or row of \c *this.
+ *
+ * In most cases it is probably better to simply use the reversed expression
+ * of a matrix. However, when reversing the matrix data itself is really needed,
+ * then this "in-place" version is probably the right choice because it provides
+ * the following additional benefits:
+ * - less error prone: doing the same operation with .reverse() requires special care:
+ * \code m = m.reverse().eval(); \endcode
+ * - this API enables reverse operations without the need for a temporary
+ *
+ * \sa DenseBase::reverseInPlace(), reverse() */
+template<typename ExpressionType, int Direction>
+void VectorwiseOp<ExpressionType,Direction>::reverseInPlace()
+{
+ internal::vectorwise_reverse_inplace_impl<Direction>::run(_expression().const_cast_derived());
+}
+
} // end namespace Eigen
#endif // EIGEN_REVERSE_H