mirror of
https://gitlab.com/libeigen/eigen.git
synced 2025-08-11 19:29:02 +08:00
fixes as discussed with Gael on IRC. Mainly, in Fuzzy.h, and Dot.h, use
ei_xpr_copy to evaluate args when needed. Had to introduce an ugly trick with ei_unref as when the XprCopy type is a reference one can't directly access member typedefs such as Scalar.
This commit is contained in:
parent
b4a156671f
commit
61e58cf602
@ -72,22 +72,24 @@ template<typename OtherDerived>
|
|||||||
typename ei_traits<Derived>::Scalar
|
typename ei_traits<Derived>::Scalar
|
||||||
MatrixBase<Derived>::dot(const MatrixBase<OtherDerived>& other) const
|
MatrixBase<Derived>::dot(const MatrixBase<OtherDerived>& other) const
|
||||||
{
|
{
|
||||||
|
typename Derived::XprCopy xprCopy(derived());
|
||||||
|
typename OtherDerived::XprCopy otherXprCopy(other.derived());
|
||||||
|
|
||||||
ei_assert(IsVectorAtCompileTime
|
ei_assert(IsVectorAtCompileTime
|
||||||
&& OtherDerived::IsVectorAtCompileTime
|
&& OtherDerived::IsVectorAtCompileTime
|
||||||
&& size() == other.size());
|
&& xprCopy.size() == otherXprCopy.size());
|
||||||
Scalar res;
|
Scalar res;
|
||||||
if(EIGEN_UNROLLED_LOOPS
|
if(SizeAtCompileTime <= EIGEN_UNROLLING_LIMIT)
|
||||||
&& SizeAtCompileTime != Dynamic
|
|
||||||
&& SizeAtCompileTime <= EIGEN_UNROLLING_LIMIT)
|
|
||||||
ei_dot_unroller<SizeAtCompileTime-1,
|
ei_dot_unroller<SizeAtCompileTime-1,
|
||||||
SizeAtCompileTime <= EIGEN_UNROLLING_LIMIT ? SizeAtCompileTime : Dynamic,
|
SizeAtCompileTime <= EIGEN_UNROLLING_LIMIT ? SizeAtCompileTime : Dynamic,
|
||||||
Derived, MatrixBase<OtherDerived> >
|
typename ei_unref<typename Derived::XprCopy>::type,
|
||||||
::run(derived(), other, res);
|
typename ei_unref<typename OtherDerived::XprCopy>::type>
|
||||||
|
::run(xprCopy, otherXprCopy, res);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
res = coeff(0) * ei_conj(other.coeff(0));
|
res = xprCopy.coeff(0) * ei_conj(otherXprCopy.coeff(0));
|
||||||
for(int i = 1; i < size(); i++)
|
for(int i = 1; i < size(); i++)
|
||||||
res += coeff(i)* ei_conj(other.coeff(i));
|
res += xprCopy.coeff(i)* ei_conj(otherXprCopy.coeff(i));
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
@ -140,7 +142,9 @@ template<typename OtherDerived>
|
|||||||
bool MatrixBase<Derived>::isOrtho
|
bool MatrixBase<Derived>::isOrtho
|
||||||
(const MatrixBase<OtherDerived>& other, RealScalar prec) const
|
(const MatrixBase<OtherDerived>& other, RealScalar prec) const
|
||||||
{
|
{
|
||||||
return ei_abs2(dot(other)) <= prec * prec * norm2() * other.norm2();
|
typename Derived::XprCopy xprCopy(derived());
|
||||||
|
typename OtherDerived::XprCopy otherXprCopy(other.derived());
|
||||||
|
return ei_abs2(xprCopy.dot(otherXprCopy)) <= prec * prec * xprCopy.norm2() * otherXprCopy.norm2();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \returns true if *this is approximately an unitary matrix,
|
/** \returns true if *this is approximately an unitary matrix,
|
||||||
@ -157,12 +161,13 @@ bool MatrixBase<Derived>::isOrtho
|
|||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
bool MatrixBase<Derived>::isOrtho(RealScalar prec) const
|
bool MatrixBase<Derived>::isOrtho(RealScalar prec) const
|
||||||
{
|
{
|
||||||
|
typename Derived::XprCopy xprCopy(derived());
|
||||||
for(int i = 0; i < cols(); i++)
|
for(int i = 0; i < cols(); i++)
|
||||||
{
|
{
|
||||||
if(!ei_isApprox(col(i).norm2(), static_cast<Scalar>(1), prec))
|
if(!ei_isApprox(xprCopy.col(i).norm2(), static_cast<Scalar>(1), prec))
|
||||||
return false;
|
return false;
|
||||||
for(int j = 0; j < i; j++)
|
for(int j = 0; j < i; j++)
|
||||||
if(!ei_isMuchSmallerThan(col(i).dot(col(j)), static_cast<Scalar>(1), prec))
|
if(!ei_isMuchSmallerThan(xprCopy.col(i).dot(xprCopy.col(j)), static_cast<Scalar>(1), prec))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
@ -80,6 +80,9 @@ template<typename T> struct ei_eval
|
|||||||
ei_traits<T>::MaxColsAtCompileTime> type;
|
ei_traits<T>::MaxColsAtCompileTime> type;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<typename T> struct ei_unref { typedef T type; };
|
||||||
|
template<typename T> struct ei_unref<T&> { typedef T type; };
|
||||||
|
|
||||||
template<typename T> struct ei_xpr_copy
|
template<typename T> struct ei_xpr_copy
|
||||||
{
|
{
|
||||||
typedef typename ei_meta_if< ei_traits<T>::Flags & EvalBeforeNestingBit,
|
typedef typename ei_meta_if< ei_traits<T>::Flags & EvalBeforeNestingBit,
|
||||||
@ -95,7 +98,7 @@ template<typename T, int n=1> struct ei_eval_if_needed_before_nesting
|
|||||||
{
|
{
|
||||||
// FIXME should we consider the additional store as well as the creation cost of the temporary ?
|
// FIXME should we consider the additional store as well as the creation cost of the temporary ?
|
||||||
enum { eval = T::Flags & EvalBeforeNestingBit
|
enum { eval = T::Flags & EvalBeforeNestingBit
|
||||||
|| n * NumTraits<typename ei_traits<T>::Scalar>::ReadCost < (n-1) * T::CoeffReadCost };
|
|| (n+1) * NumTraits<typename ei_traits<T>::Scalar>::ReadCost < (n-1) * T::CoeffReadCost };
|
||||||
typedef typename ei_meta_if<eval, typename ei_eval<T>::type, T>::ret XprType;
|
typedef typename ei_meta_if<eval, typename ei_eval<T>::type, T>::ret XprType;
|
||||||
typedef typename ei_meta_if<eval, typename ei_eval<T>::type, typename T::XprCopy>::ret CopyType;
|
typedef typename ei_meta_if<eval, typename ei_eval<T>::type, typename T::XprCopy>::ret CopyType;
|
||||||
};
|
};
|
||||||
|
@ -44,7 +44,7 @@
|
|||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
template<typename OtherDerived>
|
template<typename OtherDerived>
|
||||||
bool MatrixBase<Derived>::isApprox(
|
bool MatrixBase<Derived>::isApprox(
|
||||||
const OtherDerived& other,
|
const MatrixBase<OtherDerived>& other,
|
||||||
typename NumTraits<Scalar>::Real prec
|
typename NumTraits<Scalar>::Real prec
|
||||||
) const
|
) const
|
||||||
{
|
{
|
||||||
@ -55,9 +55,11 @@ bool MatrixBase<Derived>::isApprox(
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
typename Derived::XprCopy xprCopy(derived());
|
||||||
|
typename OtherDerived::XprCopy otherXprCopy(other.derived());
|
||||||
for(int i = 0; i < cols(); i++)
|
for(int i = 0; i < cols(); i++)
|
||||||
if((col(i) - other.col(i)).norm2()
|
if((xprCopy.col(i) - otherXprCopy.col(i)).norm2()
|
||||||
> std::min(col(i).norm2(), other.col(i).norm2()) * prec * prec)
|
> std::min(xprCopy.col(i).norm2(), otherXprCopy.col(i).norm2()) * prec * prec)
|
||||||
return false;
|
return false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -85,8 +87,9 @@ bool MatrixBase<Derived>::isMuchSmallerThan(
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
typename Derived::XprCopy xprCopy(*this);
|
||||||
for(int i = 0; i < cols(); i++)
|
for(int i = 0; i < cols(); i++)
|
||||||
if(col(i).norm2() > ei_abs2(other * prec))
|
if(xprCopy.col(i).norm2() > ei_abs2(other * prec))
|
||||||
return false;
|
return false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -116,8 +119,10 @@ bool MatrixBase<Derived>::isMuchSmallerThan(
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
typename Derived::XprCopy xprCopy(*this);
|
||||||
|
typename OtherDerived::XprCopy otherXprCopy(other);
|
||||||
for(int i = 0; i < cols(); i++)
|
for(int i = 0; i < cols(); i++)
|
||||||
if(col(i).norm2() > other.col(i).norm2() * prec * prec)
|
if(xprCopy.col(i).norm2() > otherXprCopy.col(i).norm2() * prec * prec)
|
||||||
return false;
|
return false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -340,7 +340,7 @@ template<typename Derived> class MatrixBase
|
|||||||
/// \name Comparison and diagnostic
|
/// \name Comparison and diagnostic
|
||||||
//@{
|
//@{
|
||||||
template<typename OtherDerived>
|
template<typename OtherDerived>
|
||||||
bool isApprox(const OtherDerived& other,
|
bool isApprox(const MatrixBase<OtherDerived>& other,
|
||||||
RealScalar prec = precision<Scalar>()) const;
|
RealScalar prec = precision<Scalar>()) const;
|
||||||
bool isMuchSmallerThan(const RealScalar& other,
|
bool isMuchSmallerThan(const RealScalar& other,
|
||||||
RealScalar prec = precision<Scalar>()) const;
|
RealScalar prec = precision<Scalar>()) const;
|
||||||
|
@ -106,9 +106,7 @@ Derived& MatrixBase<Derived>
|
|||||||
// copying a vector expression into a vector
|
// copying a vector expression into a vector
|
||||||
{
|
{
|
||||||
ei_assert(size() == other.size());
|
ei_assert(size() == other.size());
|
||||||
if(EIGEN_UNROLLED_LOOPS
|
if(SizeAtCompileTime <= EIGEN_UNROLLING_LIMIT)
|
||||||
&& SizeAtCompileTime != Dynamic
|
|
||||||
&& SizeAtCompileTime <= EIGEN_UNROLLING_LIMIT)
|
|
||||||
ei_vector_operator_equals_unroller
|
ei_vector_operator_equals_unroller
|
||||||
<Derived, OtherDerived,
|
<Derived, OtherDerived,
|
||||||
SizeAtCompileTime <= EIGEN_UNROLLING_LIMIT ? SizeAtCompileTime : Dynamic
|
SizeAtCompileTime <= EIGEN_UNROLLING_LIMIT ? SizeAtCompileTime : Dynamic
|
||||||
@ -120,9 +118,7 @@ Derived& MatrixBase<Derived>
|
|||||||
else // copying a matrix expression into a matrix
|
else // copying a matrix expression into a matrix
|
||||||
{
|
{
|
||||||
ei_assert(rows() == other.rows() && cols() == other.cols());
|
ei_assert(rows() == other.rows() && cols() == other.cols());
|
||||||
if(EIGEN_UNROLLED_LOOPS
|
if(SizeAtCompileTime <= EIGEN_UNROLLING_LIMIT)
|
||||||
&& SizeAtCompileTime != Dynamic
|
|
||||||
&& SizeAtCompileTime <= EIGEN_UNROLLING_LIMIT)
|
|
||||||
{
|
{
|
||||||
ei_matrix_operator_equals_unroller
|
ei_matrix_operator_equals_unroller
|
||||||
<Derived, OtherDerived,
|
<Derived, OtherDerived,
|
||||||
|
@ -133,9 +133,7 @@ template<typename Lhs, typename Rhs, int EvalMode> class Product : ei_no_assignm
|
|||||||
const Scalar _coeff(int row, int col) const
|
const Scalar _coeff(int row, int col) const
|
||||||
{
|
{
|
||||||
Scalar res;
|
Scalar res;
|
||||||
if(EIGEN_UNROLLED_LOOPS
|
if(Lhs::ColsAtCompileTime <= EIGEN_UNROLLING_LIMIT)
|
||||||
&& Lhs::ColsAtCompileTime != Dynamic
|
|
||||||
&& Lhs::ColsAtCompileTime <= EIGEN_UNROLLING_LIMIT)
|
|
||||||
ei_product_unroller<Lhs::ColsAtCompileTime-1,
|
ei_product_unroller<Lhs::ColsAtCompileTime-1,
|
||||||
Lhs::ColsAtCompileTime <= EIGEN_UNROLLING_LIMIT
|
Lhs::ColsAtCompileTime <= EIGEN_UNROLLING_LIMIT
|
||||||
? Lhs::ColsAtCompileTime : Dynamic,
|
? Lhs::ColsAtCompileTime : Dynamic,
|
||||||
|
@ -26,9 +26,7 @@
|
|||||||
#define EIGEN_UTIL_H
|
#define EIGEN_UTIL_H
|
||||||
|
|
||||||
#ifdef EIGEN_DONT_USE_UNROLLED_LOOPS
|
#ifdef EIGEN_DONT_USE_UNROLLED_LOOPS
|
||||||
#define EIGEN_UNROLLED_LOOPS (false)
|
#define EIGEN_UNROLLING_LIMIT 0
|
||||||
#else
|
|
||||||
#define EIGEN_UNROLLED_LOOPS (true)
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/** Defines the maximal loop size to enable meta unrolling of loops */
|
/** Defines the maximal loop size to enable meta unrolling of loops */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user