BooleanRedux.h 4.1 KB

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