* Make ReturnByValue have the EvalBeforeAssigningBit and explicitly
enforce this mechanism (otherwise ReturnByValue bypasses it). (use .noalias() to get the old behavior.) * Remove a hack in Inverse, futile optimization for 2x2 expressions.
This commit is contained in:
		
							parent
							
								
									48b8ace517
								
							
						
					
					
						commit
						641d968a9a
					
				| @ -45,12 +45,18 @@ class NoAlias | ||||
|   public: | ||||
|     NoAlias(ExpressionType& expression) : m_expression(expression) {} | ||||
| 
 | ||||
|     /** Behaves like MatrixBase::lazyAssign(other)
 | ||||
|       * \sa MatrixBase::lazyAssign() */ | ||||
|     /* \sa MatrixBase::lazyAssign() */ | ||||
|     template<typename OtherDerived> | ||||
|     EIGEN_STRONG_INLINE ExpressionType& operator=(const StorageBase<OtherDerived>& other) | ||||
|     { return m_expression.lazyAssign(other.derived()); } | ||||
| 
 | ||||
|     template<typename OtherDerived> | ||||
|     EIGEN_STRONG_INLINE ExpressionType& operator=(const ReturnByValue<OtherDerived>& other) | ||||
|     { | ||||
|       other.evalTo(m_expression); | ||||
|       return m_expression; | ||||
|     } | ||||
| 
 | ||||
|     /** \sa MatrixBase::operator+= */ | ||||
|     template<typename OtherDerived> | ||||
|     EIGEN_STRONG_INLINE ExpressionType& operator+=(const StorageBase<OtherDerived>& other) | ||||
|  | ||||
| @ -36,9 +36,9 @@ struct ei_traits<ReturnByValue<Derived> > | ||||
|   enum { | ||||
|     // We're disabling the DirectAccess because e.g. the constructor of
 | ||||
|     // the Block-with-DirectAccess expression requires to have a coeffRef method.
 | ||||
|     // Also, we don't want to have to implement the stride stuff.
 | ||||
|     // FIXME this should be fixed so we can have DirectAccessBit here.
 | ||||
|     Flags = (ei_traits<typename ei_traits<Derived>::ReturnType>::Flags | ||||
|              | EvalBeforeNestingBit) & ~DirectAccessBit | ||||
|              | EvalBeforeNestingBit | EvalBeforeAssigningBit) & ~DirectAccessBit | ||||
|   }; | ||||
| }; | ||||
| 
 | ||||
| @ -83,8 +83,11 @@ template<typename Derived> | ||||
| template<typename OtherDerived> | ||||
| Derived& DenseBase<Derived>::operator=(const ReturnByValue<OtherDerived>& other) | ||||
| { | ||||
|   other.evalTo(derived()); | ||||
|   return derived(); | ||||
|   // since we're by-passing the mechanisms in Assign.h, we implement here the EvalBeforeAssigningBit.
 | ||||
|   // override by using .noalias(), see corresponding operator= in NoAlias.
 | ||||
|   typename Derived::PlainObject result(rows(), cols()); | ||||
|   other.evalTo(result); | ||||
|   return (derived() = result); | ||||
| } | ||||
| 
 | ||||
| #endif // EIGEN_RETURNBYVALUE_H
 | ||||
|  | ||||
| @ -281,15 +281,9 @@ struct ei_traits<ei_inverse_impl<MatrixType> > | ||||
| template<typename MatrixType> | ||||
| struct ei_inverse_impl : public ReturnByValue<ei_inverse_impl<MatrixType> > | ||||
| { | ||||
|   // for 2x2, it's worth giving a chance to avoid evaluating.
 | ||||
|   // for larger sizes, evaluating has negligible cost, limits code size,
 | ||||
|   // and allows for vectorized paths.
 | ||||
|   typedef typename ei_meta_if< | ||||
|     MatrixType::RowsAtCompileTime == 2, | ||||
|     typename ei_nested<MatrixType,2>::type, | ||||
|     typename ei_eval<MatrixType>::type | ||||
|   >::ret MatrixTypeNested; | ||||
|   typedef typename MatrixType::Nested MatrixTypeNested; | ||||
|   typedef typename ei_cleantype<MatrixTypeNested>::type MatrixTypeNestedCleaned; | ||||
| 
 | ||||
|   const MatrixTypeNested m_matrix; | ||||
| 
 | ||||
|   ei_inverse_impl(const MatrixType& matrix) | ||||
| @ -359,14 +353,7 @@ inline void MatrixBase<Derived>::computeInverseAndDetWithCheck( | ||||
| { | ||||
|   // i'd love to put some static assertions there, but SFINAE means that they have no effect...
 | ||||
|   ei_assert(rows() == cols()); | ||||
|   // for 2x2, it's worth giving a chance to avoid evaluating.
 | ||||
|   // for larger sizes, evaluating has negligible cost and limits code size.
 | ||||
|   typedef typename ei_meta_if< | ||||
|     RowsAtCompileTime == 2, | ||||
|     typename ei_cleantype<typename ei_nested<Derived, 2>::type>::type, | ||||
|     PlainObject | ||||
|   >::ret MatrixType; | ||||
|   ei_compute_inverse_and_det_with_check<MatrixType, ResultType>::run | ||||
|   ei_compute_inverse_and_det_with_check<PlainObject, ResultType>::run | ||||
|     (derived(), absDeterminantThreshold, inverse, determinant, invertible); | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -64,7 +64,9 @@ template<typename MatrixType> void inverse_general_4x4(int repeat) | ||||
|   double error_avg = error_sum / repeat; | ||||
|   EIGEN_DEBUG_VAR(error_avg); | ||||
|   EIGEN_DEBUG_VAR(error_max); | ||||
|   VERIFY(error_avg < (NumTraits<Scalar>::IsComplex ? 8.0 : 1.2));  // FIXME that 1.2 used to be a 1.0 until the NumTraits changes on 28 April 2010, what's going wrong??
 | ||||
|   // FIXME that 1.3 used to be a 1.0 until the NumTraits changes on 28 April 2010, and then a 1.2 until the ReturnByValue/Inverse changes
 | ||||
|   // on 30 May 2010, what's going wrong (if anything) ??
 | ||||
|   VERIFY(error_avg < (NumTraits<Scalar>::IsComplex ? 8.0 : 1.3)); | ||||
|   VERIFY(error_max < (NumTraits<Scalar>::IsComplex ? 64.0 : 20.0)); | ||||
| } | ||||
| 
 | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 Benoit Jacob
						Benoit Jacob