BooleanRedux.h 4.15 KB
Newer Older
LM's avatar
LM committed
1 2 3 4 5
// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
//
Don Gagne's avatar
Don Gagne committed
6 7 8
// This Source Code Form is subject to the terms of the Mozilla
// Public License v. 2.0. If a copy of the MPL was not distributed
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
LM's avatar
LM committed
9 10 11 12

#ifndef EIGEN_ALLANDANY_H
#define EIGEN_ALLANDANY_H

Don Gagne's avatar
Don Gagne committed
13 14
namespace Eigen { 

LM's avatar
LM committed
15 16 17 18 19
namespace internal {

template<typename Derived, int UnrollCount>
struct all_unroller
{
20
  typedef typename Derived::ExpressionTraits Traits;
LM's avatar
LM committed
21
  enum {
22 23
    col = (UnrollCount-1) / Traits::RowsAtCompileTime,
    row = (UnrollCount-1) % Traits::RowsAtCompileTime
LM's avatar
LM committed
24 25
  };

Don Gagne's avatar
Don Gagne committed
26
  static inline bool run(const Derived &mat)
LM's avatar
LM committed
27 28 29 30 31 32
  {
    return all_unroller<Derived, UnrollCount-1>::run(mat) && mat.coeff(row, col);
  }
};

template<typename Derived>
33
struct all_unroller<Derived, 0>
LM's avatar
LM committed
34
{
35
  static inline bool run(const Derived &/*mat*/) { return true; }
LM's avatar
LM committed
36 37 38 39 40
};

template<typename Derived>
struct all_unroller<Derived, Dynamic>
{
Don Gagne's avatar
Don Gagne committed
41
  static inline bool run(const Derived &) { return false; }
LM's avatar
LM committed
42 43 44 45 46
};

template<typename Derived, int UnrollCount>
struct any_unroller
{
47
  typedef typename Derived::ExpressionTraits Traits;
LM's avatar
LM committed
48
  enum {
49 50
    col = (UnrollCount-1) / Traits::RowsAtCompileTime,
    row = (UnrollCount-1) % Traits::RowsAtCompileTime
LM's avatar
LM committed
51
  };
52
  
Don Gagne's avatar
Don Gagne committed
53
  static inline bool run(const Derived &mat)
LM's avatar
LM committed
54 55 56 57 58 59
  {
    return any_unroller<Derived, UnrollCount-1>::run(mat) || mat.coeff(row, col);
  }
};

template<typename Derived>
60
struct any_unroller<Derived, 0>
LM's avatar
LM committed
61
{
62
  static inline bool run(const Derived & /*mat*/) { return false; }
LM's avatar
LM committed
63 64 65 66 67
};

template<typename Derived>
struct any_unroller<Derived, Dynamic>
{
Don Gagne's avatar
Don Gagne committed
68
  static inline bool run(const Derived &) { return false; }
LM's avatar
LM committed
69 70 71 72 73 74 75 76 77 78 79 80 81 82
};

} // end namespace internal

/** \returns true if all coefficients are true
  *
  * Example: \include MatrixBase_all.cpp
  * Output: \verbinclude MatrixBase_all.out
  *
  * \sa any(), Cwise::operator<()
  */
template<typename Derived>
inline bool DenseBase<Derived>::all() const
{
83
  typedef internal::evaluator<Derived> Evaluator;
LM's avatar
LM committed
84 85
  enum {
    unroll = SizeAtCompileTime != Dynamic
86
          && SizeAtCompileTime * (Evaluator::CoeffReadCost + NumTraits<Scalar>::AddCost) <= EIGEN_UNROLLING_LIMIT
LM's avatar
LM committed
87
  };
88
  Evaluator evaluator(derived());
LM's avatar
LM committed
89
  if(unroll)
90
    return internal::all_unroller<Evaluator, unroll ? int(SizeAtCompileTime) : Dynamic>::run(evaluator);
LM's avatar
LM committed
91 92 93 94
  else
  {
    for(Index j = 0; j < cols(); ++j)
      for(Index i = 0; i < rows(); ++i)
95
        if (!evaluator.coeff(i, j)) return false;
LM's avatar
LM committed
96 97 98 99 100 101 102 103 104 105 106
    return true;
  }
}

/** \returns true if at least one coefficient is true
  *
  * \sa all()
  */
template<typename Derived>
inline bool DenseBase<Derived>::any() const
{
107
  typedef internal::evaluator<Derived> Evaluator;
LM's avatar
LM committed
108 109
  enum {
    unroll = SizeAtCompileTime != Dynamic
110
          && SizeAtCompileTime * (Evaluator::CoeffReadCost + NumTraits<Scalar>::AddCost) <= EIGEN_UNROLLING_LIMIT
LM's avatar
LM committed
111
  };
112
  Evaluator evaluator(derived());
LM's avatar
LM committed
113
  if(unroll)
114
    return internal::any_unroller<Evaluator, unroll ? int(SizeAtCompileTime) : Dynamic>::run(evaluator);
LM's avatar
LM committed
115 116 117 118
  else
  {
    for(Index j = 0; j < cols(); ++j)
      for(Index i = 0; i < rows(); ++i)
119
        if (evaluator.coeff(i, j)) return true;
LM's avatar
LM committed
120 121 122 123 124 125 126 127 128
    return false;
  }
}

/** \returns the number of coefficients which evaluate to true
  *
  * \sa all(), any()
  */
template<typename Derived>
129
inline Eigen::Index DenseBase<Derived>::count() const
LM's avatar
LM committed
130 131 132 133
{
  return derived().template cast<bool>().template cast<Index>().sum();
}

Don Gagne's avatar
Don Gagne committed
134 135 136 137 138 139 140
/** \returns true is \c *this contains at least one Not A Number (NaN).
  *
  * \sa allFinite()
  */
template<typename Derived>
inline bool DenseBase<Derived>::hasNaN() const
{
141 142 143
#if EIGEN_COMP_MSVC || (defined __FAST_MATH__)
  return derived().array().isNaN().any();
#else
Don Gagne's avatar
Don Gagne committed
144
  return !((derived().array()==derived().array()).all());
145
#endif
Don Gagne's avatar
Don Gagne committed
146 147 148 149 150 151 152 153 154
}

/** \returns true if \c *this contains only finite numbers, i.e., no NaN and no +/-INF values.
  *
  * \sa hasNaN()
  */
template<typename Derived>
inline bool DenseBase<Derived>::allFinite() const
{
155 156 157
#if EIGEN_COMP_MSVC || (defined __FAST_MATH__)
  return derived().array().isFinite().all();
#else
Don Gagne's avatar
Don Gagne committed
158
  return !((derived()-derived()).hasNaN());
159
#endif
Don Gagne's avatar
Don Gagne committed
160 161 162 163
}
    
} // end namespace Eigen

LM's avatar
LM committed
164
#endif // EIGEN_ALLANDANY_H