11#ifndef EIGEN_VISITOR_H
12#define EIGEN_VISITOR_H
15#include "./InternalHeaderCheck.h"
22template <
typename Visitor,
typename =
void>
23struct visitor_already_initialized : std::false_type {};
24template <
typename Visitor>
25struct visitor_already_initialized<Visitor, void_t<decltype(functor_traits<Visitor>::AlreadyInitialized)>>
26 : bool_constant<functor_traits<Visitor>::AlreadyInitialized> {};
28template <
typename Visitor,
typename Derived,
int UnrollCount,
29 bool Vectorize = (Derived::PacketAccess && functor_traits<Visitor>::PacketAccess),
bool LinearAccess =
false,
30 bool ShortCircuitEvaluation =
false>
33template <
typename Visitor,
bool ShortCircuitEvaluation = false>
34struct short_circuit_eval_impl {
36 static constexpr EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
bool run(
const Visitor&) {
return false; }
38template <
typename Visitor>
39struct short_circuit_eval_impl<Visitor, true> {
41 static constexpr EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
bool run(
const Visitor& visitor) {
return visitor.done(); }
45template <
typename Visitor,
typename Derived,
int UnrollCount,
bool Vectorize,
bool ShortCircuitEvaluation>
46struct visitor_impl<Visitor, Derived, UnrollCount, Vectorize, false, ShortCircuitEvaluation> {
48 using Scalar =
typename Derived::Scalar;
49 using Packet =
typename packet_traits<Scalar>::type;
50 static constexpr bool RowMajor = Derived::IsRowMajor;
51 static constexpr int RowsAtCompileTime = Derived::RowsAtCompileTime;
52 static constexpr int ColsAtCompileTime = Derived::ColsAtCompileTime;
53 static constexpr int PacketSize = packet_traits<Scalar>::size;
54 static constexpr int InnerSizeAtCompileTime =
RowMajor ? ColsAtCompileTime : RowsAtCompileTime;
55 static constexpr int OuterSizeAtCompileTime =
RowMajor ? RowsAtCompileTime : ColsAtCompileTime;
56 static constexpr int PacketOpsPerOuter =
57 Vectorize && InnerSizeAtCompileTime >= PacketSize ? InnerSizeAtCompileTime / PacketSize : 0;
58 static constexpr int FirstScalarInner = PacketOpsPerOuter * PacketSize;
59 static constexpr int ScalarOpsPerOuter = InnerSizeAtCompileTime - FirstScalarInner;
60 static constexpr int OpsPerOuter = PacketOpsPerOuter + ScalarOpsPerOuter;
61 static constexpr int OpCount = UnrollCount == 0 ? 0 : OuterSizeAtCompileTime * OpsPerOuter;
64 static constexpr bool IsPacketOp() {
65 return OpsPerOuter != 0 && (Op % OpsPerOuter) < PacketOpsPerOuter;
69 static constexpr int CoeffIndex() {
70 return OpsPerOuter == 0 ? 0
71 : (Op / OpsPerOuter) * InnerSizeAtCompileTime +
72 (IsPacketOp<Op>() ? ((Op % OpsPerOuter) * PacketSize)
73 : (FirstScalarInner + (Op % OpsPerOuter) - PacketOpsPerOuter));
76 template <int Op, std::enable_if_t<!IsPacketOp<Op>(),
bool> =
true>
77 static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
void visit(
const Derived& mat, Visitor& visitor) {
78 constexpr int K = CoeffIndex<Op>();
79 constexpr int R =
RowMajor ? (K / ColsAtCompileTime) : (K % RowsAtCompileTime);
80 constexpr int C =
RowMajor ? (K % ColsAtCompileTime) : (K / RowsAtCompileTime);
81 EIGEN_IF_CONSTEXPR (Op == 0) {
82 visitor.init(mat.coeff(R, C), R, C);
84 visitor(mat.coeff(R, C), R, C);
88 template <int Op, std::enable_if_t<IsPacketOp<Op>(),
bool> =
true>
89 static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
void visit(
const Derived& mat, Visitor& visitor) {
90 constexpr int K = CoeffIndex<Op>();
91 constexpr int R =
RowMajor ? (K / ColsAtCompileTime) : (K % RowsAtCompileTime);
92 constexpr int C =
RowMajor ? (K % ColsAtCompileTime) : (K / RowsAtCompileTime);
93 Packet P = mat.template packet<Packet>(R, C);
94 EIGEN_IF_CONSTEXPR (Op == 0) {
95 visitor.initpacket(P, R, C);
97 visitor.packet(P, R, C);
101 template <
int... Ops>
102 static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
void run_impl(
const Derived& mat, Visitor& visitor,
103 std::integer_sequence<int, Ops...>) {
104 int unused[] = {0, (visit<Ops>(mat, visitor), 0)...};
105 EIGEN_UNUSED_VARIABLE(unused);
108 static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
void run(
const Derived& mat, Visitor& visitor) {
109 run_impl(mat, visitor, std::make_integer_sequence<int, OpCount>{});
114template <
typename Visitor,
typename Derived,
int UnrollCount,
bool Vectorize,
bool ShortCircuitEvaluation>
115struct visitor_impl<Visitor, Derived, UnrollCount, Vectorize, true, ShortCircuitEvaluation> {
117 using Scalar =
typename Derived::Scalar;
118 using Packet =
typename packet_traits<Scalar>::type;
119 static constexpr int PacketSize = packet_traits<Scalar>::size;
120 static constexpr int PacketOps = Vectorize ? UnrollCount / PacketSize : 0;
121 static constexpr int FirstScalar = PacketOps * PacketSize;
122 static constexpr int ScalarOps = UnrollCount - FirstScalar;
123 static constexpr int OpCount = PacketOps + ScalarOps;
126 static constexpr bool IsPacketOp() {
127 return Op < PacketOps;
131 static constexpr int CoeffIndex() {
132 return IsPacketOp<Op>() ? (Op * PacketSize) : (FirstScalar + Op - PacketOps);
135 template <int Op, std::enable_if_t<!IsPacketOp<Op>(),
bool> =
true>
136 static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
void visit(
const Derived& mat, Visitor& visitor) {
137 constexpr int K = CoeffIndex<Op>();
138 EIGEN_IF_CONSTEXPR (Op == 0) {
139 visitor.init(mat.coeff(K), K);
141 visitor(mat.coeff(K), K);
145 template <int Op, std::enable_if_t<IsPacketOp<Op>(),
bool> =
true>
146 static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
void visit(
const Derived& mat, Visitor& visitor) {
147 constexpr int K = CoeffIndex<Op>();
148 Packet P = mat.template packet<Packet>(K);
149 EIGEN_IF_CONSTEXPR (Op == 0) {
150 visitor.initpacket(P, K);
152 visitor.packet(P, K);
156 template <
int... Ops>
157 static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
void run_impl(
const Derived& mat, Visitor& visitor,
158 std::integer_sequence<int, Ops...>) {
159 int unused[] = {0, (visit<Ops>(mat, visitor), 0)...};
160 EIGEN_UNUSED_VARIABLE(unused);
163 static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
void run(
const Derived& mat, Visitor& visitor) {
164 run_impl(mat, visitor, std::make_integer_sequence<int, OpCount>{});
169template <
typename Visitor,
typename Derived,
bool ShortCircuitEvaluation>
170struct visitor_impl<Visitor, Derived, Dynamic, false, false, ShortCircuitEvaluation> {
171 using short_circuit = short_circuit_eval_impl<Visitor, ShortCircuitEvaluation>;
172 static constexpr bool RowMajor = Derived::IsRowMajor;
174 static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
void run(
const Derived& mat, Visitor& visitor) {
175 const Index innerSize =
RowMajor ? mat.cols() : mat.rows();
176 const Index outerSize =
RowMajor ? mat.rows() : mat.cols();
177 if (innerSize == 0 || outerSize == 0)
return;
179 visitor.init(mat.coeff(0, 0), 0, 0);
180 if (short_circuit::run(visitor))
return;
181 for (Index i = 1; i < innerSize; ++i) {
184 visitor(mat.coeff(r, c), r, c);
185 if EIGEN_PREDICT_FALSE (short_circuit::run(visitor))
return;
188 for (Index j = 1; j < outerSize; j++) {
189 for (Index i = 0; i < innerSize; ++i) {
192 visitor(mat.coeff(r, c), r, c);
193 if EIGEN_PREDICT_FALSE (short_circuit::run(visitor))
return;
200template <
typename Visitor,
typename Derived,
bool ShortCircuitEvaluation>
201struct visitor_impl<Visitor, Derived, Dynamic, true, false, ShortCircuitEvaluation> {
202 using Scalar =
typename Derived::Scalar;
203 using Packet =
typename packet_traits<Scalar>::type;
204 static constexpr int PacketSize = packet_traits<Scalar>::size;
205 using short_circuit = short_circuit_eval_impl<Visitor, ShortCircuitEvaluation>;
206 static constexpr bool RowMajor = Derived::IsRowMajor;
207 static constexpr bool AlreadyInitialized = visitor_already_initialized<Visitor>::value;
209 static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
void run(
const Derived& mat, Visitor& visitor) {
210 const Index innerSize =
RowMajor ? mat.cols() : mat.rows();
211 const Index outerSize =
RowMajor ? mat.rows() : mat.cols();
212 if (innerSize == 0 || outerSize == 0)
return;
213 EIGEN_IF_CONSTEXPR (!AlreadyInitialized) {
215 if (innerSize < PacketSize) {
216 visitor.init(mat.coeff(0, 0), 0, 0);
219 Packet p = mat.template packet<Packet>(0, 0);
220 visitor.initpacket(p, 0, 0);
223 if EIGEN_PREDICT_FALSE (short_circuit::run(visitor))
return;
224 for (; i + PacketSize - 1 < innerSize; i += PacketSize) {
227 Packet p = mat.template packet<Packet>(r, c);
228 visitor.packet(p, r, c);
229 if EIGEN_PREDICT_FALSE (short_circuit::run(visitor))
return;
231 for (; i < innerSize; ++i) {
234 visitor(mat.coeff(r, c), r, c);
235 if EIGEN_PREDICT_FALSE (short_circuit::run(visitor))
return;
238 const Index packetEnd = innerSize - innerSize % PacketSize;
239 for (Index j = AlreadyInitialized ? 0 : 1; j < outerSize; j++) {
241 for (; AlreadyInitialized ? i < packetEnd : i + PacketSize - 1 < innerSize; i += PacketSize) {
244 Packet p = mat.template packet<Packet>(r, c);
245 visitor.packet(p, r, c);
246 if EIGEN_PREDICT_FALSE (short_circuit::run(visitor))
return;
248 for (; i < innerSize; ++i) {
251 visitor(mat.coeff(r, c), r, c);
252 if EIGEN_PREDICT_FALSE (short_circuit::run(visitor))
return;
259template <
typename Visitor,
typename Derived,
bool ShortCircuitEvaluation>
260struct visitor_impl<Visitor, Derived, Dynamic, false, true, ShortCircuitEvaluation> {
261 using short_circuit = short_circuit_eval_impl<Visitor, ShortCircuitEvaluation>;
263 static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
void run(
const Derived& mat, Visitor& visitor) {
264 const Index size = mat.size();
265 if (size == 0)
return;
266 visitor.init(mat.coeff(0), 0);
267 if EIGEN_PREDICT_FALSE (short_circuit::run(visitor))
return;
268 for (Index k = 1; k < size; k++) {
269 visitor(mat.coeff(k), k);
270 if EIGEN_PREDICT_FALSE (short_circuit::run(visitor))
return;
276template <
typename Visitor,
typename Derived,
bool ShortCircuitEvaluation>
277struct visitor_impl<Visitor, Derived, Dynamic, true, true, ShortCircuitEvaluation> {
278 using Scalar =
typename Derived::Scalar;
279 using Packet =
typename packet_traits<Scalar>::type;
280 static constexpr int PacketSize = packet_traits<Scalar>::size;
281 using short_circuit = short_circuit_eval_impl<Visitor, ShortCircuitEvaluation>;
282 static constexpr bool AlreadyInitialized = visitor_already_initialized<Visitor>::value;
284 static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
void run(
const Derived& mat, Visitor& visitor) {
285 const Index size = mat.size();
286 if (size == 0)
return;
287 const Index packetEnd = size - size % PacketSize;
289 EIGEN_IF_CONSTEXPR (!AlreadyInitialized) {
290 if (size < PacketSize) {
291 visitor.init(mat.coeff(0), 0);
294 Packet p = mat.template packet<Packet>(k);
295 visitor.initpacket(p, k);
298 if EIGEN_PREDICT_FALSE (short_circuit::run(visitor))
return;
300 for (; k < packetEnd; k += PacketSize) {
301 Packet p = mat.template packet<Packet>(k);
302 visitor.packet(p, k);
303 if EIGEN_PREDICT_FALSE (short_circuit::run(visitor))
return;
305 for (; k < size; k++) {
306 visitor(mat.coeff(k), k);
307 if EIGEN_PREDICT_FALSE (short_circuit::run(visitor))
return;
313template <
typename XprType>
314class visitor_evaluator {
316 using Evaluator = evaluator<XprType>;
317 using Scalar =
typename XprType::Scalar;
318 using Packet =
typename packet_traits<Scalar>::type;
319 using CoeffReturnType = std::remove_const_t<typename XprType::CoeffReturnType>;
321 static constexpr bool PacketAccess =
static_cast<bool>(Evaluator::Flags &
PacketAccessBit);
322 static constexpr bool LinearAccess =
static_cast<bool>(Evaluator::Flags &
LinearAccessBit);
323 static constexpr bool IsRowMajor =
static_cast<bool>(XprType::IsRowMajor);
324 static constexpr int RowsAtCompileTime = XprType::RowsAtCompileTime;
325 static constexpr int ColsAtCompileTime = XprType::ColsAtCompileTime;
326 static constexpr int XprAlignment = Evaluator::Alignment;
327 static constexpr int CoeffReadCost = Evaluator::CoeffReadCost;
329 EIGEN_DEVICE_FUNC
explicit visitor_evaluator(
const XprType& xpr) : m_evaluator(xpr), m_xpr(xpr) {}
331 EIGEN_DEVICE_FUNC
constexpr Index rows() const noexcept {
return m_xpr.rows(); }
332 EIGEN_DEVICE_FUNC
constexpr Index cols() const noexcept {
return m_xpr.cols(); }
333 EIGEN_DEVICE_FUNC
constexpr Index size() const noexcept {
return m_xpr.size(); }
335 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE CoeffReturnType coeff(Index row, Index col)
const {
336 return m_evaluator.coeff(row, col);
338 template <
typename Packet,
int Alignment = Unaligned>
339 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet packet(Index row, Index col)
const {
340 return m_evaluator.template packet<Alignment, Packet>(row, col);
343 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE CoeffReturnType coeff(Index index)
const {
return m_evaluator.coeff(index); }
344 template <
typename Packet,
int Alignment = XprAlignment>
345 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet packet(Index index)
const {
346 return m_evaluator.template packet<Alignment, Packet>(index);
350 Evaluator m_evaluator;
351 const XprType& m_xpr;
354template <
typename T,
typename =
void>
355struct visitor_has_linear_access : std::false_type {};
358struct visitor_has_linear_access<T, void_t<decltype(functor_traits<T>::LinearAccess)>>
359 : bool_constant<static_cast<bool>(functor_traits<T>::LinearAccess)> {};
361template <
typename Derived,
typename Visitor,
bool ShortCircuitEvaluation>
363 using Evaluator = visitor_evaluator<Derived>;
375 static constexpr bool LinearAccess = (!ShortCircuitEvaluation || visitor_already_initialized<Visitor>::value) &&
376 Evaluator::LinearAccess && visitor_has_linear_access<Visitor>::value;
377 static constexpr bool Vectorize = Evaluator::PacketAccess &&
static_cast<bool>(functor_traits<Visitor>::PacketAccess);
379 static constexpr int PacketSize = packet_traits<Scalar>::size;
380 static constexpr int VectorOps =
382 : (OuterSizeAtCompileTime * (InnerSizeAtCompileTime / PacketSize)))
386 static constexpr int TotalOps = VectorOps + ScalarOps;
388 static constexpr int UnrollCost = int(Evaluator::CoeffReadCost) + int(functor_traits<Visitor>::Cost);
389 static constexpr bool Unroll = (
SizeAtCompileTime != Dynamic) && ((TotalOps * UnrollCost) <= EIGEN_UNROLLING_LIMIT);
392 using impl = visitor_impl<Visitor, Evaluator, UnrollCount, Vectorize, LinearAccess, ShortCircuitEvaluation>;
394 static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
void run(
const DenseBase<Derived>& mat, Visitor& visitor) {
395 Evaluator evaluator(mat.derived());
396 impl::run(evaluator, visitor);
421template <
typename Derived>
422template <
typename Visitor>
424 using impl = internal::visit_impl<Derived, Visitor,
false>;
425 impl::run(derived(), visitor);
430template <
typename Scalar,
bool Approximate>
431struct fuzzy_constant_visitor {
433 typename NumTraits<Scalar>::Real precision;
436 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
void operator()(
const Scalar& x, Index, Index = 0) {
437 result = result && (Approximate ? internal::isApprox(x, value, precision)
440 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
void init(
const Scalar& x, Index r, Index c = 0) { (*this)(x, r, c); }
441 EIGEN_DEVICE_FUNC
bool done()
const {
return !result; }
442 template <
typename Packet>
443 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
void packet(
const Packet& x, Index, Index = 0) {
444 const Packet p = pset1<Packet>(precision);
446 EIGEN_IF_CONSTEXPR (Approximate) {
447 const Packet v = pset1<Packet>(value);
448 mask = pcmp_le(pabs(psub(x, v)), pmul(pmin(pabs(x), pabs(v)), p));
450 mask = pcmp_le(pabs(x), p);
453 result = result && !predux_any(pandnot(ptrue(mask), mask));
455 template <
typename Packet>
456 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
void initpacket(
const Packet& x, Index r, Index c = 0) {
461template <
typename Scalar,
bool Approximate>
462struct functor_traits<fuzzy_constant_visitor<Scalar, Approximate>> {
463 static constexpr bool AlreadyInitialized =
true;
464 static constexpr bool LinearAccess =
true;
465 static constexpr int Cost = 4 * NumTraits<Scalar>::AddCost + NumTraits<Scalar>::MulCost;
468 static constexpr bool PacketAccess =
469 (std::is_same<Scalar, float>::value || std::is_same<Scalar, double>::value) &&
470 !(EIGEN_ARCH_ARM && std::is_same<Scalar, float>::value) && packet_traits<Scalar>::HasAbs &&
471 packet_traits<Scalar>::HasCmp &&
473 (packet_traits<Scalar>::HasSub && packet_traits<Scalar>::HasMin && packet_traits<Scalar>::HasMul));
476template <
typename Scalar>
477using use_fuzzy_constant_visitor =
478 bool_constant<std::is_same<Scalar, float>::value || std::is_same<Scalar, double>::value>;
480template <
bool Approximate,
typename Derived,
481 std::enable_if_t<use_fuzzy_constant_visitor<typename Derived::Scalar>::value,
int> = 0>
482EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
bool fuzzy_constant_all(
const Derived& matrix,
483 const typename Derived::Scalar& value,
484 const typename Derived::RealScalar& precision) {
485 fuzzy_constant_visitor<typename Derived::Scalar, Approximate> visitor{value, precision};
486 visit_impl<Derived,
decltype(visitor),
true>::run(matrix, visitor);
487 return visitor.result;
491template <
bool Approximate,
typename Derived,
492 std::enable_if_t<!use_fuzzy_constant_visitor<typename Derived::Scalar>::value && Approximate,
int> = 0>
493EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
bool fuzzy_constant_all(
const Derived& matrix,
494 const typename Derived::Scalar& value,
495 const typename Derived::RealScalar& precision) {
496 for (Index j = 0; j < matrix.cols(); ++j)
497 for (Index i = 0; i < matrix.rows(); ++i)
498 if (!internal::isApprox(matrix.coeff(i, j), value, precision))
return false;
502template <
bool Approximate,
typename Derived,
503 std::enable_if_t<!use_fuzzy_constant_visitor<typename Derived::Scalar>::value && !Approximate,
int> = 0>
504EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
bool fuzzy_constant_all(
const Derived& matrix,
const typename Derived::Scalar&,
505 const typename Derived::RealScalar& precision) {
506 using Scalar =
typename Derived::Scalar;
507 for (Index j = 0; j < matrix.cols(); ++j)
508 for (Index i = 0; i < matrix.rows(); ++i)
509 if (!internal::isMuchSmallerThan(matrix.coeff(i, j), Scalar(1), precision))
return false;
513template <
typename Scalar>
515 using result_type = bool;
516 using Packet =
typename packet_traits<Scalar>::type;
517 EIGEN_DEVICE_FUNC
inline void init(
const Scalar& value, Index, Index) { res = (value != Scalar(0)); }
518 EIGEN_DEVICE_FUNC
inline void init(
const Scalar& value, Index) { res = (value != Scalar(0)); }
519 EIGEN_DEVICE_FUNC
inline bool all_predux(
const Packet& p)
const {
return predux_all(p); }
520 EIGEN_DEVICE_FUNC
inline void initpacket(
const Packet& p, Index, Index) { res = all_predux(p); }
521 EIGEN_DEVICE_FUNC
inline void initpacket(
const Packet& p, Index) { res = all_predux(p); }
522 EIGEN_DEVICE_FUNC
inline void operator()(
const Scalar& value, Index, Index) { res = res && (value != Scalar(0)); }
523 EIGEN_DEVICE_FUNC
inline void operator()(
const Scalar& value, Index) { res = res && (value != Scalar(0)); }
524 EIGEN_DEVICE_FUNC
inline void packet(
const Packet& p, Index, Index) { res = res && all_predux(p); }
525 EIGEN_DEVICE_FUNC
inline void packet(
const Packet& p, Index) { res = res && all_predux(p); }
526 EIGEN_DEVICE_FUNC
inline bool done()
const {
return !res; }
529template <
typename Scalar>
530struct functor_traits<all_visitor<Scalar>> {
531 enum { Cost = NumTraits<Scalar>::ReadCost, LinearAccess =
true, PacketAccess = packet_traits<Scalar>::HasCmp };
534template <
typename Scalar>
536 using result_type = bool;
537 using Packet =
typename packet_traits<Scalar>::type;
538 EIGEN_DEVICE_FUNC
inline void init(
const Scalar& value, Index, Index) { res = (value != Scalar(0)); }
539 EIGEN_DEVICE_FUNC
inline void init(
const Scalar& value, Index) { res = (value != Scalar(0)); }
540 EIGEN_DEVICE_FUNC
inline bool any_predux(
const Packet& p)
const {
541 return predux_any(pandnot(ptrue(p), pcmp_eq(p, pzero(p))));
543 EIGEN_DEVICE_FUNC
inline void initpacket(
const Packet& p, Index, Index) { res = any_predux(p); }
544 EIGEN_DEVICE_FUNC
inline void initpacket(
const Packet& p, Index) { res = any_predux(p); }
545 EIGEN_DEVICE_FUNC
inline void operator()(
const Scalar& value, Index, Index) { res = res || (value != Scalar(0)); }
546 EIGEN_DEVICE_FUNC
inline void operator()(
const Scalar& value, Index) { res = res || (value != Scalar(0)); }
547 EIGEN_DEVICE_FUNC
inline void packet(
const Packet& p, Index, Index) { res = res || any_predux(p); }
548 EIGEN_DEVICE_FUNC
inline void packet(
const Packet& p, Index) { res = res || any_predux(p); }
549 EIGEN_DEVICE_FUNC
inline bool done()
const {
return res; }
553EIGEN_DEVICE_FUNC
inline bool any_visitor<bool>::any_predux(
const Packet& p)
const {
556template <
typename Scalar>
557struct functor_traits<any_visitor<Scalar>> {
558 enum { Cost = NumTraits<Scalar>::ReadCost, LinearAccess =
true, PacketAccess = packet_traits<Scalar>::HasCmp };
561template <
typename Scalar>
562struct count_visitor {
563 using result_type = Index;
564 using Packet =
typename packet_traits<Scalar>::type;
565 EIGEN_DEVICE_FUNC
inline void init(
const Scalar& value, Index, Index) { res = value != Scalar(0) ? 1 : 0; }
566 EIGEN_DEVICE_FUNC
inline void init(
const Scalar& value, Index) { res = value != Scalar(0) ? 1 : 0; }
567 EIGEN_DEVICE_FUNC
inline Index count_redux(
const Packet& p)
const {
return predux_count(p); }
568 EIGEN_DEVICE_FUNC
inline void initpacket(
const Packet& p, Index, Index) { res = count_redux(p); }
569 EIGEN_DEVICE_FUNC
inline void initpacket(
const Packet& p, Index) { res = count_redux(p); }
570 EIGEN_DEVICE_FUNC
inline void operator()(
const Scalar& value, Index, Index) {
571 if (value != Scalar(0)) res++;
573 EIGEN_DEVICE_FUNC
inline void operator()(
const Scalar& value, Index) {
574 if (value != Scalar(0)) res++;
576 EIGEN_DEVICE_FUNC
inline void packet(
const Packet& p, Index, Index) { res += count_redux(p); }
577 EIGEN_DEVICE_FUNC
inline void packet(
const Packet& p, Index) { res += count_redux(p); }
581template <
typename Scalar>
582struct functor_traits<count_visitor<Scalar>> {
584 Cost = NumTraits<Scalar>::AddCost,
586 PacketAccess = packet_traits<Scalar>::HasCmp && packet_traits<Scalar>::HasAdd
593template <
typename Scalar>
594struct all_finite_visitor {
595 using result_type = bool;
596 using Packet =
typename packet_traits<Scalar>::type;
597 EIGEN_DEVICE_FUNC
inline bool finite_predux(
const Packet& p)
const {
return !predux_any(pnot(pisfinite(p))); }
598 EIGEN_DEVICE_FUNC
inline void init(
const Scalar& value, Index, Index) { res = (numext::isfinite)(value); }
599 EIGEN_DEVICE_FUNC
inline void init(
const Scalar& value, Index) { res = (numext::isfinite)(value); }
600 EIGEN_DEVICE_FUNC
inline void initpacket(
const Packet& p, Index, Index) { res = finite_predux(p); }
601 EIGEN_DEVICE_FUNC
inline void initpacket(
const Packet& p, Index) { res = finite_predux(p); }
602 EIGEN_DEVICE_FUNC
inline void operator()(
const Scalar& value, Index, Index) {
603 res = res && (numext::isfinite)(value);
605 EIGEN_DEVICE_FUNC
inline void operator()(
const Scalar& value, Index) { res = res && (numext::isfinite)(value); }
606 EIGEN_DEVICE_FUNC
inline void packet(
const Packet& p, Index, Index) { res = res && finite_predux(p); }
607 EIGEN_DEVICE_FUNC
inline void packet(
const Packet& p, Index) { res = res && finite_predux(p); }
608 EIGEN_DEVICE_FUNC
inline bool done()
const {
return !res; }
611template <
typename Scalar>
612struct functor_traits<all_finite_visitor<Scalar>> {
614 Cost = NumTraits<Scalar>::ReadCost + NumTraits<Scalar>::MulCost,
616 PacketAccess = packet_traits<Scalar>::HasCmp
620template <typename Derived, bool AlwaysTrue = NumTraits<typename traits<Derived>::Scalar>::IsInteger>
621struct all_finite_impl {
622 static EIGEN_DEVICE_FUNC
inline bool run(
const Derived& ) {
return true; }
624#if !defined(__FINITE_MATH_ONLY__) || !(__FINITE_MATH_ONLY__)
625template <
typename Derived>
626struct all_finite_impl<Derived, false> {
627 static EIGEN_DEVICE_FUNC
inline bool run(
const Derived& derived) {
628 using Visitor = all_finite_visitor<typename traits<Derived>::Scalar>;
630 visit_impl<Derived, Visitor,
true>::run(derived, visitor);
645template <
typename Derived>
647 using Visitor = internal::all_visitor<Scalar>;
648 using impl = internal::visit_impl<Derived, Visitor,
true>;
650 impl::run(derived(), visitor);
658template <
typename Derived>
660 using Visitor = internal::any_visitor<Scalar>;
661 using impl = internal::visit_impl<Derived, Visitor,
true>;
663 impl::run(derived(), visitor);
671template <
typename Derived>
673 using Visitor = internal::count_visitor<Scalar>;
674 using impl = internal::visit_impl<Derived, Visitor,
false>;
676 impl::run(derived(), visitor);
680template <
typename Derived>
681EIGEN_DEVICE_FUNC
inline bool DenseBase<Derived>::hasNaN()
const {
682 return derived().cwiseTypedNotEqual(derived()).any();
689template <
typename Derived>
691 return internal::all_finite_impl<Derived>::run(derived());
695template <
typename Derived>
697 const RealScalar& prec)
const {
698 typename internal::nested_eval<Derived, 1>::type self(derived());
699 return internal::fuzzy_constant_all<true>(self, val, prec);
710template <
typename Derived>
712 typename internal::nested_eval<Derived, 1>::type self(derived());
713 return internal::fuzzy_constant_all<false>(self,
Scalar(0), prec);
void visit(Visitor &func) const
Definition Visitor.h:423
constexpr bool isMuchSmallerThan(const typename NumTraits< Scalar >::Real &other, const RealScalar &prec) const
Definition ApproxComparisons.h:440
@ SizeAtCompileTime
Definition DenseBase.h:109
@ IsRowMajor
Definition DenseBase.h:167
@ ColsAtCompileTime
Definition DenseBase.h:103
@ RowsAtCompileTime
Definition DenseBase.h:97
constexpr DenseBase()=default
typename internal::traits< ArrayWrapper< ExpressionType > >::Scalar Scalar
Definition DenseBase.h:63
Index count() const
Definition Visitor.h:672
bool any() const
Definition Visitor.h:659
bool all() const
Definition Visitor.h:646
bool allFinite() const
Definition Visitor.h:690
bool isZero(const RealScalar &prec=NumTraits< Scalar >::dummy_precision()) const
Definition Visitor.h:711
bool isApproxToConstant(const Scalar &value, const RealScalar &prec=NumTraits< Scalar >::dummy_precision()) const
Definition Visitor.h:696
@ RowMajor
Definition Constants.h:321
constexpr unsigned int PacketAccessBit
Definition Constants.h:98
constexpr unsigned int LinearAccessBit
Definition Constants.h:134