1 // This file is part of Eigen, a lightweight C++ template library 2 // for linear algebra. 3 // 4 // Copyright (C) 2008 Gael Guennebaud <[email protected]> 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, int Rows> 18 struct all_unroller 19 { 20 enum { 21 col = (UnrollCount-1) / Rows, 22 row = (UnrollCount-1) % Rows 23 }; 24 runall_unroller25 EIGEN_DEVICE_FUNC static inline bool run(const Derived &mat) 26 { 27 return all_unroller<Derived, UnrollCount-1, Rows>::run(mat) && mat.coeff(row, col); 28 } 29 }; 30 31 template<typename Derived, int Rows> 32 struct all_unroller<Derived, 0, Rows> 33 { 34 EIGEN_DEVICE_FUNC static inline bool run(const Derived &/*mat*/) { return true; } 35 }; 36 37 template<typename Derived, int Rows> 38 struct all_unroller<Derived, Dynamic, Rows> 39 { 40 EIGEN_DEVICE_FUNC static inline bool run(const Derived &) { return false; } 41 }; 42 43 template<typename Derived, int UnrollCount, int Rows> 44 struct any_unroller 45 { 46 enum { 47 col = (UnrollCount-1) / Rows, 48 row = (UnrollCount-1) % Rows 49 }; 50 51 EIGEN_DEVICE_FUNC static inline bool run(const Derived &mat) 52 { 53 return any_unroller<Derived, UnrollCount-1, Rows>::run(mat) || mat.coeff(row, col); 54 } 55 }; 56 57 template<typename Derived, int Rows> 58 struct any_unroller<Derived, 0, Rows> 59 { 60 EIGEN_DEVICE_FUNC static inline bool run(const Derived & /*mat*/) { return false; } 61 }; 62 63 template<typename Derived, int Rows> 64 struct any_unroller<Derived, Dynamic, Rows> 65 { 66 EIGEN_DEVICE_FUNC 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 EIGEN_DEVICE_FUNC inline bool DenseBase<Derived>::all() const 80 { 81 typedef internal::evaluator<Derived> Evaluator; 82 enum { 83 unroll = SizeAtCompileTime != Dynamic 84 && SizeAtCompileTime * (int(Evaluator::CoeffReadCost) + int(NumTraits<Scalar>::AddCost)) <= EIGEN_UNROLLING_LIMIT 85 }; 86 Evaluator evaluator(derived()); 87 if(unroll) 88 return internal::all_unroller<Evaluator, unroll ? int(SizeAtCompileTime) : Dynamic, internal::traits<Derived>::RowsAtCompileTime>::run(evaluator); 89 else 90 { 91 for(Index j = 0; j < cols(); ++j) 92 for(Index i = 0; i < rows(); ++i) 93 if (!evaluator.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 EIGEN_DEVICE_FUNC inline bool DenseBase<Derived>::any() const 104 { 105 typedef internal::evaluator<Derived> Evaluator; 106 enum { 107 unroll = SizeAtCompileTime != Dynamic 108 && SizeAtCompileTime * (int(Evaluator::CoeffReadCost) + int(NumTraits<Scalar>::AddCost)) <= EIGEN_UNROLLING_LIMIT 109 }; 110 Evaluator evaluator(derived()); 111 if(unroll) 112 return internal::any_unroller<Evaluator, unroll ? int(SizeAtCompileTime) : Dynamic, internal::traits<Derived>::RowsAtCompileTime>::run(evaluator); 113 else 114 { 115 for(Index j = 0; j < cols(); ++j) 116 for(Index i = 0; i < rows(); ++i) 117 if (evaluator.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 EIGEN_DEVICE_FUNC inline Eigen::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 #if EIGEN_COMP_MSVC || (defined __FAST_MATH__) 140 return derived().array().isNaN().any(); 141 #else 142 return !((derived().array()==derived().array()).all()); 143 #endif 144 } 145 146 /** \returns true if \c *this contains only finite numbers, i.e., no NaN and no +/-INF values. 147 * 148 * \sa hasNaN() 149 */ 150 template<typename Derived> 151 inline bool DenseBase<Derived>::allFinite() const 152 { 153 #if EIGEN_COMP_MSVC || (defined __FAST_MATH__) 154 return derived().array().isFinite().all(); 155 #else 156 return !((derived()-derived()).hasNaN()); 157 #endif 158 } 159 160 } // end namespace Eigen 161 162 #endif // EIGEN_ALLANDANY_H 163