MathFunctions.h
Go to the documentation of this file.
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 // Copyright (c) 2021, NVIDIA CORPORATION. All rights reserved.
6 //
7 // This Source Code Form is subject to the terms of the Mozilla
8 // Public License v. 2.0. If a copy of the MPL was not distributed
9 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
10 
11 #ifndef EIGEN_MATHFUNCTIONS_H
12 #define EIGEN_MATHFUNCTIONS_H
13 
14 // TODO this should better be moved to NumTraits
15 // Source: WolframAlpha
16 #define EIGEN_PI 3.141592653589793238462643383279502884197169399375105820974944592307816406L
17 #define EIGEN_LOG2E 1.442695040888963407359924681001892137426645954152985934135449406931109219L
18 #define EIGEN_LN2 0.693147180559945309417232121458176568075500134360255254120680009493393621L
19 
20 #include "./InternalHeaderCheck.h"
21 
22 namespace Eigen {
23 
24 namespace internal {
25 
46 template<typename T, typename dummy = void>
47 struct global_math_functions_filtering_base
48 {
49  typedef T type;
50 };
51 
52 template<typename T> struct always_void { typedef void type; };
53 
54 template<typename T>
55 struct global_math_functions_filtering_base
56  <T,
57  typename always_void<typename T::Eigen_BaseClassForSpecializationOfGlobalMathFuncImpl>::type
58  >
59 {
60  typedef typename T::Eigen_BaseClassForSpecializationOfGlobalMathFuncImpl type;
61 };
62 
63 #define EIGEN_MATHFUNC_IMPL(func, scalar) Eigen::internal::func##_impl<typename Eigen::internal::global_math_functions_filtering_base<scalar>::type>
64 #define EIGEN_MATHFUNC_RETVAL(func, scalar) typename Eigen::internal::func##_retval<typename Eigen::internal::global_math_functions_filtering_base<scalar>::type>::type
65 
66 
70 template<typename Scalar, bool IsComplex = NumTraits<Scalar>::IsComplex>
71 struct real_default_impl
72 {
73  typedef typename NumTraits<Scalar>::Real RealScalar;
75  static inline RealScalar run(const Scalar& x)
76  {
77  return x;
78  }
79 };
80 
81 template<typename Scalar>
82 struct real_default_impl<Scalar,true>
83 {
84  typedef typename NumTraits<Scalar>::Real RealScalar;
86  static inline RealScalar run(const Scalar& x)
87  {
88  using std::real;
89  return real(x);
90  }
91 };
92 
93 template<typename Scalar> struct real_impl : real_default_impl<Scalar> {};
94 
95 #if defined(EIGEN_GPU_COMPILE_PHASE)
96 template<typename T>
97 struct real_impl<std::complex<T> >
98 {
99  typedef T RealScalar;
101  static inline T run(const std::complex<T>& x)
102  {
103  return x.real();
104  }
105 };
106 #endif
107 
108 template<typename Scalar>
109 struct real_retval
110 {
111  typedef typename NumTraits<Scalar>::Real type;
112 };
113 
114 
118 template<typename Scalar, bool IsComplex = NumTraits<Scalar>::IsComplex>
119 struct imag_default_impl
120 {
121  typedef typename NumTraits<Scalar>::Real RealScalar;
123  static inline RealScalar run(const Scalar&)
124  {
125  return RealScalar(0);
126  }
127 };
128 
129 template<typename Scalar>
130 struct imag_default_impl<Scalar,true>
131 {
132  typedef typename NumTraits<Scalar>::Real RealScalar;
134  static inline RealScalar run(const Scalar& x)
135  {
136  using std::imag;
137  return imag(x);
138  }
139 };
140 
141 template<typename Scalar> struct imag_impl : imag_default_impl<Scalar> {};
142 
143 #if defined(EIGEN_GPU_COMPILE_PHASE)
144 template<typename T>
145 struct imag_impl<std::complex<T> >
146 {
147  typedef T RealScalar;
149  static inline T run(const std::complex<T>& x)
150  {
151  return x.imag();
152  }
153 };
154 #endif
155 
156 template<typename Scalar>
157 struct imag_retval
158 {
159  typedef typename NumTraits<Scalar>::Real type;
160 };
161 
162 
166 template<typename Scalar>
167 struct real_ref_impl
168 {
169  typedef typename NumTraits<Scalar>::Real RealScalar;
171  static inline RealScalar& run(Scalar& x)
172  {
173  return reinterpret_cast<RealScalar*>(&x)[0];
174  }
176  static inline const RealScalar& run(const Scalar& x)
177  {
178  return reinterpret_cast<const RealScalar*>(&x)[0];
179  }
180 };
181 
182 template<typename Scalar>
183 struct real_ref_retval
184 {
185  typedef typename NumTraits<Scalar>::Real & type;
186 };
187 
188 
192 template<typename Scalar, bool IsComplex>
193 struct imag_ref_default_impl
194 {
195  typedef typename NumTraits<Scalar>::Real RealScalar;
197  static inline RealScalar& run(Scalar& x)
198  {
199  return reinterpret_cast<RealScalar*>(&x)[1];
200  }
202  static inline const RealScalar& run(const Scalar& x)
203  {
204  return reinterpret_cast<RealScalar*>(&x)[1];
205  }
206 };
207 
208 template<typename Scalar>
209 struct imag_ref_default_impl<Scalar, false>
210 {
212  static inline Scalar run(Scalar&)
213  {
214  return Scalar(0);
215  }
217  static inline const Scalar run(const Scalar&)
218  {
219  return Scalar(0);
220  }
221 };
222 
223 template<typename Scalar>
224 struct imag_ref_impl : imag_ref_default_impl<Scalar, NumTraits<Scalar>::IsComplex> {};
225 
226 template<typename Scalar>
227 struct imag_ref_retval
228 {
229  typedef typename NumTraits<Scalar>::Real & type;
230 };
231 
232 
236 template<typename Scalar, bool IsComplex = NumTraits<Scalar>::IsComplex>
237 struct conj_default_impl
238 {
240  static inline Scalar run(const Scalar& x)
241  {
242  return x;
243  }
244 };
245 
246 template<typename Scalar>
247 struct conj_default_impl<Scalar,true>
248 {
250  static inline Scalar run(const Scalar& x)
251  {
252  using std::conj;
253  return conj(x);
254  }
255 };
256 
257 template<typename Scalar, bool IsComplex = NumTraits<Scalar>::IsComplex>
258 struct conj_impl : conj_default_impl<Scalar, IsComplex> {};
259 
260 template<typename Scalar>
261 struct conj_retval
262 {
263  typedef Scalar type;
264 };
265 
266 
270 template<typename Scalar,bool IsComplex>
271 struct abs2_impl_default
272 {
273  typedef typename NumTraits<Scalar>::Real RealScalar;
275  static inline RealScalar run(const Scalar& x)
276  {
277  return x*x;
278  }
279 };
280 
281 template<typename Scalar>
282 struct abs2_impl_default<Scalar, true> // IsComplex
283 {
284  typedef typename NumTraits<Scalar>::Real RealScalar;
286  static inline RealScalar run(const Scalar& x)
287  {
288  return x.real()*x.real() + x.imag()*x.imag();
289  }
290 };
291 
292 template<typename Scalar>
293 struct abs2_impl
294 {
295  typedef typename NumTraits<Scalar>::Real RealScalar;
297  static inline RealScalar run(const Scalar& x)
298  {
299  return abs2_impl_default<Scalar,NumTraits<Scalar>::IsComplex>::run(x);
300  }
301 };
302 
303 template<typename Scalar>
304 struct abs2_retval
305 {
306  typedef typename NumTraits<Scalar>::Real type;
307 };
308 
309 
313 template<typename Scalar>
314 struct sqrt_impl
315 {
317  static EIGEN_ALWAYS_INLINE Scalar run(const Scalar& x)
318  {
320  return sqrt(x);
321  }
322 };
323 
324 // Complex sqrt defined in MathFunctionsImpl.h.
325 template<typename T> EIGEN_DEVICE_FUNC std::complex<T> complex_sqrt(const std::complex<T>& a_x);
326 
327 // Custom implementation is faster than `std::sqrt`, works on
328 // GPU, and correctly handles special cases (unlike MSVC).
329 template<typename T>
330 struct sqrt_impl<std::complex<T> >
331 {
333  static EIGEN_ALWAYS_INLINE std::complex<T> run(const std::complex<T>& x)
334  {
335  return complex_sqrt<T>(x);
336  }
337 };
338 
339 template<typename Scalar>
340 struct sqrt_retval
341 {
342  typedef Scalar type;
343 };
344 
345 // Default implementation relies on numext::sqrt, at bottom of file.
346 template<typename T>
347 struct rsqrt_impl;
348 
349 // Complex rsqrt defined in MathFunctionsImpl.h.
350 template<typename T> EIGEN_DEVICE_FUNC std::complex<T> complex_rsqrt(const std::complex<T>& a_x);
351 
352 template<typename T>
353 struct rsqrt_impl<std::complex<T> >
354 {
356  static EIGEN_ALWAYS_INLINE std::complex<T> run(const std::complex<T>& x)
357  {
358  return complex_rsqrt<T>(x);
359  }
360 };
361 
362 template<typename Scalar>
363 struct rsqrt_retval
364 {
365  typedef Scalar type;
366 };
367 
368 
372 template<typename Scalar, bool IsComplex>
373 struct norm1_default_impl;
374 
375 template<typename Scalar>
376 struct norm1_default_impl<Scalar,true>
377 {
378  typedef typename NumTraits<Scalar>::Real RealScalar;
380  static inline RealScalar run(const Scalar& x)
381  {
383  return abs(x.real()) + abs(x.imag());
384  }
385 };
386 
387 template<typename Scalar>
388 struct norm1_default_impl<Scalar, false>
389 {
391  static inline Scalar run(const Scalar& x)
392  {
394  return abs(x);
395  }
396 };
397 
398 template<typename Scalar>
399 struct norm1_impl : norm1_default_impl<Scalar, NumTraits<Scalar>::IsComplex> {};
400 
401 template<typename Scalar>
402 struct norm1_retval
403 {
404  typedef typename NumTraits<Scalar>::Real type;
405 };
406 
407 
411 template<typename Scalar> struct hypot_impl;
412 
413 template<typename Scalar>
414 struct hypot_retval
415 {
416  typedef typename NumTraits<Scalar>::Real type;
417 };
418 
419 
423 template<typename OldType, typename NewType, typename EnableIf = void>
424 struct cast_impl
425 {
427  static inline NewType run(const OldType& x)
428  {
429  return static_cast<NewType>(x);
430  }
431 };
432 
433 template <typename OldType>
434 struct cast_impl<OldType, bool> {
436  static inline bool run(const OldType& x) { return x != OldType(0); }
437 };
438 
439 
440 // Casting from S -> Complex<T> leads to an implicit conversion from S to T,
441 // generating warnings on clang. Here we explicitly cast the real component.
442 template<typename OldType, typename NewType>
443 struct cast_impl<OldType, NewType,
444  typename std::enable_if_t<
445  !NumTraits<OldType>::IsComplex && NumTraits<NewType>::IsComplex
446  >>
447 {
449  static inline NewType run(const OldType& x)
450  {
451  typedef typename NumTraits<NewType>::Real NewReal;
452  return static_cast<NewType>(static_cast<NewReal>(x));
453  }
454 };
455 
456 // here, for once, we're plainly returning NewType: we don't want cast to do weird things.
457 
458 template<typename OldType, typename NewType>
460 inline NewType cast(const OldType& x)
461 {
462  return cast_impl<OldType, NewType>::run(x);
463 }
464 
465 
469 // Visual Studio 2017 has a bug where arg(float) returns 0 for negative inputs.
470 // This seems to be fixed in VS 2019.
471 #if (!EIGEN_COMP_MSVC || EIGEN_COMP_MSVC >= 1920)
472 // std::arg is only defined for types of std::complex, or integer types or float/double/long double
473 template<typename Scalar,
474  bool HasStdImpl = NumTraits<Scalar>::IsComplex || is_integral<Scalar>::value
475  || is_same<Scalar, float>::value || is_same<Scalar, double>::value
476  || is_same<Scalar, long double>::value >
477 struct arg_default_impl;
478 
479 template<typename Scalar>
480 struct arg_default_impl<Scalar, true> {
481  typedef typename NumTraits<Scalar>::Real RealScalar;
483  static inline RealScalar run(const Scalar& x)
484  {
485  // There is no official ::arg on device in CUDA/HIP, so we always need to use std::arg.
486  using std::arg;
487  return static_cast<RealScalar>(arg(x));
488  }
489 };
490 
491 // Must be non-complex floating-point type (e.g. half/bfloat16).
492 template<typename Scalar>
493 struct arg_default_impl<Scalar, false> {
494  typedef typename NumTraits<Scalar>::Real RealScalar;
496  static inline RealScalar run(const Scalar& x)
497  {
498  return (x < Scalar(0)) ? RealScalar(EIGEN_PI) : RealScalar(0);
499  }
500 };
501 #else
502 template<typename Scalar, bool IsComplex = NumTraits<Scalar>::IsComplex>
503 struct arg_default_impl
504 {
505  typedef typename NumTraits<Scalar>::Real RealScalar;
507  static inline RealScalar run(const Scalar& x)
508  {
509  return (x < RealScalar(0)) ? RealScalar(EIGEN_PI) : RealScalar(0);
510  }
511 };
512 
513 template<typename Scalar>
514 struct arg_default_impl<Scalar,true>
515 {
516  typedef typename NumTraits<Scalar>::Real RealScalar;
518  static inline RealScalar run(const Scalar& x)
519  {
521  return arg(x);
522  }
523 };
524 #endif
525 template<typename Scalar> struct arg_impl : arg_default_impl<Scalar> {};
526 
527 template<typename Scalar>
528 struct arg_retval
529 {
530  typedef typename NumTraits<Scalar>::Real type;
531 };
532 
533 
537 // This implementation is based on GSL Math's expm1.
538 namespace std_fallback {
539  // fallback expm1 implementation in case there is no expm1(Scalar) function in namespace of Scalar,
540  // or that there is no suitable std::expm1 function available. Implementation
541  // attributed to Kahan. See: http://www.plunk.org/~hatch/rightway.php.
542  template<typename Scalar>
543  EIGEN_DEVICE_FUNC inline Scalar expm1(const Scalar& x) {
545  typedef typename NumTraits<Scalar>::Real RealScalar;
546 
548  Scalar u = exp(x);
549  if (numext::equal_strict(u, Scalar(1))) {
550  return x;
551  }
552  Scalar um1 = u - RealScalar(1);
553  if (numext::equal_strict(um1, Scalar(-1))) {
554  return RealScalar(-1);
555  }
556 
558  Scalar logu = log(u);
559  return numext::equal_strict(u, logu) ? u : (u - RealScalar(1)) * x / logu;
560  }
561 }
562 
563 template<typename Scalar>
564 struct expm1_impl {
565  EIGEN_DEVICE_FUNC static inline Scalar run(const Scalar& x)
566  {
569  return expm1(x);
570  }
571 };
572 
573 template<typename Scalar>
574 struct expm1_retval
575 {
576  typedef Scalar type;
577 };
578 
579 
583 // Complex log defined in MathFunctionsImpl.h.
584 template<typename T> EIGEN_DEVICE_FUNC std::complex<T> complex_log(const std::complex<T>& z);
585 
586 template<typename Scalar>
587 struct log_impl {
588  EIGEN_DEVICE_FUNC static inline Scalar run(const Scalar& x)
589  {
591  return static_cast<Scalar>(log(x));
592  }
593 };
594 
595 template<typename Scalar>
596 struct log_impl<std::complex<Scalar> > {
597  EIGEN_DEVICE_FUNC static inline std::complex<Scalar> run(const std::complex<Scalar>& z)
598  {
599  return complex_log(z);
600  }
601 };
602 
603 
607 namespace std_fallback {
608  // fallback log1p implementation in case there is no log1p(Scalar) function in namespace of Scalar,
609  // or that there is no suitable std::log1p function available
610  template<typename Scalar>
611  EIGEN_DEVICE_FUNC inline Scalar log1p(const Scalar& x) {
613  typedef typename NumTraits<Scalar>::Real RealScalar;
615  Scalar x1p = RealScalar(1) + x;
616  Scalar log_1p = log_impl<Scalar>::run(x1p);
617  const bool is_small = numext::equal_strict(x1p, Scalar(1));
618  const bool is_inf = numext::equal_strict(x1p, log_1p);
619  return (is_small || is_inf) ? x : x * (log_1p / (x1p - RealScalar(1)));
620  }
621 }
622 
623 template<typename Scalar>
624 struct log1p_impl {
626 
627  EIGEN_DEVICE_FUNC static inline Scalar run(const Scalar& x)
628  {
630  return log1p(x);
631  }
632 };
633 
634 // Specialization for complex types that are not supported by std::log1p.
635 template <typename RealScalar>
636 struct log1p_impl<std::complex<RealScalar> > {
638 
639  EIGEN_DEVICE_FUNC static inline std::complex<RealScalar> run(
640  const std::complex<RealScalar>& x) {
641  return std_fallback::log1p(x);
642  }
643 };
644 
645 template<typename Scalar>
646 struct log1p_retval
647 {
648  typedef Scalar type;
649 };
650 
651 
655 template<typename ScalarX,typename ScalarY, bool IsInteger = NumTraits<ScalarX>::IsInteger&&NumTraits<ScalarY>::IsInteger>
656 struct pow_impl
657 {
658  //typedef Scalar retval;
659  typedef typename ScalarBinaryOpTraits<ScalarX,ScalarY,internal::scalar_pow_op<ScalarX,ScalarY> >::ReturnType result_type;
660  static EIGEN_DEVICE_FUNC inline result_type run(const ScalarX& x, const ScalarY& y)
661  {
663  return pow(x, y);
664  }
665 };
666 
667 template<typename ScalarX,typename ScalarY>
668 struct pow_impl<ScalarX,ScalarY, true>
669 {
670  typedef ScalarX result_type;
671  static EIGEN_DEVICE_FUNC inline ScalarX run(ScalarX x, ScalarY y)
672  {
673  ScalarX res(1);
675  if(y & 1) res *= x;
676  y >>= 1;
677  while(y)
678  {
679  x *= x;
680  if(y&1) res *= x;
681  y >>= 1;
682  }
683  return res;
684  }
685 };
686 
687 
691 template<typename Scalar,
692  bool IsComplex,
693  bool IsInteger>
694 struct random_default_impl {};
695 
696 template<typename Scalar>
697 struct random_impl : random_default_impl<Scalar, NumTraits<Scalar>::IsComplex, NumTraits<Scalar>::IsInteger> {};
698 
699 template<typename Scalar>
700 struct random_retval
701 {
702  typedef Scalar type;
703 };
704 
705 template<typename Scalar> inline EIGEN_MATHFUNC_RETVAL(random, Scalar) random(const Scalar& x, const Scalar& y);
706 template<typename Scalar> inline EIGEN_MATHFUNC_RETVAL(random, Scalar) random();
707 
708 template<typename Scalar>
709 struct random_default_impl<Scalar, false, false>
710 {
711  static inline Scalar run(const Scalar& x, const Scalar& y)
712  {
713  return x + (y-x) * Scalar(std::rand()) / Scalar(RAND_MAX);
714  }
715  static inline Scalar run()
716  {
717  return run(Scalar(NumTraits<Scalar>::IsSigned ? -1 : 0), Scalar(1));
718  }
719 };
720 
721 enum {
726 };
727 
728 template<unsigned int n, int lower, int upper> struct meta_floor_log2_selector
729 {
730  enum { middle = (lower + upper) / 2,
731  value = (upper <= lower + 1) ? int(meta_floor_log2_terminate)
732  : (n < (1 << middle)) ? int(meta_floor_log2_move_down)
733  : (n==0) ? int(meta_floor_log2_bogus)
735  };
736 };
737 
738 template<unsigned int n,
739  int lower = 0,
740  int upper = sizeof(unsigned int) * CHAR_BIT - 1,
741  int selector = meta_floor_log2_selector<n, lower, upper>::value>
742 struct meta_floor_log2 {};
743 
744 template<unsigned int n, int lower, int upper>
745 struct meta_floor_log2<n, lower, upper, meta_floor_log2_move_down>
746 {
747  enum { value = meta_floor_log2<n, lower, meta_floor_log2_selector<n, lower, upper>::middle>::value };
748 };
749 
750 template<unsigned int n, int lower, int upper>
751 struct meta_floor_log2<n, lower, upper, meta_floor_log2_move_up>
752 {
753  enum { value = meta_floor_log2<n, meta_floor_log2_selector<n, lower, upper>::middle, upper>::value };
754 };
755 
756 template<unsigned int n, int lower, int upper>
757 struct meta_floor_log2<n, lower, upper, meta_floor_log2_terminate>
758 {
759  enum { value = (n >= ((unsigned int)(1) << (lower+1))) ? lower+1 : lower };
760 };
761 
762 template<unsigned int n, int lower, int upper>
763 struct meta_floor_log2<n, lower, upper, meta_floor_log2_bogus>
764 {
765  // no value, error at compile time
766 };
767 
768 template<typename Scalar>
769 struct random_default_impl<Scalar, false, true>
770 {
771  static inline Scalar run(const Scalar& x, const Scalar& y)
772  {
773  if (y <= x)
774  return x;
775  // ScalarU is the unsigned counterpart of Scalar, possibly Scalar itself.
776  typedef typename make_unsigned<Scalar>::type ScalarU;
777  // ScalarX is the widest of ScalarU and unsigned int.
778  // We'll deal only with ScalarX and unsigned int below thus avoiding signed
779  // types and arithmetic and signed overflows (which are undefined behavior).
780  typedef std::conditional_t<(ScalarU(-1) > unsigned(-1)), ScalarU, unsigned> ScalarX;
781  // The following difference doesn't overflow, provided our integer types are two's
782  // complement and have the same number of padding bits in signed and unsigned variants.
783  // This is the case in most modern implementations of C++.
784  ScalarX range = ScalarX(y) - ScalarX(x);
785  ScalarX offset = 0;
786  ScalarX divisor = 1;
787  ScalarX multiplier = 1;
788  const unsigned rand_max = RAND_MAX;
789  if (range <= rand_max) divisor = (rand_max + 1) / (range + 1);
790  else multiplier = 1 + range / (rand_max + 1);
791  // Rejection sampling.
792  do {
793  offset = (unsigned(std::rand()) * multiplier) / divisor;
794  } while (offset > range);
795  return Scalar(ScalarX(x) + offset);
796  }
797 
798  static inline Scalar run()
799  {
800 #ifdef EIGEN_MAKING_DOCS
801  return run(Scalar(NumTraits<Scalar>::IsSigned ? -10 : 0), Scalar(10));
802 #else
803  enum { rand_bits = meta_floor_log2<(unsigned int)(RAND_MAX)+1>::value,
804  scalar_bits = sizeof(Scalar) * CHAR_BIT,
805  shift = plain_enum_max(0, int(rand_bits) - int(scalar_bits)),
806  offset = NumTraits<Scalar>::IsSigned ? (1 << (plain_enum_min(rand_bits, scalar_bits)-1)) : 0
807  };
808  return Scalar((std::rand() >> shift) - offset);
809 #endif
810  }
811 };
812 
813 template<typename Scalar>
814 struct random_default_impl<Scalar, true, false>
815 {
816  static inline Scalar run(const Scalar& x, const Scalar& y)
817  {
818  return Scalar(random(x.real(), y.real()),
819  random(x.imag(), y.imag()));
820  }
821  static inline Scalar run()
822  {
823  typedef typename NumTraits<Scalar>::Real RealScalar;
824  return Scalar(random<RealScalar>(), random<RealScalar>());
825  }
826 };
827 
828 template<typename Scalar>
829 inline EIGEN_MATHFUNC_RETVAL(random, Scalar) random(const Scalar& x, const Scalar& y)
830 {
831  return EIGEN_MATHFUNC_IMPL(random, Scalar)::run(x, y);
832 }
833 
834 template<typename Scalar>
835 inline EIGEN_MATHFUNC_RETVAL(random, Scalar) random()
836 {
837  return EIGEN_MATHFUNC_IMPL(random, Scalar)::run();
838 }
839 
840 // Implementation of is* functions
841 
842 template <typename T>
843 EIGEN_DEVICE_FUNC std::enable_if_t<!(std::numeric_limits<T>::has_infinity ||
844  std::numeric_limits<T>::has_quiet_NaN ||
845  std::numeric_limits<T>::has_signaling_NaN),
846  bool>
847 isfinite_impl(const T&) {
848  return true;
849 }
850 
851 template <typename T>
852 EIGEN_DEVICE_FUNC std::enable_if_t<(std::numeric_limits<T>::has_infinity || std::numeric_limits<T>::has_quiet_NaN ||
853  std::numeric_limits<T>::has_signaling_NaN) &&
855  bool>
856 isfinite_impl(const T& x) {
858  return isfinite EIGEN_NOT_A_MACRO (x);
859 }
860 
861 template <typename T>
862 EIGEN_DEVICE_FUNC std::enable_if_t<!std::numeric_limits<T>::has_infinity, bool>
863 isinf_impl(const T&) {
864  return false;
865 }
866 
867 template <typename T>
868 EIGEN_DEVICE_FUNC std::enable_if_t<
869  (std::numeric_limits<T>::has_infinity && !NumTraits<T>::IsComplex), bool>
870 isinf_impl(const T& x) {
872  return isinf EIGEN_NOT_A_MACRO (x);
873 }
874 
875 template <typename T>
876 EIGEN_DEVICE_FUNC std::enable_if_t<!(std::numeric_limits<T>::has_quiet_NaN ||
877  std::numeric_limits<T>::has_signaling_NaN),
878  bool>
879 isnan_impl(const T&) {
880  return false;
881 }
882 
883 template <typename T>
885  std::enable_if_t<(std::numeric_limits<T>::has_quiet_NaN ||
886  std::numeric_limits<T>::has_signaling_NaN) &&
888  bool>
889  isnan_impl(const T& x) {
891  return isnan EIGEN_NOT_A_MACRO (x);
892 }
893 
894 // The following overload are defined at the end of this file
895 template <typename T>
896 EIGEN_DEVICE_FUNC bool isfinite_impl(const std::complex<T>& x);
897 template <typename T>
898 EIGEN_DEVICE_FUNC bool isnan_impl(const std::complex<T>& x);
899 template <typename T>
900 EIGEN_DEVICE_FUNC bool isinf_impl(const std::complex<T>& x);
901 template <typename T>
902 T generic_fast_tanh_float(const T& a_x);
903 
904 
907 template <typename Scalar, bool IsComplex = (NumTraits<Scalar>::IsComplex != 0),
908  bool IsInteger = (NumTraits<Scalar>::IsInteger != 0)>
909 struct sign_impl {
911  static inline Scalar run(const Scalar& a) {
912  return Scalar((a > Scalar(0)) - (a < Scalar(0)));
913  }
914 };
915 
916 template <typename Scalar>
917 struct sign_impl<Scalar, false, false> {
919  static inline Scalar run(const Scalar& a) {
920  return (isnan_impl<Scalar>)(a) ? a
921  : Scalar((a > Scalar(0)) - (a < Scalar(0)));
922  }
923 };
924 
925 template <typename Scalar, bool IsInteger>
926 struct sign_impl<Scalar, true, IsInteger> {
928  static inline Scalar run(const Scalar& a) {
929  using real_type = typename NumTraits<Scalar>::Real;
931  real_type aa = abs(a);
932  if (aa == real_type(0)) return Scalar(0);
933  aa = real_type(1) / aa;
934  return Scalar(a.real() * aa, a.imag() * aa);
935  }
936 };
937 
938 // The sign function for bool is the identity.
939 template <>
940 struct sign_impl<bool, false, true> {
942  static inline bool run(const bool& a) { return a; }
943 };
944 
945 template <typename Scalar>
946 struct sign_retval {
947  typedef Scalar type;
948 };
949 
950 
951 template <typename Scalar, bool IsInteger = NumTraits<typename unpacket_traits<Scalar>::type>::IsInteger>
952 struct nearest_integer_impl {
953  static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar run_floor(const Scalar& x) { EIGEN_USING_STD(floor) return floor(x); }
954  static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar run_ceil(const Scalar& x) { EIGEN_USING_STD(ceil) return ceil(x); }
955  static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar run_rint(const Scalar& x) { EIGEN_USING_STD(rint) return rint(x); }
956  static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar run_round(const Scalar& x) { EIGEN_USING_STD(round) return round(x); }
957 };
958 template <typename Scalar>
959 struct nearest_integer_impl<Scalar, true> {
960  static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar run_floor(const Scalar& x) { return x; }
961  static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar run_ceil(const Scalar& x) { return x; }
962  static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar run_rint(const Scalar& x) { return x; }
963  static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar run_round(const Scalar& x) { return x; }
964 };
965 
966 } // end namespace internal
967 
968 
972 namespace numext {
973 
974 #if (!defined(EIGEN_GPUCC) || defined(EIGEN_CONSTEXPR_ARE_DEVICE_FUNC))
975 template<typename T>
977 EIGEN_ALWAYS_INLINE T mini(const T& x, const T& y)
978 {
980  return min EIGEN_NOT_A_MACRO (x,y);
981 }
982 
983 template<typename T>
985 EIGEN_ALWAYS_INLINE T maxi(const T& x, const T& y)
986 {
988  return max EIGEN_NOT_A_MACRO (x,y);
989 }
990 #else
991 template<typename T>
993 EIGEN_ALWAYS_INLINE T mini(const T& x, const T& y)
994 {
995  return y < x ? y : x;
996 }
997 template<>
999 EIGEN_ALWAYS_INLINE float mini(const float& x, const float& y)
1000 {
1001  return fminf(x, y);
1002 }
1003 template<>
1005 EIGEN_ALWAYS_INLINE double mini(const double& x, const double& y)
1006 {
1007  return fmin(x, y);
1008 }
1009 
1010 #ifndef EIGEN_GPU_COMPILE_PHASE
1011 template<>
1013 EIGEN_ALWAYS_INLINE long double mini(const long double& x, const long double& y)
1014 {
1015 #if defined(EIGEN_HIPCC)
1016  // no "fminl" on HIP yet
1017  return (x < y) ? x : y;
1018 #else
1019  return fminl(x, y);
1020 #endif
1021 }
1022 #endif
1023 
1024 template<typename T>
1026 EIGEN_ALWAYS_INLINE T maxi(const T& x, const T& y)
1027 {
1028  return x < y ? y : x;
1029 }
1030 template<>
1032 EIGEN_ALWAYS_INLINE float maxi(const float& x, const float& y)
1033 {
1034  return fmaxf(x, y);
1035 }
1036 template<>
1038 EIGEN_ALWAYS_INLINE double maxi(const double& x, const double& y)
1039 {
1040  return fmax(x, y);
1041 }
1042 #ifndef EIGEN_GPU_COMPILE_PHASE
1043 template<>
1045 EIGEN_ALWAYS_INLINE long double maxi(const long double& x, const long double& y)
1046 {
1047 #if defined(EIGEN_HIPCC)
1048  // no "fmaxl" on HIP yet
1049  return (x > y) ? x : y;
1050 #else
1051  return fmaxl(x, y);
1052 #endif
1053 }
1054 #endif
1055 #endif
1056 
1057 #if defined(SYCL_DEVICE_ONLY)
1058 
1059 
1060 #define SYCL_SPECIALIZE_SIGNED_INTEGER_TYPES_BINARY(NAME, FUNC) \
1061  SYCL_SPECIALIZE_BINARY_FUNC(NAME, FUNC, cl::sycl::cl_char) \
1062  SYCL_SPECIALIZE_BINARY_FUNC(NAME, FUNC, cl::sycl::cl_short) \
1063  SYCL_SPECIALIZE_BINARY_FUNC(NAME, FUNC, cl::sycl::cl_int) \
1064  SYCL_SPECIALIZE_BINARY_FUNC(NAME, FUNC, cl::sycl::cl_long)
1065 #define SYCL_SPECIALIZE_SIGNED_INTEGER_TYPES_UNARY(NAME, FUNC) \
1066  SYCL_SPECIALIZE_UNARY_FUNC(NAME, FUNC, cl::sycl::cl_char) \
1067  SYCL_SPECIALIZE_UNARY_FUNC(NAME, FUNC, cl::sycl::cl_short) \
1068  SYCL_SPECIALIZE_UNARY_FUNC(NAME, FUNC, cl::sycl::cl_int) \
1069  SYCL_SPECIALIZE_UNARY_FUNC(NAME, FUNC, cl::sycl::cl_long)
1070 #define SYCL_SPECIALIZE_UNSIGNED_INTEGER_TYPES_BINARY(NAME, FUNC) \
1071  SYCL_SPECIALIZE_BINARY_FUNC(NAME, FUNC, cl::sycl::cl_uchar) \
1072  SYCL_SPECIALIZE_BINARY_FUNC(NAME, FUNC, cl::sycl::cl_ushort) \
1073  SYCL_SPECIALIZE_BINARY_FUNC(NAME, FUNC, cl::sycl::cl_uint) \
1074  SYCL_SPECIALIZE_BINARY_FUNC(NAME, FUNC, cl::sycl::cl_ulong)
1075 #define SYCL_SPECIALIZE_UNSIGNED_INTEGER_TYPES_UNARY(NAME, FUNC) \
1076  SYCL_SPECIALIZE_UNARY_FUNC(NAME, FUNC, cl::sycl::cl_uchar) \
1077  SYCL_SPECIALIZE_UNARY_FUNC(NAME, FUNC, cl::sycl::cl_ushort) \
1078  SYCL_SPECIALIZE_UNARY_FUNC(NAME, FUNC, cl::sycl::cl_uint) \
1079  SYCL_SPECIALIZE_UNARY_FUNC(NAME, FUNC, cl::sycl::cl_ulong)
1080 #define SYCL_SPECIALIZE_INTEGER_TYPES_BINARY(NAME, FUNC) \
1081  SYCL_SPECIALIZE_SIGNED_INTEGER_TYPES_BINARY(NAME, FUNC) \
1082  SYCL_SPECIALIZE_UNSIGNED_INTEGER_TYPES_BINARY(NAME, FUNC)
1083 #define SYCL_SPECIALIZE_INTEGER_TYPES_UNARY(NAME, FUNC) \
1084  SYCL_SPECIALIZE_SIGNED_INTEGER_TYPES_UNARY(NAME, FUNC) \
1085  SYCL_SPECIALIZE_UNSIGNED_INTEGER_TYPES_UNARY(NAME, FUNC)
1086 #define SYCL_SPECIALIZE_FLOATING_TYPES_BINARY(NAME, FUNC) \
1087  SYCL_SPECIALIZE_BINARY_FUNC(NAME, FUNC, cl::sycl::cl_float) \
1088  SYCL_SPECIALIZE_BINARY_FUNC(NAME, FUNC,cl::sycl::cl_double)
1089 #define SYCL_SPECIALIZE_FLOATING_TYPES_UNARY(NAME, FUNC) \
1090  SYCL_SPECIALIZE_UNARY_FUNC(NAME, FUNC, cl::sycl::cl_float) \
1091  SYCL_SPECIALIZE_UNARY_FUNC(NAME, FUNC,cl::sycl::cl_double)
1092 #define SYCL_SPECIALIZE_FLOATING_TYPES_UNARY_FUNC_RET_TYPE(NAME, FUNC, RET_TYPE) \
1093  SYCL_SPECIALIZE_GEN_UNARY_FUNC(NAME, FUNC, RET_TYPE, cl::sycl::cl_float) \
1094  SYCL_SPECIALIZE_GEN_UNARY_FUNC(NAME, FUNC, RET_TYPE, cl::sycl::cl_double)
1095 
1096 #define SYCL_SPECIALIZE_GEN_UNARY_FUNC(NAME, FUNC, RET_TYPE, ARG_TYPE) \
1097 template<> \
1098  EIGEN_DEVICE_FUNC \
1099  EIGEN_ALWAYS_INLINE RET_TYPE NAME(const ARG_TYPE& x) { \
1100  return cl::sycl::FUNC(x); \
1101  }
1102 
1103 #define SYCL_SPECIALIZE_UNARY_FUNC(NAME, FUNC, TYPE) \
1104  SYCL_SPECIALIZE_GEN_UNARY_FUNC(NAME, FUNC, TYPE, TYPE)
1105 
1106 #define SYCL_SPECIALIZE_GEN1_BINARY_FUNC(NAME, FUNC, RET_TYPE, ARG_TYPE1, ARG_TYPE2) \
1107  template<> \
1108  EIGEN_DEVICE_FUNC \
1109  EIGEN_ALWAYS_INLINE RET_TYPE NAME(const ARG_TYPE1& x, const ARG_TYPE2& y) { \
1110  return cl::sycl::FUNC(x, y); \
1111  }
1112 
1113 #define SYCL_SPECIALIZE_GEN2_BINARY_FUNC(NAME, FUNC, RET_TYPE, ARG_TYPE) \
1114  SYCL_SPECIALIZE_GEN1_BINARY_FUNC(NAME, FUNC, RET_TYPE, ARG_TYPE, ARG_TYPE)
1115 
1116 #define SYCL_SPECIALIZE_BINARY_FUNC(NAME, FUNC, TYPE) \
1117  SYCL_SPECIALIZE_GEN2_BINARY_FUNC(NAME, FUNC, TYPE, TYPE)
1118 
1119 SYCL_SPECIALIZE_INTEGER_TYPES_BINARY(mini, min)
1120 SYCL_SPECIALIZE_FLOATING_TYPES_BINARY(mini, fmin)
1121 SYCL_SPECIALIZE_INTEGER_TYPES_BINARY(maxi, max)
1122 SYCL_SPECIALIZE_FLOATING_TYPES_BINARY(maxi, fmax)
1123 
1124 #endif
1125 
1126 
1127 template<typename Scalar>
1129 inline EIGEN_MATHFUNC_RETVAL(real, Scalar) real(const Scalar& x)
1130 {
1131  return EIGEN_MATHFUNC_IMPL(real, Scalar)::run(x);
1132 }
1133 
1134 template<typename Scalar>
1137 {
1138  return internal::real_ref_impl<Scalar>::run(x);
1139 }
1140 
1141 template<typename Scalar>
1143 inline EIGEN_MATHFUNC_RETVAL(real_ref, Scalar) real_ref(Scalar& x)
1144 {
1145  return EIGEN_MATHFUNC_IMPL(real_ref, Scalar)::run(x);
1146 }
1147 
1148 template<typename Scalar>
1150 inline EIGEN_MATHFUNC_RETVAL(imag, Scalar) imag(const Scalar& x)
1151 {
1152  return EIGEN_MATHFUNC_IMPL(imag, Scalar)::run(x);
1153 }
1154 
1155 template<typename Scalar>
1157 inline EIGEN_MATHFUNC_RETVAL(arg, Scalar) arg(const Scalar& x)
1158 {
1159  return EIGEN_MATHFUNC_IMPL(arg, Scalar)::run(x);
1160 }
1161 
1162 template<typename Scalar>
1165 {
1166  return internal::imag_ref_impl<Scalar>::run(x);
1167 }
1168 
1169 template<typename Scalar>
1171 inline EIGEN_MATHFUNC_RETVAL(imag_ref, Scalar) imag_ref(Scalar& x)
1172 {
1173  return EIGEN_MATHFUNC_IMPL(imag_ref, Scalar)::run(x);
1174 }
1175 
1176 template<typename Scalar>
1178 inline EIGEN_MATHFUNC_RETVAL(conj, Scalar) conj(const Scalar& x)
1179 {
1180  return EIGEN_MATHFUNC_IMPL(conj, Scalar)::run(x);
1181 }
1182 
1183 template<typename Scalar>
1185 inline EIGEN_MATHFUNC_RETVAL(sign, Scalar) sign(const Scalar& x)
1186 {
1187  return EIGEN_MATHFUNC_IMPL(sign, Scalar)::run(x);
1188 }
1189 
1190 template<typename Scalar>
1192 inline EIGEN_MATHFUNC_RETVAL(abs2, Scalar) abs2(const Scalar& x)
1193 {
1194  return EIGEN_MATHFUNC_IMPL(abs2, Scalar)::run(x);
1195 }
1196 
1198 inline bool abs2(bool x) { return x; }
1199 
1200 template<typename T>
1202 EIGEN_ALWAYS_INLINE T absdiff(const T& x, const T& y)
1203 {
1204  return x > y ? x - y : y - x;
1205 }
1206 template<>
1208 EIGEN_ALWAYS_INLINE float absdiff(const float& x, const float& y)
1209 {
1210  return fabsf(x - y);
1211 }
1212 template<>
1214 EIGEN_ALWAYS_INLINE double absdiff(const double& x, const double& y)
1215 {
1216  return fabs(x - y);
1217 }
1218 
1219 // HIP and CUDA do not support long double.
1220 #ifndef EIGEN_GPU_COMPILE_PHASE
1221 template<>
1223 EIGEN_ALWAYS_INLINE long double absdiff(const long double& x, const long double& y) {
1224  return fabsl(x - y);
1225 }
1226 #endif
1227 
1228 template<typename Scalar>
1230 inline EIGEN_MATHFUNC_RETVAL(norm1, Scalar) norm1(const Scalar& x)
1231 {
1232  return EIGEN_MATHFUNC_IMPL(norm1, Scalar)::run(x);
1233 }
1234 
1235 template<typename Scalar>
1237 inline EIGEN_MATHFUNC_RETVAL(hypot, Scalar) hypot(const Scalar& x, const Scalar& y)
1238 {
1239  return EIGEN_MATHFUNC_IMPL(hypot, Scalar)::run(x, y);
1240 }
1241 
1242 #if defined(SYCL_DEVICE_ONLY)
1243  SYCL_SPECIALIZE_FLOATING_TYPES_BINARY(hypot, hypot)
1244 #endif
1245 
1246 template<typename Scalar>
1248 inline EIGEN_MATHFUNC_RETVAL(log1p, Scalar) log1p(const Scalar& x)
1249 {
1250  return EIGEN_MATHFUNC_IMPL(log1p, Scalar)::run(x);
1251 }
1252 
1253 #if defined(SYCL_DEVICE_ONLY)
1254 SYCL_SPECIALIZE_FLOATING_TYPES_UNARY(log1p, log1p)
1255 #endif
1256 
1257 #if defined(EIGEN_GPUCC)
1259 float log1p(const float &x) { return ::log1pf(x); }
1260 
1262 double log1p(const double &x) { return ::log1p(x); }
1263 #endif
1264 
1265 template<typename ScalarX,typename ScalarY>
1267 inline typename internal::pow_impl<ScalarX,ScalarY>::result_type pow(const ScalarX& x, const ScalarY& y)
1268 {
1269  return internal::pow_impl<ScalarX,ScalarY>::run(x, y);
1270 }
1271 
1272 #if defined(SYCL_DEVICE_ONLY)
1273 SYCL_SPECIALIZE_FLOATING_TYPES_BINARY(pow, pow)
1274 #endif
1275 
1276 template<typename T> EIGEN_DEVICE_FUNC bool (isnan) (const T &x) { return internal::isnan_impl(x); }
1277 template<typename T> EIGEN_DEVICE_FUNC bool (isinf) (const T &x) { return internal::isinf_impl(x); }
1278 template<typename T> EIGEN_DEVICE_FUNC bool (isfinite)(const T &x) { return internal::isfinite_impl(x); }
1279 
1280 #if defined(SYCL_DEVICE_ONLY)
1281 SYCL_SPECIALIZE_FLOATING_TYPES_UNARY_FUNC_RET_TYPE(isnan, isnan, bool)
1282 SYCL_SPECIALIZE_FLOATING_TYPES_UNARY_FUNC_RET_TYPE(isinf, isinf, bool)
1283 SYCL_SPECIALIZE_FLOATING_TYPES_UNARY_FUNC_RET_TYPE(isfinite, isfinite, bool)
1284 #endif
1285 
1286 template<typename Scalar>
1287 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
1288 Scalar rint(const Scalar& x)
1289 {
1290  return internal::nearest_integer_impl<Scalar>::run_rint(x);
1291 }
1292 
1293 template<typename Scalar>
1294 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
1295 Scalar round(const Scalar& x)
1296 {
1297  return internal::nearest_integer_impl<Scalar>::run_round(x);
1298 }
1299 
1300 #if defined(SYCL_DEVICE_ONLY)
1301 SYCL_SPECIALIZE_FLOATING_TYPES_UNARY(round, round)
1302 #endif
1303 
1304 template<typename Scalar>
1305 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
1306 Scalar (floor)(const Scalar& x)
1307 {
1308  return internal::nearest_integer_impl<Scalar>::run_floor(x);
1309 }
1310 
1311 #if defined(SYCL_DEVICE_ONLY)
1312 SYCL_SPECIALIZE_FLOATING_TYPES_UNARY(floor, floor)
1313 #endif
1314 
1315 #if defined(EIGEN_GPUCC)
1317 float floor(const float &x) { return ::floorf(x); }
1318 
1320 double floor(const double &x) { return ::floor(x); }
1321 #endif
1322 
1323 template<typename Scalar>
1324 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
1325 Scalar (ceil)(const Scalar& x)
1326 {
1327  return internal::nearest_integer_impl<Scalar>::run_ceil(x);
1328 }
1329 
1330 #if defined(SYCL_DEVICE_ONLY)
1331 SYCL_SPECIALIZE_FLOATING_TYPES_UNARY(ceil, ceil)
1332 #endif
1333 
1334 #if defined(EIGEN_GPUCC)
1336 float ceil(const float &x) { return ::ceilf(x); }
1337 
1339 double ceil(const double &x) { return ::ceil(x); }
1340 #endif
1341 
1342 
1345 inline int log2(int x)
1346 {
1347  eigen_assert(x>=0);
1348  unsigned int v(x);
1349  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 };
1350  v |= v >> 1;
1351  v |= v >> 2;
1352  v |= v >> 4;
1353  v |= v >> 8;
1354  v |= v >> 16;
1355  return table[(v * 0x07C4ACDDU) >> 27];
1356 }
1357 
1367 template<typename Scalar>
1370 {
1371  return EIGEN_MATHFUNC_IMPL(sqrt, Scalar)::run(x);
1372 }
1373 
1374 // Boolean specialization, avoids implicit float to bool conversion (-Wimplicit-conversion-floating-point-to-bool).
1375 template<>
1377 bool sqrt<bool>(const bool &x) { return x; }
1378 
1379 #if defined(SYCL_DEVICE_ONLY)
1380 SYCL_SPECIALIZE_FLOATING_TYPES_UNARY(sqrt, sqrt)
1381 #endif
1382 
1384 template<typename T>
1386 T rsqrt(const T& x)
1387 {
1388  return internal::rsqrt_impl<T>::run(x);
1389 }
1390 
1391 template<typename T>
1393 T log(const T &x) {
1394  return internal::log_impl<T>::run(x);
1395 }
1396 
1397 #if defined(SYCL_DEVICE_ONLY)
1398 SYCL_SPECIALIZE_FLOATING_TYPES_UNARY(log, log)
1399 #endif
1400 
1401 
1402 #if defined(EIGEN_GPUCC)
1404 float log(const float &x) { return ::logf(x); }
1405 
1407 double log(const double &x) { return ::log(x); }
1408 #endif
1409 
1410 template<typename T>
1412 std::enable_if_t<NumTraits<T>::IsSigned || NumTraits<T>::IsComplex,typename NumTraits<T>::Real>
1413 abs(const T &x) {
1415  return abs(x);
1416 }
1417 
1418 template<typename T>
1420 std::enable_if_t<!(NumTraits<T>::IsSigned || NumTraits<T>::IsComplex),typename NumTraits<T>::Real>
1421 abs(const T &x) {
1422  return x;
1423 }
1424 
1425 #if defined(SYCL_DEVICE_ONLY)
1426 SYCL_SPECIALIZE_INTEGER_TYPES_UNARY(abs, abs)
1427 SYCL_SPECIALIZE_FLOATING_TYPES_UNARY(abs, fabs)
1428 #endif
1429 
1430 #if defined(EIGEN_GPUCC)
1432 float abs(const float &x) { return ::fabsf(x); }
1433 
1435 double abs(const double &x) { return ::fabs(x); }
1436 
1438 float abs(const std::complex<float>& x) {
1439  return ::hypotf(x.real(), x.imag());
1440 }
1441 
1443 double abs(const std::complex<double>& x) {
1444  return ::hypot(x.real(), x.imag());
1445 }
1446 #endif
1447 
1448 template <typename Scalar, bool IsInteger = NumTraits<Scalar>::IsInteger, bool IsSigned = NumTraits<Scalar>::IsSigned>
1450 template <typename Scalar>
1451 struct signbit_impl<Scalar, false, true> {
1452  static constexpr size_t Size = sizeof(Scalar);
1453  static constexpr size_t Shift = (CHAR_BIT * Size) - 1;
1455  EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE static Scalar run(const Scalar& x) {
1456  intSize_t a = bit_cast<intSize_t, Scalar>(x);
1457  a = a >> Shift;
1458  Scalar result = bit_cast<Scalar, intSize_t>(a);
1459  return result;
1460  }
1461 };
1462 template <typename Scalar>
1463 struct signbit_impl<Scalar, true, true> {
1464  static constexpr size_t Size = sizeof(Scalar);
1465  static constexpr size_t Shift = (CHAR_BIT * Size) - 1;
1466  EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE static constexpr Scalar run(const Scalar& x) { return x >> Shift; }
1467 };
1468 template <typename Scalar>
1469 struct signbit_impl<Scalar, true, false> {
1470  EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE static constexpr Scalar run(const Scalar& ) {
1471  return Scalar(0);
1472  }
1473 };
1474 template <typename Scalar>
1475 EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE static constexpr Scalar signbit(const Scalar& x) {
1476  return signbit_impl<Scalar>::run(x);
1477 }
1478 
1479 template<typename T>
1481 T exp(const T &x) {
1483  return exp(x);
1484 }
1485 
1486 #if defined(SYCL_DEVICE_ONLY)
1487 SYCL_SPECIALIZE_FLOATING_TYPES_UNARY(exp, exp)
1488 #endif
1489 
1490 #if defined(EIGEN_GPUCC)
1492 float exp(const float &x) { return ::expf(x); }
1493 
1495 double exp(const double &x) { return ::exp(x); }
1496 
1498 std::complex<float> exp(const std::complex<float>& x) {
1499  float com = ::expf(x.real());
1500  float res_real = com * ::cosf(x.imag());
1501  float res_imag = com * ::sinf(x.imag());
1502  return std::complex<float>(res_real, res_imag);
1503 }
1504 
1506 std::complex<double> exp(const std::complex<double>& x) {
1507  double com = ::exp(x.real());
1508  double res_real = com * ::cos(x.imag());
1509  double res_imag = com * ::sin(x.imag());
1510  return std::complex<double>(res_real, res_imag);
1511 }
1512 #endif
1513 
1514 template<typename Scalar>
1516 inline EIGEN_MATHFUNC_RETVAL(expm1, Scalar) expm1(const Scalar& x)
1517 {
1518  return EIGEN_MATHFUNC_IMPL(expm1, Scalar)::run(x);
1519 }
1520 
1521 #if defined(SYCL_DEVICE_ONLY)
1522 SYCL_SPECIALIZE_FLOATING_TYPES_UNARY(expm1, expm1)
1523 #endif
1524 
1525 #if defined(EIGEN_GPUCC)
1527 float expm1(const float &x) { return ::expm1f(x); }
1528 
1530 double expm1(const double &x) { return ::expm1(x); }
1531 #endif
1532 
1533 template<typename T>
1535 T cos(const T &x) {
1537  return cos(x);
1538 }
1539 
1540 #if defined(SYCL_DEVICE_ONLY)
1541 SYCL_SPECIALIZE_FLOATING_TYPES_UNARY(cos,cos)
1542 #endif
1543 
1544 #if defined(EIGEN_GPUCC)
1546 float cos(const float &x) { return ::cosf(x); }
1547 
1549 double cos(const double &x) { return ::cos(x); }
1550 #endif
1551 
1552 template<typename T>
1554 T sin(const T &x) {
1556  return sin(x);
1557 }
1558 
1559 #if defined(SYCL_DEVICE_ONLY)
1560 SYCL_SPECIALIZE_FLOATING_TYPES_UNARY(sin, sin)
1561 #endif
1562 
1563 #if defined(EIGEN_GPUCC)
1565 float sin(const float &x) { return ::sinf(x); }
1566 
1568 double sin(const double &x) { return ::sin(x); }
1569 #endif
1570 
1571 template<typename T>
1573 T tan(const T &x) {
1575  return tan(x);
1576 }
1577 
1578 #if defined(SYCL_DEVICE_ONLY)
1579 SYCL_SPECIALIZE_FLOATING_TYPES_UNARY(tan, tan)
1580 #endif
1581 
1582 #if defined(EIGEN_GPUCC)
1584 float tan(const float &x) { return ::tanf(x); }
1585 
1587 double tan(const double &x) { return ::tan(x); }
1588 #endif
1589 
1590 template<typename T>
1592 T acos(const T &x) {
1594  return acos(x);
1595 }
1596 
1597 template<typename T>
1599 T acosh(const T &x) {
1601  return static_cast<T>(acosh(x));
1602 }
1603 
1604 #if defined(SYCL_DEVICE_ONLY)
1605 SYCL_SPECIALIZE_FLOATING_TYPES_UNARY(acos, acos)
1606 SYCL_SPECIALIZE_FLOATING_TYPES_UNARY(acosh, acosh)
1607 #endif
1608 
1609 #if defined(EIGEN_GPUCC)
1611 float acos(const float &x) { return ::acosf(x); }
1612 
1614 double acos(const double &x) { return ::acos(x); }
1615 #endif
1616 
1617 template<typename T>
1619 T asin(const T &x) {
1621  return asin(x);
1622 }
1623 
1624 template<typename T>
1626 T asinh(const T &x) {
1628  return static_cast<T>(asinh(x));
1629 }
1630 
1631 #if defined(SYCL_DEVICE_ONLY)
1632 SYCL_SPECIALIZE_FLOATING_TYPES_UNARY(asin, asin)
1633 SYCL_SPECIALIZE_FLOATING_TYPES_UNARY(asinh, asinh)
1634 #endif
1635 
1636 #if defined(EIGEN_GPUCC)
1638 float asin(const float &x) { return ::asinf(x); }
1639 
1641 double asin(const double &x) { return ::asin(x); }
1642 #endif
1643 
1644 template<typename T>
1646 T atan(const T &x) {
1648  return static_cast<T>(atan(x));
1649 }
1650 
1651 template <typename T, std::enable_if_t<!NumTraits<T>::IsComplex, int> = 0>
1654  return static_cast<T>(atan2(y, x));
1655 }
1656 
1657 template<typename T>
1659 T atanh(const T &x) {
1661  return static_cast<T>(atanh(x));
1662 }
1663 
1664 #if defined(SYCL_DEVICE_ONLY)
1665 SYCL_SPECIALIZE_FLOATING_TYPES_UNARY(atan, atan)
1666 SYCL_SPECIALIZE_FLOATING_TYPES_UNARY(atanh, atanh)
1667 #endif
1668 
1669 #if defined(EIGEN_GPUCC)
1671 float atan(const float &x) { return ::atanf(x); }
1672 
1674 double atan(const double &x) { return ::atan(x); }
1675 #endif
1676 
1677 
1678 template<typename T>
1680 T cosh(const T &x) {
1682  return static_cast<T>(cosh(x));
1683 }
1684 
1685 #if defined(SYCL_DEVICE_ONLY)
1686 SYCL_SPECIALIZE_FLOATING_TYPES_UNARY(cosh, cosh)
1687 #endif
1688 
1689 #if defined(EIGEN_GPUCC)
1691 float cosh(const float &x) { return ::coshf(x); }
1692 
1694 double cosh(const double &x) { return ::cosh(x); }
1695 #endif
1696 
1697 template<typename T>
1699 T sinh(const T &x) {
1701  return static_cast<T>(sinh(x));
1702 }
1703 
1704 #if defined(SYCL_DEVICE_ONLY)
1705 SYCL_SPECIALIZE_FLOATING_TYPES_UNARY(sinh, sinh)
1706 #endif
1707 
1708 #if defined(EIGEN_GPUCC)
1710 float sinh(const float &x) { return ::sinhf(x); }
1711 
1713 double sinh(const double &x) { return ::sinh(x); }
1714 #endif
1715 
1716 template<typename T>
1718 T tanh(const T &x) {
1720  return tanh(x);
1721 }
1722 
1723 #if (!defined(EIGEN_GPUCC)) && EIGEN_FAST_MATH && !defined(SYCL_DEVICE_ONLY)
1725 float tanh(float x) { return internal::generic_fast_tanh_float(x); }
1726 #endif
1727 
1728 #if defined(SYCL_DEVICE_ONLY)
1729 SYCL_SPECIALIZE_FLOATING_TYPES_UNARY(tanh, tanh)
1730 #endif
1731 
1732 #if defined(EIGEN_GPUCC)
1734 float tanh(const float &x) { return ::tanhf(x); }
1735 
1737 double tanh(const double &x) { return ::tanh(x); }
1738 #endif
1739 
1740 template <typename T>
1742 T fmod(const T& a, const T& b) {
1744  return fmod(a, b);
1745 }
1746 
1747 #if defined(SYCL_DEVICE_ONLY)
1748 SYCL_SPECIALIZE_FLOATING_TYPES_BINARY(fmod, fmod)
1749 #endif
1750 
1751 #if defined(EIGEN_GPUCC)
1752 template <>
1754 float fmod(const float& a, const float& b) {
1755  return ::fmodf(a, b);
1756 }
1757 
1758 template <>
1760 double fmod(const double& a, const double& b) {
1761  return ::fmod(a, b);
1762 }
1763 #endif
1764 
1765 #if defined(SYCL_DEVICE_ONLY)
1766 #undef SYCL_SPECIALIZE_SIGNED_INTEGER_TYPES_BINARY
1767 #undef SYCL_SPECIALIZE_SIGNED_INTEGER_TYPES_UNARY
1768 #undef SYCL_SPECIALIZE_UNSIGNED_INTEGER_TYPES_BINARY
1769 #undef SYCL_SPECIALIZE_UNSIGNED_INTEGER_TYPES_UNARY
1770 #undef SYCL_SPECIALIZE_INTEGER_TYPES_BINARY
1771 #undef SYCL_SPECIALIZE_UNSIGNED_INTEGER_TYPES_UNARY
1772 #undef SYCL_SPECIALIZE_FLOATING_TYPES_BINARY
1773 #undef SYCL_SPECIALIZE_FLOATING_TYPES_UNARY
1774 #undef SYCL_SPECIALIZE_FLOATING_TYPES_UNARY_FUNC_RET_TYPE
1775 #undef SYCL_SPECIALIZE_GEN_UNARY_FUNC
1776 #undef SYCL_SPECIALIZE_UNARY_FUNC
1777 #undef SYCL_SPECIALIZE_GEN1_BINARY_FUNC
1778 #undef SYCL_SPECIALIZE_GEN2_BINARY_FUNC
1779 #undef SYCL_SPECIALIZE_BINARY_FUNC
1780 #endif
1781 
1782 } // end namespace numext
1783 
1784 namespace internal {
1785 
1786 template<typename T>
1787 EIGEN_DEVICE_FUNC bool isfinite_impl(const std::complex<T>& x)
1788 {
1790 }
1791 
1792 template<typename T>
1793 EIGEN_DEVICE_FUNC bool isnan_impl(const std::complex<T>& x)
1794 {
1796 }
1797 
1798 template<typename T>
1799 EIGEN_DEVICE_FUNC bool isinf_impl(const std::complex<T>& x)
1800 {
1801  return ((numext::isinf)(numext::real(x)) || (numext::isinf)(numext::imag(x))) && (!(numext::isnan)(x));
1802 }
1803 
1804 
1808 template<typename Scalar,
1809  bool IsComplex,
1810  bool IsInteger>
1811 struct scalar_fuzzy_default_impl {};
1812 
1813 template<typename Scalar>
1814 struct scalar_fuzzy_default_impl<Scalar, false, false>
1815 {
1816  typedef typename NumTraits<Scalar>::Real RealScalar;
1817  template<typename OtherScalar> EIGEN_DEVICE_FUNC
1818  static inline bool isMuchSmallerThan(const Scalar& x, const OtherScalar& y, const RealScalar& prec)
1819  {
1820  return numext::abs(x) <= numext::abs(y) * prec;
1821  }
1823  static inline bool isApprox(const Scalar& x, const Scalar& y, const RealScalar& prec)
1824  {
1825  return numext::abs(x - y) <= numext::mini(numext::abs(x), numext::abs(y)) * prec;
1826  }
1828  static inline bool isApproxOrLessThan(const Scalar& x, const Scalar& y, const RealScalar& prec)
1829  {
1830  return x <= y || isApprox(x, y, prec);
1831  }
1832 };
1833 
1834 template<typename Scalar>
1835 struct scalar_fuzzy_default_impl<Scalar, false, true>
1836 {
1837  typedef typename NumTraits<Scalar>::Real RealScalar;
1838  template<typename OtherScalar> EIGEN_DEVICE_FUNC
1839  static inline bool isMuchSmallerThan(const Scalar& x, const Scalar&, const RealScalar&)
1840  {
1841  return x == Scalar(0);
1842  }
1844  static inline bool isApprox(const Scalar& x, const Scalar& y, const RealScalar&)
1845  {
1846  return x == y;
1847  }
1849  static inline bool isApproxOrLessThan(const Scalar& x, const Scalar& y, const RealScalar&)
1850  {
1851  return x <= y;
1852  }
1853 };
1854 
1855 template<typename Scalar>
1856 struct scalar_fuzzy_default_impl<Scalar, true, false>
1857 {
1858  typedef typename NumTraits<Scalar>::Real RealScalar;
1859  template<typename OtherScalar> EIGEN_DEVICE_FUNC
1860  static inline bool isMuchSmallerThan(const Scalar& x, const OtherScalar& y, const RealScalar& prec)
1861  {
1862  return numext::abs2(x) <= numext::abs2(y) * prec * prec;
1863  }
1865  static inline bool isApprox(const Scalar& x, const Scalar& y, const RealScalar& prec)
1866  {
1867  return numext::abs2(x - y) <= numext::mini(numext::abs2(x), numext::abs2(y)) * prec * prec;
1868  }
1869 };
1870 
1871 template<typename Scalar>
1872 struct scalar_fuzzy_impl : scalar_fuzzy_default_impl<Scalar, NumTraits<Scalar>::IsComplex, NumTraits<Scalar>::IsInteger> {};
1873 
1874 template<typename Scalar, typename OtherScalar> EIGEN_DEVICE_FUNC
1875 inline bool isMuchSmallerThan(const Scalar& x, const OtherScalar& y,
1876  const typename NumTraits<Scalar>::Real &precision = NumTraits<Scalar>::dummy_precision())
1877 {
1878  return scalar_fuzzy_impl<Scalar>::template isMuchSmallerThan<OtherScalar>(x, y, precision);
1879 }
1880 
1881 template<typename Scalar> EIGEN_DEVICE_FUNC
1882 inline bool isApprox(const Scalar& x, const Scalar& y,
1883  const typename NumTraits<Scalar>::Real &precision = NumTraits<Scalar>::dummy_precision())
1884 {
1885  return scalar_fuzzy_impl<Scalar>::isApprox(x, y, precision);
1886 }
1887 
1888 template<typename Scalar> EIGEN_DEVICE_FUNC
1889 inline bool isApproxOrLessThan(const Scalar& x, const Scalar& y,
1890  const typename NumTraits<Scalar>::Real &precision = NumTraits<Scalar>::dummy_precision())
1891 {
1893 }
1894 
1895 
1899 template<> struct random_impl<bool>
1900 {
1901  static inline bool run()
1902  {
1903  return random<int>(0,1)==0 ? false : true;
1904  }
1905 
1906  static inline bool run(const bool& a, const bool& b)
1907  {
1908  return random<int>(a, b)==0 ? false : true;
1909  }
1910 };
1911 
1912 template<> struct scalar_fuzzy_impl<bool>
1913 {
1914  typedef bool RealScalar;
1915 
1916  template<typename OtherScalar> EIGEN_DEVICE_FUNC
1917  static inline bool isMuchSmallerThan(const bool& x, const bool&, const bool&)
1918  {
1919  return !x;
1920  }
1921 
1923  static inline bool isApprox(bool x, bool y, bool)
1924  {
1925  return x == y;
1926  }
1927 
1929  static inline bool isApproxOrLessThan(const bool& x, const bool& y, const bool&)
1930  {
1931  return (!x) || y;
1932  }
1933 
1934 };
1935 
1936 } // end namespace internal
1937 
1938 // Default implementations that rely on other numext implementations
1939 namespace internal {
1940 
1941 // Specialization for complex types that are not supported by std::expm1.
1942 template <typename RealScalar>
1943 struct expm1_impl<std::complex<RealScalar> > {
1945 
1946  EIGEN_DEVICE_FUNC static inline std::complex<RealScalar> run(
1947  const std::complex<RealScalar>& x) {
1948  RealScalar xr = x.real();
1949  RealScalar xi = x.imag();
1950  // expm1(z) = exp(z) - 1
1951  // = exp(x + i * y) - 1
1952  // = exp(x) * (cos(y) + i * sin(y)) - 1
1953  // = exp(x) * cos(y) - 1 + i * exp(x) * sin(y)
1954  // Imag(expm1(z)) = exp(x) * sin(y)
1955  // Real(expm1(z)) = exp(x) * cos(y) - 1
1956  // = exp(x) * cos(y) - 1.
1957  // = expm1(x) + exp(x) * (cos(y) - 1)
1958  // = expm1(x) + exp(x) * (2 * sin(y / 2) ** 2)
1959  RealScalar erm1 = numext::expm1<RealScalar>(xr);
1960  RealScalar er = erm1 + RealScalar(1.);
1961  RealScalar sin2 = numext::sin(xi / RealScalar(2.));
1962  sin2 = sin2 * sin2;
1963  RealScalar s = numext::sin(xi);
1964  RealScalar real_part = erm1 - RealScalar(2.) * er * sin2;
1965  return std::complex<RealScalar>(real_part, er * s);
1966  }
1967 };
1968 
1969 template<typename T>
1970 struct rsqrt_impl {
1972  static EIGEN_ALWAYS_INLINE T run(const T& x) {
1973  return T(1)/numext::sqrt(x);
1974  }
1975 };
1976 
1977 #if defined(EIGEN_GPU_COMPILE_PHASE)
1978 template<typename T>
1979 struct conj_impl<std::complex<T>, true>
1980 {
1982  static inline std::complex<T> run(const std::complex<T>& x)
1983  {
1984  return std::complex<T>(numext::real(x), -numext::imag(x));
1985  }
1986 };
1987 #endif
1988 
1989 } // end namespace internal
1990 
1991 } // end namespace Eigen
1992 
1993 #endif // EIGEN_MATHFUNCTIONS_H
const AtanReturnType atan() const
const AcosReturnType acos() const
const AsinReturnType asin() const
const ExpReturnType exp() const
const ArgReturnType arg() const
const CeilReturnType ceil() const
const SinReturnType sin() const
const SinhReturnType sinh() const
const TanReturnType tan() const
const Log1pReturnType log1p() const
const Expm1ReturnType expm1() const
const FloorReturnType floor() const
const CoshReturnType cosh() const
const TanhReturnType tanh() const
const LogReturnType log() const
const CosReturnType cos() const
Array< int, Dynamic, 1 > v
Array< int, 3, 1 > b
int n
const ImagReturnType imag() const
RealReturnType real() const
#define EIGEN_ALWAYS_INLINE
Definition: Macros.h:836
#define EIGEN_USING_STD(FUNC)
Definition: Macros.h:1080
#define EIGEN_CONSTEXPR
Definition: Macros.h:747
#define EIGEN_DEVICE_FUNC
Definition: Macros.h:883
#define eigen_assert(x)
Definition: Macros.h:902
#define EIGEN_NOT_A_MACRO
Definition: Macros.h:804
#define EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
Definition: Macros.h:892
#define EIGEN_MATHFUNC_IMPL(func, scalar)
Definition: MathFunctions.h:63
#define EIGEN_PI
Definition: MathFunctions.h:16
cout<< "Here is the matrix m:"<< endl<< m<< endl;Matrix< ptrdiff_t, 3, 1 > res
#define EIGEN_STATIC_ASSERT_NON_INTEGER(TYPE)
Definition: StaticAssert.h:81
ArrayXXf table(10, 4)
Eigen::Triplet< double > T
bfloat16 fmax(const bfloat16 &a, const bfloat16 &b)
Definition: BFloat16.h:702
bfloat16() max(const bfloat16 &a, const bfloat16 &b)
Definition: BFloat16.h:690
bfloat16 fmin(const bfloat16 &a, const bfloat16 &b)
Definition: BFloat16.h:696
bfloat16() min(const bfloat16 &a, const bfloat16 &b)
Definition: BFloat16.h:684
constexpr int plain_enum_min(A a, B b)
Definition: Meta.h:516
std::enable_if_t<!(std::numeric_limits< T >::has_quiet_NaN||std::numeric_limits< T >::has_signaling_NaN), bool > isnan_impl(const T &)
constexpr int plain_enum_max(A a, B b)
Definition: Meta.h:524
const Scalar & y
bool isApproxOrLessThan(const Scalar &x, const Scalar &y, const typename NumTraits< Scalar >::Real &precision=NumTraits< Scalar >::dummy_precision())
std::enable_if_t<!(std::numeric_limits< T >::has_infinity||std::numeric_limits< T >::has_quiet_NaN||std::numeric_limits< T >::has_signaling_NaN), bool > isfinite_impl(const T &)
std::enable_if_t<!std::numeric_limits< T >::has_infinity, bool > isinf_impl(const T &)
std::complex< T > complex_log(const std::complex< T > &z)
std::complex< T > complex_rsqrt(const std::complex< T > &a_x)
NewType cast(const OldType &x)
std::complex< T > complex_sqrt(const std::complex< T > &a_x)
bool isApprox(const Scalar &x, const Scalar &y, const typename NumTraits< Scalar >::Real &precision=NumTraits< Scalar >::dummy_precision())
T generic_fast_tanh_float(const T &a_x)
bool isMuchSmallerThan(const Scalar &x, const OtherScalar &y, const typename NumTraits< Scalar >::Real &precision=NumTraits< Scalar >::dummy_precision())
typename add_const_on_value_type< T >::type add_const_on_value_type_t
Definition: Meta.h:176
EIGEN_MATHFUNC_RETVAL(random, Scalar) random(const Scalar &x
Scalar round(const Scalar &x)
const Scalar & y
bool equal_strict(const X &x, const Y &y)
Definition: Meta.h:460
EIGEN_ALWAYS_INLINE T cosh(const T &x)
EIGEN_ALWAYS_INLINE T tan(const T &x)
int log2(int x)
EIGEN_MATHFUNC_RETVAL(real, Scalar) real(const Scalar &x)
EIGEN_ALWAYS_INLINE T absdiff(const T &x, const T &y)
EIGEN_ALWAYS_INLINE bool() isinf(const Eigen::bfloat16 &h)
Definition: BFloat16.h:784
EIGEN_ALWAYS_INLINE T acosh(const T &x)
internal::add_const_on_value_type_t< EIGEN_MATHFUNC_RETVAL(imag_ref, Scalar) > imag_ref(const Scalar &x)
EIGEN_ALWAYS_INLINE T atan(const T &x)
EIGEN_ALWAYS_INLINE T atanh(const T &x)
bool abs2(bool x)
internal::add_const_on_value_type_t< EIGEN_MATHFUNC_RETVAL(real_ref, Scalar) > real_ref(const Scalar &x)
EIGEN_ALWAYS_INLINE T sin(const T &x)
internal::pow_impl< ScalarX, ScalarY >::result_type pow(const ScalarX &x, const ScalarY &y)
Scalar rint(const Scalar &x)
EIGEN_ALWAYS_INLINE T tanh(const T &x)
EIGEN_ALWAYS_INLINE T maxi(const T &x, const T &y)
EIGEN_ALWAYS_INLINE T acos(const T &x)
EIGEN_ALWAYS_INLINE float sqrt(const float &x)
EIGEN_ALWAYS_INLINE T exp(const T &x)
EIGEN_ALWAYS_INLINE T sinh(const T &x)
Scalar() floor(const Scalar &x)
EIGEN_ALWAYS_INLINE T atan2(const T &y, const T &x)
Scalar() ceil(const Scalar &x)
EIGEN_ALWAYS_INLINE T fmod(const T &a, const T &b)
EIGEN_ALWAYS_INLINE T asinh(const T &x)
static constexpr EIGEN_ALWAYS_INLINE Scalar signbit(const Scalar &x)
EIGEN_ALWAYS_INLINE bool() isnan(const Eigen::bfloat16 &h)
Definition: BFloat16.h:778
EIGEN_ALWAYS_INLINE bool() isfinite(const Eigen::bfloat16 &h)
Definition: BFloat16.h:790
EIGEN_ALWAYS_INLINE T asin(const T &x)
EIGEN_ALWAYS_INLINE T mini(const T &x, const T &y)
EIGEN_ALWAYS_INLINE T cos(const T &x)
EIGEN_ALWAYS_INLINE std::enable_if_t< NumTraits< T >::IsSigned||NumTraits< T >::IsComplex, typename NumTraits< T >::Real > abs(const T &x)
EIGEN_ALWAYS_INLINE T rsqrt(const T &x)
EIGEN_ALWAYS_INLINE T log(const T &x)
EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS bool sqrt< bool >(const bool &x)
: InteropHeaders
Definition: Core:139
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_rint_op< typename Derived::Scalar >, const Derived > rint(const Eigen::ArrayBase< Derived > &x)
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_imag_op< typename Derived::Scalar >, const Derived > imag(const Eigen::ArrayBase< Derived > &x)
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_isinf_op< typename Derived::Scalar >, const Derived > isinf(const Eigen::ArrayBase< Derived > &x)
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_sign_op< typename Derived::Scalar >, const Derived > sign(const Eigen::ArrayBase< Derived > &x)
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_isnan_op< typename Derived::Scalar >, const Derived > isnan(const Eigen::ArrayBase< Derived > &x)
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_arg_op< typename Derived::Scalar >, const Derived > arg(const Eigen::ArrayBase< Derived > &x)
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_ceil_op< typename Derived::Scalar >, const Derived > ceil(const Eigen::ArrayBase< Derived > &x)
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_conjugate_op< typename Derived::Scalar >, const Derived > conj(const Eigen::ArrayBase< Derived > &x)
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_isfinite_op< typename Derived::Scalar >, const Derived > isfinite(const Eigen::ArrayBase< Derived > &x)
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_floor_op< typename Derived::Scalar >, const Derived > floor(const Eigen::ArrayBase< Derived > &x)
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_log1p_op< typename Derived::Scalar >, const Derived > log1p(const Eigen::ArrayBase< Derived > &x)
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_real_op< typename Derived::Scalar >, const Derived > real(const Eigen::ArrayBase< Derived > &x)
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_round_op< typename Derived::Scalar >, const Derived > round(const Eigen::ArrayBase< Derived > &x)
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_abs_op< typename Derived::Scalar >, const Derived > abs(const Eigen::ArrayBase< Derived > &x)
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_exp_op< typename Derived::Scalar >, const Derived > exp(const Eigen::ArrayBase< Derived > &x)
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_expm1_op< typename Derived::Scalar >, const Derived > expm1(const Eigen::ArrayBase< Derived > &x)
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_log_op< typename Derived::Scalar >, const Derived > log(const Eigen::ArrayBase< Derived > &x)
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_sqrt_op< typename Derived::Scalar >, const Derived > sqrt(const Eigen::ArrayBase< Derived > &x)
Definition: BFloat16.h:222
Holds information about the various numeric (i.e. scalar) types allowed by Eigen.
Definition: NumTraits.h:231
static EIGEN_ALWAYS_INLINE Scalar run(const Scalar &x)
typename get_integer_by_size< Size >::signed_type intSize_t
static constexpr EIGEN_ALWAYS_INLINE Scalar run(const Scalar &)
static constexpr EIGEN_ALWAYS_INLINE Scalar run(const Scalar &x)