This commit is contained in:
Gael Guennebaud 2015-10-21 13:49:13 +02:00
commit 5ca2e25967
6 changed files with 95 additions and 3 deletions

View File

@ -1149,6 +1149,19 @@ are the smallest of the reduced values.
Reduce a tensor using the prod() operator. The resulting values
are the product of the reduced values.
### <Operation> all(const Dimensions& new_dims)
### <Operation> all()
Reduce a tensor using the all() operator. Casts tensor to bool and then checks
whether all elements are true. Runs through all elements rather than
short-circuiting, so may be significantly inefficient.
### <Operation> any(const Dimensions& new_dims)
### <Operation> any()
Reduce a tensor using the any() operator. Casts tensor to bool and then checks
whether any element is true. Runs through all elements rather than
short-circuiting, so may be significantly inefficient.
### <Operation> reduce(const Dimensions& new_dims, const Reducer& reducer)
Reduce a tensor using a user-defined reduction operator. See ```SumReducer```

View File

@ -363,6 +363,32 @@ class TensorBase<Derived, ReadOnlyAccessors>
return TensorReductionOp<internal::MinReducer<CoeffReturnType>, const DimensionList<Index, NumDimensions>, const Derived>(derived(), in_dims, internal::MinReducer<CoeffReturnType>());
}
template <typename Dims> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
const TensorReductionOp<internal::AndReducer, const Dims, const TensorConversionOp<bool, const Derived> >
all(const Dims& dims) const {
return cast<bool>().reduce(dims, internal::AndReducer());
}
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
const TensorReductionOp<internal::AndReducer, const DimensionList<Index, NumDimensions>, const TensorConversionOp<bool, const Derived> >
all() const {
DimensionList<Index, NumDimensions> in_dims;
return cast<bool>().reduce(in_dims, internal::AndReducer());
}
template <typename Dims> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
const TensorReductionOp<internal::OrReducer, const Dims, const TensorConversionOp<bool, const Derived> >
any(const Dims& dims) const {
return cast<bool>().reduce(dims, internal::OrReducer());
}
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
const TensorReductionOp<internal::OrReducer, const DimensionList<Index, NumDimensions>, const TensorConversionOp<bool, const Derived> >
any() const {
DimensionList<Index, NumDimensions> in_dims;
return cast<bool>().reduce(in_dims, internal::OrReducer());
}
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
const TensorTupleReducerOp<
internal::ArgMaxTupleReducer<Tuple<Index, CoeffReturnType> >,

View File

@ -124,8 +124,8 @@ class TensorConversionOp : public TensorBase<TensorConversionOp<TargetType, XprT
typedef typename internal::traits<TensorConversionOp>::StorageKind StorageKind;
typedef typename internal::traits<TensorConversionOp>::Index Index;
typedef typename internal::nested<TensorConversionOp>::type Nested;
typedef typename XprType::CoeffReturnType CoeffReturnType;
typedef typename XprType::PacketReturnType PacketReturnType;
typedef Scalar CoeffReturnType;
typedef Packet PacketReturnType;
typedef typename NumTraits<Scalar>::Real RealScalar;
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TensorConversionOp(const XprType& xpr)

View File

@ -219,6 +219,33 @@ template <typename T> struct ProdReducer
};
struct AndReducer
{
static const bool PacketAccess = false;
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void reduce(bool t, bool* accum) const {
*accum = *accum && t;
}
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE bool initialize() const {
return true;
}
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE bool finalize(bool accum) const {
return accum;
}
};
struct OrReducer {
static const bool PacketAccess = false;
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void reduce(bool t, bool* accum) const {
*accum = *accum || t;
}
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE bool initialize() const {
return false;
}
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE bool finalize(bool accum) const {
return accum;
}
};
// Argmin/Argmax reducers
template <typename T> struct ArgMaxTupleReducer
{

View File

@ -26,8 +26,17 @@
* void foo(){}
*/
// SFINAE requires variadic templates
#ifdef EIGEN_HAS_VARIADIC_TEMPLATES
#define EIGEN_HAS_SFINAE
// SFINAE doesn't work for gcc <= 4.7
#ifdef EIGEN_COMP_GNUC
#if EIGEN_GNUC_AT_LEAST(4,8)
#define EIGEN_HAS_SFINAE
#endif
#else
#define EIGEN_HAS_SFINAE
#endif
#endif
#define EIGEN_SFINAE_ENABLE_IF( __condition__ ) \

View File

@ -180,6 +180,23 @@ static void test_simple_reductions() {
VERIFY_IS_APPROX(mean1(0), mean2(0));
}
{
Tensor<int, 1> ints(10);
std::iota(ints.data(), ints.data() + ints.dimension(0), 0);
TensorFixedSize<bool, Sizes<1> > all;
all = ints.all();
VERIFY(!all(0));
all = (ints >= ints.constant(0)).all();
VERIFY(all(0));
TensorFixedSize<bool, Sizes<1> > any;
any = (ints > ints.constant(10)).any();
VERIFY(!any(0));
any = (ints < ints.constant(1)).any();
VERIFY(any(0));
}
}
template <int DataLayout>