aboutsummaryrefslogtreecommitdiffhomepage
path: root/Eigen/src/Core/Transpose.h
diff options
context:
space:
mode:
authorGravatar Gael Guennebaud <g.gael@free.fr>2009-08-15 22:19:29 +0200
committerGravatar Gael Guennebaud <g.gael@free.fr>2009-08-15 22:19:29 +0200
commit239ada95b7680c75f793086eaa35fe7ec1047204 (patch)
tree88a7f107a3866e1c7f284feb818fbbc2cd22ffa3 /Eigen/src/Core/Transpose.h
parenta3e6047c25a4cbc2153974e04fe124c5776a23c0 (diff)
add overloads of lazyAssign to detect common aliasing issue with
transpose and adjoint
Diffstat (limited to 'Eigen/src/Core/Transpose.h')
-rw-r--r--Eigen/src/Core/Transpose.h88
1 files changed, 88 insertions, 0 deletions
diff --git a/Eigen/src/Core/Transpose.h b/Eigen/src/Core/Transpose.h
index 0787daa61..8527edc2a 100644
--- a/Eigen/src/Core/Transpose.h
+++ b/Eigen/src/Core/Transpose.h
@@ -267,4 +267,92 @@ inline void MatrixBase<Derived>::adjointInPlace()
derived() = adjoint().eval();
}
+#ifndef EIGEN_NO_DEBUG
+
+// The following is to detect aliasing problems in the following common cases:
+// a = a.transpose()
+// a = a.transpose() + X
+// a = X + a.transpose()
+// a = a.adjoint()
+// a = a.adjoint() + X
+// a = X + a.adjoint()
+
+template<typename T, int Access=ei_blas_traits<T>::ActualAccess>
+struct ei_extract_data_selector {
+ static typename T::Scalar* run(const T& m)
+ {
+ return &ei_blas_traits<T>::extract(m).const_cast_derived().coeffRef(0,0);
+ }
+};
+
+template<typename T>
+struct ei_extract_data_selector<T,NoDirectAccess> {
+ static typename T::Scalar* run(const T&) { return 0; }
+};
+
+template<typename T> typename T::Scalar* ei_extract_data(const T& m)
+{
+ return ei_extract_data_selector<T>::run(m);
+}
+
+template<typename Derived>
+template<typename OtherDerived>
+Derived& MatrixBase<Derived>::lazyAssign(const Transpose<OtherDerived>& other)
+{
+ ei_assert(ei_extract_data(other) != ei_extract_data(derived())
+ && "aliasing detected during tranposition, please use transposeInPlace()");
+ return lazyAssign(static_cast<const MatrixBase<Transpose<OtherDerived> >& >(other));
+}
+
+template<typename Derived>
+template<typename DerivedA, typename DerivedB>
+Derived& MatrixBase<Derived>::
+lazyAssign(const CwiseBinaryOp<ei_scalar_sum_op<Scalar>,Transpose<DerivedA>,DerivedB>& other)
+{
+ ei_assert(ei_extract_data(derived()) != ei_extract_data(other.lhs())
+ && "aliasing detected during tranposition, please evaluate your expression");
+ return lazyAssign(static_cast<const MatrixBase<CwiseBinaryOp<ei_scalar_sum_op<Scalar>,Transpose<DerivedA>,DerivedB> >& >(other));
+}
+
+template<typename Derived>
+template<typename DerivedA, typename DerivedB>
+Derived& MatrixBase<Derived>::
+lazyAssign(const CwiseBinaryOp<ei_scalar_sum_op<Scalar>,DerivedA,Transpose<DerivedB> >& other)
+{
+ ei_assert(ei_extract_data(derived()) != ei_extract_data(other.rhs())
+ && "aliasing detected during tranposition, please evaluate your expression");
+ return lazyAssign(static_cast<const MatrixBase<CwiseBinaryOp<ei_scalar_sum_op<Scalar>,DerivedA,Transpose<DerivedB> > >& >(other));
+}
+
+template<typename Derived>
+template<typename OtherDerived> Derived&
+MatrixBase<Derived>::
+lazyAssign(const CwiseUnaryOp<ei_scalar_conjugate_op<Scalar>, NestByValue<Eigen::Transpose<OtherDerived> > >& other)
+{
+ ei_assert(ei_extract_data(other) != ei_extract_data(derived())
+ && "aliasing detected during tranposition, please use adjointInPlace()");
+ return lazyAssign(static_cast<const MatrixBase<CwiseUnaryOp<ei_scalar_conjugate_op<Scalar>, NestByValue<Eigen::Transpose<OtherDerived> > > >& >(other));
+}
+
+template<typename Derived>
+template<typename DerivedA, typename DerivedB>
+Derived& MatrixBase<Derived>::
+lazyAssign(const CwiseBinaryOp<ei_scalar_sum_op<Scalar>,CwiseUnaryOp<ei_scalar_conjugate_op<Scalar>, NestByValue<Eigen::Transpose<DerivedA> > >,DerivedB>& other)
+{
+ ei_assert(ei_extract_data(derived()) != ei_extract_data(other.lhs())
+ && "aliasing detected during tranposition, please evaluate your expression");
+ return lazyAssign(static_cast<const MatrixBase<CwiseBinaryOp<ei_scalar_sum_op<Scalar>,CwiseUnaryOp<ei_scalar_conjugate_op<Scalar>, NestByValue<Eigen::Transpose<DerivedA> > >,DerivedB> >& >(other));
+}
+
+template<typename Derived>
+template<typename DerivedA, typename DerivedB>
+Derived& MatrixBase<Derived>::
+lazyAssign(const CwiseBinaryOp<ei_scalar_sum_op<Scalar>,DerivedA,CwiseUnaryOp<ei_scalar_conjugate_op<Scalar>, NestByValue<Eigen::Transpose<DerivedB> > > >& other)
+{
+ ei_assert(ei_extract_data(derived()) != ei_extract_data(other.rhs())
+ && "aliasing detected during tranposition, please evaluate your expression");
+ return lazyAssign(static_cast<const MatrixBase<CwiseBinaryOp<ei_scalar_sum_op<Scalar>,DerivedA,CwiseUnaryOp<ei_scalar_conjugate_op<Scalar>, NestByValue<Eigen::Transpose<DerivedB> > > > >& >(other));
+}
+#endif
+
#endif // EIGEN_TRANSPOSE_H