Home | History | Annotate | Download | only in Core
      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 (at) 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 
     13 namespace Eigen {
     14 
     15 namespace internal {
     16 
     17 template<typename Derived, int UnrollCount>
     18 struct 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 
     31 template<typename Derived>
     32 struct all_unroller<Derived, 0>
     33 {
     34   static inline bool run(const Derived &/*mat*/) { return true; }
     35 };
     36 
     37 template<typename Derived>
     38 struct all_unroller<Derived, Dynamic>
     39 {
     40   static inline bool run(const Derived &) { return false; }
     41 };
     42 
     43 template<typename Derived, int UnrollCount>
     44 struct 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 
     57 template<typename Derived>
     58 struct any_unroller<Derived, 0>
     59 {
     60   static inline bool run(const Derived & /*mat*/) { return false; }
     61 };
     62 
     63 template<typename Derived>
     64 struct 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   */
     78 template<typename Derived>
     79 inline 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, unroll ? int(SizeAtCompileTime) : Dynamic>::run(derived());
     89   else
     90   {
     91     for(Index j = 0; j < cols(); ++j)
     92       for(Index i = 0; i < rows(); ++i)
     93         if (!coeff(i, j)) return false;
     94     return true;
     95   }
     96 }
     97 
     98 /** \returns true if at least one coefficient is true
     99   *
    100   * \sa all()
    101   */
    102 template<typename Derived>
    103 inline bool DenseBase<Derived>::any() const
    104 {
    105   enum {
    106     unroll = SizeAtCompileTime != Dynamic
    107           && CoeffReadCost != Dynamic
    108           && NumTraits<Scalar>::AddCost != Dynamic
    109           && SizeAtCompileTime * (CoeffReadCost + NumTraits<Scalar>::AddCost) <= EIGEN_UNROLLING_LIMIT
    110   };
    111   if(unroll)
    112     return internal::any_unroller<Derived, unroll ? int(SizeAtCompileTime) : Dynamic>::run(derived());
    113   else
    114   {
    115     for(Index j = 0; j < cols(); ++j)
    116       for(Index i = 0; i < rows(); ++i)
    117         if (coeff(i, j)) return true;
    118     return false;
    119   }
    120 }
    121 
    122 /** \returns the number of coefficients which evaluate to true
    123   *
    124   * \sa all(), any()
    125   */
    126 template<typename Derived>
    127 inline typename DenseBase<Derived>::Index DenseBase<Derived>::count() const
    128 {
    129   return derived().template cast<bool>().template cast<Index>().sum();
    130 }
    131 
    132 /** \returns true is \c *this contains at least one Not A Number (NaN).
    133   *
    134   * \sa allFinite()
    135   */
    136 template<typename Derived>
    137 inline bool DenseBase<Derived>::hasNaN() const
    138 {
    139   return !((derived().array()==derived().array()).all());
    140 }
    141 
    142 /** \returns true if \c *this contains only finite numbers, i.e., no NaN and no +/-INF values.
    143   *
    144   * \sa hasNaN()
    145   */
    146 template<typename Derived>
    147 inline bool DenseBase<Derived>::allFinite() const
    148 {
    149   return !((derived()-derived()).hasNaN());
    150 }
    151 
    152 } // end namespace Eigen
    153 
    154 #endif // EIGEN_ALLANDANY_H
    155