mirror of
https://gitlab.com/libeigen/eigen.git
synced 2025-09-12 17:33:15 +08:00
Fix Random().normalized() by introducing a nested_eval helper (recall that the old nested<> class is deprecated)
This commit is contained in:
parent
34694d8828
commit
94acccc126
@ -141,8 +141,13 @@ template<typename Derived>
|
|||||||
inline const typename MatrixBase<Derived>::PlainObject
|
inline const typename MatrixBase<Derived>::PlainObject
|
||||||
MatrixBase<Derived>::normalized() const
|
MatrixBase<Derived>::normalized() const
|
||||||
{
|
{
|
||||||
typedef typename internal::nested<Derived>::type Nested;
|
#ifndef EIGEN_TEST_EVALUATORS
|
||||||
|
typedef typename internal::nested<Derived,2>::type Nested;
|
||||||
typedef typename internal::remove_reference<Nested>::type _Nested;
|
typedef typename internal::remove_reference<Nested>::type _Nested;
|
||||||
|
#else
|
||||||
|
typedef typename internal::nested_eval<Derived,2>::type _Nested;
|
||||||
|
// typedef typename internal::remove_reference<Nested>::type _Nested;
|
||||||
|
#endif // EIGEN_TEST_EVALUATORS
|
||||||
_Nested n(derived());
|
_Nested n(derived());
|
||||||
return n / n.norm();
|
return n / n.norm();
|
||||||
}
|
}
|
||||||
|
@ -296,11 +296,40 @@ struct transfer_constness
|
|||||||
#ifdef EIGEN_TEST_EVALUATORS
|
#ifdef EIGEN_TEST_EVALUATORS
|
||||||
|
|
||||||
// When using evaluators, we never evaluate when assembling the expression!!
|
// When using evaluators, we never evaluate when assembling the expression!!
|
||||||
|
// TODO: get rid of this nested class since it's just an alias for ref_selector.
|
||||||
template<typename T, int n=1, typename PlainObject = typename eval<T>::type> struct nested
|
template<typename T, int n=1, typename PlainObject = typename eval<T>::type> struct nested
|
||||||
{
|
{
|
||||||
typedef typename ref_selector<T>::type type;
|
typedef typename ref_selector<T>::type type;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// However, we still need a mechanism to detect whether an expression which is evaluated multiple time
|
||||||
|
// has to be evaluated into a temporary.
|
||||||
|
// That's the purpose of this new nested_eval helper:
|
||||||
|
template<typename T, int n, typename PlainObject = typename eval<T>::type> struct nested_eval
|
||||||
|
{
|
||||||
|
enum {
|
||||||
|
// For the purpose of this test, to keep it reasonably simple, we arbitrarily choose a value of Dynamic values.
|
||||||
|
// the choice of 10000 makes it larger than any practical fixed value and even most dynamic values.
|
||||||
|
// in extreme cases where these assumptions would be wrong, we would still at worst suffer performance issues
|
||||||
|
// (poor choice of temporaries).
|
||||||
|
// It's important that this value can still be squared without integer overflowing.
|
||||||
|
DynamicAsInteger = 10000,
|
||||||
|
ScalarReadCost = NumTraits<typename traits<T>::Scalar>::ReadCost,
|
||||||
|
ScalarReadCostAsInteger = ScalarReadCost == Dynamic ? int(DynamicAsInteger) : int(ScalarReadCost),
|
||||||
|
CoeffReadCost = traits<T>::CoeffReadCost,
|
||||||
|
CoeffReadCostAsInteger = CoeffReadCost == Dynamic ? int(DynamicAsInteger) : int(CoeffReadCost),
|
||||||
|
NAsInteger = n == Dynamic ? int(DynamicAsInteger) : n,
|
||||||
|
CostEvalAsInteger = (NAsInteger+1) * ScalarReadCostAsInteger + CoeffReadCostAsInteger,
|
||||||
|
CostNoEvalAsInteger = NAsInteger * CoeffReadCostAsInteger
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef typename conditional<
|
||||||
|
int(CostEvalAsInteger) < int(CostNoEvalAsInteger),
|
||||||
|
PlainObject,
|
||||||
|
typename ref_selector<T>::type
|
||||||
|
>::type type;
|
||||||
|
};
|
||||||
|
|
||||||
#else
|
#else
|
||||||
/** \internal Determines how a given expression should be nested into another one.
|
/** \internal Determines how a given expression should be nested into another one.
|
||||||
* For example, when you do a * (b+c), Eigen will determine how the expression b+c should be
|
* For example, when you do a * (b+c), Eigen will determine how the expression b+c should be
|
||||||
|
Loading…
x
Reference in New Issue
Block a user