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 | |
26 | 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 | |