Do not use the masked value of the first container entry as initial value.

This behaviour does not work for computing a global inner product.
Therfore this commit introduces a new function to the functor that
returns an appropriate initial value.
This commit is contained in:
Markus Blatt 2015-05-22 20:43:27 +02:00
parent fa279d6b16
commit 3fb7af1719

View File

@ -298,9 +298,7 @@ private:
//auto newVal = container.begin(); //auto newVal = container.begin();
auto mask = ownerMask_.begin(); auto mask = ownerMask_.begin();
auto& value = std::get<I>(values); auto& value = std::get<I>(values);
value = reduceOperator.maskValue(container[0], *mask); value = reduceOperator.getInitialValue();
++mask;
//++newVal;
for( auto endVal=ownerMask_.end(); mask!=endVal; for( auto endVal=ownerMask_.end(); mask!=endVal;
/*++newVal,*/ ++mask ) /*++newVal,*/ ++mask )
@ -372,6 +370,11 @@ private:
template<typename BinaryOperator> template<typename BinaryOperator>
struct MaskIDOperator struct MaskIDOperator
{ {
// This is a real nice one: numeric limits needs a type without const
// or reference qualifier. Otherwise we get complete nonesense.
typedef typename std::remove_cv<
typename std::remove_reference<typename BinaryOperator::result_type>::type
>::type Result;
/// \brief Apply the underlying binary operator according to the mask. /// \brief Apply the underlying binary operator according to the mask.
/// ///
/// The BinaryOperator will be called with t1, and mask*t2. /// The BinaryOperator will be called with t1, and mask*t2.
@ -392,6 +395,10 @@ private:
{ {
return b_; return b_;
} }
Result getInitialValue()
{
return Result();
}
private: private:
BinaryOperator b_; BinaryOperator b_;
}; };
@ -433,17 +440,21 @@ private:
} }
else else
{ {
//g++-4.4 does not support std::numeric_limits<T>::lowest(); return getInitialValue();
// we rely on IEE 754 for floating point values and use min() }
// for integral types. }
if( std::is_integral<T>::value ) Result getInitialValue()
{ {
return -std::numeric_limits<Result>::min(); //g++-4.4 does not support std::numeric_limits<T>::lowest();
} // we rely on IEE 754 for floating point values and use min()
else // for integral types.
{ if( std::is_integral<Result>::value )
return -std::numeric_limits<Result>::max(); {
} return -std::numeric_limits<Result>::min();
}
else
{
return -std::numeric_limits<Result>::max();
} }
} }
/// \brief Get the underlying binary operator. /// \brief Get the underlying binary operator.
@ -500,6 +511,10 @@ private:
{ {
return b_; return b_;
} }
Result getInitialValue()
{
return std::numeric_limits<Result>::max();
}
private: private:
BinaryOperator b_; BinaryOperator b_;
}; };