BooleanRedux.h 3.83 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 20 21 22 23 24
namespace internal {

template<typename Derived, int UnrollCount>
struct all_unroller
{
  enum {
    col = (UnrollCount-1) / Derived::RowsAtCompileTime,
    row = (UnrollCount-1) % Derived::RowsAtCompileTime
  };

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

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

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

template<typename Derived, int UnrollCount>
struct any_unroller
{
  enum {
    col = (UnrollCount-1) / Derived::RowsAtCompileTime,
    row = (UnrollCount-1) % Derived::RowsAtCompileTime
  };

Don Gagne's avatar
Don Gagne committed
51
  static inline bool run(const Derived &mat)
LM's avatar
LM committed
52 53 54 55 56 57
  {
    return any_unroller<Derived, UnrollCount-1>::run(mat) || mat.coeff(row, col);
  }
};

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

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

} // 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
{
  enum {
    unroll = SizeAtCompileTime != Dynamic
          && CoeffReadCost != Dynamic
          && NumTraits<Scalar>::AddCost != Dynamic
          && SizeAtCompileTime * (CoeffReadCost + NumTraits<Scalar>::AddCost) <= EIGEN_UNROLLING_LIMIT
  };
  if(unroll)
Don Gagne's avatar
Don Gagne committed
88
    return internal::all_unroller<Derived, unroll ? int(SizeAtCompileTime) : Dynamic>::run(derived());
LM's avatar
LM committed
89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111
  else
  {
    for(Index j = 0; j < cols(); ++j)
      for(Index i = 0; i < rows(); ++i)
        if (!coeff(i, j)) return false;
    return true;
  }
}

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

/** \returns the number of coefficients which evaluate to true
  *
  * \sa all(), any()
  */
template<typename Derived>
inline typename DenseBase<Derived>::Index DenseBase<Derived>::count() const
{
  return derived().template cast<bool>().template cast<Index>().sum();
}

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

/** \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
{
  return !((derived()-derived()).hasNaN());
}
    
} // end namespace Eigen

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