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 13 namespace Eigen { 14 15 namespace internal { 16 17 template<typename Derived, int UnrollCount> 18 struct all_unroller 19 { 20 typedef typename Derived::ExpressionTraits Traits; 21 enum { 22 col = (UnrollCount-1) / Traits::RowsAtCompileTime, 23 row = (UnrollCount-1) % Traits::RowsAtCompileTime 24 }; 25 runall_unroller26 static inline bool run(const Derived &mat) 27 { 28 return all_unroller<Derived, UnrollCount-1>::run(mat) && mat.coeff(row, col); 29 } 30 }; 31 32 template<typename Derived> 33 struct all_unroller<Derived, 0> 34 { 35 static inline bool run(const Derived &/*mat*/) { return true; } 36 }; 37 38 template<typename Derived> 39 struct all_unroller<Derived, Dynamic> 40 { 41 static inline bool run(const Derived &) { return false; } 42 }; 43 44 template<typename Derived, int UnrollCount> 45 struct any_unroller 46 { 47 typedef typename Derived::ExpressionTraits Traits; 48 enum { 49 col = (UnrollCount-1) / Traits::RowsAtCompileTime, 50 row = (UnrollCount-1) % Traits::RowsAtCompileTime 51 }; 52 53 static inline bool run(const Derived &mat) 54 { 55 return any_unroller<Derived, UnrollCount-1>::run(mat) || mat.coeff(row, col); 56 } 57 }; 58 59 template<typename Derived> 60 struct any_unroller<Derived, 0> 61 { 62 static inline bool run(const Derived & /*mat*/) { return false; } 63 }; 64 65 template<typename Derived> 66 struct any_unroller<Derived, Dynamic> 67 { 68 static inline bool run(const Derived &) { return false; } 69 }; 70 71 } // end namespace internal 72 73 /** \returns true if all coefficients are true 74 * 75 * Example: \include MatrixBase_all.cpp 76 * Output: \verbinclude MatrixBase_all.out 77 * 78 * \sa any(), Cwise::operator<() 79 */ 80 template<typename Derived> 81 inline bool DenseBase<Derived>::all() const 82 { 83 typedef internal::evaluator<Derived> Evaluator; 84 enum { 85 unroll = SizeAtCompileTime != Dynamic 86 && SizeAtCompileTime * (Evaluator::CoeffReadCost + NumTraits<Scalar>::AddCost) <= EIGEN_UNROLLING_LIMIT 87 }; 88 Evaluator evaluator(derived()); 89 if(unroll) 90 return internal::all_unroller<Evaluator, unroll ? int(SizeAtCompileTime) : Dynamic>::run(evaluator); 91 else 92 { 93 for(Index j = 0; j < cols(); ++j) 94 for(Index i = 0; i < rows(); ++i) 95 if (!evaluator.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 */ 104 template<typename Derived> 105 inline bool DenseBase<Derived>::any() const 106 { 107 typedef internal::evaluator<Derived> Evaluator; 108 enum { 109 unroll = SizeAtCompileTime != Dynamic 110 && SizeAtCompileTime * (Evaluator::CoeffReadCost + NumTraits<Scalar>::AddCost) <= EIGEN_UNROLLING_LIMIT 111 }; 112 Evaluator evaluator(derived()); 113 if(unroll) 114 return internal::any_unroller<Evaluator, unroll ? int(SizeAtCompileTime) : Dynamic>::run(evaluator); 115 else 116 { 117 for(Index j = 0; j < cols(); ++j) 118 for(Index i = 0; i < rows(); ++i) 119 if (evaluator.coeff(i, j)) return true; 120 return false; 121 } 122 } 123 124 /** \returns the number of coefficients which evaluate to true 125 * 126 * \sa all(), any() 127 */ 128 template<typename Derived> 129 inline Eigen::Index DenseBase<Derived>::count() const 130 { 131 return derived().template cast<bool>().template cast<Index>().sum(); 132 } 133 134 /** \returns true is \c *this contains at least one Not A Number (NaN). 135 * 136 * \sa allFinite() 137 */ 138 template<typename Derived> 139 inline bool DenseBase<Derived>::hasNaN() const 140 { 141 #if EIGEN_COMP_MSVC || (defined __FAST_MATH__) 142 return derived().array().isNaN().any(); 143 #else 144 return !((derived().array()==derived().array()).all()); 145 #endif 146 } 147 148 /** \returns true if \c *this contains only finite numbers, i.e., no NaN and no +/-INF values. 149 * 150 * \sa hasNaN() 151 */ 152 template<typename Derived> 153 inline bool DenseBase<Derived>::allFinite() const 154 { 155 #if EIGEN_COMP_MSVC || (defined __FAST_MATH__) 156 return derived().array().isFinite().all(); 157 #else 158 return !((derived()-derived()).hasNaN()); 159 #endif 160 } 161 162 } // end namespace Eigen 163 164 #endif // EIGEN_ALLANDANY_H 165