BooleanRedux.h revision c981c48f5bc9aefeffc0bcb0cc3934c2fae179dd
1// This file is part of Eigen, a lightweight C++ template library
2// for linear algebra.
3//
4// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
5//
6// This Source Code Form is subject to the terms of the Mozilla
7// Public License v. 2.0. If a copy of the MPL was not distributed
8// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
9
10#ifndef EIGEN_ALLANDANY_H
11#define EIGEN_ALLANDANY_H
12
13namespace Eigen {
14
15namespace internal {
16
17template<typename Derived, int UnrollCount>
18struct all_unroller
19{
20  enum {
21    col = (UnrollCount-1) / Derived::RowsAtCompileTime,
22    row = (UnrollCount-1) % Derived::RowsAtCompileTime
23  };
24
25  static inline bool run(const Derived &mat)
26  {
27    return all_unroller<Derived, UnrollCount-1>::run(mat) && mat.coeff(row, col);
28  }
29};
30
31template<typename Derived>
32struct all_unroller<Derived, 1>
33{
34  static inline bool run(const Derived &mat) { return mat.coeff(0, 0); }
35};
36
37template<typename Derived>
38struct all_unroller<Derived, Dynamic>
39{
40  static inline bool run(const Derived &) { return false; }
41};
42
43template<typename Derived, int UnrollCount>
44struct any_unroller
45{
46  enum {
47    col = (UnrollCount-1) / Derived::RowsAtCompileTime,
48    row = (UnrollCount-1) % Derived::RowsAtCompileTime
49  };
50
51  static inline bool run(const Derived &mat)
52  {
53    return any_unroller<Derived, UnrollCount-1>::run(mat) || mat.coeff(row, col);
54  }
55};
56
57template<typename Derived>
58struct any_unroller<Derived, 1>
59{
60  static inline bool run(const Derived &mat) { return mat.coeff(0, 0); }
61};
62
63template<typename Derived>
64struct any_unroller<Derived, Dynamic>
65{
66  static inline bool run(const Derived &) { return false; }
67};
68
69} // end namespace internal
70
71/** \returns true if all coefficients are true
72  *
73  * Example: \include MatrixBase_all.cpp
74  * Output: \verbinclude MatrixBase_all.out
75  *
76  * \sa any(), Cwise::operator<()
77  */
78template<typename Derived>
79inline bool DenseBase<Derived>::all() const
80{
81  enum {
82    unroll = SizeAtCompileTime != Dynamic
83          && CoeffReadCost != Dynamic
84          && NumTraits<Scalar>::AddCost != Dynamic
85          && SizeAtCompileTime * (CoeffReadCost + NumTraits<Scalar>::AddCost) <= EIGEN_UNROLLING_LIMIT
86  };
87  if(unroll)
88    return internal::all_unroller<Derived,
89                           unroll ? int(SizeAtCompileTime) : Dynamic
90     >::run(derived());
91  else
92  {
93    for(Index j = 0; j < cols(); ++j)
94      for(Index i = 0; i < rows(); ++i)
95        if (!coeff(i, j)) return false;
96    return true;
97  }
98}
99
100/** \returns true if at least one coefficient is true
101  *
102  * \sa all()
103  */
104template<typename Derived>
105inline bool DenseBase<Derived>::any() const
106{
107  enum {
108    unroll = SizeAtCompileTime != Dynamic
109          && CoeffReadCost != Dynamic
110          && NumTraits<Scalar>::AddCost != Dynamic
111          && SizeAtCompileTime * (CoeffReadCost + NumTraits<Scalar>::AddCost) <= EIGEN_UNROLLING_LIMIT
112  };
113  if(unroll)
114    return internal::any_unroller<Derived,
115                           unroll ? int(SizeAtCompileTime) : Dynamic
116           >::run(derived());
117  else
118  {
119    for(Index j = 0; j < cols(); ++j)
120      for(Index i = 0; i < rows(); ++i)
121        if (coeff(i, j)) return true;
122    return false;
123  }
124}
125
126/** \returns the number of coefficients which evaluate to true
127  *
128  * \sa all(), any()
129  */
130template<typename Derived>
131inline typename DenseBase<Derived>::Index DenseBase<Derived>::count() const
132{
133  return derived().template cast<bool>().template cast<Index>().sum();
134}
135
136} // end namespace Eigen
137
138#endif // EIGEN_ALLANDANY_H
139