aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Gael Guennebaud <g.gael@free.fr>2009-12-16 11:41:16 +0100
committerGravatar Gael Guennebaud <g.gael@free.fr>2009-12-16 11:41:16 +0100
commit6db6774c4685b997ab4343e5c5b4d48af84e45e7 (patch)
tree6e0a2bb73d959179b735a7cebb588cb72cdef570
parent0d8ffe5240e4324a6ada046eeb2c2bb25b36af9a (diff)
* fix aliasing checks when the lhs is also transposed. At the same time,
significantly simplify the code of these checks while extending them to catch much more expressions! * move the enabling/disabling of vectorized sin/cos to the architecture traits
-rw-r--r--Eigen/src/Array/Functors.h4
-rw-r--r--Eigen/src/Core/Assign.h3
-rw-r--r--Eigen/src/Core/MatrixBase.h23
-rw-r--r--Eigen/src/Core/Transpose.h78
-rw-r--r--Eigen/src/Core/arch/SSE/PacketMath.h4
-rw-r--r--Eigen/src/Core/util/BlasUtil.h4
-rw-r--r--test/adjoint.cpp8
7 files changed, 46 insertions, 78 deletions
diff --git a/Eigen/src/Array/Functors.h b/Eigen/src/Array/Functors.h
index fd259f7bc..120c56cc1 100644
--- a/Eigen/src/Array/Functors.h
+++ b/Eigen/src/Array/Functors.h
@@ -87,7 +87,7 @@ struct ei_functor_traits<ei_scalar_cos_op<Scalar> >
{
enum {
Cost = 5 * NumTraits<Scalar>::MulCost,
- PacketAccess = ei_packet_traits<Scalar>::HasCos && EIGEN_FAST_MATH
+ PacketAccess = ei_packet_traits<Scalar>::HasCos
};
};
@@ -109,7 +109,7 @@ struct ei_functor_traits<ei_scalar_sin_op<Scalar> >
{
enum {
Cost = 5 * NumTraits<Scalar>::MulCost,
- PacketAccess = ei_packet_traits<Scalar>::HasSin && EIGEN_FAST_MATH
+ PacketAccess = ei_packet_traits<Scalar>::HasSin
};
};
diff --git a/Eigen/src/Core/Assign.h b/Eigen/src/Core/Assign.h
index 00febdc5d..d544a6198 100644
--- a/Eigen/src/Core/Assign.h
+++ b/Eigen/src/Core/Assign.h
@@ -485,6 +485,9 @@ EIGEN_STRONG_INLINE Derived& MatrixBase<Derived>
#ifdef EIGEN_DEBUG_ASSIGN
ei_assign_traits<Derived, OtherDerived>::debug();
#endif
+#ifndef EIGEN_NO_DEBUG
+ checkTransposeAliasing(other.derived());
+#endif
return derived();
}
diff --git a/Eigen/src/Core/MatrixBase.h b/Eigen/src/Core/MatrixBase.h
index 03d8d5f55..593108522 100644
--- a/Eigen/src/Core/MatrixBase.h
+++ b/Eigen/src/Core/MatrixBase.h
@@ -436,21 +436,12 @@ template<typename Derived> class MatrixBase
void transposeInPlace();
const AdjointReturnType adjoint() const;
void adjointInPlace();
- #ifndef EIGEN_NO_DEBUG
- template<typename OtherDerived>
- Derived& lazyAssign(const Transpose<OtherDerived>& other);
- template<typename DerivedA, typename DerivedB>
- Derived& lazyAssign(const CwiseBinaryOp<ei_scalar_sum_op<Scalar>,Transpose<DerivedA>,DerivedB>& other);
- template<typename DerivedA, typename DerivedB>
- Derived& lazyAssign(const CwiseBinaryOp<ei_scalar_sum_op<Scalar>,DerivedA,Transpose<DerivedB> >& other);
-
+#ifndef EIGEN_NO_DEBUG
+ protected:
template<typename OtherDerived>
- Derived& lazyAssign(const CwiseUnaryOp<ei_scalar_conjugate_op<Scalar>, Eigen::Transpose<OtherDerived> >& other);
- template<typename DerivedA, typename DerivedB>
- Derived& lazyAssign(const CwiseBinaryOp<ei_scalar_sum_op<Scalar>,CwiseUnaryOp<ei_scalar_conjugate_op<Scalar>, Eigen::Transpose<DerivedA> >,DerivedB>& other);
- template<typename DerivedA, typename DerivedB>
- Derived& lazyAssign(const CwiseBinaryOp<ei_scalar_sum_op<Scalar>,DerivedA,CwiseUnaryOp<ei_scalar_conjugate_op<Scalar>, Eigen::Transpose<DerivedB> > >& other);
- #endif
+ void checkTransposeAliasing(const OtherDerived& other) const;
+ public:
+#endif
RowXpr row(int i);
const RowXpr row(int i) const;
@@ -638,7 +629,7 @@ template<typename Derived> class MatrixBase
const CwiseBinaryOp<CustomBinaryOp, Derived, OtherDerived>
binaryExpr(const MatrixBase<OtherDerived> &other, const CustomBinaryOp& func = CustomBinaryOp()) const;
-
+
Scalar sum() const;
Scalar mean() const;
Scalar trace() const;
@@ -818,7 +809,7 @@ template<typename Derived> class MatrixBase
INVALID_MATRIXBASE_TEMPLATE_PARAMETERS)
#endif
}
-
+
private:
explicit MatrixBase(int);
MatrixBase(int,int);
diff --git a/Eigen/src/Core/Transpose.h b/Eigen/src/Core/Transpose.h
index 79aef9fa7..796ec8573 100644
--- a/Eigen/src/Core/Transpose.h
+++ b/Eigen/src/Core/Transpose.h
@@ -268,13 +268,7 @@ inline void MatrixBase<Derived>::adjointInPlace()
#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()
+// The following is to detect aliasing problems in most common cases.
template<typename T, int Access=ei_blas_traits<T>::ActualAccess>
struct ei_extract_data_selector {
@@ -294,63 +288,31 @@ 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>, Eigen::Transpose<OtherDerived> >& other)
+template<typename Scalar, bool DestIsTranposed, typename OtherDerived>
+struct ei_check_transpose_aliasing_selector
{
- 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>, Eigen::Transpose<OtherDerived> > >& >(other));
-}
+ static bool run(const Scalar* dest, const OtherDerived& src)
+ {
+ return (ei_blas_traits<OtherDerived>::IsTransposed != DestIsTranposed) && (dest==ei_extract_data(src));
+ }
+};
-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>, Eigen::Transpose<DerivedA> >,DerivedB>& other)
+template<typename Scalar, bool DestIsTranposed, typename BinOp, typename DerivedA, typename DerivedB>
+struct ei_check_transpose_aliasing_selector<Scalar,DestIsTranposed,CwiseBinaryOp<BinOp,DerivedA,DerivedB> >
{
- 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>, Eigen::Transpose<DerivedA> >,DerivedB> >& >(other));
-}
+ static bool run(const Scalar* dest, const CwiseBinaryOp<BinOp,DerivedA,DerivedB>& src)
+ {
+ return ((ei_blas_traits<DerivedA>::IsTransposed != DestIsTranposed) && dest==ei_extract_data(src.lhs()))
+ || ((ei_blas_traits<DerivedB>::IsTransposed != DestIsTranposed) && dest==ei_extract_data(src.rhs()));
+ }
+};
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>, Eigen::Transpose<DerivedB> > >& other)
+template<typename OtherDerived>
+void MatrixBase<Derived>::checkTransposeAliasing(const OtherDerived& other) const
{
- 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>, Eigen::Transpose<DerivedB> > > >& >(other));
+ ei_assert((!ei_check_transpose_aliasing_selector<Scalar,ei_blas_traits<Derived>::IsTransposed,OtherDerived>::run(ei_extract_data(derived()), other))
+ && "aliasing detected during tranposition, use transposeInPlace() or evaluate the rhs into a temporary using .eval()");
}
#endif
diff --git a/Eigen/src/Core/arch/SSE/PacketMath.h b/Eigen/src/Core/arch/SSE/PacketMath.h
index 69f6979bd..dbdddb38d 100644
--- a/Eigen/src/Core/arch/SSE/PacketMath.h
+++ b/Eigen/src/Core/arch/SSE/PacketMath.h
@@ -58,8 +58,8 @@ template<> struct ei_packet_traits<float> : ei_default_packet_traits
{
typedef Packet4f type; enum {size=4};
enum {
- HasSin = 1,
- HasCos = 1,
+ HasSin = EIGEN_FAST_MATH,
+ HasCos = EIGEN_FAST_MATH,
HasLog = 1,
HasExp = 1,
HasSqrt = 1
diff --git a/Eigen/src/Core/util/BlasUtil.h b/Eigen/src/Core/util/BlasUtil.h
index a012a6e12..fa21ceebb 100644
--- a/Eigen/src/Core/util/BlasUtil.h
+++ b/Eigen/src/Core/util/BlasUtil.h
@@ -160,6 +160,7 @@ template<typename XprType> struct ei_blas_traits
typedef XprType _ExtractType;
enum {
IsComplex = NumTraits<Scalar>::IsComplex,
+ IsTransposed = false,
NeedToConjugate = false,
ActualAccess = int(ei_traits<XprType>::Flags)&DirectAccessBit ? HasDirectAccess : NoDirectAccess
};
@@ -227,6 +228,9 @@ struct ei_blas_traits<Transpose<NestedXpr> >
ExtractType,
typename ExtractType::PlainMatrixType
>::ret DirectLinearAccessType;
+ enum {
+ IsTransposed = Base::IsTransposed ? 0 : 1
+ };
static inline const ExtractType extract(const XprType& x) { return Base::extract(x._expression()); }
static inline Scalar extractScalarFactor(const XprType& x) { return Base::extractScalarFactor(x._expression()); }
};
diff --git a/test/adjoint.cpp b/test/adjoint.cpp
index 344399257..b34112249 100644
--- a/test/adjoint.cpp
+++ b/test/adjoint.cpp
@@ -128,6 +128,14 @@ void test_adjoint()
VERIFY_RAISES_ASSERT(a = a.adjoint());
VERIFY_RAISES_ASSERT(a = a.adjoint() + b);
VERIFY_RAISES_ASSERT(a = b + a.adjoint());
+
+ // no assertion should be triggered for these cases:
+ a.transpose() = a.transpose();
+ a.transpose() += a.transpose();
+ a.transpose() += a.transpose() + b;
+ a.transpose() = a.adjoint();
+ a.transpose() += a.adjoint();
+ a.transpose() += a.adjoint() + b;
}
#endif
}