Path Tracer
thirdparty/Eigen/src/Core/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 // TODO this should better be moved to NumTraits
14 // Source: WolframAlpha
15 #define EIGEN_PI 3.141592653589793238462643383279502884197169399375105820974944592307816406L
16 #define EIGEN_LOG2E 1.442695040888963407359924681001892137426645954152985934135449406931109219L
17 #define EIGEN_LN2 0.693147180559945309417232121458176568075500134360255254120680009493393621L
18 
19 namespace Eigen {
20 
21 // On WINCE, std::abs is defined for int only, so let's defined our own overloads:
22 // This issue has been confirmed with MSVC 2008 only, but the issue might exist for more recent versions too.
23 #if EIGEN_OS_WINCE && EIGEN_COMP_MSVC && EIGEN_COMP_MSVC<=1500
24 long abs(long x) { return (labs(x)); }
25 double abs(double x) { return (fabs(x)); }
26 float abs(float x) { return (fabsf(x)); }
27 long double abs(long double x) { return (fabsl(x)); }
28 #endif
29 
30 namespace internal {
31 
52 template<typename T, typename dummy = void>
54 {
55  typedef T type;
56 };
57 
58 template<typename T> struct always_void { typedef void type; };
59 
60 template<typename T>
62  <T,
63  typename always_void<typename T::Eigen_BaseClassForSpecializationOfGlobalMathFuncImpl>::type
64  >
65 {
66  typedef typename T::Eigen_BaseClassForSpecializationOfGlobalMathFuncImpl type;
67 };
68 
69 #define EIGEN_MATHFUNC_IMPL(func, scalar) Eigen::internal::func##_impl<typename Eigen::internal::global_math_functions_filtering_base<scalar>::type>
70 #define EIGEN_MATHFUNC_RETVAL(func, scalar) typename Eigen::internal::func##_retval<typename Eigen::internal::global_math_functions_filtering_base<scalar>::type>::type
71 
72 /****************************************************************************
73 * Implementation of real *
74 ****************************************************************************/
75 
76 template<typename Scalar, bool IsComplex = NumTraits<Scalar>::IsComplex>
78 {
79  typedef typename NumTraits<Scalar>::Real RealScalar;
80  EIGEN_DEVICE_FUNC
81  static inline RealScalar run(const Scalar& x)
82  {
83  return x;
84  }
85 };
86 
87 template<typename Scalar>
88 struct real_default_impl<Scalar,true>
89 {
90  typedef typename NumTraits<Scalar>::Real RealScalar;
91  EIGEN_DEVICE_FUNC
92  static inline RealScalar run(const Scalar& x)
93  {
94  using std::real;
95  return real(x);
96  }
97 };
98 
99 template<typename Scalar> struct real_impl : real_default_impl<Scalar> {};
100 
101 #if defined(EIGEN_GPU_COMPILE_PHASE)
102 template<typename T>
103 struct real_impl<std::complex<T> >
104 {
105  typedef T RealScalar;
106  EIGEN_DEVICE_FUNC
107  static inline T run(const std::complex<T>& x)
108  {
109  return x.real();
110  }
111 };
112 #endif
113 
114 template<typename Scalar>
116 {
117  typedef typename NumTraits<Scalar>::Real type;
118 };
119 
120 /****************************************************************************
121 * Implementation of imag *
122 ****************************************************************************/
123 
124 template<typename Scalar, bool IsComplex = NumTraits<Scalar>::IsComplex>
126 {
127  typedef typename NumTraits<Scalar>::Real RealScalar;
128  EIGEN_DEVICE_FUNC
129  static inline RealScalar run(const Scalar&)
130  {
131  return RealScalar(0);
132  }
133 };
134 
135 template<typename Scalar>
136 struct imag_default_impl<Scalar,true>
137 {
138  typedef typename NumTraits<Scalar>::Real RealScalar;
139  EIGEN_DEVICE_FUNC
140  static inline RealScalar run(const Scalar& x)
141  {
142  using std::imag;
143  return imag(x);
144  }
145 };
146 
147 template<typename Scalar> struct imag_impl : imag_default_impl<Scalar> {};
148 
149 #if defined(EIGEN_GPU_COMPILE_PHASE)
150 template<typename T>
151 struct imag_impl<std::complex<T> >
152 {
153  typedef T RealScalar;
154  EIGEN_DEVICE_FUNC
155  static inline T run(const std::complex<T>& x)
156  {
157  return x.imag();
158  }
159 };
160 #endif
161 
162 template<typename Scalar>
164 {
165  typedef typename NumTraits<Scalar>::Real type;
166 };
167 
168 /****************************************************************************
169 * Implementation of real_ref *
170 ****************************************************************************/
171 
172 template<typename Scalar>
174 {
175  typedef typename NumTraits<Scalar>::Real RealScalar;
176  EIGEN_DEVICE_FUNC
177  static inline RealScalar& run(Scalar& x)
178  {
179  return reinterpret_cast<RealScalar*>(&x)[0];
180  }
181  EIGEN_DEVICE_FUNC
182  static inline const RealScalar& run(const Scalar& x)
183  {
184  return reinterpret_cast<const RealScalar*>(&x)[0];
185  }
186 };
187 
188 template<typename Scalar>
190 {
191  typedef typename NumTraits<Scalar>::Real & type;
192 };
193 
194 /****************************************************************************
195 * Implementation of imag_ref *
196 ****************************************************************************/
197 
198 template<typename Scalar, bool IsComplex>
200 {
201  typedef typename NumTraits<Scalar>::Real RealScalar;
202  EIGEN_DEVICE_FUNC
203  static inline RealScalar& run(Scalar& x)
204  {
205  return reinterpret_cast<RealScalar*>(&x)[1];
206  }
207  EIGEN_DEVICE_FUNC
208  static inline const RealScalar& run(const Scalar& x)
209  {
210  return reinterpret_cast<RealScalar*>(&x)[1];
211  }
212 };
213 
214 template<typename Scalar>
215 struct imag_ref_default_impl<Scalar, false>
216 {
217  EIGEN_DEVICE_FUNC
218  static inline Scalar run(Scalar&)
219  {
220  return Scalar(0);
221  }
222  EIGEN_DEVICE_FUNC
223  static inline const Scalar run(const Scalar&)
224  {
225  return Scalar(0);
226  }
227 };
228 
229 template<typename Scalar>
230 struct imag_ref_impl : imag_ref_default_impl<Scalar, NumTraits<Scalar>::IsComplex> {};
231 
232 template<typename Scalar>
234 {
235  typedef typename NumTraits<Scalar>::Real & type;
236 };
237 
238 /****************************************************************************
239 * Implementation of conj *
240 ****************************************************************************/
241 
242 template<typename Scalar, bool IsComplex = NumTraits<Scalar>::IsComplex>
244 {
245  EIGEN_DEVICE_FUNC
246  static inline Scalar run(const Scalar& x)
247  {
248  return x;
249  }
250 };
251 
252 template<typename Scalar>
253 struct conj_default_impl<Scalar,true>
254 {
255  EIGEN_DEVICE_FUNC
256  static inline Scalar run(const Scalar& x)
257  {
258  using std::conj;
259  return conj(x);
260  }
261 };
262 
263 template<typename Scalar> struct conj_impl : conj_default_impl<Scalar> {};
264 
265 #if defined(EIGEN_GPU_COMPILE_PHASE)
266 template<typename T>
267 struct conj_impl<std::complex<T> >
268 {
269  EIGEN_DEVICE_FUNC
270  static inline std::complex<T> run(const std::complex<T>& x)
271  {
272  return std::complex<T>(x.real(), -x.imag());
273  }
274 };
275 #endif
276 
277 template<typename Scalar>
279 {
280  typedef Scalar type;
281 };
282 
283 /****************************************************************************
284 * Implementation of abs2 *
285 ****************************************************************************/
286 
287 template<typename Scalar,bool IsComplex>
289 {
290  typedef typename NumTraits<Scalar>::Real RealScalar;
291  EIGEN_DEVICE_FUNC
292  static inline RealScalar run(const Scalar& x)
293  {
294  return x*x;
295  }
296 };
297 
298 template<typename Scalar>
299 struct abs2_impl_default<Scalar, true> // IsComplex
300 {
301  typedef typename NumTraits<Scalar>::Real RealScalar;
302  EIGEN_DEVICE_FUNC
303  static inline RealScalar run(const Scalar& x)
304  {
305  return x.real()*x.real() + x.imag()*x.imag();
306  }
307 };
308 
309 template<typename Scalar>
310 struct abs2_impl
311 {
312  typedef typename NumTraits<Scalar>::Real RealScalar;
313  EIGEN_DEVICE_FUNC
314  static inline RealScalar run(const Scalar& x)
315  {
317  }
318 };
319 
320 template<typename Scalar>
322 {
323  typedef typename NumTraits<Scalar>::Real type;
324 };
325 
326 /****************************************************************************
327 * Implementation of norm1 *
328 ****************************************************************************/
329 
330 template<typename Scalar, bool IsComplex>
332 
333 template<typename Scalar>
334 struct norm1_default_impl<Scalar,true>
335 {
336  typedef typename NumTraits<Scalar>::Real RealScalar;
337  EIGEN_DEVICE_FUNC
338  static inline RealScalar run(const Scalar& x)
339  {
340  EIGEN_USING_STD(abs);
341  return abs(x.real()) + abs(x.imag());
342  }
343 };
344 
345 template<typename Scalar>
346 struct norm1_default_impl<Scalar, false>
347 {
348  EIGEN_DEVICE_FUNC
349  static inline Scalar run(const Scalar& x)
350  {
351  EIGEN_USING_STD(abs);
352  return abs(x);
353  }
354 };
355 
356 template<typename Scalar>
357 struct norm1_impl : norm1_default_impl<Scalar, NumTraits<Scalar>::IsComplex> {};
358 
359 template<typename Scalar>
361 {
362  typedef typename NumTraits<Scalar>::Real type;
363 };
364 
365 /****************************************************************************
366 * Implementation of hypot *
367 ****************************************************************************/
368 
369 template<typename Scalar> struct hypot_impl;
370 
371 template<typename Scalar>
373 {
374  typedef typename NumTraits<Scalar>::Real type;
375 };
376 
377 /****************************************************************************
378 * Implementation of cast *
379 ****************************************************************************/
380 
381 template<typename OldType, typename NewType, typename EnableIf = void>
382 struct cast_impl
383 {
384  EIGEN_DEVICE_FUNC
385  static inline NewType run(const OldType& x)
386  {
387  return static_cast<NewType>(x);
388  }
389 };
390 
391 // Casting from S -> Complex<T> leads to an implicit conversion from S to T,
392 // generating warnings on clang. Here we explicitly cast the real component.
393 template<typename OldType, typename NewType>
394 struct cast_impl<OldType, NewType,
395  typename internal::enable_if<
396  !NumTraits<OldType>::IsComplex && NumTraits<NewType>::IsComplex
397  >::type>
398 {
399  EIGEN_DEVICE_FUNC
400  static inline NewType run(const OldType& x)
401  {
402  typedef typename NumTraits<NewType>::Real NewReal;
403  return static_cast<NewType>(static_cast<NewReal>(x));
404  }
405 };
406 
407 // here, for once, we're plainly returning NewType: we don't want cast to do weird things.
408 
409 template<typename OldType, typename NewType>
410 EIGEN_DEVICE_FUNC
411 inline NewType cast(const OldType& x)
412 {
414 }
415 
416 /****************************************************************************
417 * Implementation of round *
418 ****************************************************************************/
419 
420 #if EIGEN_HAS_CXX11_MATH
421  template<typename Scalar>
422  struct round_impl {
423  EIGEN_DEVICE_FUNC
424  static inline Scalar run(const Scalar& x)
425  {
426  EIGEN_STATIC_ASSERT((!NumTraits<Scalar>::IsComplex), NUMERIC_TYPE_MUST_BE_REAL)
427  EIGEN_USING_STD(round);
428  return Scalar(round(x));
429  }
430  };
431 #else
432  template<typename Scalar>
433  struct round_impl
434  {
435  EIGEN_DEVICE_FUNC
436  static inline Scalar run(const Scalar& x)
437  {
438  EIGEN_STATIC_ASSERT((!NumTraits<Scalar>::IsComplex), NUMERIC_TYPE_MUST_BE_REAL)
439  EIGEN_USING_STD(floor);
440  EIGEN_USING_STD(ceil);
441  return (x > Scalar(0)) ? floor(x + Scalar(0.5)) : ceil(x - Scalar(0.5));
442  }
443  };
444 #endif
445 
446 template<typename Scalar>
448 {
449  typedef Scalar type;
450 };
451 
452 /****************************************************************************
453 * Implementation of rint *
454 ****************************************************************************/
455 
456 template<typename Scalar>
457 struct rint_impl {
458  EIGEN_DEVICE_FUNC
459  static inline Scalar run(const Scalar& x)
460  {
461  EIGEN_STATIC_ASSERT((!NumTraits<Scalar>::IsComplex), NUMERIC_TYPE_MUST_BE_REAL)
462 #if EIGEN_HAS_CXX11_MATH
463  EIGEN_USING_STD(rint);
464 #endif
465  return rint(x);
466  }
467 };
468 
469 #if !EIGEN_HAS_CXX11_MATH
470 template<>
471 struct rint_impl<double> {
472  EIGEN_DEVICE_FUNC
473  static inline double run(const double& x)
474  {
475  return ::rint(x);
476  }
477 };
478 template<>
479 struct rint_impl<float> {
480  EIGEN_DEVICE_FUNC
481  static inline float run(const float& x)
482  {
483  return ::rintf(x);
484  }
485 };
486 #endif
487 
488 template<typename Scalar>
490 {
491  typedef Scalar type;
492 };
493 
494 /****************************************************************************
495 * Implementation of arg *
496 ****************************************************************************/
497 
498 #if EIGEN_HAS_CXX11_MATH
499  template<typename Scalar>
500  struct arg_impl {
501  EIGEN_DEVICE_FUNC
502  static inline Scalar run(const Scalar& x)
503  {
504  #if defined(EIGEN_HIP_DEVICE_COMPILE)
505  // HIP does not seem to have a native device side implementation for the math routine "arg"
506  using std::arg;
507  #else
508  EIGEN_USING_STD(arg);
509  #endif
510  return arg(x);
511  }
512  };
513 #else
514  template<typename Scalar, bool IsComplex = NumTraits<Scalar>::IsComplex>
516  {
517  typedef typename NumTraits<Scalar>::Real RealScalar;
518  EIGEN_DEVICE_FUNC
519  static inline RealScalar run(const Scalar& x)
520  {
521  return (x < Scalar(0)) ? Scalar(EIGEN_PI) : Scalar(0); }
522  };
523 
524  template<typename Scalar>
525  struct arg_default_impl<Scalar,true>
526  {
527  typedef typename NumTraits<Scalar>::Real RealScalar;
528  EIGEN_DEVICE_FUNC
529  static inline RealScalar run(const Scalar& x)
530  {
531  EIGEN_USING_STD(arg);
532  return arg(x);
533  }
534  };
535 
536  template<typename Scalar> struct arg_impl : arg_default_impl<Scalar> {};
537 #endif
538 
539 template<typename Scalar>
541 {
542  typedef typename NumTraits<Scalar>::Real type;
543 };
544 
545 /****************************************************************************
546 * Implementation of expm1 *
547 ****************************************************************************/
548 
549 // This implementation is based on GSL Math's expm1.
550 namespace std_fallback {
551  // fallback expm1 implementation in case there is no expm1(Scalar) function in namespace of Scalar,
552  // or that there is no suitable std::expm1 function available. Implementation
553  // attributed to Kahan. See: http://www.plunk.org/~hatch/rightway.php.
554  template<typename Scalar>
555  EIGEN_DEVICE_FUNC inline Scalar expm1(const Scalar& x) {
556  EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar)
557  typedef typename NumTraits<Scalar>::Real RealScalar;
558 
559  EIGEN_USING_STD(exp);
560  Scalar u = exp(x);
561  if (numext::equal_strict(u, Scalar(1))) {
562  return x;
563  }
564  Scalar um1 = u - RealScalar(1);
565  if (numext::equal_strict(um1, Scalar(-1))) {
566  return RealScalar(-1);
567  }
568 
569  EIGEN_USING_STD(log);
570  Scalar logu = log(u);
571  return numext::equal_strict(u, logu) ? u : (u - RealScalar(1)) * x / logu;
572  }
573 }
574 
575 template<typename Scalar>
576 struct expm1_impl {
577  EIGEN_DEVICE_FUNC static inline Scalar run(const Scalar& x)
578  {
579  EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar)
580  #if EIGEN_HAS_CXX11_MATH
581  using std::expm1;
582  #else
583  using std_fallback::expm1;
584  #endif
585  return expm1(x);
586  }
587 };
588 
589 // Specialization for complex types that are not supported by std::expm1.
590 template <typename RealScalar>
591 struct expm1_impl<std::complex<RealScalar> > {
592  EIGEN_DEVICE_FUNC static inline std::complex<RealScalar> run(
593  const std::complex<RealScalar>& x) {
594  EIGEN_STATIC_ASSERT_NON_INTEGER(RealScalar)
595  RealScalar xr = x.real();
596  RealScalar xi = x.imag();
597  // expm1(z) = exp(z) - 1
598  // = exp(x + i * y) - 1
599  // = exp(x) * (cos(y) + i * sin(y)) - 1
600  // = exp(x) * cos(y) - 1 + i * exp(x) * sin(y)
601  // Imag(expm1(z)) = exp(x) * sin(y)
602  // Real(expm1(z)) = exp(x) * cos(y) - 1
603  // = exp(x) * cos(y) - 1.
604  // = expm1(x) + exp(x) * (cos(y) - 1)
605  // = expm1(x) + exp(x) * (2 * sin(y / 2) ** 2)
606 
607  // TODO better use numext::expm1 and numext::sin (but that would require forward declarations or moving this specialization down).
608  RealScalar erm1 = expm1_impl<RealScalar>::run(xr);
609  RealScalar er = erm1 + RealScalar(1.);
610  EIGEN_USING_STD(sin);
611  RealScalar sin2 = sin(xi / RealScalar(2.));
612  sin2 = sin2 * sin2;
613  RealScalar s = sin(xi);
614  RealScalar real_part = erm1 - RealScalar(2.) * er * sin2;
615  return std::complex<RealScalar>(real_part, er * s);
616  }
617 };
618 
619 template<typename Scalar>
621 {
622  typedef Scalar type;
623 };
624 
625 /****************************************************************************
626 * Implementation of log1p *
627 ****************************************************************************/
628 
629 namespace std_fallback {
630  // fallback log1p implementation in case there is no log1p(Scalar) function in namespace of Scalar,
631  // or that there is no suitable std::log1p function available
632  template<typename Scalar>
633  EIGEN_DEVICE_FUNC inline Scalar log1p(const Scalar& x) {
634  EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar)
635  typedef typename NumTraits<Scalar>::Real RealScalar;
636  EIGEN_USING_STD(log);
637  Scalar x1p = RealScalar(1) + x;
638  Scalar log_1p = log(x1p);
639  const bool is_small = numext::equal_strict(x1p, Scalar(1));
640  const bool is_inf = numext::equal_strict(x1p, log_1p);
641  return (is_small || is_inf) ? x : x * (log_1p / (x1p - RealScalar(1)));
642  }
643 }
644 
645 template<typename Scalar>
646 struct log1p_impl {
647  EIGEN_DEVICE_FUNC static inline Scalar run(const Scalar& x)
648  {
649  EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar)
650  #if EIGEN_HAS_CXX11_MATH
651  using std::log1p;
652  #else
653  using std_fallback::log1p;
654  #endif
655  return log1p(x);
656  }
657 };
658 
659 // Specialization for complex types that are not supported by std::log1p.
660 template <typename RealScalar>
661 struct log1p_impl<std::complex<RealScalar> > {
662  EIGEN_DEVICE_FUNC static inline std::complex<RealScalar> run(
663  const std::complex<RealScalar>& x) {
664  EIGEN_STATIC_ASSERT_NON_INTEGER(RealScalar)
665  return std_fallback::log1p(x);
666  }
667 };
668 
669 template<typename Scalar>
671 {
672  typedef Scalar type;
673 };
674 
675 /****************************************************************************
676 * Implementation of pow *
677 ****************************************************************************/
678 
679 template<typename ScalarX,typename ScalarY, bool IsInteger = NumTraits<ScalarX>::IsInteger&&NumTraits<ScalarY>::IsInteger>
680 struct pow_impl
681 {
682  //typedef Scalar retval;
684  static EIGEN_DEVICE_FUNC inline result_type run(const ScalarX& x, const ScalarY& y)
685  {
686  EIGEN_USING_STD(pow);
687  return pow(x, y);
688  }
689 };
690 
691 template<typename ScalarX,typename ScalarY>
692 struct pow_impl<ScalarX,ScalarY, true>
693 {
694  typedef ScalarX result_type;
695  static EIGEN_DEVICE_FUNC inline ScalarX run(ScalarX x, ScalarY y)
696  {
697  ScalarX res(1);
698  eigen_assert(!NumTraits<ScalarY>::IsSigned || y >= 0);
699  if(y & 1) res *= x;
700  y >>= 1;
701  while(y)
702  {
703  x *= x;
704  if(y&1) res *= x;
705  y >>= 1;
706  }
707  return res;
708  }
709 };
710 
711 /****************************************************************************
712 * Implementation of random *
713 ****************************************************************************/
714 
715 template<typename Scalar,
716  bool IsComplex,
717  bool IsInteger>
719 
720 template<typename Scalar>
721 struct random_impl : random_default_impl<Scalar, NumTraits<Scalar>::IsComplex, NumTraits<Scalar>::IsInteger> {};
722 
723 template<typename Scalar>
725 {
726  typedef Scalar type;
727 };
728 
729 template<typename Scalar> inline EIGEN_MATHFUNC_RETVAL(random, Scalar) random(const Scalar& x, const Scalar& y);
730 template<typename Scalar> inline EIGEN_MATHFUNC_RETVAL(random, Scalar) random();
731 
732 template<typename Scalar>
733 struct random_default_impl<Scalar, false, false>
734 {
735  static inline Scalar run(const Scalar& x, const Scalar& y)
736  {
737  return x + (y-x) * Scalar(std::rand()) / Scalar(RAND_MAX);
738  }
739  static inline Scalar run()
740  {
741  return run(Scalar(NumTraits<Scalar>::IsSigned ? -1 : 0), Scalar(1));
742  }
743 };
744 
745 enum {
746  meta_floor_log2_terminate,
747  meta_floor_log2_move_up,
748  meta_floor_log2_move_down,
749  meta_floor_log2_bogus
750 };
751 
752 template<unsigned int n, int lower, int upper> struct meta_floor_log2_selector
753 {
754  enum { middle = (lower + upper) / 2,
755  value = (upper <= lower + 1) ? int(meta_floor_log2_terminate)
756  : (n < (1 << middle)) ? int(meta_floor_log2_move_down)
757  : (n==0) ? int(meta_floor_log2_bogus)
758  : int(meta_floor_log2_move_up)
759  };
760 };
761 
762 template<unsigned int n,
763  int lower = 0,
764  int upper = sizeof(unsigned int) * CHAR_BIT - 1,
766 struct meta_floor_log2 {};
767 
768 template<unsigned int n, int lower, int upper>
770 {
772 };
773 
774 template<unsigned int n, int lower, int upper>
775 struct meta_floor_log2<n, lower, upper, meta_floor_log2_move_up>
776 {
778 };
779 
780 template<unsigned int n, int lower, int upper>
781 struct meta_floor_log2<n, lower, upper, meta_floor_log2_terminate>
782 {
783  enum { value = (n >= ((unsigned int)(1) << (lower+1))) ? lower+1 : lower };
784 };
785 
786 template<unsigned int n, int lower, int upper>
787 struct meta_floor_log2<n, lower, upper, meta_floor_log2_bogus>
788 {
789  // no value, error at compile time
790 };
791 
792 template<typename Scalar>
793 struct random_default_impl<Scalar, false, true>
794 {
795  static inline Scalar run(const Scalar& x, const Scalar& y)
796  {
797  if (y <= x)
798  return x;
799  // ScalarU is the unsigned counterpart of Scalar, possibly Scalar itself.
800  typedef typename make_unsigned<Scalar>::type ScalarU;
801  // ScalarX is the widest of ScalarU and unsigned int.
802  // We'll deal only with ScalarX and unsigned int below thus avoiding signed
803  // types and arithmetic and signed overflows (which are undefined behavior).
804  typedef typename conditional<(ScalarU(-1) > unsigned(-1)), ScalarU, unsigned>::type ScalarX;
805  // The following difference doesn't overflow, provided our integer types are two's
806  // complement and have the same number of padding bits in signed and unsigned variants.
807  // This is the case in most modern implementations of C++.
808  ScalarX range = ScalarX(y) - ScalarX(x);
809  ScalarX offset = 0;
810  ScalarX divisor = 1;
811  ScalarX multiplier = 1;
812  const unsigned rand_max = RAND_MAX;
813  if (range <= rand_max) divisor = (rand_max + 1) / (range + 1);
814  else multiplier = 1 + range / (rand_max + 1);
815  // Rejection sampling.
816  do {
817  offset = (unsigned(std::rand()) * multiplier) / divisor;
818  } while (offset > range);
819  return Scalar(ScalarX(x) + offset);
820  }
821 
822  static inline Scalar run()
823  {
824 #ifdef EIGEN_MAKING_DOCS
825  return run(Scalar(NumTraits<Scalar>::IsSigned ? -10 : 0), Scalar(10));
826 #else
827  enum { rand_bits = meta_floor_log2<(unsigned int)(RAND_MAX)+1>::value,
828  scalar_bits = sizeof(Scalar) * CHAR_BIT,
829  shift = EIGEN_PLAIN_ENUM_MAX(0, int(rand_bits) - int(scalar_bits)),
830  offset = NumTraits<Scalar>::IsSigned ? (1 << (EIGEN_PLAIN_ENUM_MIN(rand_bits,scalar_bits)-1)) : 0
831  };
832  return Scalar((std::rand() >> shift) - offset);
833 #endif
834  }
835 };
836 
837 template<typename Scalar>
838 struct random_default_impl<Scalar, true, false>
839 {
840  static inline Scalar run(const Scalar& x, const Scalar& y)
841  {
842  return Scalar(random(x.real(), y.real()),
843  random(x.imag(), y.imag()));
844  }
845  static inline Scalar run()
846  {
847  typedef typename NumTraits<Scalar>::Real RealScalar;
848  return Scalar(random<RealScalar>(), random<RealScalar>());
849  }
850 };
851 
852 template<typename Scalar>
853 inline EIGEN_MATHFUNC_RETVAL(random, Scalar) random(const Scalar& x, const Scalar& y)
854 {
855  return EIGEN_MATHFUNC_IMPL(random, Scalar)::run(x, y);
856 }
857 
858 template<typename Scalar>
859 inline EIGEN_MATHFUNC_RETVAL(random, Scalar) random()
860 {
861  return EIGEN_MATHFUNC_IMPL(random, Scalar)::run();
862 }
863 
864 // Implementation of is* functions
865 
866 // std::is* do not work with fast-math and gcc, std::is* are available on MSVC 2013 and newer, as well as in clang.
867 #if (EIGEN_HAS_CXX11_MATH && !(EIGEN_COMP_GNUC_STRICT && __FINITE_MATH_ONLY__)) || (EIGEN_COMP_MSVC>=1800) || (EIGEN_COMP_CLANG)
868 #define EIGEN_USE_STD_FPCLASSIFY 1
869 #else
870 #define EIGEN_USE_STD_FPCLASSIFY 0
871 #endif
872 
873 template<typename T>
874 EIGEN_DEVICE_FUNC
875 typename internal::enable_if<internal::is_integral<T>::value,bool>::type
876 isnan_impl(const T&) { return false; }
877 
878 template<typename T>
879 EIGEN_DEVICE_FUNC
880 typename internal::enable_if<internal::is_integral<T>::value,bool>::type
881 isinf_impl(const T&) { return false; }
882 
883 template<typename T>
884 EIGEN_DEVICE_FUNC
885 typename internal::enable_if<internal::is_integral<T>::value,bool>::type
886 isfinite_impl(const T&) { return true; }
887 
888 template<typename T>
889 EIGEN_DEVICE_FUNC
890 typename internal::enable_if<(!internal::is_integral<T>::value)&&(!NumTraits<T>::IsComplex),bool>::type
891 isfinite_impl(const T& x)
892 {
893  #if defined(EIGEN_GPU_COMPILE_PHASE)
894  return (::isfinite)(x);
895  #elif EIGEN_USE_STD_FPCLASSIFY
896  using std::isfinite;
897  return isfinite EIGEN_NOT_A_MACRO (x);
898  #else
899  return x<=NumTraits<T>::highest() && x>=NumTraits<T>::lowest();
900  #endif
901 }
902 
903 template<typename T>
904 EIGEN_DEVICE_FUNC
905 typename internal::enable_if<(!internal::is_integral<T>::value)&&(!NumTraits<T>::IsComplex),bool>::type
906 isinf_impl(const T& x)
907 {
908  #if defined(EIGEN_GPU_COMPILE_PHASE)
909  return (::isinf)(x);
910  #elif EIGEN_USE_STD_FPCLASSIFY
911  using std::isinf;
912  return isinf EIGEN_NOT_A_MACRO (x);
913  #else
914  return x>NumTraits<T>::highest() || x<NumTraits<T>::lowest();
915  #endif
916 }
917 
918 template<typename T>
919 EIGEN_DEVICE_FUNC
920 typename internal::enable_if<(!internal::is_integral<T>::value)&&(!NumTraits<T>::IsComplex),bool>::type
921 isnan_impl(const T& x)
922 {
923  #if defined(EIGEN_GPU_COMPILE_PHASE)
924  return (::isnan)(x);
925  #elif EIGEN_USE_STD_FPCLASSIFY
926  using std::isnan;
927  return isnan EIGEN_NOT_A_MACRO (x);
928  #else
929  return x != x;
930  #endif
931 }
932 
933 #if (!EIGEN_USE_STD_FPCLASSIFY)
934 
935 #if EIGEN_COMP_MSVC
936 
937 template<typename T> EIGEN_DEVICE_FUNC bool isinf_msvc_helper(T x)
938 {
939  return _fpclass(x)==_FPCLASS_NINF || _fpclass(x)==_FPCLASS_PINF;
940 }
941 
942 //MSVC defines a _isnan builtin function, but for double only
943 EIGEN_DEVICE_FUNC inline bool isnan_impl(const long double& x) { return _isnan(x)!=0; }
944 EIGEN_DEVICE_FUNC inline bool isnan_impl(const double& x) { return _isnan(x)!=0; }
945 EIGEN_DEVICE_FUNC inline bool isnan_impl(const float& x) { return _isnan(x)!=0; }
946 
947 EIGEN_DEVICE_FUNC inline bool isinf_impl(const long double& x) { return isinf_msvc_helper(x); }
948 EIGEN_DEVICE_FUNC inline bool isinf_impl(const double& x) { return isinf_msvc_helper(x); }
949 EIGEN_DEVICE_FUNC inline bool isinf_impl(const float& x) { return isinf_msvc_helper(x); }
950 
951 #elif (defined __FINITE_MATH_ONLY__ && __FINITE_MATH_ONLY__ && EIGEN_COMP_GNUC)
952 
953 #if EIGEN_GNUC_AT_LEAST(5,0)
954  #define EIGEN_TMP_NOOPT_ATTRIB EIGEN_DEVICE_FUNC inline __attribute__((optimize("no-finite-math-only")))
955 #else
956  // NOTE the inline qualifier and noinline attribute are both needed: the former is to avoid linking issue (duplicate symbol),
957  // while the second prevent too aggressive optimizations in fast-math mode:
958  #define EIGEN_TMP_NOOPT_ATTRIB EIGEN_DEVICE_FUNC inline __attribute__((noinline,optimize("no-finite-math-only")))
959 #endif
960 
961 template<> EIGEN_TMP_NOOPT_ATTRIB bool isnan_impl(const long double& x) { return __builtin_isnan(x); }
962 template<> EIGEN_TMP_NOOPT_ATTRIB bool isnan_impl(const double& x) { return __builtin_isnan(x); }
963 template<> EIGEN_TMP_NOOPT_ATTRIB bool isnan_impl(const float& x) { return __builtin_isnan(x); }
964 template<> EIGEN_TMP_NOOPT_ATTRIB bool isinf_impl(const double& x) { return __builtin_isinf(x); }
965 template<> EIGEN_TMP_NOOPT_ATTRIB bool isinf_impl(const float& x) { return __builtin_isinf(x); }
966 template<> EIGEN_TMP_NOOPT_ATTRIB bool isinf_impl(const long double& x) { return __builtin_isinf(x); }
967 
968 #undef EIGEN_TMP_NOOPT_ATTRIB
969 
970 #endif
971 
972 #endif
973 
974 // The following overload are defined at the end of this file
975 template<typename T> EIGEN_DEVICE_FUNC bool isfinite_impl(const std::complex<T>& x);
976 template<typename T> EIGEN_DEVICE_FUNC bool isnan_impl(const std::complex<T>& x);
977 template<typename T> EIGEN_DEVICE_FUNC bool isinf_impl(const std::complex<T>& x);
978 
979 template<typename T> T generic_fast_tanh_float(const T& a_x);
980 } // end namespace internal
981 
982 /****************************************************************************
983 * Generic math functions *
984 ****************************************************************************/
985 
986 namespace numext {
987 
988 #if (!defined(EIGEN_GPUCC) || defined(EIGEN_CONSTEXPR_ARE_DEVICE_FUNC))
989 template<typename T>
990 EIGEN_DEVICE_FUNC
991 EIGEN_ALWAYS_INLINE T mini(const T& x, const T& y)
992 {
993  EIGEN_USING_STD(min)
994  return min EIGEN_NOT_A_MACRO (x,y);
995 }
996 
997 template<typename T>
998 EIGEN_DEVICE_FUNC
999 EIGEN_ALWAYS_INLINE T maxi(const T& x, const T& y)
1000 {
1001  EIGEN_USING_STD(max)
1002  return max EIGEN_NOT_A_MACRO (x,y);
1003 }
1004 #else
1005 template<typename T>
1006 EIGEN_DEVICE_FUNC
1007 EIGEN_ALWAYS_INLINE T mini(const T& x, const T& y)
1008 {
1009  return y < x ? y : x;
1010 }
1011 template<>
1012 EIGEN_DEVICE_FUNC
1013 EIGEN_ALWAYS_INLINE float mini(const float& x, const float& y)
1014 {
1015  return fminf(x, y);
1016 }
1017 template<>
1018 EIGEN_DEVICE_FUNC
1019 EIGEN_ALWAYS_INLINE double mini(const double& x, const double& y)
1020 {
1021  return fmin(x, y);
1022 }
1023 template<>
1024 EIGEN_DEVICE_FUNC
1025 EIGEN_ALWAYS_INLINE long double mini(const long double& x, const long double& y)
1026 {
1027 #if defined(EIGEN_HIPCC)
1028  // no "fminl" on HIP yet
1029  return (x < y) ? x : y;
1030 #else
1031  return fminl(x, y);
1032 #endif
1033 }
1034 
1035 template<typename T>
1036 EIGEN_DEVICE_FUNC
1037 EIGEN_ALWAYS_INLINE T maxi(const T& x, const T& y)
1038 {
1039  return x < y ? y : x;
1040 }
1041 template<>
1042 EIGEN_DEVICE_FUNC
1043 EIGEN_ALWAYS_INLINE float maxi(const float& x, const float& y)
1044 {
1045  return fmaxf(x, y);
1046 }
1047 template<>
1048 EIGEN_DEVICE_FUNC
1049 EIGEN_ALWAYS_INLINE double maxi(const double& x, const double& y)
1050 {
1051  return fmax(x, y);
1052 }
1053 template<>
1054 EIGEN_DEVICE_FUNC
1055 EIGEN_ALWAYS_INLINE long double maxi(const long double& x, const long double& y)
1056 {
1057 #if defined(EIGEN_HIPCC)
1058  // no "fmaxl" on HIP yet
1059  return (x > y) ? x : y;
1060 #else
1061  return fmaxl(x, y);
1062 #endif
1063 }
1064 #endif
1065 
1066 #if defined(SYCL_DEVICE_ONLY)
1067 
1068 
1069 #define SYCL_SPECIALIZE_SIGNED_INTEGER_TYPES_BINARY(NAME, FUNC) \
1070  SYCL_SPECIALIZE_BINARY_FUNC(NAME, FUNC, cl::sycl::cl_char) \
1071  SYCL_SPECIALIZE_BINARY_FUNC(NAME, FUNC, cl::sycl::cl_short) \
1072  SYCL_SPECIALIZE_BINARY_FUNC(NAME, FUNC, cl::sycl::cl_int) \
1073  SYCL_SPECIALIZE_BINARY_FUNC(NAME, FUNC, cl::sycl::cl_long)
1074 #define SYCL_SPECIALIZE_SIGNED_INTEGER_TYPES_UNARY(NAME, FUNC) \
1075  SYCL_SPECIALIZE_UNARY_FUNC(NAME, FUNC, cl::sycl::cl_char) \
1076  SYCL_SPECIALIZE_UNARY_FUNC(NAME, FUNC, cl::sycl::cl_short) \
1077  SYCL_SPECIALIZE_UNARY_FUNC(NAME, FUNC, cl::sycl::cl_int) \
1078  SYCL_SPECIALIZE_UNARY_FUNC(NAME, FUNC, cl::sycl::cl_long)
1079 #define SYCL_SPECIALIZE_UNSIGNED_INTEGER_TYPES_BINARY(NAME, FUNC) \
1080  SYCL_SPECIALIZE_BINARY_FUNC(NAME, FUNC, cl::sycl::cl_uchar) \
1081  SYCL_SPECIALIZE_BINARY_FUNC(NAME, FUNC, cl::sycl::cl_ushort) \
1082  SYCL_SPECIALIZE_BINARY_FUNC(NAME, FUNC, cl::sycl::cl_uint) \
1083  SYCL_SPECIALIZE_BINARY_FUNC(NAME, FUNC, cl::sycl::cl_ulong)
1084 #define SYCL_SPECIALIZE_UNSIGNED_INTEGER_TYPES_UNARY(NAME, FUNC) \
1085  SYCL_SPECIALIZE_UNARY_FUNC(NAME, FUNC, cl::sycl::cl_uchar) \
1086  SYCL_SPECIALIZE_UNARY_FUNC(NAME, FUNC, cl::sycl::cl_ushort) \
1087  SYCL_SPECIALIZE_UNARY_FUNC(NAME, FUNC, cl::sycl::cl_uint) \
1088  SYCL_SPECIALIZE_UNARY_FUNC(NAME, FUNC, cl::sycl::cl_ulong)
1089 #define SYCL_SPECIALIZE_INTEGER_TYPES_BINARY(NAME, FUNC) \
1090  SYCL_SPECIALIZE_SIGNED_INTEGER_TYPES_BINARY(NAME, FUNC) \
1091  SYCL_SPECIALIZE_UNSIGNED_INTEGER_TYPES_BINARY(NAME, FUNC)
1092 #define SYCL_SPECIALIZE_INTEGER_TYPES_UNARY(NAME, FUNC) \
1093  SYCL_SPECIALIZE_SIGNED_INTEGER_TYPES_UNARY(NAME, FUNC) \
1094  SYCL_SPECIALIZE_UNSIGNED_INTEGER_TYPES_UNARY(NAME, FUNC)
1095 #define SYCL_SPECIALIZE_FLOATING_TYPES_BINARY(NAME, FUNC) \
1096  SYCL_SPECIALIZE_BINARY_FUNC(NAME, FUNC, cl::sycl::cl_float) \
1097  SYCL_SPECIALIZE_BINARY_FUNC(NAME, FUNC,cl::sycl::cl_double)
1098 #define SYCL_SPECIALIZE_FLOATING_TYPES_UNARY(NAME, FUNC) \
1099  SYCL_SPECIALIZE_UNARY_FUNC(NAME, FUNC, cl::sycl::cl_float) \
1100  SYCL_SPECIALIZE_UNARY_FUNC(NAME, FUNC,cl::sycl::cl_double)
1101 #define SYCL_SPECIALIZE_FLOATING_TYPES_UNARY_FUNC_RET_TYPE(NAME, FUNC, RET_TYPE) \
1102  SYCL_SPECIALIZE_GEN_UNARY_FUNC(NAME, FUNC, RET_TYPE, cl::sycl::cl_float) \
1103  SYCL_SPECIALIZE_GEN_UNARY_FUNC(NAME, FUNC, RET_TYPE, cl::sycl::cl_double)
1104 
1105 #define SYCL_SPECIALIZE_GEN_UNARY_FUNC(NAME, FUNC, RET_TYPE, ARG_TYPE) \
1106 template<> \
1107  EIGEN_DEVICE_FUNC \
1108  EIGEN_ALWAYS_INLINE RET_TYPE NAME(const ARG_TYPE& x) { \
1109  return cl::sycl::FUNC(x); \
1110  }
1111 
1112 #define SYCL_SPECIALIZE_UNARY_FUNC(NAME, FUNC, TYPE) \
1113  SYCL_SPECIALIZE_GEN_UNARY_FUNC(NAME, FUNC, TYPE, TYPE)
1114 
1115 #define SYCL_SPECIALIZE_GEN1_BINARY_FUNC(NAME, FUNC, RET_TYPE, ARG_TYPE1, ARG_TYPE2) \
1116  template<> \
1117  EIGEN_DEVICE_FUNC \
1118  EIGEN_ALWAYS_INLINE RET_TYPE NAME(const ARG_TYPE1& x, const ARG_TYPE2& y) { \
1119  return cl::sycl::FUNC(x, y); \
1120  }
1121 
1122 #define SYCL_SPECIALIZE_GEN2_BINARY_FUNC(NAME, FUNC, RET_TYPE, ARG_TYPE) \
1123  SYCL_SPECIALIZE_GEN1_BINARY_FUNC(NAME, FUNC, RET_TYPE, ARG_TYPE, ARG_TYPE)
1124 
1125 #define SYCL_SPECIALIZE_BINARY_FUNC(NAME, FUNC, TYPE) \
1126  SYCL_SPECIALIZE_GEN2_BINARY_FUNC(NAME, FUNC, TYPE, TYPE)
1127 
1128 SYCL_SPECIALIZE_INTEGER_TYPES_BINARY(mini, min)
1129 SYCL_SPECIALIZE_FLOATING_TYPES_BINARY(mini, fmin)
1130 SYCL_SPECIALIZE_INTEGER_TYPES_BINARY(maxi, max)
1131 SYCL_SPECIALIZE_FLOATING_TYPES_BINARY(maxi, fmax)
1132 
1133 #endif
1134 
1135 
1136 template<typename Scalar>
1137 EIGEN_DEVICE_FUNC
1138 inline EIGEN_MATHFUNC_RETVAL(real, Scalar) real(const Scalar& x)
1139 {
1140  return EIGEN_MATHFUNC_IMPL(real, Scalar)::run(x);
1141 }
1142 
1143 template<typename Scalar>
1144 EIGEN_DEVICE_FUNC
1145 inline typename internal::add_const_on_value_type< EIGEN_MATHFUNC_RETVAL(real_ref, Scalar) >::type real_ref(const Scalar& x)
1146 {
1147  return internal::real_ref_impl<Scalar>::run(x);
1148 }
1149 
1150 template<typename Scalar>
1151 EIGEN_DEVICE_FUNC
1152 inline EIGEN_MATHFUNC_RETVAL(real_ref, Scalar) real_ref(Scalar& x)
1153 {
1154  return EIGEN_MATHFUNC_IMPL(real_ref, Scalar)::run(x);
1155 }
1156 
1157 template<typename Scalar>
1158 EIGEN_DEVICE_FUNC
1159 inline EIGEN_MATHFUNC_RETVAL(imag, Scalar) imag(const Scalar& x)
1160 {
1161  return EIGEN_MATHFUNC_IMPL(imag, Scalar)::run(x);
1162 }
1163 
1164 template<typename Scalar>
1165 EIGEN_DEVICE_FUNC
1166 inline EIGEN_MATHFUNC_RETVAL(arg, Scalar) arg(const Scalar& x)
1167 {
1168  return EIGEN_MATHFUNC_IMPL(arg, Scalar)::run(x);
1169 }
1170 
1171 template<typename Scalar>
1172 EIGEN_DEVICE_FUNC
1173 inline typename internal::add_const_on_value_type< EIGEN_MATHFUNC_RETVAL(imag_ref, Scalar) >::type imag_ref(const Scalar& x)
1174 {
1175  return internal::imag_ref_impl<Scalar>::run(x);
1176 }
1177 
1178 template<typename Scalar>
1179 EIGEN_DEVICE_FUNC
1180 inline EIGEN_MATHFUNC_RETVAL(imag_ref, Scalar) imag_ref(Scalar& x)
1181 {
1182  return EIGEN_MATHFUNC_IMPL(imag_ref, Scalar)::run(x);
1183 }
1184 
1185 template<typename Scalar>
1186 EIGEN_DEVICE_FUNC
1187 inline EIGEN_MATHFUNC_RETVAL(conj, Scalar) conj(const Scalar& x)
1188 {
1189  return EIGEN_MATHFUNC_IMPL(conj, Scalar)::run(x);
1190 }
1191 
1192 template<typename Scalar>
1193 EIGEN_DEVICE_FUNC
1194 inline EIGEN_MATHFUNC_RETVAL(abs2, Scalar) abs2(const Scalar& x)
1195 {
1196  return EIGEN_MATHFUNC_IMPL(abs2, Scalar)::run(x);
1197 }
1198 
1199 EIGEN_DEVICE_FUNC
1200 inline bool abs2(bool x) { return x; }
1201 
1202 template<typename T>
1203 EIGEN_DEVICE_FUNC
1204 EIGEN_ALWAYS_INLINE T absdiff(const T& x, const T& y)
1205 {
1206  return x > y ? x - y : y - x;
1207 }
1208 template<>
1209 EIGEN_DEVICE_FUNC
1210 EIGEN_ALWAYS_INLINE float absdiff(const float& x, const float& y)
1211 {
1212  return fabsf(x - y);
1213 }
1214 template<>
1215 EIGEN_DEVICE_FUNC
1216 EIGEN_ALWAYS_INLINE double absdiff(const double& x, const double& y)
1217 {
1218  return fabs(x - y);
1219 }
1220 
1221 #if !defined(EIGEN_GPUCC)
1222 // HIP and CUDA do not support long double.
1223 template<>
1224 EIGEN_DEVICE_FUNC
1225 EIGEN_ALWAYS_INLINE long double absdiff(const long double& x, const long double& y) {
1226  return fabsl(x - y);
1227 }
1228 #endif
1229 
1230 template<typename Scalar>
1231 EIGEN_DEVICE_FUNC
1232 inline EIGEN_MATHFUNC_RETVAL(norm1, Scalar) norm1(const Scalar& x)
1233 {
1234  return EIGEN_MATHFUNC_IMPL(norm1, Scalar)::run(x);
1235 }
1236 
1237 template<typename Scalar>
1238 EIGEN_DEVICE_FUNC
1239 inline EIGEN_MATHFUNC_RETVAL(hypot, Scalar) hypot(const Scalar& x, const Scalar& y)
1240 {
1241  return EIGEN_MATHFUNC_IMPL(hypot, Scalar)::run(x, y);
1242 }
1243 
1244 #if defined(SYCL_DEVICE_ONLY)
1245  SYCL_SPECIALIZE_FLOATING_TYPES_BINARY(hypot, hypot)
1246 #endif
1247 
1248 template<typename Scalar>
1249 EIGEN_DEVICE_FUNC
1250 inline EIGEN_MATHFUNC_RETVAL(log1p, Scalar) log1p(const Scalar& x)
1251 {
1252  return EIGEN_MATHFUNC_IMPL(log1p, Scalar)::run(x);
1253 }
1254 
1255 #if defined(SYCL_DEVICE_ONLY)
1256 SYCL_SPECIALIZE_FLOATING_TYPES_UNARY(log1p, log1p)
1257 #endif
1258 
1259 #if defined(EIGEN_GPUCC)
1260 template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
1261 float log1p(const float &x) { return ::log1pf(x); }
1262 
1263 template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
1264 double log1p(const double &x) { return ::log1p(x); }
1265 #endif
1266 
1267 template<typename ScalarX,typename ScalarY>
1268 EIGEN_DEVICE_FUNC
1269 inline typename internal::pow_impl<ScalarX,ScalarY>::result_type pow(const ScalarX& x, const ScalarY& y)
1270 {
1271  return internal::pow_impl<ScalarX,ScalarY>::run(x, y);
1272 }
1273 
1274 #if defined(SYCL_DEVICE_ONLY)
1275 SYCL_SPECIALIZE_FLOATING_TYPES_BINARY(pow, pow)
1276 #endif
1277 
1278 template<typename T> EIGEN_DEVICE_FUNC bool (isnan) (const T &x) { return internal::isnan_impl(x); }
1279 template<typename T> EIGEN_DEVICE_FUNC bool (isinf) (const T &x) { return internal::isinf_impl(x); }
1280 template<typename T> EIGEN_DEVICE_FUNC bool (isfinite)(const T &x) { return internal::isfinite_impl(x); }
1281 
1282 #if defined(SYCL_DEVICE_ONLY)
1283 SYCL_SPECIALIZE_FLOATING_TYPES_UNARY_FUNC_RET_TYPE(isnan, isnan, bool)
1284 SYCL_SPECIALIZE_FLOATING_TYPES_UNARY_FUNC_RET_TYPE(isinf, isinf, bool)
1285 SYCL_SPECIALIZE_FLOATING_TYPES_UNARY_FUNC_RET_TYPE(isfinite, isfinite, bool)
1286 #endif
1287 
1288 template<typename Scalar>
1289 EIGEN_DEVICE_FUNC
1290 inline EIGEN_MATHFUNC_RETVAL(rint, Scalar) rint(const Scalar& x)
1291 {
1292  return EIGEN_MATHFUNC_IMPL(rint, Scalar)::run(x);
1293 }
1294 
1295 template<typename Scalar>
1296 EIGEN_DEVICE_FUNC
1297 inline EIGEN_MATHFUNC_RETVAL(round, Scalar) round(const Scalar& x)
1298 {
1299  return EIGEN_MATHFUNC_IMPL(round, Scalar)::run(x);
1300 }
1301 
1302 #if defined(SYCL_DEVICE_ONLY)
1303 SYCL_SPECIALIZE_FLOATING_TYPES_UNARY(round, round)
1304 #endif
1305 
1306 template<typename T>
1307 EIGEN_DEVICE_FUNC
1308 T (floor)(const T& x)
1309 {
1310  EIGEN_USING_STD(floor)
1311  return floor(x);
1312 }
1313 
1314 #if defined(SYCL_DEVICE_ONLY)
1315 SYCL_SPECIALIZE_FLOATING_TYPES_UNARY(floor, floor)
1316 #endif
1317 
1318 #if defined(EIGEN_GPUCC)
1319 template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
1320 float floor(const float &x) { return ::floorf(x); }
1321 
1322 template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
1323 double floor(const double &x) { return ::floor(x); }
1324 #endif
1325 
1326 template<typename T>
1327 EIGEN_DEVICE_FUNC
1328 T (ceil)(const T& x)
1329 {
1330  EIGEN_USING_STD(ceil);
1331  return ceil(x);
1332 }
1333 
1334 #if defined(SYCL_DEVICE_ONLY)
1335 SYCL_SPECIALIZE_FLOATING_TYPES_UNARY(ceil, ceil)
1336 #endif
1337 
1338 #if defined(EIGEN_GPUCC)
1339 template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
1340 float ceil(const float &x) { return ::ceilf(x); }
1341 
1342 template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
1343 double ceil(const double &x) { return ::ceil(x); }
1344 #endif
1345 
1346 
1349 inline int log2(int x)
1350 {
1351  eigen_assert(x>=0);
1352  unsigned int v(x);
1353  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 };
1354  v |= v >> 1;
1355  v |= v >> 2;
1356  v |= v >> 4;
1357  v |= v >> 8;
1358  v |= v >> 16;
1359  return table[(v * 0x07C4ACDDU) >> 27];
1360 }
1361 
1371 template<typename T>
1372 EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
1373 T sqrt(const T &x)
1374 {
1375  EIGEN_USING_STD(sqrt);
1376  return sqrt(x);
1377 }
1378 
1379 // Boolean specialization, avoids implicit float to bool conversion (-Wimplicit-conversion-floating-point-to-bool).
1380 template<>
1381 EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS EIGEN_DEVICE_FUNC
1382 bool sqrt<bool>(const bool &x) { return x; }
1383 
1384 #if defined(SYCL_DEVICE_ONLY)
1385 SYCL_SPECIALIZE_FLOATING_TYPES_UNARY(sqrt, sqrt)
1386 #endif
1387 
1388 template<typename T>
1389 EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
1390 T log(const T &x) {
1391  EIGEN_USING_STD(log);
1392  return log(x);
1393 }
1394 
1395 #if defined(SYCL_DEVICE_ONLY)
1396 SYCL_SPECIALIZE_FLOATING_TYPES_UNARY(log, log)
1397 #endif
1398 
1399 
1400 #if defined(EIGEN_GPUCC)
1401 template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
1402 float log(const float &x) { return ::logf(x); }
1403 
1404 template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
1405 double log(const double &x) { return ::log(x); }
1406 #endif
1407 
1408 template<typename T>
1409 EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
1410 typename internal::enable_if<NumTraits<T>::IsSigned || NumTraits<T>::IsComplex,typename NumTraits<T>::Real>::type
1411 abs(const T &x) {
1412  EIGEN_USING_STD(abs);
1413  return abs(x);
1414 }
1415 
1416 template<typename T>
1417 EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
1418 typename internal::enable_if<!(NumTraits<T>::IsSigned || NumTraits<T>::IsComplex),typename NumTraits<T>::Real>::type
1419 abs(const T &x) {
1420  return x;
1421 }
1422 
1423 #if defined(SYCL_DEVICE_ONLY)
1424 SYCL_SPECIALIZE_INTEGER_TYPES_UNARY(abs, abs)
1425 SYCL_SPECIALIZE_FLOATING_TYPES_UNARY(abs, fabs)
1426 #endif
1427 
1428 #if defined(EIGEN_GPUCC)
1429 template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
1430 float abs(const float &x) { return ::fabsf(x); }
1431 
1432 template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
1433 double abs(const double &x) { return ::fabs(x); }
1434 
1435 template <> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
1436 float abs(const std::complex<float>& x) {
1437  return ::hypotf(x.real(), x.imag());
1438 }
1439 
1440 template <> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
1441 double abs(const std::complex<double>& x) {
1442  return ::hypot(x.real(), x.imag());
1443 }
1444 #endif
1445 
1446 template<typename T>
1447 EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
1448 T exp(const T &x) {
1449  EIGEN_USING_STD(exp);
1450  return exp(x);
1451 }
1452 
1453 #if defined(SYCL_DEVICE_ONLY)
1454 SYCL_SPECIALIZE_FLOATING_TYPES_UNARY(exp, exp)
1455 #endif
1456 
1457 #if defined(EIGEN_GPUCC)
1458 template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
1459 float exp(const float &x) { return ::expf(x); }
1460 
1461 template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
1462 double exp(const double &x) { return ::exp(x); }
1463 
1464 template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
1465 std::complex<float> exp(const std::complex<float>& x) {
1466  float com = ::expf(x.real());
1467  float res_real = com * ::cosf(x.imag());
1468  float res_imag = com * ::sinf(x.imag());
1469  return std::complex<float>(res_real, res_imag);
1470 }
1471 
1472 template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
1473 std::complex<double> exp(const std::complex<double>& x) {
1474  double com = ::exp(x.real());
1475  double res_real = com * ::cos(x.imag());
1476  double res_imag = com * ::sin(x.imag());
1477  return std::complex<double>(res_real, res_imag);
1478 }
1479 #endif
1480 
1481 template<typename Scalar>
1482 EIGEN_DEVICE_FUNC
1483 inline EIGEN_MATHFUNC_RETVAL(expm1, Scalar) expm1(const Scalar& x)
1484 {
1485  return EIGEN_MATHFUNC_IMPL(expm1, Scalar)::run(x);
1486 }
1487 
1488 #if defined(SYCL_DEVICE_ONLY)
1489 SYCL_SPECIALIZE_FLOATING_TYPES_UNARY(expm1, expm1)
1490 #endif
1491 
1492 #if defined(EIGEN_GPUCC)
1493 template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
1494 float expm1(const float &x) { return ::expm1f(x); }
1495 
1496 template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
1497 double expm1(const double &x) { return ::expm1(x); }
1498 #endif
1499 
1500 template<typename T>
1501 EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
1502 T cos(const T &x) {
1503  EIGEN_USING_STD(cos);
1504  return cos(x);
1505 }
1506 
1507 #if defined(SYCL_DEVICE_ONLY)
1508 SYCL_SPECIALIZE_FLOATING_TYPES_UNARY(cos,cos)
1509 #endif
1510 
1511 #if defined(EIGEN_GPUCC)
1512 template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
1513 float cos(const float &x) { return ::cosf(x); }
1514 
1515 template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
1516 double cos(const double &x) { return ::cos(x); }
1517 #endif
1518 
1519 template<typename T>
1520 EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
1521 T sin(const T &x) {
1522  EIGEN_USING_STD(sin);
1523  return sin(x);
1524 }
1525 
1526 #if defined(SYCL_DEVICE_ONLY)
1527 SYCL_SPECIALIZE_FLOATING_TYPES_UNARY(sin, sin)
1528 #endif
1529 
1530 #if defined(EIGEN_GPUCC)
1531 template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
1532 float sin(const float &x) { return ::sinf(x); }
1533 
1534 template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
1535 double sin(const double &x) { return ::sin(x); }
1536 #endif
1537 
1538 template<typename T>
1539 EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
1540 T tan(const T &x) {
1541  EIGEN_USING_STD(tan);
1542  return tan(x);
1543 }
1544 
1545 #if defined(SYCL_DEVICE_ONLY)
1546 SYCL_SPECIALIZE_FLOATING_TYPES_UNARY(tan, tan)
1547 #endif
1548 
1549 #if defined(EIGEN_GPUCC)
1550 template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
1551 float tan(const float &x) { return ::tanf(x); }
1552 
1553 template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
1554 double tan(const double &x) { return ::tan(x); }
1555 #endif
1556 
1557 template<typename T>
1558 EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
1559 T acos(const T &x) {
1560  EIGEN_USING_STD(acos);
1561  return acos(x);
1562 }
1563 
1564 #if EIGEN_HAS_CXX11_MATH
1565 template<typename T>
1566 EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
1567 T acosh(const T &x) {
1568  EIGEN_USING_STD(acosh);
1569  return acosh(x);
1570 }
1571 #endif
1572 
1573 #if defined(SYCL_DEVICE_ONLY)
1574 SYCL_SPECIALIZE_FLOATING_TYPES_UNARY(acos, acos)
1575 SYCL_SPECIALIZE_FLOATING_TYPES_UNARY(acosh, acosh)
1576 #endif
1577 
1578 #if defined(EIGEN_GPUCC)
1579 template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
1580 float acos(const float &x) { return ::acosf(x); }
1581 
1582 template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
1583 double acos(const double &x) { return ::acos(x); }
1584 #endif
1585 
1586 template<typename T>
1587 EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
1588 T asin(const T &x) {
1589  EIGEN_USING_STD(asin);
1590  return asin(x);
1591 }
1592 
1593 #if EIGEN_HAS_CXX11_MATH
1594 template<typename T>
1595 EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
1596 T asinh(const T &x) {
1597  EIGEN_USING_STD(asinh);
1598  return asinh(x);
1599 }
1600 #endif
1601 
1602 #if defined(SYCL_DEVICE_ONLY)
1603 SYCL_SPECIALIZE_FLOATING_TYPES_UNARY(asin, asin)
1604 SYCL_SPECIALIZE_FLOATING_TYPES_UNARY(asinh, asinh)
1605 #endif
1606 
1607 #if defined(EIGEN_GPUCC)
1608 template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
1609 float asin(const float &x) { return ::asinf(x); }
1610 
1611 template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
1612 double asin(const double &x) { return ::asin(x); }
1613 #endif
1614 
1615 template<typename T>
1616 EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
1617 T atan(const T &x) {
1618  EIGEN_USING_STD(atan);
1619  return atan(x);
1620 }
1621 
1622 #if EIGEN_HAS_CXX11_MATH
1623 template<typename T>
1624 EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
1625 T atanh(const T &x) {
1626  EIGEN_USING_STD(atanh);
1627  return atanh(x);
1628 }
1629 #endif
1630 
1631 #if defined(SYCL_DEVICE_ONLY)
1632 SYCL_SPECIALIZE_FLOATING_TYPES_UNARY(atan, atan)
1633 SYCL_SPECIALIZE_FLOATING_TYPES_UNARY(atanh, atanh)
1634 #endif
1635 
1636 #if defined(EIGEN_GPUCC)
1637 template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
1638 float atan(const float &x) { return ::atanf(x); }
1639 
1640 template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
1641 double atan(const double &x) { return ::atan(x); }
1642 #endif
1643 
1644 
1645 template<typename T>
1646 EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
1647 T cosh(const T &x) {
1648  EIGEN_USING_STD(cosh);
1649  return cosh(x);
1650 }
1651 
1652 #if defined(SYCL_DEVICE_ONLY)
1653 SYCL_SPECIALIZE_FLOATING_TYPES_UNARY(cosh, cosh)
1654 #endif
1655 
1656 #if defined(EIGEN_GPUCC)
1657 template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
1658 float cosh(const float &x) { return ::coshf(x); }
1659 
1660 template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
1661 double cosh(const double &x) { return ::cosh(x); }
1662 #endif
1663 
1664 template<typename T>
1665 EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
1666 T sinh(const T &x) {
1667  EIGEN_USING_STD(sinh);
1668  return sinh(x);
1669 }
1670 
1671 #if defined(SYCL_DEVICE_ONLY)
1672 SYCL_SPECIALIZE_FLOATING_TYPES_UNARY(sinh, sinh)
1673 #endif
1674 
1675 #if defined(EIGEN_GPUCC)
1676 template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
1677 float sinh(const float &x) { return ::sinhf(x); }
1678 
1679 template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
1680 double sinh(const double &x) { return ::sinh(x); }
1681 #endif
1682 
1683 template<typename T>
1684 EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
1685 T tanh(const T &x) {
1686  EIGEN_USING_STD(tanh);
1687  return tanh(x);
1688 }
1689 
1690 #if (!defined(EIGEN_GPUCC)) && EIGEN_FAST_MATH && !defined(SYCL_DEVICE_ONLY)
1691 EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
1692 float tanh(float x) { return internal::generic_fast_tanh_float(x); }
1693 #endif
1694 
1695 #if defined(SYCL_DEVICE_ONLY)
1696 SYCL_SPECIALIZE_FLOATING_TYPES_UNARY(tanh, tanh)
1697 #endif
1698 
1699 #if defined(EIGEN_GPUCC)
1700 template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
1701 float tanh(const float &x) { return ::tanhf(x); }
1702 
1703 template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
1704 double tanh(const double &x) { return ::tanh(x); }
1705 #endif
1706 
1707 template <typename T>
1708 EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
1709 T fmod(const T& a, const T& b) {
1710  EIGEN_USING_STD(fmod);
1711  return fmod(a, b);
1712 }
1713 
1714 #if defined(SYCL_DEVICE_ONLY)
1715 SYCL_SPECIALIZE_FLOATING_TYPES_BINARY(fmod, fmod)
1716 #endif
1717 
1718 #if defined(EIGEN_GPUCC)
1719 template <>
1720 EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
1721 float fmod(const float& a, const float& b) {
1722  return ::fmodf(a, b);
1723 }
1724 
1725 template <>
1726 EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
1727 double fmod(const double& a, const double& b) {
1728  return ::fmod(a, b);
1729 }
1730 #endif
1731 
1732 #if defined(SYCL_DEVICE_ONLY)
1733 #undef SYCL_SPECIALIZE_SIGNED_INTEGER_TYPES_BINARY
1734 #undef SYCL_SPECIALIZE_SIGNED_INTEGER_TYPES_UNARY
1735 #undef SYCL_SPECIALIZE_UNSIGNED_INTEGER_TYPES_BINARY
1736 #undef SYCL_SPECIALIZE_UNSIGNED_INTEGER_TYPES_UNARY
1737 #undef SYCL_SPECIALIZE_INTEGER_TYPES_BINARY
1738 #undef SYCL_SPECIALIZE_UNSIGNED_INTEGER_TYPES_UNARY
1739 #undef SYCL_SPECIALIZE_FLOATING_TYPES_BINARY
1740 #undef SYCL_SPECIALIZE_FLOATING_TYPES_UNARY
1741 #undef SYCL_SPECIALIZE_FLOATING_TYPES_UNARY_FUNC_RET_TYPE
1742 #undef SYCL_SPECIALIZE_GEN_UNARY_FUNC
1743 #undef SYCL_SPECIALIZE_UNARY_FUNC
1744 #undef SYCL_SPECIALIZE_GEN1_BINARY_FUNC
1745 #undef SYCL_SPECIALIZE_GEN2_BINARY_FUNC
1746 #undef SYCL_SPECIALIZE_BINARY_FUNC
1747 #endif
1748 
1749 } // end namespace numext
1750 
1751 namespace internal {
1752 
1753 template<typename T>
1754 EIGEN_DEVICE_FUNC bool isfinite_impl(const std::complex<T>& x)
1755 {
1756  return (numext::isfinite)(numext::real(x)) && (numext::isfinite)(numext::imag(x));
1757 }
1758 
1759 template<typename T>
1760 EIGEN_DEVICE_FUNC bool isnan_impl(const std::complex<T>& x)
1761 {
1762  return (numext::isnan)(numext::real(x)) || (numext::isnan)(numext::imag(x));
1763 }
1764 
1765 template<typename T>
1766 EIGEN_DEVICE_FUNC bool isinf_impl(const std::complex<T>& x)
1767 {
1768  return ((numext::isinf)(numext::real(x)) || (numext::isinf)(numext::imag(x))) && (!(numext::isnan)(x));
1769 }
1770 
1771 /****************************************************************************
1772 * Implementation of fuzzy comparisons *
1773 ****************************************************************************/
1774 
1775 template<typename Scalar,
1776  bool IsComplex,
1777  bool IsInteger>
1779 
1780 template<typename Scalar>
1781 struct scalar_fuzzy_default_impl<Scalar, false, false>
1782 {
1783  typedef typename NumTraits<Scalar>::Real RealScalar;
1784  template<typename OtherScalar> EIGEN_DEVICE_FUNC
1785  static inline bool isMuchSmallerThan(const Scalar& x, const OtherScalar& y, const RealScalar& prec)
1786  {
1787  return numext::abs(x) <= numext::abs(y) * prec;
1788  }
1789  EIGEN_DEVICE_FUNC
1790  static inline bool isApprox(const Scalar& x, const Scalar& y, const RealScalar& prec)
1791  {
1792  return numext::abs(x - y) <= numext::mini(numext::abs(x), numext::abs(y)) * prec;
1793  }
1794  EIGEN_DEVICE_FUNC
1795  static inline bool isApproxOrLessThan(const Scalar& x, const Scalar& y, const RealScalar& prec)
1796  {
1797  return x <= y || isApprox(x, y, prec);
1798  }
1799 };
1800 
1801 template<typename Scalar>
1802 struct scalar_fuzzy_default_impl<Scalar, false, true>
1803 {
1804  typedef typename NumTraits<Scalar>::Real RealScalar;
1805  template<typename OtherScalar> EIGEN_DEVICE_FUNC
1806  static inline bool isMuchSmallerThan(const Scalar& x, const Scalar&, const RealScalar&)
1807  {
1808  return x == Scalar(0);
1809  }
1810  EIGEN_DEVICE_FUNC
1811  static inline bool isApprox(const Scalar& x, const Scalar& y, const RealScalar&)
1812  {
1813  return x == y;
1814  }
1815  EIGEN_DEVICE_FUNC
1816  static inline bool isApproxOrLessThan(const Scalar& x, const Scalar& y, const RealScalar&)
1817  {
1818  return x <= y;
1819  }
1820 };
1821 
1822 template<typename Scalar>
1823 struct scalar_fuzzy_default_impl<Scalar, true, false>
1824 {
1825  typedef typename NumTraits<Scalar>::Real RealScalar;
1826  template<typename OtherScalar> EIGEN_DEVICE_FUNC
1827  static inline bool isMuchSmallerThan(const Scalar& x, const OtherScalar& y, const RealScalar& prec)
1828  {
1829  return numext::abs2(x) <= numext::abs2(y) * prec * prec;
1830  }
1831  EIGEN_DEVICE_FUNC
1832  static inline bool isApprox(const Scalar& x, const Scalar& y, const RealScalar& prec)
1833  {
1834  return numext::abs2(x - y) <= numext::mini(numext::abs2(x), numext::abs2(y)) * prec * prec;
1835  }
1836 };
1837 
1838 template<typename Scalar>
1839 struct scalar_fuzzy_impl : scalar_fuzzy_default_impl<Scalar, NumTraits<Scalar>::IsComplex, NumTraits<Scalar>::IsInteger> {};
1840 
1841 template<typename Scalar, typename OtherScalar> EIGEN_DEVICE_FUNC
1842 inline bool isMuchSmallerThan(const Scalar& x, const OtherScalar& y,
1843  const typename NumTraits<Scalar>::Real &precision = NumTraits<Scalar>::dummy_precision())
1844 {
1845  return scalar_fuzzy_impl<Scalar>::template isMuchSmallerThan<OtherScalar>(x, y, precision);
1846 }
1847 
1848 template<typename Scalar> EIGEN_DEVICE_FUNC
1849 inline bool isApprox(const Scalar& x, const Scalar& y,
1850  const typename NumTraits<Scalar>::Real &precision = NumTraits<Scalar>::dummy_precision())
1851 {
1852  return scalar_fuzzy_impl<Scalar>::isApprox(x, y, precision);
1853 }
1854 
1855 template<typename Scalar> EIGEN_DEVICE_FUNC
1856 inline bool isApproxOrLessThan(const Scalar& x, const Scalar& y,
1857  const typename NumTraits<Scalar>::Real &precision = NumTraits<Scalar>::dummy_precision())
1858 {
1859  return scalar_fuzzy_impl<Scalar>::isApproxOrLessThan(x, y, precision);
1860 }
1861 
1862 /******************************************
1863 *** The special case of the bool type ***
1864 ******************************************/
1865 
1866 template<> struct random_impl<bool>
1867 {
1868  static inline bool run()
1869  {
1870  return random<int>(0,1)==0 ? false : true;
1871  }
1872 
1873  static inline bool run(const bool& a, const bool& b)
1874  {
1875  return random<int>(a, b)==0 ? false : true;
1876  }
1877 };
1878 
1879 template<> struct scalar_fuzzy_impl<bool>
1880 {
1881  typedef bool RealScalar;
1882 
1883  template<typename OtherScalar> EIGEN_DEVICE_FUNC
1884  static inline bool isMuchSmallerThan(const bool& x, const bool&, const bool&)
1885  {
1886  return !x;
1887  }
1888 
1889  EIGEN_DEVICE_FUNC
1890  static inline bool isApprox(bool x, bool y, bool)
1891  {
1892  return x == y;
1893  }
1894 
1895  EIGEN_DEVICE_FUNC
1896  static inline bool isApproxOrLessThan(const bool& x, const bool& y, const bool&)
1897  {
1898  return (!x) || y;
1899  }
1900 
1901 };
1902 
1903 
1904 } // end namespace internal
1905 
1906 } // end namespace Eigen
1907 
1908 #endif // EIGEN_MATHFUNCTIONS_H
Eigen::internal::real_ref_retval
Definition: thirdparty/Eigen/src/Core/MathFunctions.h:190
Eigen::internal::global_math_functions_filtering_base
Definition: thirdparty/Eigen/src/Core/MathFunctions.h:54
Eigen::internal::cast_impl
Definition: thirdparty/Eigen/src/Core/MathFunctions.h:383
Eigen::internal::random_retval
Definition: thirdparty/Eigen/src/Core/MathFunctions.h:725
Eigen
Namespace containing all symbols from the Eigen library.
Definition: LDLT.h:16
Eigen::internal::hypot_impl
Definition: MathFunctionsImpl.h:92
Eigen::internal::pow_impl
Definition: thirdparty/Eigen/src/Core/MathFunctions.h:681
Eigen::internal::conj_retval
Definition: thirdparty/Eigen/src/Core/MathFunctions.h:279
Eigen::internal::norm1_impl
Definition: thirdparty/Eigen/src/Core/MathFunctions.h:357
Eigen::internal::meta_floor_log2
Definition: thirdparty/Eigen/src/Core/MathFunctions.h:766
Eigen::internal::meta_floor_log2< n, lower, upper, meta_floor_log2_move_down >
Definition: thirdparty/Eigen/src/Core/MathFunctions.h:770
Eigen::internal::abs2_impl_default
Definition: thirdparty/Eigen/src/Core/MathFunctions.h:289
Eigen::internal::conj_default_impl
Definition: thirdparty/Eigen/src/Core/MathFunctions.h:244
Eigen::internal::arg_default_impl
Definition: thirdparty/Eigen/src/Core/MathFunctions.h:516
Eigen::ScalarBinaryOpTraits
Determines whether the given binary operation of two numeric types is allowed and what the scalar ret...
Definition: XprHelper.h:814
Eigen::internal::imag_ref_retval
Definition: thirdparty/Eigen/src/Core/MathFunctions.h:234
Eigen::internal::norm1_default_impl
Definition: thirdparty/Eigen/src/Core/MathFunctions.h:331
Eigen::internal::imag_default_impl
Definition: thirdparty/Eigen/src/Core/MathFunctions.h:126
Eigen::internal::abs2_retval
Definition: thirdparty/Eigen/src/Core/MathFunctions.h:322
Eigen::internal::scalar_fuzzy_default_impl
Definition: thirdparty/Eigen/src/Core/MathFunctions.h:1778
Eigen::internal::imag_retval
Definition: thirdparty/Eigen/src/Core/MathFunctions.h:164
Eigen::internal::hypot_retval
Definition: thirdparty/Eigen/src/Core/MathFunctions.h:373
Eigen::internal::log1p_impl
Definition: thirdparty/Eigen/src/Core/MathFunctions.h:646
Eigen::internal::log1p_retval
Definition: thirdparty/Eigen/src/Core/MathFunctions.h:671
Eigen::internal::expm1_impl
Definition: thirdparty/Eigen/src/Core/MathFunctions.h:576
Eigen::internal::arg_retval
Definition: thirdparty/Eigen/src/Core/MathFunctions.h:541
Eigen::internal::rint_impl
Definition: thirdparty/Eigen/src/Core/MathFunctions.h:457
Eigen::internal::abs2_impl
Definition: thirdparty/Eigen/src/Core/MathFunctions.h:311
Eigen::internal::random_default_impl
Definition: thirdparty/Eigen/src/Core/MathFunctions.h:718
Eigen::internal::random_impl
Definition: thirdparty/Eigen/src/Core/MathFunctions.h:721
Eigen::internal::rint_retval
Definition: thirdparty/Eigen/src/Core/MathFunctions.h:490
Eigen::internal::conj_impl
Definition: thirdparty/Eigen/src/Core/MathFunctions.h:263
Eigen::internal::scalar_fuzzy_impl
Definition: thirdparty/Eigen/src/Core/MathFunctions.h:1839
Eigen::internal::real_default_impl
Definition: thirdparty/Eigen/src/Core/MathFunctions.h:78
Eigen::internal::real_impl
Definition: thirdparty/Eigen/src/Core/MathFunctions.h:99
Eigen::internal::real_retval
Definition: thirdparty/Eigen/src/Core/MathFunctions.h:116
Eigen::internal::conditional
Definition: Meta.h:76
Eigen::internal::round_retval
Definition: thirdparty/Eigen/src/Core/MathFunctions.h:448
Eigen::internal::meta_floor_log2_selector
Definition: thirdparty/Eigen/src/Core/MathFunctions.h:753
Eigen::internal::round_impl
Definition: thirdparty/Eigen/src/Core/MathFunctions.h:434
Eigen::internal::imag_impl
Definition: thirdparty/Eigen/src/Core/MathFunctions.h:147
Eigen::internal::enable_if
Definition: Meta.h:234
Eigen::internal::expm1_retval
Definition: thirdparty/Eigen/src/Core/MathFunctions.h:621
Eigen::internal::imag_ref_impl
Definition: thirdparty/Eigen/src/Core/MathFunctions.h:230
Eigen::internal::imag_ref_default_impl
Definition: thirdparty/Eigen/src/Core/MathFunctions.h:200
Eigen::internal::always_void
Definition: thirdparty/Eigen/src/Core/MathFunctions.h:58
Eigen::internal::norm1_retval
Definition: thirdparty/Eigen/src/Core/MathFunctions.h:361
Eigen::NumTraits
Holds information about the various numeric (i.e. scalar) types allowed by Eigen.
Definition: NumTraits.h:213
Eigen::internal::make_unsigned
Definition: Meta.h:149
Eigen::internal::arg_impl
Definition: thirdparty/Eigen/src/Core/MathFunctions.h:536
Eigen::internal::real_ref_impl
Definition: thirdparty/Eigen/src/Core/MathFunctions.h:174