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 mask = ownerMask_.begin();
auto& value = std::get<I>(values);
value = reduceOperator.maskValue(container[0], *mask);
++mask;
//++newVal;
value = reduceOperator.getInitialValue();
for( auto endVal=ownerMask_.end(); mask!=endVal;
/*++newVal,*/ ++mask )
@ -372,6 +370,11 @@ private:
template<typename BinaryOperator>
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.
///
/// The BinaryOperator will be called with t1, and mask*t2.
@ -392,6 +395,10 @@ private:
{
return b_;
}
Result getInitialValue()
{
return Result();
}
private:
BinaryOperator b_;
};
@ -433,17 +440,21 @@ private:
}
else
{
//g++-4.4 does not support std::numeric_limits<T>::lowest();
// we rely on IEE 754 for floating point values and use min()
// for integral types.
if( std::is_integral<T>::value )
{
return -std::numeric_limits<Result>::min();
}
else
{
return -std::numeric_limits<Result>::max();
}
return getInitialValue();
}
}
Result getInitialValue()
{
//g++-4.4 does not support std::numeric_limits<T>::lowest();
// we rely on IEE 754 for floating point values and use min()
// for integral types.
if( std::is_integral<Result>::value )
{
return -std::numeric_limits<Result>::min();
}
else
{
return -std::numeric_limits<Result>::max();
}
}
/// \brief Get the underlying binary operator.
@ -500,6 +511,10 @@ private:
{
return b_;
}
Result getInitialValue()
{
return std::numeric_limits<Result>::max();
}
private:
BinaryOperator b_;
};