Please, help us to better know about our user community by answering the following short survey: https://forms.gle/wpyrxWi18ox9Z5ae9
Eigen  3.3.8
MathFunctions.h
1 // This file is part of Eigen, a lightweight C++ template library
2 // for linear algebra.
3 //
4 // Copyright (C) 2006-2010 Benoit Jacob <jacob.benoit.1@gmail.com>
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_MATHFUNCTIONS_H
11 #define EIGEN_MATHFUNCTIONS_H
12 
13 // source: http://www.geom.uiuc.edu/~huberty/math5337/groupe/digits.html
14 // TODO this should better be moved to NumTraits
15 #define EIGEN_PI 3.141592653589793238462643383279502884197169399375105820974944592307816406L
16 
17 
18 namespace Eigen {
19 
20 // On WINCE, std::abs is defined for int only, so let's defined our own overloads:
21 // This issue has been confirmed with MSVC 2008 only, but the issue might exist for more recent versions too.
22 #if EIGEN_OS_WINCE && EIGEN_COMP_MSVC && EIGEN_COMP_MSVC<=1500
23 long abs(long x) { return (labs(x)); }
24 double abs(double x) { return (fabs(x)); }
25 float abs(float x) { return (fabsf(x)); }
26 long double abs(long double x) { return (fabsl(x)); }
27 #endif
28 
29 namespace internal {
30 
51 template<typename T, typename dummy = void>
52 struct global_math_functions_filtering_base
53 {
54  typedef T type;
55 };
56 
57 template<typename T> struct always_void { typedef void type; };
58 
59 template<typename T>
60 struct global_math_functions_filtering_base
61  <T,
62  typename always_void<typename T::Eigen_BaseClassForSpecializationOfGlobalMathFuncImpl>::type
63  >
64 {
65  typedef typename T::Eigen_BaseClassForSpecializationOfGlobalMathFuncImpl type;
66 };
67 
68 #define EIGEN_MATHFUNC_IMPL(func, scalar) Eigen::internal::func##_impl<typename Eigen::internal::global_math_functions_filtering_base<scalar>::type>
69 #define EIGEN_MATHFUNC_RETVAL(func, scalar) typename Eigen::internal::func##_retval<typename Eigen::internal::global_math_functions_filtering_base<scalar>::type>::type
70 
71 /****************************************************************************
72 * Implementation of real *
73 ****************************************************************************/
74 
75 template<typename Scalar, bool IsComplex = NumTraits<Scalar>::IsComplex>
76 struct real_default_impl
77 {
78  typedef typename NumTraits<Scalar>::Real RealScalar;
79  EIGEN_DEVICE_FUNC
80  static inline RealScalar run(const Scalar& x)
81  {
82  return x;
83  }
84 };
85 
86 template<typename Scalar>
87 struct real_default_impl<Scalar,true>
88 {
89  typedef typename NumTraits<Scalar>::Real RealScalar;
90  EIGEN_DEVICE_FUNC
91  static inline RealScalar run(const Scalar& x)
92  {
93  using std::real;
94  return real(x);
95  }
96 };
97 
98 template<typename Scalar> struct real_impl : real_default_impl<Scalar> {};
99 
100 #ifdef __CUDA_ARCH__
101 template<typename T>
102 struct real_impl<std::complex<T> >
103 {
104  typedef T RealScalar;
105  EIGEN_DEVICE_FUNC
106  static inline T run(const std::complex<T>& x)
107  {
108  return x.real();
109  }
110 };
111 #endif
112 
113 template<typename Scalar>
114 struct real_retval
115 {
116  typedef typename NumTraits<Scalar>::Real type;
117 };
118 
119 /****************************************************************************
120 * Implementation of imag *
121 ****************************************************************************/
122 
123 template<typename Scalar, bool IsComplex = NumTraits<Scalar>::IsComplex>
124 struct imag_default_impl
125 {
126  typedef typename NumTraits<Scalar>::Real RealScalar;
127  EIGEN_DEVICE_FUNC
128  static inline RealScalar run(const Scalar&)
129  {
130  return RealScalar(0);
131  }
132 };
133 
134 template<typename Scalar>
135 struct imag_default_impl<Scalar,true>
136 {
137  typedef typename NumTraits<Scalar>::Real RealScalar;
138  EIGEN_DEVICE_FUNC
139  static inline RealScalar run(const Scalar& x)
140  {
141  using std::imag;
142  return imag(x);
143  }
144 };
145 
146 template<typename Scalar> struct imag_impl : imag_default_impl<Scalar> {};
147 
148 #ifdef __CUDA_ARCH__
149 template<typename T>
150 struct imag_impl<std::complex<T> >
151 {
152  typedef T RealScalar;
153  EIGEN_DEVICE_FUNC
154  static inline T run(const std::complex<T>& x)
155  {
156  return x.imag();
157  }
158 };
159 #endif
160 
161 template<typename Scalar>
162 struct imag_retval
163 {
164  typedef typename NumTraits<Scalar>::Real type;
165 };
166 
167 /****************************************************************************
168 * Implementation of real_ref *
169 ****************************************************************************/
170 
171 template<typename Scalar>
172 struct real_ref_impl
173 {
174  typedef typename NumTraits<Scalar>::Real RealScalar;
175  EIGEN_DEVICE_FUNC
176  static inline RealScalar& run(Scalar& x)
177  {
178  return reinterpret_cast<RealScalar*>(&x)[0];
179  }
180  EIGEN_DEVICE_FUNC
181  static inline const RealScalar& run(const Scalar& x)
182  {
183  return reinterpret_cast<const RealScalar*>(&x)[0];
184  }
185 };
186 
187 template<typename Scalar>
188 struct real_ref_retval
189 {
190  typedef typename NumTraits<Scalar>::Real & type;
191 };
192 
193 /****************************************************************************
194 * Implementation of imag_ref *
195 ****************************************************************************/
196 
197 template<typename Scalar, bool IsComplex>
198 struct imag_ref_default_impl
199 {
200  typedef typename NumTraits<Scalar>::Real RealScalar;
201  EIGEN_DEVICE_FUNC
202  static inline RealScalar& run(Scalar& x)
203  {
204  return reinterpret_cast<RealScalar*>(&x)[1];
205  }
206  EIGEN_DEVICE_FUNC
207  static inline const RealScalar& run(const Scalar& x)
208  {
209  return reinterpret_cast<RealScalar*>(&x)[1];
210  }
211 };
212 
213 template<typename Scalar>
214 struct imag_ref_default_impl<Scalar, false>
215 {
216  EIGEN_DEVICE_FUNC
217  static inline Scalar run(Scalar&)
218  {
219  return Scalar(0);
220  }
221  EIGEN_DEVICE_FUNC
222  static inline const Scalar run(const Scalar&)
223  {
224  return Scalar(0);
225  }
226 };
227 
228 template<typename Scalar>
229 struct imag_ref_impl : imag_ref_default_impl<Scalar, NumTraits<Scalar>::IsComplex> {};
230 
231 template<typename Scalar>
232 struct imag_ref_retval
233 {
234  typedef typename NumTraits<Scalar>::Real & type;
235 };
236 
237 /****************************************************************************
238 * Implementation of conj *
239 ****************************************************************************/
240 
241 template<typename Scalar, bool IsComplex = NumTraits<Scalar>::IsComplex>
242 struct conj_impl
243 {
244  EIGEN_DEVICE_FUNC
245  static inline Scalar run(const Scalar& x)
246  {
247  return x;
248  }
249 };
250 
251 template<typename Scalar>
252 struct conj_impl<Scalar,true>
253 {
254  EIGEN_DEVICE_FUNC
255  static inline Scalar run(const Scalar& x)
256  {
257  using std::conj;
258  return conj(x);
259  }
260 };
261 
262 template<typename Scalar>
263 struct conj_retval
264 {
265  typedef Scalar type;
266 };
267 
268 /****************************************************************************
269 * Implementation of abs2 *
270 ****************************************************************************/
271 
272 template<typename Scalar,bool IsComplex>
273 struct abs2_impl_default
274 {
275  typedef typename NumTraits<Scalar>::Real RealScalar;
276  EIGEN_DEVICE_FUNC
277  static inline RealScalar run(const Scalar& x)
278  {
279  return x*x;
280  }
281 };
282 
283 template<typename Scalar>
284 struct abs2_impl_default<Scalar, true> // IsComplex
285 {
286  typedef typename NumTraits<Scalar>::Real RealScalar;
287  EIGEN_DEVICE_FUNC
288  static inline RealScalar run(const Scalar& x)
289  {
290  return x.real()*x.real() + x.imag()*x.imag();
291  }
292 };
293 
294 template<typename Scalar>
295 struct abs2_impl
296 {
297  typedef typename NumTraits<Scalar>::Real RealScalar;
298  EIGEN_DEVICE_FUNC
299  static inline RealScalar run(const Scalar& x)
300  {
301  return abs2_impl_default<Scalar,NumTraits<Scalar>::IsComplex>::run(x);
302  }
303 };
304 
305 template<typename Scalar>
306 struct abs2_retval
307 {
308  typedef typename NumTraits<Scalar>::Real type;
309 };
310 
311 /****************************************************************************
312 * Implementation of norm1 *
313 ****************************************************************************/
314 
315 template<typename Scalar, bool IsComplex>
316 struct norm1_default_impl;
317 
318 template<typename Scalar>
319 struct norm1_default_impl<Scalar,true>
320 {
321  typedef typename NumTraits<Scalar>::Real RealScalar;
322  EIGEN_DEVICE_FUNC
323  static inline RealScalar run(const Scalar& x)
324  {
325  EIGEN_USING_STD_MATH(abs);
326  return abs(x.real()) + abs(x.imag());
327  }
328 };
329 
330 template<typename Scalar>
331 struct norm1_default_impl<Scalar, false>
332 {
333  EIGEN_DEVICE_FUNC
334  static inline Scalar run(const Scalar& x)
335  {
336  EIGEN_USING_STD_MATH(abs);
337  return abs(x);
338  }
339 };
340 
341 template<typename Scalar>
342 struct norm1_impl : norm1_default_impl<Scalar, NumTraits<Scalar>::IsComplex> {};
343 
344 template<typename Scalar>
345 struct norm1_retval
346 {
347  typedef typename NumTraits<Scalar>::Real type;
348 };
349 
350 /****************************************************************************
351 * Implementation of hypot *
352 ****************************************************************************/
353 
354 template<typename Scalar> struct hypot_impl;
355 
356 template<typename Scalar>
357 struct hypot_retval
358 {
359  typedef typename NumTraits<Scalar>::Real type;
360 };
361 
362 /****************************************************************************
363 * Implementation of cast *
364 ****************************************************************************/
365 
366 template<typename OldType, typename NewType>
367 struct cast_impl
368 {
369  EIGEN_DEVICE_FUNC
370  static inline NewType run(const OldType& x)
371  {
372  return static_cast<NewType>(x);
373  }
374 };
375 
376 // here, for once, we're plainly returning NewType: we don't want cast to do weird things.
377 
378 template<typename OldType, typename NewType>
379 EIGEN_DEVICE_FUNC
380 inline NewType cast(const OldType& x)
381 {
382  return cast_impl<OldType, NewType>::run(x);
383 }
384 
385 /****************************************************************************
386 * Implementation of round *
387 ****************************************************************************/
388 
389 #if EIGEN_HAS_CXX11_MATH
390  template<typename Scalar>
391  struct round_impl {
392  static inline Scalar run(const Scalar& x)
393  {
394  EIGEN_STATIC_ASSERT((!NumTraits<Scalar>::IsComplex), NUMERIC_TYPE_MUST_BE_REAL)
395  using std::round;
396  return round(x);
397  }
398  };
399 #else
400  template<typename Scalar>
401  struct round_impl
402  {
403  static inline Scalar run(const Scalar& x)
404  {
405  EIGEN_STATIC_ASSERT((!NumTraits<Scalar>::IsComplex), NUMERIC_TYPE_MUST_BE_REAL)
406  EIGEN_USING_STD_MATH(floor);
407  EIGEN_USING_STD_MATH(ceil);
408  return (x > Scalar(0)) ? floor(x + Scalar(0.5)) : ceil(x - Scalar(0.5));
409  }
410  };
411 #endif
412 
413 template<typename Scalar>
414 struct round_retval
415 {
416  typedef Scalar type;
417 };
418 
419 /****************************************************************************
420 * Implementation of arg *
421 ****************************************************************************/
422 
423 #if EIGEN_HAS_CXX11_MATH
424  template<typename Scalar>
425  struct arg_impl {
426  static inline Scalar run(const Scalar& x)
427  {
428  EIGEN_USING_STD_MATH(arg);
429  return arg(x);
430  }
431  };
432 #else
433  template<typename Scalar, bool IsComplex = NumTraits<Scalar>::IsComplex>
434  struct arg_default_impl
435  {
436  typedef typename NumTraits<Scalar>::Real RealScalar;
437  EIGEN_DEVICE_FUNC
438  static inline RealScalar run(const Scalar& x)
439  {
440  return (x < Scalar(0)) ? Scalar(EIGEN_PI) : Scalar(0); }
441  };
442 
443  template<typename Scalar>
444  struct arg_default_impl<Scalar,true>
445  {
446  typedef typename NumTraits<Scalar>::Real RealScalar;
447  EIGEN_DEVICE_FUNC
448  static inline RealScalar run(const Scalar& x)
449  {
450  EIGEN_USING_STD_MATH(arg);
451  return arg(x);
452  }
453  };
454 
455  template<typename Scalar> struct arg_impl : arg_default_impl<Scalar> {};
456 #endif
457 
458 template<typename Scalar>
459 struct arg_retval
460 {
461  typedef typename NumTraits<Scalar>::Real type;
462 };
463 
464 /****************************************************************************
465 * Implementation of log1p *
466 ****************************************************************************/
467 
468 namespace std_fallback {
469  // fallback log1p implementation in case there is no log1p(Scalar) function in namespace of Scalar,
470  // or that there is no suitable std::log1p function available
471  template<typename Scalar>
472  EIGEN_DEVICE_FUNC inline Scalar log1p(const Scalar& x) {
473  EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar)
474  typedef typename NumTraits<Scalar>::Real RealScalar;
475  EIGEN_USING_STD_MATH(log);
476  Scalar x1p = RealScalar(1) + x;
477  return numext::equal_strict(x1p, Scalar(1)) ? x : x * ( log(x1p) / (x1p - RealScalar(1)) );
478  }
479 }
480 
481 template<typename Scalar>
482 struct log1p_impl {
483  static inline Scalar run(const Scalar& x)
484  {
485  EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar)
486  #if EIGEN_HAS_CXX11_MATH
487  using std::log1p;
488  #endif
489  using std_fallback::log1p;
490  return log1p(x);
491  }
492 };
493 
494 
495 template<typename Scalar>
496 struct log1p_retval
497 {
498  typedef Scalar type;
499 };
500 
501 /****************************************************************************
502 * Implementation of pow *
503 ****************************************************************************/
504 
505 template<typename ScalarX,typename ScalarY, bool IsInteger = NumTraits<ScalarX>::IsInteger&&NumTraits<ScalarY>::IsInteger>
506 struct pow_impl
507 {
508  //typedef Scalar retval;
509  typedef typename ScalarBinaryOpTraits<ScalarX,ScalarY,internal::scalar_pow_op<ScalarX,ScalarY> >::ReturnType result_type;
510  static EIGEN_DEVICE_FUNC inline result_type run(const ScalarX& x, const ScalarY& y)
511  {
512  EIGEN_USING_STD_MATH(pow);
513  return pow(x, y);
514  }
515 };
516 
517 template<typename ScalarX,typename ScalarY>
518 struct pow_impl<ScalarX,ScalarY, true>
519 {
520  typedef ScalarX result_type;
521  static EIGEN_DEVICE_FUNC inline ScalarX run(ScalarX x, ScalarY y)
522  {
523  ScalarX res(1);
524  eigen_assert(!NumTraits<ScalarY>::IsSigned || y >= 0);
525  if(y & 1) res *= x;
526  y >>= 1;
527  while(y)
528  {
529  x *= x;
530  if(y&1) res *= x;
531  y >>= 1;
532  }
533  return res;
534  }
535 };
536 
537 /****************************************************************************
538 * Implementation of random *
539 ****************************************************************************/
540 
541 template<typename Scalar,
542  bool IsComplex,
543  bool IsInteger>
544 struct random_default_impl {};
545 
546 template<typename Scalar>
547 struct random_impl : random_default_impl<Scalar, NumTraits<Scalar>::IsComplex, NumTraits<Scalar>::IsInteger> {};
548 
549 template<typename Scalar>
550 struct random_retval
551 {
552  typedef Scalar type;
553 };
554 
555 template<typename Scalar> inline EIGEN_MATHFUNC_RETVAL(random, Scalar) random(const Scalar& x, const Scalar& y);
556 template<typename Scalar> inline EIGEN_MATHFUNC_RETVAL(random, Scalar) random();
557 
558 template<typename Scalar>
559 struct random_default_impl<Scalar, false, false>
560 {
561  static inline Scalar run(const Scalar& x, const Scalar& y)
562  {
563  return x + (y-x) * Scalar(std::rand()) / Scalar(RAND_MAX);
564  }
565  static inline Scalar run()
566  {
567  return run(Scalar(NumTraits<Scalar>::IsSigned ? -1 : 0), Scalar(1));
568  }
569 };
570 
571 enum {
572  meta_floor_log2_terminate,
573  meta_floor_log2_move_up,
574  meta_floor_log2_move_down,
575  meta_floor_log2_bogus
576 };
577 
578 template<unsigned int n, int lower, int upper> struct meta_floor_log2_selector
579 {
580  enum { middle = (lower + upper) / 2,
581  value = (upper <= lower + 1) ? int(meta_floor_log2_terminate)
582  : (n < (1 << middle)) ? int(meta_floor_log2_move_down)
583  : (n==0) ? int(meta_floor_log2_bogus)
584  : int(meta_floor_log2_move_up)
585  };
586 };
587 
588 template<unsigned int n,
589  int lower = 0,
590  int upper = sizeof(unsigned int) * CHAR_BIT - 1,
591  int selector = meta_floor_log2_selector<n, lower, upper>::value>
592 struct meta_floor_log2 {};
593 
594 template<unsigned int n, int lower, int upper>
595 struct meta_floor_log2<n, lower, upper, meta_floor_log2_move_down>
596 {
597  enum { value = meta_floor_log2<n, lower, meta_floor_log2_selector<n, lower, upper>::middle>::value };
598 };
599 
600 template<unsigned int n, int lower, int upper>
601 struct meta_floor_log2<n, lower, upper, meta_floor_log2_move_up>
602 {
603  enum { value = meta_floor_log2<n, meta_floor_log2_selector<n, lower, upper>::middle, upper>::value };
604 };
605 
606 template<unsigned int n, int lower, int upper>
607 struct meta_floor_log2<n, lower, upper, meta_floor_log2_terminate>
608 {
609  enum { value = (n >= ((unsigned int)(1) << (lower+1))) ? lower+1 : lower };
610 };
611 
612 template<unsigned int n, int lower, int upper>
613 struct meta_floor_log2<n, lower, upper, meta_floor_log2_bogus>
614 {
615  // no value, error at compile time
616 };
617 
618 template<typename Scalar>
619 struct random_default_impl<Scalar, false, true>
620 {
621  static inline Scalar run(const Scalar& x, const Scalar& y)
622  {
623  if (y <= x)
624  return x;
625  // ScalarU is the unsigned counterpart of Scalar, possibly Scalar itself.
626  typedef typename make_unsigned<Scalar>::type ScalarU;
627  // ScalarX is the widest of ScalarU and unsigned int.
628  // We'll deal only with ScalarX and unsigned int below thus avoiding signed
629  // types and arithmetic and signed overflows (which are undefined behavior).
630  typedef typename conditional<(ScalarU(-1) > unsigned(-1)), ScalarU, unsigned>::type ScalarX;
631  // The following difference doesn't overflow, provided our integer types are two's
632  // complement and have the same number of padding bits in signed and unsigned variants.
633  // This is the case in most modern implementations of C++.
634  ScalarX range = ScalarX(y) - ScalarX(x);
635  ScalarX offset = 0;
636  ScalarX divisor = 1;
637  ScalarX multiplier = 1;
638  const unsigned rand_max = RAND_MAX;
639  if (range <= rand_max) divisor = (rand_max + 1) / (range + 1);
640  else multiplier = 1 + range / (rand_max + 1);
641  // Rejection sampling.
642  do {
643  offset = (unsigned(std::rand()) * multiplier) / divisor;
644  } while (offset > range);
645  return Scalar(ScalarX(x) + offset);
646  }
647 
648  static inline Scalar run()
649  {
650 #ifdef EIGEN_MAKING_DOCS
651  return run(Scalar(NumTraits<Scalar>::IsSigned ? -10 : 0), Scalar(10));
652 #else
653  enum { rand_bits = meta_floor_log2<(unsigned int)(RAND_MAX)+1>::value,
654  scalar_bits = sizeof(Scalar) * CHAR_BIT,
655  shift = EIGEN_PLAIN_ENUM_MAX(0, int(rand_bits) - int(scalar_bits)),
656  offset = NumTraits<Scalar>::IsSigned ? (1 << (EIGEN_PLAIN_ENUM_MIN(rand_bits,scalar_bits)-1)) : 0
657  };
658  return Scalar((std::rand() >> shift) - offset);
659 #endif
660  }
661 };
662 
663 template<typename Scalar>
664 struct random_default_impl<Scalar, true, false>
665 {
666  static inline Scalar run(const Scalar& x, const Scalar& y)
667  {
668  return Scalar(random(x.real(), y.real()),
669  random(x.imag(), y.imag()));
670  }
671  static inline Scalar run()
672  {
673  typedef typename NumTraits<Scalar>::Real RealScalar;
674  return Scalar(random<RealScalar>(), random<RealScalar>());
675  }
676 };
677 
678 template<typename Scalar>
679 inline EIGEN_MATHFUNC_RETVAL(random, Scalar) random(const Scalar& x, const Scalar& y)
680 {
681  return EIGEN_MATHFUNC_IMPL(random, Scalar)::run(x, y);
682 }
683 
684 template<typename Scalar>
685 inline EIGEN_MATHFUNC_RETVAL(random, Scalar) random()
686 {
687  return EIGEN_MATHFUNC_IMPL(random, Scalar)::run();
688 }
689 
690 // Implementatin of is* functions
691 
692 // std::is* do not work with fast-math and gcc, std::is* are available on MSVC 2013 and newer, as well as in clang.
693 #if (EIGEN_HAS_CXX11_MATH && !(EIGEN_COMP_GNUC_STRICT && __FINITE_MATH_ONLY__)) || (EIGEN_COMP_MSVC>=1800) || (EIGEN_COMP_CLANG)
694 #define EIGEN_USE_STD_FPCLASSIFY 1
695 #else
696 #define EIGEN_USE_STD_FPCLASSIFY 0
697 #endif
698 
699 template<typename T>
700 EIGEN_DEVICE_FUNC
701 typename internal::enable_if<internal::is_integral<T>::value,bool>::type
702 isnan_impl(const T&) { return false; }
703 
704 template<typename T>
705 EIGEN_DEVICE_FUNC
706 typename internal::enable_if<internal::is_integral<T>::value,bool>::type
707 isinf_impl(const T&) { return false; }
708 
709 template<typename T>
710 EIGEN_DEVICE_FUNC
711 typename internal::enable_if<internal::is_integral<T>::value,bool>::type
712 isfinite_impl(const T&) { return true; }
713 
714 template<typename T>
715 EIGEN_DEVICE_FUNC
716 typename internal::enable_if<(!internal::is_integral<T>::value)&&(!NumTraits<T>::IsComplex),bool>::type
717 isfinite_impl(const T& x)
718 {
719  #ifdef __CUDA_ARCH__
720  return (::isfinite)(x);
721  #elif EIGEN_USE_STD_FPCLASSIFY
722  using std::isfinite;
723  return isfinite EIGEN_NOT_A_MACRO (x);
724  #else
725  return x<=NumTraits<T>::highest() && x>=NumTraits<T>::lowest();
726  #endif
727 }
728 
729 template<typename T>
730 EIGEN_DEVICE_FUNC
731 typename internal::enable_if<(!internal::is_integral<T>::value)&&(!NumTraits<T>::IsComplex),bool>::type
732 isinf_impl(const T& x)
733 {
734  #ifdef __CUDA_ARCH__
735  return (::isinf)(x);
736  #elif EIGEN_USE_STD_FPCLASSIFY
737  using std::isinf;
738  return isinf EIGEN_NOT_A_MACRO (x);
739  #else
740  return x>NumTraits<T>::highest() || x<NumTraits<T>::lowest();
741  #endif
742 }
743 
744 template<typename T>
745 EIGEN_DEVICE_FUNC
746 typename internal::enable_if<(!internal::is_integral<T>::value)&&(!NumTraits<T>::IsComplex),bool>::type
747 isnan_impl(const T& x)
748 {
749  #ifdef __CUDA_ARCH__
750  return (::isnan)(x);
751  #elif EIGEN_USE_STD_FPCLASSIFY
752  using std::isnan;
753  return isnan EIGEN_NOT_A_MACRO (x);
754  #else
755  return x != x;
756  #endif
757 }
758 
759 #if (!EIGEN_USE_STD_FPCLASSIFY)
760 
761 #if EIGEN_COMP_MSVC
762 
763 template<typename T> EIGEN_DEVICE_FUNC bool isinf_msvc_helper(T x)
764 {
765  return _fpclass(x)==_FPCLASS_NINF || _fpclass(x)==_FPCLASS_PINF;
766 }
767 
768 //MSVC defines a _isnan builtin function, but for double only
769 EIGEN_DEVICE_FUNC inline bool isnan_impl(const long double& x) { return _isnan(x)!=0; }
770 EIGEN_DEVICE_FUNC inline bool isnan_impl(const double& x) { return _isnan(x)!=0; }
771 EIGEN_DEVICE_FUNC inline bool isnan_impl(const float& x) { return _isnan(x)!=0; }
772 
773 EIGEN_DEVICE_FUNC inline bool isinf_impl(const long double& x) { return isinf_msvc_helper(x); }
774 EIGEN_DEVICE_FUNC inline bool isinf_impl(const double& x) { return isinf_msvc_helper(x); }
775 EIGEN_DEVICE_FUNC inline bool isinf_impl(const float& x) { return isinf_msvc_helper(x); }
776 
777 #elif (defined __FINITE_MATH_ONLY__ && __FINITE_MATH_ONLY__ && EIGEN_COMP_GNUC)
778 
779 #if EIGEN_GNUC_AT_LEAST(5,0)
780  #define EIGEN_TMP_NOOPT_ATTRIB EIGEN_DEVICE_FUNC inline __attribute__((optimize("no-finite-math-only")))
781 #else
782  // NOTE the inline qualifier and noinline attribute are both needed: the former is to avoid linking issue (duplicate symbol),
783  // while the second prevent too aggressive optimizations in fast-math mode:
784  #define EIGEN_TMP_NOOPT_ATTRIB EIGEN_DEVICE_FUNC inline __attribute__((noinline,optimize("no-finite-math-only")))
785 #endif
786 
787 template<> EIGEN_TMP_NOOPT_ATTRIB bool isnan_impl(const long double& x) { return __builtin_isnan(x); }
788 template<> EIGEN_TMP_NOOPT_ATTRIB bool isnan_impl(const double& x) { return __builtin_isnan(x); }
789 template<> EIGEN_TMP_NOOPT_ATTRIB bool isnan_impl(const float& x) { return __builtin_isnan(x); }
790 template<> EIGEN_TMP_NOOPT_ATTRIB bool isinf_impl(const double& x) { return __builtin_isinf(x); }
791 template<> EIGEN_TMP_NOOPT_ATTRIB bool isinf_impl(const float& x) { return __builtin_isinf(x); }
792 template<> EIGEN_TMP_NOOPT_ATTRIB bool isinf_impl(const long double& x) { return __builtin_isinf(x); }
793 
794 #undef EIGEN_TMP_NOOPT_ATTRIB
795 
796 #endif
797 
798 #endif
799 
800 // The following overload are defined at the end of this file
801 template<typename T> EIGEN_DEVICE_FUNC bool isfinite_impl(const std::complex<T>& x);
802 template<typename T> EIGEN_DEVICE_FUNC bool isnan_impl(const std::complex<T>& x);
803 template<typename T> EIGEN_DEVICE_FUNC bool isinf_impl(const std::complex<T>& x);
804 
805 template<typename T> T generic_fast_tanh_float(const T& a_x);
806 
807 } // end namespace internal
808 
809 /****************************************************************************
810 * Generic math functions *
811 ****************************************************************************/
812 
813 namespace numext {
814 
815 #ifndef __CUDA_ARCH__
816 template<typename T>
817 EIGEN_DEVICE_FUNC
818 EIGEN_ALWAYS_INLINE T mini(const T& x, const T& y)
819 {
820  EIGEN_USING_STD_MATH(min);
821  return min EIGEN_NOT_A_MACRO (x,y);
822 }
823 
824 template<typename T>
825 EIGEN_DEVICE_FUNC
826 EIGEN_ALWAYS_INLINE T maxi(const T& x, const T& y)
827 {
828  EIGEN_USING_STD_MATH(max);
829  return max EIGEN_NOT_A_MACRO (x,y);
830 }
831 #else
832 template<typename T>
833 EIGEN_DEVICE_FUNC
834 EIGEN_ALWAYS_INLINE T mini(const T& x, const T& y)
835 {
836  return y < x ? y : x;
837 }
838 template<>
839 EIGEN_DEVICE_FUNC
840 EIGEN_ALWAYS_INLINE float mini(const float& x, const float& y)
841 {
842  return fminf(x, y);
843 }
844 template<typename T>
845 EIGEN_DEVICE_FUNC
846 EIGEN_ALWAYS_INLINE T maxi(const T& x, const T& y)
847 {
848  return x < y ? y : x;
849 }
850 template<>
851 EIGEN_DEVICE_FUNC
852 EIGEN_ALWAYS_INLINE float maxi(const float& x, const float& y)
853 {
854  return fmaxf(x, y);
855 }
856 #endif
857 
858 
859 template<typename Scalar>
860 EIGEN_DEVICE_FUNC
861 inline EIGEN_MATHFUNC_RETVAL(real, Scalar) real(const Scalar& x)
862 {
863  return EIGEN_MATHFUNC_IMPL(real, Scalar)::run(x);
864 }
865 
866 template<typename Scalar>
867 EIGEN_DEVICE_FUNC
868 inline typename internal::add_const_on_value_type< EIGEN_MATHFUNC_RETVAL(real_ref, Scalar) >::type real_ref(const Scalar& x)
869 {
870  return internal::real_ref_impl<Scalar>::run(x);
871 }
872 
873 template<typename Scalar>
874 EIGEN_DEVICE_FUNC
875 inline EIGEN_MATHFUNC_RETVAL(real_ref, Scalar) real_ref(Scalar& x)
876 {
877  return EIGEN_MATHFUNC_IMPL(real_ref, Scalar)::run(x);
878 }
879 
880 template<typename Scalar>
881 EIGEN_DEVICE_FUNC
882 inline EIGEN_MATHFUNC_RETVAL(imag, Scalar) imag(const Scalar& x)
883 {
884  return EIGEN_MATHFUNC_IMPL(imag, Scalar)::run(x);
885 }
886 
887 template<typename Scalar>
888 EIGEN_DEVICE_FUNC
889 inline EIGEN_MATHFUNC_RETVAL(arg, Scalar) arg(const Scalar& x)
890 {
891  return EIGEN_MATHFUNC_IMPL(arg, Scalar)::run(x);
892 }
893 
894 template<typename Scalar>
895 EIGEN_DEVICE_FUNC
896 inline typename internal::add_const_on_value_type< EIGEN_MATHFUNC_RETVAL(imag_ref, Scalar) >::type imag_ref(const Scalar& x)
897 {
898  return internal::imag_ref_impl<Scalar>::run(x);
899 }
900 
901 template<typename Scalar>
902 EIGEN_DEVICE_FUNC
903 inline EIGEN_MATHFUNC_RETVAL(imag_ref, Scalar) imag_ref(Scalar& x)
904 {
905  return EIGEN_MATHFUNC_IMPL(imag_ref, Scalar)::run(x);
906 }
907 
908 template<typename Scalar>
909 EIGEN_DEVICE_FUNC
910 inline EIGEN_MATHFUNC_RETVAL(conj, Scalar) conj(const Scalar& x)
911 {
912  return EIGEN_MATHFUNC_IMPL(conj, Scalar)::run(x);
913 }
914 
915 template<typename Scalar>
916 EIGEN_DEVICE_FUNC
917 inline EIGEN_MATHFUNC_RETVAL(abs2, Scalar) abs2(const Scalar& x)
918 {
919  return EIGEN_MATHFUNC_IMPL(abs2, Scalar)::run(x);
920 }
921 
922 EIGEN_DEVICE_FUNC
923 inline bool abs2(bool x) { return x; }
924 
925 template<typename Scalar>
926 EIGEN_DEVICE_FUNC
927 inline EIGEN_MATHFUNC_RETVAL(norm1, Scalar) norm1(const Scalar& x)
928 {
929  return EIGEN_MATHFUNC_IMPL(norm1, Scalar)::run(x);
930 }
931 
932 template<typename Scalar>
933 EIGEN_DEVICE_FUNC
934 inline EIGEN_MATHFUNC_RETVAL(hypot, Scalar) hypot(const Scalar& x, const Scalar& y)
935 {
936  return EIGEN_MATHFUNC_IMPL(hypot, Scalar)::run(x, y);
937 }
938 
939 template<typename Scalar>
940 EIGEN_DEVICE_FUNC
941 inline EIGEN_MATHFUNC_RETVAL(log1p, Scalar) log1p(const Scalar& x)
942 {
943  return EIGEN_MATHFUNC_IMPL(log1p, Scalar)::run(x);
944 }
945 
946 #ifdef __CUDACC__
947 template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
948 float log1p(const float &x) { return ::log1pf(x); }
949 
950 template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
951 double log1p(const double &x) { return ::log1p(x); }
952 #endif
953 
954 template<typename ScalarX,typename ScalarY>
955 EIGEN_DEVICE_FUNC
956 inline typename internal::pow_impl<ScalarX,ScalarY>::result_type pow(const ScalarX& x, const ScalarY& y)
957 {
958  return internal::pow_impl<ScalarX,ScalarY>::run(x, y);
959 }
960 
961 template<typename T> EIGEN_DEVICE_FUNC bool (isnan) (const T &x) { return internal::isnan_impl(x); }
962 template<typename T> EIGEN_DEVICE_FUNC bool (isinf) (const T &x) { return internal::isinf_impl(x); }
963 template<typename T> EIGEN_DEVICE_FUNC bool (isfinite)(const T &x) { return internal::isfinite_impl(x); }
964 
965 template<typename Scalar>
966 EIGEN_DEVICE_FUNC
967 inline EIGEN_MATHFUNC_RETVAL(round, Scalar) round(const Scalar& x)
968 {
969  return EIGEN_MATHFUNC_IMPL(round, Scalar)::run(x);
970 }
971 
972 template<typename T>
973 EIGEN_DEVICE_FUNC
974 T (floor)(const T& x)
975 {
976  EIGEN_USING_STD_MATH(floor);
977  return floor(x);
978 }
979 
980 #ifdef __CUDACC__
981 template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
982 float floor(const float &x) { return ::floorf(x); }
983 
984 template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
985 double floor(const double &x) { return ::floor(x); }
986 #endif
987 
988 template<typename T>
989 EIGEN_DEVICE_FUNC
990 T (ceil)(const T& x)
991 {
992  EIGEN_USING_STD_MATH(ceil);
993  return ceil(x);
994 }
995 
996 #ifdef __CUDACC__
997 template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
998 float ceil(const float &x) { return ::ceilf(x); }
999 
1000 template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
1001 double ceil(const double &x) { return ::ceil(x); }
1002 #endif
1003 
1004 
1007 inline int log2(int x)
1008 {
1009  eigen_assert(x>=0);
1010  unsigned int v(x);
1011  static const int table[32] = { 0, 9, 1, 10, 13, 21, 2, 29, 11, 14, 16, 18, 22, 25, 3, 30, 8, 12, 20, 28, 15, 17, 24, 7, 19, 27, 23, 6, 26, 5, 4, 31 };
1012  v |= v >> 1;
1013  v |= v >> 2;
1014  v |= v >> 4;
1015  v |= v >> 8;
1016  v |= v >> 16;
1017  return table[(v * 0x07C4ACDDU) >> 27];
1018 }
1019 
1029 template<typename T>
1030 EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
1031 T sqrt(const T &x)
1032 {
1033  EIGEN_USING_STD_MATH(sqrt);
1034  return sqrt(x);
1035 }
1036 
1037 template<typename T>
1038 EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
1039 T log(const T &x) {
1040  EIGEN_USING_STD_MATH(log);
1041  return log(x);
1042 }
1043 
1044 #ifdef __CUDACC__
1045 template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
1046 float log(const float &x) { return ::logf(x); }
1047 
1048 template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
1049 double log(const double &x) { return ::log(x); }
1050 #endif
1051 
1052 template<typename T>
1053 EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
1054 typename internal::enable_if<NumTraits<T>::IsSigned || NumTraits<T>::IsComplex,typename NumTraits<T>::Real>::type
1055 abs(const T &x) {
1056  EIGEN_USING_STD_MATH(abs);
1057  return abs(x);
1058 }
1059 
1060 template<typename T>
1061 EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
1062 typename internal::enable_if<!(NumTraits<T>::IsSigned || NumTraits<T>::IsComplex),typename NumTraits<T>::Real>::type
1063 abs(const T &x) {
1064  return x;
1065 }
1066 
1067 #if defined(__SYCL_DEVICE_ONLY__)
1068 EIGEN_ALWAYS_INLINE float abs(float x) { return cl::sycl::fabs(x); }
1069 EIGEN_ALWAYS_INLINE double abs(double x) { return cl::sycl::fabs(x); }
1070 #endif // defined(__SYCL_DEVICE_ONLY__)
1071 
1072 #ifdef __CUDACC__
1073 template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
1074 float abs(const float &x) { return ::fabsf(x); }
1075 
1076 template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
1077 double abs(const double &x) { return ::fabs(x); }
1078 
1079 template <> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
1080 float abs(const std::complex<float>& x) {
1081  return ::hypotf(x.real(), x.imag());
1082 }
1083 
1084 template <> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
1085 double abs(const std::complex<double>& x) {
1086  return ::hypot(x.real(), x.imag());
1087 }
1088 #endif
1089 
1090 template<typename T>
1091 EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
1092 T exp(const T &x) {
1093  EIGEN_USING_STD_MATH(exp);
1094  return exp(x);
1095 }
1096 
1097 #ifdef __CUDACC__
1098 template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
1099 float exp(const float &x) { return ::expf(x); }
1100 
1101 template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
1102 double exp(const double &x) { return ::exp(x); }
1103 #endif
1104 
1105 template<typename T>
1106 EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
1107 T cos(const T &x) {
1108  EIGEN_USING_STD_MATH(cos);
1109  return cos(x);
1110 }
1111 
1112 #ifdef __CUDACC__
1113 template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
1114 float cos(const float &x) { return ::cosf(x); }
1115 
1116 template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
1117 double cos(const double &x) { return ::cos(x); }
1118 #endif
1119 
1120 template<typename T>
1121 EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
1122 T sin(const T &x) {
1123  EIGEN_USING_STD_MATH(sin);
1124  return sin(x);
1125 }
1126 
1127 #ifdef __CUDACC__
1128 template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
1129 float sin(const float &x) { return ::sinf(x); }
1130 
1131 template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
1132 double sin(const double &x) { return ::sin(x); }
1133 #endif
1134 
1135 template<typename T>
1136 EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
1137 T tan(const T &x) {
1138  EIGEN_USING_STD_MATH(tan);
1139  return tan(x);
1140 }
1141 
1142 #ifdef __CUDACC__
1143 template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
1144 float tan(const float &x) { return ::tanf(x); }
1145 
1146 template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
1147 double tan(const double &x) { return ::tan(x); }
1148 #endif
1149 
1150 template<typename T>
1151 EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
1152 T acos(const T &x) {
1153  EIGEN_USING_STD_MATH(acos);
1154  return acos(x);
1155 }
1156 
1157 #ifdef __CUDACC__
1158 template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
1159 float acos(const float &x) { return ::acosf(x); }
1160 
1161 template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
1162 double acos(const double &x) { return ::acos(x); }
1163 #endif
1164 
1165 template<typename T>
1166 EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
1167 T asin(const T &x) {
1168  EIGEN_USING_STD_MATH(asin);
1169  return asin(x);
1170 }
1171 
1172 #ifdef __CUDACC__
1173 template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
1174 float asin(const float &x) { return ::asinf(x); }
1175 
1176 template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
1177 double asin(const double &x) { return ::asin(x); }
1178 #endif
1179 
1180 template<typename T>
1181 EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
1182 T atan(const T &x) {
1183  EIGEN_USING_STD_MATH(atan);
1184  return atan(x);
1185 }
1186 
1187 #ifdef __CUDACC__
1188 template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
1189 float atan(const float &x) { return ::atanf(x); }
1190 
1191 template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
1192 double atan(const double &x) { return ::atan(x); }
1193 #endif
1194 
1195 
1196 template<typename T>
1197 EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
1198 T cosh(const T &x) {
1199  EIGEN_USING_STD_MATH(cosh);
1200  return cosh(x);
1201 }
1202 
1203 #ifdef __CUDACC__
1204 template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
1205 float cosh(const float &x) { return ::coshf(x); }
1206 
1207 template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
1208 double cosh(const double &x) { return ::cosh(x); }
1209 #endif
1210 
1211 template<typename T>
1212 EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
1213 T sinh(const T &x) {
1214  EIGEN_USING_STD_MATH(sinh);
1215  return sinh(x);
1216 }
1217 
1218 #ifdef __CUDACC__
1219 template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
1220 float sinh(const float &x) { return ::sinhf(x); }
1221 
1222 template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
1223 double sinh(const double &x) { return ::sinh(x); }
1224 #endif
1225 
1226 template<typename T>
1227 EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
1228 T tanh(const T &x) {
1229  EIGEN_USING_STD_MATH(tanh);
1230  return tanh(x);
1231 }
1232 
1233 #if (!defined(__CUDACC__)) && EIGEN_FAST_MATH
1234 EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
1235 float tanh(float x) { return internal::generic_fast_tanh_float(x); }
1236 #endif
1237 
1238 #ifdef __CUDACC__
1239 template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
1240 float tanh(const float &x) { return ::tanhf(x); }
1241 
1242 template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
1243 double tanh(const double &x) { return ::tanh(x); }
1244 #endif
1245 
1246 template <typename T>
1247 EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
1248 T fmod(const T& a, const T& b) {
1249  EIGEN_USING_STD_MATH(fmod);
1250  return fmod(a, b);
1251 }
1252 
1253 #ifdef __CUDACC__
1254 template <>
1255 EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
1256 float fmod(const float& a, const float& b) {
1257  return ::fmodf(a, b);
1258 }
1259 
1260 template <>
1261 EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
1262 double fmod(const double& a, const double& b) {
1263  return ::fmod(a, b);
1264 }
1265 #endif
1266 
1267 } // end namespace numext
1268 
1269 namespace internal {
1270 
1271 template<typename T>
1272 EIGEN_DEVICE_FUNC bool isfinite_impl(const std::complex<T>& x)
1273 {
1274  return (numext::isfinite)(numext::real(x)) && (numext::isfinite)(numext::imag(x));
1275 }
1276 
1277 template<typename T>
1278 EIGEN_DEVICE_FUNC bool isnan_impl(const std::complex<T>& x)
1279 {
1280  return (numext::isnan)(numext::real(x)) || (numext::isnan)(numext::imag(x));
1281 }
1282 
1283 template<typename T>
1284 EIGEN_DEVICE_FUNC bool isinf_impl(const std::complex<T>& x)
1285 {
1286  return ((numext::isinf)(numext::real(x)) || (numext::isinf)(numext::imag(x))) && (!(numext::isnan)(x));
1287 }
1288 
1289 /****************************************************************************
1290 * Implementation of fuzzy comparisons *
1291 ****************************************************************************/
1292 
1293 template<typename Scalar,
1294  bool IsComplex,
1295  bool IsInteger>
1296 struct scalar_fuzzy_default_impl {};
1297 
1298 template<typename Scalar>
1299 struct scalar_fuzzy_default_impl<Scalar, false, false>
1300 {
1301  typedef typename NumTraits<Scalar>::Real RealScalar;
1302  template<typename OtherScalar> EIGEN_DEVICE_FUNC
1303  static inline bool isMuchSmallerThan(const Scalar& x, const OtherScalar& y, const RealScalar& prec)
1304  {
1305  return numext::abs(x) <= numext::abs(y) * prec;
1306  }
1307  EIGEN_DEVICE_FUNC
1308  static inline bool isApprox(const Scalar& x, const Scalar& y, const RealScalar& prec)
1309  {
1310  return numext::abs(x - y) <= numext::mini(numext::abs(x), numext::abs(y)) * prec;
1311  }
1312  EIGEN_DEVICE_FUNC
1313  static inline bool isApproxOrLessThan(const Scalar& x, const Scalar& y, const RealScalar& prec)
1314  {
1315  return x <= y || isApprox(x, y, prec);
1316  }
1317 };
1318 
1319 template<typename Scalar>
1320 struct scalar_fuzzy_default_impl<Scalar, false, true>
1321 {
1322  typedef typename NumTraits<Scalar>::Real RealScalar;
1323  template<typename OtherScalar> EIGEN_DEVICE_FUNC
1324  static inline bool isMuchSmallerThan(const Scalar& x, const Scalar&, const RealScalar&)
1325  {
1326  return x == Scalar(0);
1327  }
1328  EIGEN_DEVICE_FUNC
1329  static inline bool isApprox(const Scalar& x, const Scalar& y, const RealScalar&)
1330  {
1331  return x == y;
1332  }
1333  EIGEN_DEVICE_FUNC
1334  static inline bool isApproxOrLessThan(const Scalar& x, const Scalar& y, const RealScalar&)
1335  {
1336  return x <= y;
1337  }
1338 };
1339 
1340 template<typename Scalar>
1341 struct scalar_fuzzy_default_impl<Scalar, true, false>
1342 {
1343  typedef typename NumTraits<Scalar>::Real RealScalar;
1344  template<typename OtherScalar> EIGEN_DEVICE_FUNC
1345  static inline bool isMuchSmallerThan(const Scalar& x, const OtherScalar& y, const RealScalar& prec)
1346  {
1347  return numext::abs2(x) <= numext::abs2(y) * prec * prec;
1348  }
1349  EIGEN_DEVICE_FUNC
1350  static inline bool isApprox(const Scalar& x, const Scalar& y, const RealScalar& prec)
1351  {
1352  return numext::abs2(x - y) <= numext::mini(numext::abs2(x), numext::abs2(y)) * prec * prec;
1353  }
1354 };
1355 
1356 template<typename Scalar>
1357 struct scalar_fuzzy_impl : scalar_fuzzy_default_impl<Scalar, NumTraits<Scalar>::IsComplex, NumTraits<Scalar>::IsInteger> {};
1358 
1359 template<typename Scalar, typename OtherScalar> EIGEN_DEVICE_FUNC
1360 inline bool isMuchSmallerThan(const Scalar& x, const OtherScalar& y,
1361  const typename NumTraits<Scalar>::Real &precision = NumTraits<Scalar>::dummy_precision())
1362 {
1363  return scalar_fuzzy_impl<Scalar>::template isMuchSmallerThan<OtherScalar>(x, y, precision);
1364 }
1365 
1366 template<typename Scalar> EIGEN_DEVICE_FUNC
1367 inline bool isApprox(const Scalar& x, const Scalar& y,
1368  const typename NumTraits<Scalar>::Real &precision = NumTraits<Scalar>::dummy_precision())
1369 {
1370  return scalar_fuzzy_impl<Scalar>::isApprox(x, y, precision);
1371 }
1372 
1373 template<typename Scalar> EIGEN_DEVICE_FUNC
1374 inline bool isApproxOrLessThan(const Scalar& x, const Scalar& y,
1375  const typename NumTraits<Scalar>::Real &precision = NumTraits<Scalar>::dummy_precision())
1376 {
1377  return scalar_fuzzy_impl<Scalar>::isApproxOrLessThan(x, y, precision);
1378 }
1379 
1380 /******************************************
1381 *** The special case of the bool type ***
1382 ******************************************/
1383 
1384 template<> struct random_impl<bool>
1385 {
1386  static inline bool run()
1387  {
1388  return random<int>(0,1)==0 ? false : true;
1389  }
1390 };
1391 
1392 template<> struct scalar_fuzzy_impl<bool>
1393 {
1394  typedef bool RealScalar;
1395 
1396  template<typename OtherScalar> EIGEN_DEVICE_FUNC
1397  static inline bool isMuchSmallerThan(const bool& x, const bool&, const bool&)
1398  {
1399  return !x;
1400  }
1401 
1402  EIGEN_DEVICE_FUNC
1403  static inline bool isApprox(bool x, bool y, bool)
1404  {
1405  return x == y;
1406  }
1407 
1408  EIGEN_DEVICE_FUNC
1409  static inline bool isApproxOrLessThan(const bool& x, const bool& y, const bool&)
1410  {
1411  return (!x) || y;
1412  }
1413 
1414 };
1415 
1416 
1417 } // end namespace internal
1418 
1419 } // end namespace Eigen
1420 
1421 #endif // EIGEN_MATHFUNCTIONS_H
Eigen
Namespace containing all symbols from the Eigen library.
Definition: Core:309
Eigen::log1p
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_log1p_op< typename Derived::Scalar >, const Derived > log1p(const Eigen::ArrayBase< Derived > &x)
Eigen::sqrt
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_sqrt_op< typename Derived::Scalar >, const Derived > sqrt(const Eigen::ArrayBase< Derived > &x)
Eigen::round
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_round_op< typename Derived::Scalar >, const Derived > round(const Eigen::ArrayBase< Derived > &x)
Eigen::ceil
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_ceil_op< typename Derived::Scalar >, const Derived > ceil(const Eigen::ArrayBase< Derived > &x)
Eigen::isnan
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_isnan_op< typename Derived::Scalar >, const Derived > isnan(const Eigen::ArrayBase< Derived > &x)
Eigen::sin
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_sin_op< typename Derived::Scalar >, const Derived > sin(const Eigen::ArrayBase< Derived > &x)
Eigen::real
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_real_op< typename Derived::Scalar >, const Derived > real(const Eigen::ArrayBase< Derived > &x)
Eigen::tan
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_tan_op< typename Derived::Scalar >, const Derived > tan(const Eigen::ArrayBase< Derived > &x)
Eigen::asin
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_asin_op< typename Derived::Scalar >, const Derived > asin(const Eigen::ArrayBase< Derived > &x)
Eigen::acos
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_acos_op< typename Derived::Scalar >, const Derived > acos(const Eigen::ArrayBase< Derived > &x)
Eigen::floor
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_floor_op< typename Derived::Scalar >, const Derived > floor(const Eigen::ArrayBase< Derived > &x)
Eigen::abs2
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_abs2_op< typename Derived::Scalar >, const Derived > abs2(const Eigen::ArrayBase< Derived > &x)
Eigen::arg
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_arg_op< typename Derived::Scalar >, const Derived > arg(const Eigen::ArrayBase< Derived > &x)
Eigen::isfinite
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_isfinite_op< typename Derived::Scalar >, const Derived > isfinite(const Eigen::ArrayBase< Derived > &x)
Eigen::abs
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_abs_op< typename Derived::Scalar >, const Derived > abs(const Eigen::ArrayBase< Derived > &x)
Eigen::cos
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_cos_op< typename Derived::Scalar >, const Derived > cos(const Eigen::ArrayBase< Derived > &x)
Eigen::log
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_log_op< typename Derived::Scalar >, const Derived > log(const Eigen::ArrayBase< Derived > &x)
Eigen::sinh
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_sinh_op< typename Derived::Scalar >, const Derived > sinh(const Eigen::ArrayBase< Derived > &x)
Eigen::atan
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_atan_op< typename Derived::Scalar >, const Derived > atan(const Eigen::ArrayBase< Derived > &x)
Eigen::cosh
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_cosh_op< typename Derived::Scalar >, const Derived > cosh(const Eigen::ArrayBase< Derived > &x)
Eigen::imag
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_imag_op< typename Derived::Scalar >, const Derived > imag(const Eigen::ArrayBase< Derived > &x)
Eigen::tanh
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_tanh_op< typename Derived::Scalar >, const Derived > tanh(const Eigen::ArrayBase< Derived > &x)
Eigen::isinf
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_isinf_op< typename Derived::Scalar >, const Derived > isinf(const Eigen::ArrayBase< Derived > &x)
Eigen::conj
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_conjugate_op< typename Derived::Scalar >, const Derived > conj(const Eigen::ArrayBase< Derived > &x)
Eigen::exp
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_exp_op< typename Derived::Scalar >, const Derived > exp(const Eigen::ArrayBase< Derived > &x)