Viskores  1.0
Math.h
Go to the documentation of this file.
1 //============================================================================
2 // The contents of this file are covered by the Viskores license. See
3 // LICENSE.txt for details.
4 //
5 // By contributing to this file, all contributors agree to the Developer
6 // Certificate of Origin Version 1.1 (DCO 1.1) as stated in DCO.txt.
7 //============================================================================
8 
9 //============================================================================
10 // Copyright (c) Kitware, Inc.
11 // All rights reserved.
12 // See LICENSE.txt for details.
13 //
14 // This software is distributed WITHOUT ANY WARRANTY; without even
15 // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
16 // PURPOSE. See the above copyright notice for more information.
17 //============================================================================
18 // **** DO NOT EDIT THIS FILE!!! ****
19 // This file is automatically generated by Math.h.in
20 
21 #ifndef viskores_Math_h
22 #define viskores_Math_h
23 
24 #include <viskores/TypeTraits.h>
25 #include <viskores/Types.h>
26 #include <viskores/VecTraits.h>
27 
28 #include <limits> // must be found with or without CUDA.
29 #ifndef VISKORES_CUDA
30 #include <cmath>
31 #include <cstring>
32 #include <limits.h>
33 #include <math.h>
34 #include <stdlib.h>
35 #endif // !VISKORES_CUDA
36 
37 #if !defined(VISKORES_CUDA_DEVICE_PASS)
38 #define VISKORES_USE_STL
39 #include <algorithm>
40 #endif
41 
42 #ifdef VISKORES_MSVC
43 #include <intrin.h> // For bitwise intrinsics (__popcnt, etc)
44 #include <viskores/internal/Windows.h> // for types used by MSVC intrinsics.
45 #ifndef VISKORES_CUDA
46 #include <math.h>
47 #endif // VISKORES_CUDA
48 #endif // VISKORES_MSVC
49 
50 #define VISKORES_CUDA_MATH_FUNCTION_32(func) func##f
51 #define VISKORES_CUDA_MATH_FUNCTION_64(func) func
52 
53 namespace viskores
54 {
55 
56 //-----------------------------------------------------------------------------
57 namespace detail
58 {
59 template <typename T>
60 struct FloatingPointReturnType
61 {
62  using ctype = typename viskores::VecTraits<T>::ComponentType;
63  using representable_as_float_type =
64  std::integral_constant<bool,
65  ((sizeof(ctype) < sizeof(float)) ||
66  std::is_same<ctype, viskores::Float32>::value)>;
67  using Type = typename std::
68  conditional<representable_as_float_type::value, viskores::Float32, viskores::Float64>::type;
69 };
70 } // namespace detail
71 
74 template <typename T = viskores::Float64>
75 static constexpr inline VISKORES_EXEC_CONT typename detail::FloatingPointReturnType<T>::Type TwoPi()
76 {
77  using FT = typename detail::FloatingPointReturnType<T>::Type;
78  return static_cast<FT>(6.28318530717958647692528676655900576);
79 }
80 
83 template <typename T = viskores::Float64>
84 static constexpr inline VISKORES_EXEC_CONT typename detail::FloatingPointReturnType<T>::Type Pi()
85 {
86  using FT = typename detail::FloatingPointReturnType<T>::Type;
87  return static_cast<FT>(3.14159265358979323846264338327950288);
88 }
89 
92 template <typename T = viskores::Float64>
93 static constexpr inline VISKORES_EXEC_CONT typename detail::FloatingPointReturnType<T>::Type Pi_2()
94 {
95  using FT = typename detail::FloatingPointReturnType<T>::Type;
96  return static_cast<FT>(1.57079632679489661923132169163975144);
97 }
98 
101 template <typename T = viskores::Float64>
102 static constexpr inline VISKORES_EXEC_CONT typename detail::FloatingPointReturnType<T>::Type Pi_3()
103 {
104  using FT = typename detail::FloatingPointReturnType<T>::Type;
105  return static_cast<FT>(1.04719755119659774615421446109316762);
106 }
107 
110 template <typename T = viskores::Float64>
111 static constexpr inline VISKORES_EXEC_CONT typename detail::FloatingPointReturnType<T>::Type Pi_4()
112 {
113  using FT = typename detail::FloatingPointReturnType<T>::Type;
114  return static_cast<FT>(0.78539816339744830961566084581987572);
115 }
116 
119 template <typename T = viskores::Float64>
120 static constexpr inline VISKORES_EXEC_CONT typename detail::FloatingPointReturnType<T>::Type Pi_180()
121 {
122  using FT = typename detail::FloatingPointReturnType<T>::Type;
123  return static_cast<FT>(0.01745329251994329547437168059786927);
124 }
125 
128 static constexpr inline VISKORES_EXEC_CONT viskores::Float32 TwoPif()
129 {
130  return TwoPi<viskores::Float32>();
131 }
132 
135 static constexpr inline VISKORES_EXEC_CONT viskores::Float32 Pif()
136 {
137  return Pi<viskores::Float32>();
138 }
139 
142 static constexpr inline VISKORES_EXEC_CONT viskores::Float32 Pi_2f()
143 {
144  return Pi_2<viskores::Float32>();
145 }
146 
149 static constexpr inline VISKORES_EXEC_CONT viskores::Float32 Pi_3f()
150 {
151  return Pi_3<viskores::Float32>();
152 }
153 
156 static constexpr inline VISKORES_EXEC_CONT viskores::Float32 Pi_4f()
157 {
158  return Pi_4<viskores::Float32>();
159 }
160 
163 static constexpr inline VISKORES_EXEC_CONT viskores::Float32 Pi_180f()
164 {
165  return Pi_180<viskores::Float32>();
166 }
167 
168 // clang-format off
169 
173 
175 {
176 #ifdef VISKORES_CUDA
177  return VISKORES_CUDA_MATH_FUNCTION_32(sin)(x);
178 #else
179  return std::sin(x);
180 #endif
181 }
182 
184 {
185 #ifdef VISKORES_CUDA
186  return VISKORES_CUDA_MATH_FUNCTION_64(sin)(x);
187 #else
188  return std::sin(x);
189 #endif
190 }
191 template <typename T>
192 static inline VISKORES_EXEC_CONT typename detail::FloatingPointReturnType<T>::Type Sin(const T& x)
193 {
194  using RT = typename detail::FloatingPointReturnType<T>::Type;
195  return viskores::Sin(static_cast<RT>(x));
196 }
197 template <typename T, viskores::IdComponent N>
199  const viskores::Vec<T, N>& x)
200 {
202  for (viskores::IdComponent index = 0; index < N; index++)
203  {
204  result[index] = viskores::Sin(x[index]);
205  }
206  return result;
207 }
208 template <typename T>
210  const viskores::Vec<T, 4>& x)
211 {
213  viskores::Sin(x[0]), viskores::Sin(x[1]), viskores::Sin(x[2]), viskores::Sin(x[3]));
214 }
215 template <typename T>
217  const viskores::Vec<T, 3>& x)
218 {
220  viskores::Sin(x[0]), viskores::Sin(x[1]), viskores::Sin(x[2]));
221 }
222 template <typename T>
224  const viskores::Vec<T, 2>& x)
225 {
227  viskores::Sin(x[1]));
228 }
230 
234 
236 {
237 #ifdef VISKORES_CUDA
238  return VISKORES_CUDA_MATH_FUNCTION_32(cos)(x);
239 #else
240  return std::cos(x);
241 #endif
242 }
243 
245 {
246 #ifdef VISKORES_CUDA
247  return VISKORES_CUDA_MATH_FUNCTION_64(cos)(x);
248 #else
249  return std::cos(x);
250 #endif
251 }
252 template <typename T>
253 static inline VISKORES_EXEC_CONT typename detail::FloatingPointReturnType<T>::Type Cos(const T& x)
254 {
255  using RT = typename detail::FloatingPointReturnType<T>::Type;
256  return viskores::Cos(static_cast<RT>(x));
257 }
258 template <typename T, viskores::IdComponent N>
260  const viskores::Vec<T, N>& x)
261 {
263  for (viskores::IdComponent index = 0; index < N; index++)
264  {
265  result[index] = viskores::Cos(x[index]);
266  }
267  return result;
268 }
269 template <typename T>
271  const viskores::Vec<T, 4>& x)
272 {
274  viskores::Cos(x[0]), viskores::Cos(x[1]), viskores::Cos(x[2]), viskores::Cos(x[3]));
275 }
276 template <typename T>
278  const viskores::Vec<T, 3>& x)
279 {
281  viskores::Cos(x[0]), viskores::Cos(x[1]), viskores::Cos(x[2]));
282 }
283 template <typename T>
285  const viskores::Vec<T, 2>& x)
286 {
288  viskores::Cos(x[1]));
289 }
291 
295 
297 {
298 #ifdef VISKORES_CUDA
299  return VISKORES_CUDA_MATH_FUNCTION_32(tan)(x);
300 #else
301  return std::tan(x);
302 #endif
303 }
304 
306 {
307 #ifdef VISKORES_CUDA
308  return VISKORES_CUDA_MATH_FUNCTION_64(tan)(x);
309 #else
310  return std::tan(x);
311 #endif
312 }
313 template <typename T>
314 static inline VISKORES_EXEC_CONT typename detail::FloatingPointReturnType<T>::Type Tan(const T& x)
315 {
316  using RT = typename detail::FloatingPointReturnType<T>::Type;
317  return viskores::Tan(static_cast<RT>(x));
318 }
319 template <typename T, viskores::IdComponent N>
321  const viskores::Vec<T, N>& x)
322 {
324  for (viskores::IdComponent index = 0; index < N; index++)
325  {
326  result[index] = viskores::Tan(x[index]);
327  }
328  return result;
329 }
330 template <typename T>
332  const viskores::Vec<T, 4>& x)
333 {
335  viskores::Tan(x[0]), viskores::Tan(x[1]), viskores::Tan(x[2]), viskores::Tan(x[3]));
336 }
337 template <typename T>
339  const viskores::Vec<T, 3>& x)
340 {
342  viskores::Tan(x[0]), viskores::Tan(x[1]), viskores::Tan(x[2]));
343 }
344 template <typename T>
346  const viskores::Vec<T, 2>& x)
347 {
349  viskores::Tan(x[1]));
350 }
352 
356 
358 {
359 #ifdef VISKORES_CUDA
360  return VISKORES_CUDA_MATH_FUNCTION_32(asin)(x);
361 #else
362  return std::asin(x);
363 #endif
364 }
365 
367 {
368 #ifdef VISKORES_CUDA
369  return VISKORES_CUDA_MATH_FUNCTION_64(asin)(x);
370 #else
371  return std::asin(x);
372 #endif
373 }
374 template <typename T>
375 static inline VISKORES_EXEC_CONT typename detail::FloatingPointReturnType<T>::Type ASin(const T& x)
376 {
377  using RT = typename detail::FloatingPointReturnType<T>::Type;
378  return viskores::ASin(static_cast<RT>(x));
379 }
380 template <typename T, viskores::IdComponent N>
382  const viskores::Vec<T, N>& x)
383 {
385  for (viskores::IdComponent index = 0; index < N; index++)
386  {
387  result[index] = viskores::ASin(x[index]);
388  }
389  return result;
390 }
391 template <typename T>
393  const viskores::Vec<T, 4>& x)
394 {
396  viskores::ASin(x[0]), viskores::ASin(x[1]), viskores::ASin(x[2]), viskores::ASin(x[3]));
397 }
398 template <typename T>
400  const viskores::Vec<T, 3>& x)
401 {
403  viskores::ASin(x[0]), viskores::ASin(x[1]), viskores::ASin(x[2]));
404 }
405 template <typename T>
407  const viskores::Vec<T, 2>& x)
408 {
410  viskores::ASin(x[1]));
411 }
413 
417 
419 {
420 #ifdef VISKORES_CUDA
421  return VISKORES_CUDA_MATH_FUNCTION_32(acos)(x);
422 #else
423  return std::acos(x);
424 #endif
425 }
426 
428 {
429 #ifdef VISKORES_CUDA
430  return VISKORES_CUDA_MATH_FUNCTION_64(acos)(x);
431 #else
432  return std::acos(x);
433 #endif
434 }
435 template <typename T>
436 static inline VISKORES_EXEC_CONT typename detail::FloatingPointReturnType<T>::Type ACos(const T& x)
437 {
438  using RT = typename detail::FloatingPointReturnType<T>::Type;
439  return viskores::ACos(static_cast<RT>(x));
440 }
441 template <typename T, viskores::IdComponent N>
443  const viskores::Vec<T, N>& x)
444 {
446  for (viskores::IdComponent index = 0; index < N; index++)
447  {
448  result[index] = viskores::ACos(x[index]);
449  }
450  return result;
451 }
452 template <typename T>
454  const viskores::Vec<T, 4>& x)
455 {
457  viskores::ACos(x[0]), viskores::ACos(x[1]), viskores::ACos(x[2]), viskores::ACos(x[3]));
458 }
459 template <typename T>
461  const viskores::Vec<T, 3>& x)
462 {
464  viskores::ACos(x[0]), viskores::ACos(x[1]), viskores::ACos(x[2]));
465 }
466 template <typename T>
468  const viskores::Vec<T, 2>& x)
469 {
471  viskores::ACos(x[1]));
472 }
474 
478 
480 {
481 #ifdef VISKORES_CUDA
482  return VISKORES_CUDA_MATH_FUNCTION_32(atan)(x);
483 #else
484  return std::atan(x);
485 #endif
486 }
487 
489 {
490 #ifdef VISKORES_CUDA
491  return VISKORES_CUDA_MATH_FUNCTION_64(atan)(x);
492 #else
493  return std::atan(x);
494 #endif
495 }
496 template <typename T>
497 static inline VISKORES_EXEC_CONT typename detail::FloatingPointReturnType<T>::Type ATan(const T& x)
498 {
499  using RT = typename detail::FloatingPointReturnType<T>::Type;
500  return viskores::ATan(static_cast<RT>(x));
501 }
502 template <typename T, viskores::IdComponent N>
504  const viskores::Vec<T, N>& x)
505 {
507  for (viskores::IdComponent index = 0; index < N; index++)
508  {
509  result[index] = viskores::ATan(x[index]);
510  }
511  return result;
512 }
513 template <typename T>
515  const viskores::Vec<T, 4>& x)
516 {
518  viskores::ATan(x[0]), viskores::ATan(x[1]), viskores::ATan(x[2]), viskores::ATan(x[3]));
519 }
520 template <typename T>
522  const viskores::Vec<T, 3>& x)
523 {
525  viskores::ATan(x[0]), viskores::ATan(x[1]), viskores::ATan(x[2]));
526 }
527 template <typename T>
529  const viskores::Vec<T, 2>& x)
530 {
532  viskores::ATan(x[1]));
533 }
535 
541 {
542 #ifdef VISKORES_CUDA
543  return VISKORES_CUDA_MATH_FUNCTION_32(atan2)(x, y);
544 #else
545  return std::atan2(x, y);
546 #endif
547 }
549 {
550 #ifdef VISKORES_CUDA
551  return VISKORES_CUDA_MATH_FUNCTION_64(atan2)(x, y);
552 #else
553  return std::atan2(x, y);
554 #endif
555 }
557 
561 
563 {
564 #ifdef VISKORES_CUDA
565  return VISKORES_CUDA_MATH_FUNCTION_32(sinh)(x);
566 #else
567  return std::sinh(x);
568 #endif
569 }
570 
572 {
573 #ifdef VISKORES_CUDA
574  return VISKORES_CUDA_MATH_FUNCTION_64(sinh)(x);
575 #else
576  return std::sinh(x);
577 #endif
578 }
579 template <typename T>
580 static inline VISKORES_EXEC_CONT typename detail::FloatingPointReturnType<T>::Type SinH(const T& x)
581 {
582  using RT = typename detail::FloatingPointReturnType<T>::Type;
583  return viskores::SinH(static_cast<RT>(x));
584 }
585 template <typename T, viskores::IdComponent N>
587  const viskores::Vec<T, N>& x)
588 {
590  for (viskores::IdComponent index = 0; index < N; index++)
591  {
592  result[index] = viskores::SinH(x[index]);
593  }
594  return result;
595 }
596 template <typename T>
598  const viskores::Vec<T, 4>& x)
599 {
601  viskores::SinH(x[0]), viskores::SinH(x[1]), viskores::SinH(x[2]), viskores::SinH(x[3]));
602 }
603 template <typename T>
605  const viskores::Vec<T, 3>& x)
606 {
608  viskores::SinH(x[0]), viskores::SinH(x[1]), viskores::SinH(x[2]));
609 }
610 template <typename T>
612  const viskores::Vec<T, 2>& x)
613 {
615  viskores::SinH(x[1]));
616 }
618 
622 
624 {
625 #ifdef VISKORES_CUDA
626  return VISKORES_CUDA_MATH_FUNCTION_32(cosh)(x);
627 #else
628  return std::cosh(x);
629 #endif
630 }
631 
633 {
634 #ifdef VISKORES_CUDA
635  return VISKORES_CUDA_MATH_FUNCTION_64(cosh)(x);
636 #else
637  return std::cosh(x);
638 #endif
639 }
640 template <typename T>
641 static inline VISKORES_EXEC_CONT typename detail::FloatingPointReturnType<T>::Type CosH(const T& x)
642 {
643  using RT = typename detail::FloatingPointReturnType<T>::Type;
644  return viskores::CosH(static_cast<RT>(x));
645 }
646 template <typename T, viskores::IdComponent N>
648  const viskores::Vec<T, N>& x)
649 {
651  for (viskores::IdComponent index = 0; index < N; index++)
652  {
653  result[index] = viskores::CosH(x[index]);
654  }
655  return result;
656 }
657 template <typename T>
659  const viskores::Vec<T, 4>& x)
660 {
662  viskores::CosH(x[0]), viskores::CosH(x[1]), viskores::CosH(x[2]), viskores::CosH(x[3]));
663 }
664 template <typename T>
666  const viskores::Vec<T, 3>& x)
667 {
669  viskores::CosH(x[0]), viskores::CosH(x[1]), viskores::CosH(x[2]));
670 }
671 template <typename T>
673  const viskores::Vec<T, 2>& x)
674 {
676  viskores::CosH(x[1]));
677 }
679 
683 
685 {
686 #ifdef VISKORES_CUDA
687  return VISKORES_CUDA_MATH_FUNCTION_32(tanh)(x);
688 #else
689  return std::tanh(x);
690 #endif
691 }
692 
694 {
695 #ifdef VISKORES_CUDA
696  return VISKORES_CUDA_MATH_FUNCTION_64(tanh)(x);
697 #else
698  return std::tanh(x);
699 #endif
700 }
701 template <typename T>
702 static inline VISKORES_EXEC_CONT typename detail::FloatingPointReturnType<T>::Type TanH(const T& x)
703 {
704  using RT = typename detail::FloatingPointReturnType<T>::Type;
705  return viskores::TanH(static_cast<RT>(x));
706 }
707 template <typename T, viskores::IdComponent N>
709  const viskores::Vec<T, N>& x)
710 {
712  for (viskores::IdComponent index = 0; index < N; index++)
713  {
714  result[index] = viskores::TanH(x[index]);
715  }
716  return result;
717 }
718 template <typename T>
720  const viskores::Vec<T, 4>& x)
721 {
723  viskores::TanH(x[0]), viskores::TanH(x[1]), viskores::TanH(x[2]), viskores::TanH(x[3]));
724 }
725 template <typename T>
727  const viskores::Vec<T, 3>& x)
728 {
730  viskores::TanH(x[0]), viskores::TanH(x[1]), viskores::TanH(x[2]));
731 }
732 template <typename T>
734  const viskores::Vec<T, 2>& x)
735 {
737  viskores::TanH(x[1]));
738 }
740 
744 
746 {
747 #ifdef VISKORES_CUDA
748  return VISKORES_CUDA_MATH_FUNCTION_32(asinh)(x);
749 #else
750  return std::asinh(x);
751 #endif
752 }
753 
755 {
756 #ifdef VISKORES_CUDA
757  return VISKORES_CUDA_MATH_FUNCTION_64(asinh)(x);
758 #else
759  return std::asinh(x);
760 #endif
761 }
762 template <typename T>
763 static inline VISKORES_EXEC_CONT typename detail::FloatingPointReturnType<T>::Type ASinH(const T& x)
764 {
765  using RT = typename detail::FloatingPointReturnType<T>::Type;
766  return viskores::ASinH(static_cast<RT>(x));
767 }
768 template <typename T, viskores::IdComponent N>
770  const viskores::Vec<T, N>& x)
771 {
773  for (viskores::IdComponent index = 0; index < N; index++)
774  {
775  result[index] = viskores::ASinH(x[index]);
776  }
777  return result;
778 }
779 template <typename T>
781  const viskores::Vec<T, 4>& x)
782 {
785 }
786 template <typename T>
788  const viskores::Vec<T, 3>& x)
789 {
791  viskores::ASinH(x[0]), viskores::ASinH(x[1]), viskores::ASinH(x[2]));
792 }
793 template <typename T>
795  const viskores::Vec<T, 2>& x)
796 {
798  viskores::ASinH(x[1]));
799 }
801 
805 
807 {
808 #ifdef VISKORES_CUDA
809  return VISKORES_CUDA_MATH_FUNCTION_32(acosh)(x);
810 #else
811  return std::acosh(x);
812 #endif
813 }
814 
816 {
817 #ifdef VISKORES_CUDA
818  return VISKORES_CUDA_MATH_FUNCTION_64(acosh)(x);
819 #else
820  return std::acosh(x);
821 #endif
822 }
823 template <typename T>
824 static inline VISKORES_EXEC_CONT typename detail::FloatingPointReturnType<T>::Type ACosH(const T& x)
825 {
826  using RT = typename detail::FloatingPointReturnType<T>::Type;
827  return viskores::ACosH(static_cast<RT>(x));
828 }
829 template <typename T, viskores::IdComponent N>
831  const viskores::Vec<T, N>& x)
832 {
834  for (viskores::IdComponent index = 0; index < N; index++)
835  {
836  result[index] = viskores::ACosH(x[index]);
837  }
838  return result;
839 }
840 template <typename T>
842  const viskores::Vec<T, 4>& x)
843 {
846 }
847 template <typename T>
849  const viskores::Vec<T, 3>& x)
850 {
852  viskores::ACosH(x[0]), viskores::ACosH(x[1]), viskores::ACosH(x[2]));
853 }
854 template <typename T>
856  const viskores::Vec<T, 2>& x)
857 {
859  viskores::ACosH(x[1]));
860 }
862 
866 
868 {
869 #ifdef VISKORES_CUDA
870  return VISKORES_CUDA_MATH_FUNCTION_32(atanh)(x);
871 #else
872  return std::atanh(x);
873 #endif
874 }
875 
877 {
878 #ifdef VISKORES_CUDA
879  return VISKORES_CUDA_MATH_FUNCTION_64(atanh)(x);
880 #else
881  return std::atanh(x);
882 #endif
883 }
884 template <typename T>
885 static inline VISKORES_EXEC_CONT typename detail::FloatingPointReturnType<T>::Type ATanH(const T& x)
886 {
887  using RT = typename detail::FloatingPointReturnType<T>::Type;
888  return viskores::ATanH(static_cast<RT>(x));
889 }
890 template <typename T, viskores::IdComponent N>
892  const viskores::Vec<T, N>& x)
893 {
895  for (viskores::IdComponent index = 0; index < N; index++)
896  {
897  result[index] = viskores::ATanH(x[index]);
898  }
899  return result;
900 }
901 template <typename T>
903  const viskores::Vec<T, 4>& x)
904 {
907 }
908 template <typename T>
910  const viskores::Vec<T, 3>& x)
911 {
913  viskores::ATanH(x[0]), viskores::ATanH(x[1]), viskores::ATanH(x[2]));
914 }
915 template <typename T>
917  const viskores::Vec<T, 2>& x)
918 {
920  viskores::ATanH(x[1]));
921 }
923 
924 //-----------------------------------------------------------------------------
929 {
930 #ifdef VISKORES_CUDA
931  return VISKORES_CUDA_MATH_FUNCTION_32(pow)(x, y);
932 #else
933  return std::pow(x, y);
934 #endif
935 }
937 {
938 #ifdef VISKORES_CUDA
939  return VISKORES_CUDA_MATH_FUNCTION_64(pow)(x, y);
940 #else
941  return std::pow(x, y);
942 #endif
943 }
945 
950 
952 {
953 #ifdef VISKORES_CUDA
954  return VISKORES_CUDA_MATH_FUNCTION_32(sqrt)(x);
955 #else
956  return std::sqrt(x);
957 #endif
958 }
959 
961 {
962 #ifdef VISKORES_CUDA
963  return VISKORES_CUDA_MATH_FUNCTION_64(sqrt)(x);
964 #else
965  return std::sqrt(x);
966 #endif
967 }
968 template <typename T>
969 static inline VISKORES_EXEC_CONT typename detail::FloatingPointReturnType<T>::Type Sqrt(const T& x)
970 {
971  using RT = typename detail::FloatingPointReturnType<T>::Type;
972  return viskores::Sqrt(static_cast<RT>(x));
973 }
974 template <typename T, viskores::IdComponent N>
976  const viskores::Vec<T, N>& x)
977 {
979  for (viskores::IdComponent index = 0; index < N; index++)
980  {
981  result[index] = viskores::Sqrt(x[index]);
982  }
983  return result;
984 }
985 template <typename T>
987  const viskores::Vec<T, 4>& x)
988 {
990  viskores::Sqrt(x[0]), viskores::Sqrt(x[1]), viskores::Sqrt(x[2]), viskores::Sqrt(x[3]));
991 }
992 template <typename T>
994  const viskores::Vec<T, 3>& x)
995 {
997  viskores::Sqrt(x[0]), viskores::Sqrt(x[1]), viskores::Sqrt(x[2]));
998 }
999 template <typename T>
1001  const viskores::Vec<T, 2>& x)
1002 {
1004  viskores::Sqrt(x[1]));
1005 }
1007 
1014 #ifdef VISKORES_CUDA
1016 {
1017  return rsqrtf(x);
1018 }
1020 {
1021  return rsqrt(x);
1022 }
1023 template <typename T>
1024 static inline VISKORES_EXEC_CONT viskores::Float64 RSqrt(T x)
1025 {
1026  return rsqrt(static_cast<viskores::Float64>(x));
1027 }
1028 #else // !VISKORES_CUDA
1030 {
1031  return 1 / viskores::Sqrt(x);
1032 }
1034 {
1035  return 1 / viskores::Sqrt(x);
1036 }
1037 template <typename T>
1038 static inline VISKORES_EXEC_CONT viskores::Float64 RSqrt(T x)
1039 {
1040  return 1 / static_cast<viskores::Float64>(x);
1041 }
1042 #endif // !VISKORES_CUDA
1043 
1044 template <typename T, viskores::IdComponent N>
1046  const viskores::Vec<T, N>& x)
1047 {
1049  for (viskores::IdComponent index = 0; index < N; index++)
1050  {
1051  result[index] = viskores::RSqrt(x[index]);
1052  }
1053  return result;
1054 }
1055 template <typename T>
1057  const viskores::Vec<T, 4>& x)
1058 {
1060  viskores::RSqrt(x[0]), viskores::RSqrt(x[1]), viskores::RSqrt(x[2]), viskores::RSqrt(x[3]));
1061 }
1062 template <typename T>
1064  const viskores::Vec<T, 3>& x)
1065 {
1067  viskores::RSqrt(x[0]), viskores::RSqrt(x[1]), viskores::RSqrt(x[2]));
1068 }
1069 template <typename T>
1071  const viskores::Vec<T, 2>& x)
1072 {
1073  return viskores::Vec<typename detail::FloatingPointReturnType<T>::Type, 2>(viskores::RSqrt(x[0]),
1074  viskores::RSqrt(x[1]));
1075 }
1077 
1081 
1083 {
1084 #ifdef VISKORES_CUDA
1085  return VISKORES_CUDA_MATH_FUNCTION_32(cbrt)(x);
1086 #else
1087  return std::cbrt(x);
1088 #endif
1089 }
1090 
1092 {
1093 #ifdef VISKORES_CUDA
1094  return VISKORES_CUDA_MATH_FUNCTION_64(cbrt)(x);
1095 #else
1096  return std::cbrt(x);
1097 #endif
1098 }
1099 template <typename T>
1100 static inline VISKORES_EXEC_CONT typename detail::FloatingPointReturnType<T>::Type Cbrt(const T& x)
1101 {
1102  using RT = typename detail::FloatingPointReturnType<T>::Type;
1103  return viskores::Cbrt(static_cast<RT>(x));
1104 }
1105 template <typename T, viskores::IdComponent N>
1107  const viskores::Vec<T, N>& x)
1108 {
1110  for (viskores::IdComponent index = 0; index < N; index++)
1111  {
1112  result[index] = viskores::Cbrt(x[index]);
1113  }
1114  return result;
1115 }
1116 template <typename T>
1118  const viskores::Vec<T, 4>& x)
1119 {
1121  viskores::Cbrt(x[0]), viskores::Cbrt(x[1]), viskores::Cbrt(x[2]), viskores::Cbrt(x[3]));
1122 }
1123 template <typename T>
1125  const viskores::Vec<T, 3>& x)
1126 {
1128  viskores::Cbrt(x[0]), viskores::Cbrt(x[1]), viskores::Cbrt(x[2]));
1129 }
1130 template <typename T>
1132  const viskores::Vec<T, 2>& x)
1133 {
1135  viskores::Cbrt(x[1]));
1136 }
1138 
1145 #ifdef VISKORES_CUDA
1147 {
1148  return rcbrtf(x);
1149 }
1151 {
1152  return rcbrt(x);
1153 }
1154 template <typename T>
1155 static inline VISKORES_EXEC_CONT viskores::Float64 RCbrt(T x)
1156 {
1157  return rcbrt(static_cast<viskores::Float64>(x));
1158 }
1159 #else // !VISKORES_CUDA
1161 {
1162  return 1 / viskores::Cbrt(x);
1163 }
1165 {
1166  return 1 / viskores::Cbrt(x);
1167 }
1168 template <typename T>
1169 static inline VISKORES_EXEC_CONT viskores::Float64 RCbrt(T x)
1170 {
1171  return 1 / viskores::Cbrt(static_cast<viskores::Float64>(x));
1172 }
1173 #endif // !VISKORES_CUDA
1174 
1175 template <typename T, viskores::IdComponent N>
1177  const viskores::Vec<T, N>& x)
1178 {
1180  for (viskores::IdComponent index = 0; index < N; index++)
1181  {
1182  result[index] = viskores::RCbrt(x[index]);
1183  }
1184  return result;
1185 }
1186 template <typename T>
1188  const viskores::Vec<T, 4>& x)
1189 {
1191  viskores::RCbrt(x[0]), viskores::RCbrt(x[1]), viskores::RCbrt(x[2]), viskores::RCbrt(x[3]));
1192 }
1193 template <typename T>
1195  const viskores::Vec<T, 3>& x)
1196 {
1198  viskores::RCbrt(x[0]), viskores::RCbrt(x[1]), viskores::RCbrt(x[2]));
1199 }
1200 template <typename T>
1202  const viskores::Vec<T, 2>& x)
1203 {
1204  return viskores::Vec<typename detail::FloatingPointReturnType<T>::Type, 2>(viskores::RCbrt(x[0]),
1205  viskores::RCbrt(x[1]));
1206 }
1208 
1212 
1214 {
1215 #ifdef VISKORES_CUDA
1216  return VISKORES_CUDA_MATH_FUNCTION_32(exp)(x);
1217 #else
1218  return std::exp(x);
1219 #endif
1220 }
1221 
1223 {
1224 #ifdef VISKORES_CUDA
1225  return VISKORES_CUDA_MATH_FUNCTION_64(exp)(x);
1226 #else
1227  return std::exp(x);
1228 #endif
1229 }
1230 template <typename T>
1231 static inline VISKORES_EXEC_CONT typename detail::FloatingPointReturnType<T>::Type Exp(const T& x)
1232 {
1233  using RT = typename detail::FloatingPointReturnType<T>::Type;
1234  return viskores::Exp(static_cast<RT>(x));
1235 }
1236 template <typename T, viskores::IdComponent N>
1238  const viskores::Vec<T, N>& x)
1239 {
1241  for (viskores::IdComponent index = 0; index < N; index++)
1242  {
1243  result[index] = viskores::Exp(x[index]);
1244  }
1245  return result;
1246 }
1247 template <typename T>
1249  const viskores::Vec<T, 4>& x)
1250 {
1252  viskores::Exp(x[0]), viskores::Exp(x[1]), viskores::Exp(x[2]), viskores::Exp(x[3]));
1253 }
1254 template <typename T>
1256  const viskores::Vec<T, 3>& x)
1257 {
1259  viskores::Exp(x[0]), viskores::Exp(x[1]), viskores::Exp(x[2]));
1260 }
1261 template <typename T>
1263  const viskores::Vec<T, 2>& x)
1264 {
1266  viskores::Exp(x[1]));
1267 }
1269 
1273 
1275 {
1276 #ifdef VISKORES_CUDA
1277  return VISKORES_CUDA_MATH_FUNCTION_32(exp2)(x);
1278 #else
1279  return std::exp2(x);
1280 #endif
1281 }
1282 
1284 {
1285 #ifdef VISKORES_CUDA
1286  return VISKORES_CUDA_MATH_FUNCTION_64(exp2)(x);
1287 #else
1288  return std::exp2(x);
1289 #endif
1290 }
1291 template <typename T>
1292 static inline VISKORES_EXEC_CONT typename detail::FloatingPointReturnType<T>::Type Exp2(const T& x)
1293 {
1294  using RT = typename detail::FloatingPointReturnType<T>::Type;
1295  return viskores::Exp2(static_cast<RT>(x));
1296 }
1297 template <typename T, viskores::IdComponent N>
1299  const viskores::Vec<T, N>& x)
1300 {
1302  for (viskores::IdComponent index = 0; index < N; index++)
1303  {
1304  result[index] = viskores::Exp2(x[index]);
1305  }
1306  return result;
1307 }
1308 template <typename T>
1310  const viskores::Vec<T, 4>& x)
1311 {
1313  viskores::Exp2(x[0]), viskores::Exp2(x[1]), viskores::Exp2(x[2]), viskores::Exp2(x[3]));
1314 }
1315 template <typename T>
1317  const viskores::Vec<T, 3>& x)
1318 {
1320  viskores::Exp2(x[0]), viskores::Exp2(x[1]), viskores::Exp2(x[2]));
1321 }
1322 template <typename T>
1324  const viskores::Vec<T, 2>& x)
1325 {
1327  viskores::Exp2(x[1]));
1328 }
1330 
1335 
1337 {
1338 #ifdef VISKORES_CUDA
1339  return VISKORES_CUDA_MATH_FUNCTION_32(expm1)(x);
1340 #else
1341  return std::expm1(x);
1342 #endif
1343 }
1344 
1346 {
1347 #ifdef VISKORES_CUDA
1348  return VISKORES_CUDA_MATH_FUNCTION_64(expm1)(x);
1349 #else
1350  return std::expm1(x);
1351 #endif
1352 }
1353 template <typename T>
1354 static inline VISKORES_EXEC_CONT typename detail::FloatingPointReturnType<T>::Type ExpM1(const T& x)
1355 {
1356  using RT = typename detail::FloatingPointReturnType<T>::Type;
1357  return viskores::ExpM1(static_cast<RT>(x));
1358 }
1359 template <typename T, viskores::IdComponent N>
1361  const viskores::Vec<T, N>& x)
1362 {
1364  for (viskores::IdComponent index = 0; index < N; index++)
1365  {
1366  result[index] = viskores::ExpM1(x[index]);
1367  }
1368  return result;
1369 }
1370 template <typename T>
1372  const viskores::Vec<T, 4>& x)
1373 {
1375  viskores::ExpM1(x[0]), viskores::ExpM1(x[1]), viskores::ExpM1(x[2]), viskores::ExpM1(x[3]));
1376 }
1377 template <typename T>
1379  const viskores::Vec<T, 3>& x)
1380 {
1382  viskores::ExpM1(x[0]), viskores::ExpM1(x[1]), viskores::ExpM1(x[2]));
1383 }
1384 template <typename T>
1386  const viskores::Vec<T, 2>& x)
1387 {
1389  viskores::ExpM1(x[1]));
1390 }
1392 
1396 #ifdef VISKORES_CUDA
1398 {
1399  return exp10f(x);
1400 }
1402 {
1403  return exp10(x);
1404 }
1405 template <typename T>
1406 static inline VISKORES_EXEC_CONT viskores::Float64 Exp10(T x)
1407 {
1408  return exp10(static_cast<viskores::Float64>(x));
1409 }
1410 #else // !VISKORES_CUDA
1412 {
1413  return viskores::Pow(10, x);
1414 }
1416 {
1417  return viskores::Pow(10, x);
1418 }
1419 template <typename T>
1420 static inline VISKORES_EXEC_CONT viskores::Float64 Exp10(T x)
1421 {
1422  return viskores::Pow(10, static_cast<viskores::Float64>(x));
1423 }
1424 #endif // !VISKORES_CUDA
1425 
1426 template <typename T, viskores::IdComponent N>
1428  const viskores::Vec<T, N>& x)
1429 {
1431  for (viskores::IdComponent index = 0; index < N; index++)
1432  {
1433  result[index] = viskores::Exp10(x[index]);
1434  }
1435  return result;
1436 }
1437 template <typename T>
1439  const viskores::Vec<T, 4>& x)
1440 {
1442  viskores::Exp10(x[0]), viskores::Exp10(x[1]), viskores::Exp10(x[2]), viskores::Exp10(x[3]));
1443 }
1444 template <typename T>
1446  const viskores::Vec<T, 3>& x)
1447 {
1449  viskores::Exp10(x[0]), viskores::Exp10(x[1]), viskores::Exp10(x[2]));
1450 }
1451 template <typename T>
1453  const viskores::Vec<T, 2>& x)
1454 {
1455  return viskores::Vec<typename detail::FloatingPointReturnType<T>::Type, 2>(viskores::Exp10(x[0]),
1456  viskores::Exp10(x[1]));
1457 }
1459 
1463 
1465 {
1466 #ifdef VISKORES_CUDA
1467  return VISKORES_CUDA_MATH_FUNCTION_32(log)(x);
1468 #else
1469  return std::log(x);
1470 #endif
1471 }
1472 
1474 {
1475 #ifdef VISKORES_CUDA
1476  return VISKORES_CUDA_MATH_FUNCTION_64(log)(x);
1477 #else
1478  return std::log(x);
1479 #endif
1480 }
1481 template <typename T>
1482 static inline VISKORES_EXEC_CONT typename detail::FloatingPointReturnType<T>::Type Log(const T& x)
1483 {
1484  using RT = typename detail::FloatingPointReturnType<T>::Type;
1485  return viskores::Log(static_cast<RT>(x));
1486 }
1487 template <typename T, viskores::IdComponent N>
1489  const viskores::Vec<T, N>& x)
1490 {
1492  for (viskores::IdComponent index = 0; index < N; index++)
1493  {
1494  result[index] = viskores::Log(x[index]);
1495  }
1496  return result;
1497 }
1498 template <typename T>
1500  const viskores::Vec<T, 4>& x)
1501 {
1503  viskores::Log(x[0]), viskores::Log(x[1]), viskores::Log(x[2]), viskores::Log(x[3]));
1504 }
1505 template <typename T>
1507  const viskores::Vec<T, 3>& x)
1508 {
1510  viskores::Log(x[0]), viskores::Log(x[1]), viskores::Log(x[2]));
1511 }
1512 template <typename T>
1514  const viskores::Vec<T, 2>& x)
1515 {
1517  viskores::Log(x[1]));
1518 }
1520 
1524 
1526 {
1527 #ifdef VISKORES_CUDA
1528  return VISKORES_CUDA_MATH_FUNCTION_32(log2)(x);
1529 #else
1530  return std::log2(x);
1531 #endif
1532 }
1533 
1535 {
1536 #ifdef VISKORES_CUDA
1537  return VISKORES_CUDA_MATH_FUNCTION_64(log2)(x);
1538 #else
1539  return std::log2(x);
1540 #endif
1541 }
1542 template <typename T>
1543 static inline VISKORES_EXEC_CONT typename detail::FloatingPointReturnType<T>::Type Log2(const T& x)
1544 {
1545  using RT = typename detail::FloatingPointReturnType<T>::Type;
1546  return viskores::Log2(static_cast<RT>(x));
1547 }
1548 template <typename T, viskores::IdComponent N>
1550  const viskores::Vec<T, N>& x)
1551 {
1553  for (viskores::IdComponent index = 0; index < N; index++)
1554  {
1555  result[index] = viskores::Log2(x[index]);
1556  }
1557  return result;
1558 }
1559 template <typename T>
1561  const viskores::Vec<T, 4>& x)
1562 {
1564  viskores::Log2(x[0]), viskores::Log2(x[1]), viskores::Log2(x[2]), viskores::Log2(x[3]));
1565 }
1566 template <typename T>
1568  const viskores::Vec<T, 3>& x)
1569 {
1571  viskores::Log2(x[0]), viskores::Log2(x[1]), viskores::Log2(x[2]));
1572 }
1573 template <typename T>
1575  const viskores::Vec<T, 2>& x)
1576 {
1578  viskores::Log2(x[1]));
1579 }
1581 
1585 
1587 {
1588 #ifdef VISKORES_CUDA
1589  return VISKORES_CUDA_MATH_FUNCTION_32(log10)(x);
1590 #else
1591  return std::log10(x);
1592 #endif
1593 }
1594 
1596 {
1597 #ifdef VISKORES_CUDA
1598  return VISKORES_CUDA_MATH_FUNCTION_64(log10)(x);
1599 #else
1600  return std::log10(x);
1601 #endif
1602 }
1603 template <typename T>
1604 static inline VISKORES_EXEC_CONT typename detail::FloatingPointReturnType<T>::Type Log10(const T& x)
1605 {
1606  using RT = typename detail::FloatingPointReturnType<T>::Type;
1607  return viskores::Log10(static_cast<RT>(x));
1608 }
1609 template <typename T, viskores::IdComponent N>
1611  const viskores::Vec<T, N>& x)
1612 {
1614  for (viskores::IdComponent index = 0; index < N; index++)
1615  {
1616  result[index] = viskores::Log10(x[index]);
1617  }
1618  return result;
1619 }
1620 template <typename T>
1622  const viskores::Vec<T, 4>& x)
1623 {
1625  viskores::Log10(x[0]), viskores::Log10(x[1]), viskores::Log10(x[2]), viskores::Log10(x[3]));
1626 }
1627 template <typename T>
1629  const viskores::Vec<T, 3>& x)
1630 {
1632  viskores::Log10(x[0]), viskores::Log10(x[1]), viskores::Log10(x[2]));
1633 }
1634 template <typename T>
1636  const viskores::Vec<T, 2>& x)
1637 {
1639  viskores::Log10(x[1]));
1640 }
1642 
1646 
1648 {
1649 #ifdef VISKORES_CUDA
1650  return VISKORES_CUDA_MATH_FUNCTION_32(log1p)(x);
1651 #else
1652  return std::log1p(x);
1653 #endif
1654 }
1655 
1657 {
1658 #ifdef VISKORES_CUDA
1659  return VISKORES_CUDA_MATH_FUNCTION_64(log1p)(x);
1660 #else
1661  return std::log1p(x);
1662 #endif
1663 }
1664 template <typename T>
1665 static inline VISKORES_EXEC_CONT typename detail::FloatingPointReturnType<T>::Type Log1P(const T& x)
1666 {
1667  using RT = typename detail::FloatingPointReturnType<T>::Type;
1668  return viskores::Log1P(static_cast<RT>(x));
1669 }
1670 template <typename T, viskores::IdComponent N>
1672  const viskores::Vec<T, N>& x)
1673 {
1675  for (viskores::IdComponent index = 0; index < N; index++)
1676  {
1677  result[index] = viskores::Log1P(x[index]);
1678  }
1679  return result;
1680 }
1681 template <typename T>
1683  const viskores::Vec<T, 4>& x)
1684 {
1686  viskores::Log1P(x[0]), viskores::Log1P(x[1]), viskores::Log1P(x[2]), viskores::Log1P(x[3]));
1687 }
1688 template <typename T>
1690  const viskores::Vec<T, 3>& x)
1691 {
1693  viskores::Log1P(x[0]), viskores::Log1P(x[1]), viskores::Log1P(x[2]));
1694 }
1695 template <typename T>
1697  const viskores::Vec<T, 2>& x)
1698 {
1700  viskores::Log1P(x[1]));
1701 }
1703 
1704 //-----------------------------------------------------------------------------
1708 template <typename T>
1709 static inline VISKORES_EXEC_CONT T Max(const T& x, const T& y);
1710 #ifdef VISKORES_USE_STL
1712 {
1713  return (std::max)(x, y);
1714 }
1716 {
1717  return (std::max)(x, y);
1718 }
1719 #else // !VISKORES_USE_STL
1721 {
1722 #ifdef VISKORES_CUDA
1723  return VISKORES_CUDA_MATH_FUNCTION_32(fmax)(x, y);
1724 #else
1725  return std::fmax(x, y);
1726 #endif
1727 }
1729 {
1730 #ifdef VISKORES_CUDA
1731  return VISKORES_CUDA_MATH_FUNCTION_64(fmax)(x, y);
1732 #else
1733  return std::fmax(x, y);
1734 #endif
1735 }
1736 #endif // !VISKORES_USE_STL
1737 
1742 template <typename T>
1743 static inline VISKORES_EXEC_CONT T Min(const T& x, const T& y);
1744 #if defined(VISKORES_USE_STL) && !defined(VISKORES_HIP)
1746 {
1747  return (std::min)(x, y);
1748 }
1750 {
1751  return (std::min)(x, y);
1752 }
1753 #else // !VISKORES_USE_STL OR HIP
1755 {
1756 #ifdef VISKORES_CUDA
1757  return VISKORES_CUDA_MATH_FUNCTION_32(fmin)(x, y);
1758 #else
1759  return std::fmin(x, y);
1760 #endif
1761 }
1763 {
1764 #ifdef VISKORES_CUDA
1765  return VISKORES_CUDA_MATH_FUNCTION_64(fmin)(x, y);
1766 #else
1767  return std::fmin(x, y);
1768 #endif
1769 }
1770 #endif // !VISKORES_USE_STL
1771 
1773 namespace detail
1774 {
1775 
1776 template <typename T>
1777 static inline VISKORES_EXEC_CONT T Max(T x, T y, viskores::TypeTraitsScalarTag)
1778 {
1779  return (x < y) ? y : x;
1780 }
1781 
1782 template <typename T>
1783 static inline VISKORES_EXEC_CONT T Max(const T& x, const T& y, viskores::TypeTraitsVectorTag)
1784 {
1785  using Traits = viskores::VecTraits<T>;
1786  T result;
1787  for (viskores::IdComponent index = 0; index < Traits::NUM_COMPONENTS; index++)
1788  {
1789  Traits::SetComponent(
1790  result, index, viskores::Max(Traits::GetComponent(x, index), Traits::GetComponent(y, index)));
1791  }
1792  return result;
1793 }
1794 
1795 template <typename T>
1796 static inline VISKORES_EXEC_CONT T Min(T x, T y, viskores::TypeTraitsScalarTag)
1797 {
1798  return (x < y) ? x : y;
1799 }
1800 
1801 template <typename T>
1802 static inline VISKORES_EXEC_CONT T Min(const T& x, const T& y, viskores::TypeTraitsVectorTag)
1803 {
1804  using Traits = viskores::VecTraits<T>;
1805  T result;
1806  for (viskores::IdComponent index = 0; index < Traits::NUM_COMPONENTS; index++)
1807  {
1808  Traits::SetComponent(
1809  result, index, viskores::Min(Traits::GetComponent(x, index), Traits::GetComponent(y, index)));
1810  }
1811  return result;
1812 }
1813 
1814 } // namespace detail
1815 
1818 template <typename T>
1819 static inline VISKORES_EXEC_CONT T Max(const T& x, const T& y)
1820 {
1821  return detail::Max(x, y, typename viskores::TypeTraits<T>::DimensionalityTag());
1822 }
1823 
1826 template <typename T>
1827 static inline VISKORES_EXEC_CONT T Min(const T& x, const T& y)
1828 {
1829  return detail::Min(x, y, typename viskores::TypeTraits<T>::DimensionalityTag());
1830 }
1831 
1836 {
1837  return x > lo ? (x < hi ? x : hi) : lo;
1838 }
1839 
1841 {
1842  return x > lo ? (x < hi ? x : hi) : lo;
1843 }
1845 
1846 //-----------------------------------------------------------------------------
1847 
1848 //#ifdef VISKORES_CUDA
1849 #define VISKORES_USE_IEEE_NONFINITE
1850 //#endif
1851 
1852 #ifdef VISKORES_USE_IEEE_NONFINITE
1853 
1854 namespace detail
1855 {
1856 
1857 union IEEE754Bits32 {
1858  viskores::UInt32 bits;
1859  viskores::Float32 scalar;
1860 };
1861 #define VISKORES_NAN_BITS_32 0x7FC00000U
1862 #define VISKORES_INF_BITS_32 0x7F800000U
1863 #define VISKORES_NEG_INF_BITS_32 0xFF800000U
1864 #define VISKORES_EPSILON_32 1e-5f
1865 
1866 union IEEE754Bits64 {
1867  viskores::UInt64 bits;
1868  viskores::Float64 scalar;
1869 };
1870 #define VISKORES_NAN_BITS_64 0x7FF8000000000000ULL
1871 #define VISKORES_INF_BITS_64 0x7FF0000000000000ULL
1872 #define VISKORES_NEG_INF_BITS_64 0xFFF0000000000000ULL
1873 #define VISKORES_EPSILON_64 1e-9
1874 
1875 template <typename T>
1876 struct FloatLimits;
1877 
1878 template <>
1879 struct FloatLimits<viskores::Float32>
1880 {
1881  using BitsType = viskores::detail::IEEE754Bits32;
1882 
1884  static viskores::Float32 Nan()
1885  {
1886  BitsType nan = { VISKORES_NAN_BITS_32 };
1887  return nan.scalar;
1888  }
1889 
1891  static viskores::Float32 Infinity()
1892  {
1893  BitsType inf = { VISKORES_INF_BITS_32 };
1894  return inf.scalar;
1895  }
1896 
1898  static viskores::Float32 NegativeInfinity()
1899  {
1900  BitsType neginf = { VISKORES_NEG_INF_BITS_32 };
1901  return neginf.scalar;
1902  }
1903 
1905  static viskores::Float32 Epsilon() { return VISKORES_EPSILON_32; }
1906 };
1907 
1908 template <int N>
1909 struct FloatLimits<viskores::Vec<viskores::Float32, N>>
1910 {
1911  using BitsType = viskores::detail::IEEE754Bits32;
1912 
1915  {
1916  BitsType nan = { VISKORES_NAN_BITS_32 };
1917  return viskores::Vec<viskores::Float32, N>(nan.scalar);
1918  }
1919 
1921  static viskores::Vec<viskores::Float32, N> Infinity()
1922  {
1923  BitsType inf = { VISKORES_INF_BITS_32 };
1924  return viskores::Vec<viskores::Float32, N>(inf.scalar);
1925  }
1926 
1928  static viskores::Vec<viskores::Float32, N> NegativeInfinity()
1929  {
1930  BitsType neginf = { VISKORES_NEG_INF_BITS_32 };
1931  return viskores::Vec<viskores::Float32, N>(neginf.scalar);
1932  }
1933 
1935  static viskores::Vec<viskores::Float32, N> Epsilon()
1936  {
1938  }
1939 };
1940 
1941 template <>
1942 struct FloatLimits<viskores::Float64>
1943 {
1944  using BitsType = viskores::detail::IEEE754Bits64;
1945 
1947  static viskores::Float64 Nan()
1948  {
1949  BitsType nan = { VISKORES_NAN_BITS_64 };
1950  return nan.scalar;
1951  }
1952 
1954  static viskores::Float64 Infinity()
1955  {
1956  BitsType inf = { VISKORES_INF_BITS_64 };
1957  return inf.scalar;
1958  }
1959 
1961  static viskores::Float64 NegativeInfinity()
1962  {
1963  BitsType neginf = { VISKORES_NEG_INF_BITS_64 };
1964  return neginf.scalar;
1965  }
1966 
1968  static viskores::Float64 Epsilon() { return VISKORES_EPSILON_64; }
1969 };
1970 
1971 template <int N>
1972 struct FloatLimits<viskores::Vec<viskores::Float64, N>>
1973 {
1974  using BitsType = viskores::detail::IEEE754Bits64;
1975 
1978  {
1979  BitsType nan = { VISKORES_NAN_BITS_64 };
1980  return viskores::Vec<viskores::Float64, N>(nan.scalar);
1981  }
1982 
1984  static viskores::Vec<viskores::Float64, N> Infinity()
1985  {
1986  BitsType inf = { VISKORES_INF_BITS_64 };
1987  return viskores::Vec<viskores::Float64, N>(inf.scalar);
1988  }
1989 
1991  static viskores::Vec<viskores::Float64, N> NegativeInfinity()
1992  {
1993  BitsType neginf = { VISKORES_NEG_INF_BITS_64 };
1994  return viskores::Vec<viskores::Float64, N>(neginf.scalar);
1995  }
1996 
1998  static viskores::Vec<viskores::Float64, N> Epsilon()
1999  {
2001  }
2002 };
2003 
2004 #undef VISKORES_NAN_BITS_32
2005 #undef VISKORES_INF_BITS_32
2006 #undef VISKORES_NEG_INF_BITS_32
2007 #undef VISKORES_EPSILON_32
2008 #undef VISKORES_NAN_BITS_64
2009 #undef VISKORES_INF_BITS_64
2010 #undef VISKORES_NEG_INF_BITS_64
2011 #undef VISKORES_EPSILON_64
2012 
2013 } // namespace detail
2014 #endif //VISKORES_USE_IEEE_NONFINITE
2015 
2023 #ifdef VISKORES_USE_IEEE_NONFINITE
2024 template <typename T>
2025 static inline VISKORES_EXEC_CONT T Nan()
2026 {
2027  return detail::FloatLimits<T>::Nan();
2028 }
2029 #else // !VISKORES_USE_IEEE_NONFINITE
2030 template <typename T>
2031 static inline VISKORES_EXEC_CONT T Nan()
2032 {
2033  return std::numeric_limits<T>::quiet_NaN();
2034 }
2035 #endif // !VISKORES_USE_IEEE_NONFINITE
2036 static inline VISKORES_EXEC_CONT viskores::Float32 Nan32()
2037 {
2038  return viskores::Nan<viskores::Float32>();
2039 }
2040 static inline VISKORES_EXEC_CONT viskores::Float64 Nan64()
2041 {
2042  return viskores::Nan<viskores::Float64>();
2043 }
2045 
2053 #ifdef VISKORES_USE_IEEE_NONFINITE
2054 template <typename T>
2055 static inline VISKORES_EXEC_CONT T Infinity()
2056 {
2057  return detail::FloatLimits<T>::Infinity();
2058 }
2059 #else // !VISKORES_USE_IEEE_NONFINITE
2060 template <typename T>
2061 static inline VISKORES_EXEC_CONT T Infinity()
2062 {
2063  return std::numeric_limits<T>::infinity();
2064 }
2065 #endif // !VISKORES_USE_IEEE_NONFINITE
2066 static inline VISKORES_EXEC_CONT viskores::Float32 Infinity32()
2067 {
2068  return viskores::Infinity<viskores::Float32>();
2069 }
2070 static inline VISKORES_EXEC_CONT viskores::Float64 Infinity64()
2071 {
2072  return viskores::Infinity<viskores::Float64>();
2073 }
2075 
2084 #ifdef VISKORES_USE_IEEE_NONFINITE
2085 template <typename T>
2086 static inline VISKORES_EXEC_CONT T NegativeInfinity()
2087 {
2088  return detail::FloatLimits<T>::NegativeInfinity();
2089 }
2090 #else // !VISKORES_USE_IEEE_NONFINITE
2091 template <typename T>
2092 static inline VISKORES_EXEC_CONT T NegativeInfinity()
2093 {
2094  return -std::numeric_limits<T>::infinity();
2095 }
2096 #endif // !VISKORES_USE_IEEE_NONFINITE
2097 static inline VISKORES_EXEC_CONT viskores::Float32 NegativeInfinity32()
2098 {
2099  return viskores::NegativeInfinity<viskores::Float32>();
2100 }
2101 static inline VISKORES_EXEC_CONT viskores::Float64 NegativeInfinity64()
2102 {
2103  return viskores::NegativeInfinity<viskores::Float64>();
2104 }
2106 
2114 #ifdef VISKORES_USE_IEEE_NONFINITE
2115 template <typename T>
2116 static inline VISKORES_EXEC_CONT T Epsilon()
2117 {
2118  return detail::FloatLimits<T>::Epsilon();
2119 }
2120 #else // !VISKORES_USE_IEEE_NONFINITE
2121 template <typename T>
2122 static inline VISKORES_EXEC_CONT T Epsilon()
2123 {
2124  return std::numeric_limits<T>::epsilon();
2125 }
2126 #endif // !VISKORES_USE_IEEE_NONFINITE
2127 static inline VISKORES_EXEC_CONT viskores::Float32 Epsilon32()
2128 {
2129  return viskores::Epsilon<viskores::Float32>();
2130 }
2131 static inline VISKORES_EXEC_CONT viskores::Float64 Epsilon64()
2132 {
2133  return viskores::Epsilon<viskores::Float64>();
2134 }
2136 
2137 
2138 //-----------------------------------------------------------------------------
2141 template <typename T>
2142 static inline VISKORES_EXEC_CONT bool IsNan(T x)
2143 {
2144 #ifndef VISKORES_CUDA
2145  using std::isnan;
2146 #endif
2147  return (isnan(x) != 0);
2148 }
2149 
2152 template <typename T>
2153 static inline VISKORES_EXEC_CONT bool IsInf(T x)
2154 {
2155 #ifndef VISKORES_CUDA
2156  using std::isinf;
2157 #endif
2158  return (isinf(x) != 0);
2159 }
2160 
2163 template <typename T>
2164 static inline VISKORES_EXEC_CONT bool IsFinite(T x)
2165 {
2166 #ifndef VISKORES_CUDA
2167  using std::isfinite;
2168 #endif
2169  return (isfinite(x) != 0);
2170 }
2171 
2172 //-----------------------------------------------------------------------------
2176 
2178 {
2179 #ifdef VISKORES_CUDA
2180  return VISKORES_CUDA_MATH_FUNCTION_32(ceil)(x);
2181 #else
2182  return std::ceil(x);
2183 #endif
2184 }
2185 
2187 {
2188 #ifdef VISKORES_CUDA
2189  return VISKORES_CUDA_MATH_FUNCTION_64(ceil)(x);
2190 #else
2191  return std::ceil(x);
2192 #endif
2193 }
2194 template <typename T>
2195 static inline VISKORES_EXEC_CONT typename detail::FloatingPointReturnType<T>::Type Ceil(const T& x)
2196 {
2197  using RT = typename detail::FloatingPointReturnType<T>::Type;
2198  return viskores::Ceil(static_cast<RT>(x));
2199 }
2200 template <typename T, viskores::IdComponent N>
2202  const viskores::Vec<T, N>& x)
2203 {
2205  for (viskores::IdComponent index = 0; index < N; index++)
2206  {
2207  result[index] = viskores::Ceil(x[index]);
2208  }
2209  return result;
2210 }
2211 template <typename T>
2213  const viskores::Vec<T, 4>& x)
2214 {
2216  viskores::Ceil(x[0]), viskores::Ceil(x[1]), viskores::Ceil(x[2]), viskores::Ceil(x[3]));
2217 }
2218 template <typename T>
2220  const viskores::Vec<T, 3>& x)
2221 {
2223  viskores::Ceil(x[0]), viskores::Ceil(x[1]), viskores::Ceil(x[2]));
2224 }
2225 template <typename T>
2227  const viskores::Vec<T, 2>& x)
2228 {
2230  viskores::Ceil(x[1]));
2231 }
2233 
2237 
2239 {
2240 #ifdef VISKORES_CUDA
2241  return VISKORES_CUDA_MATH_FUNCTION_32(floor)(x);
2242 #else
2243  return std::floor(x);
2244 #endif
2245 }
2246 
2248 {
2249 #ifdef VISKORES_CUDA
2250  return VISKORES_CUDA_MATH_FUNCTION_64(floor)(x);
2251 #else
2252  return std::floor(x);
2253 #endif
2254 }
2255 template <typename T>
2256 static inline VISKORES_EXEC_CONT typename detail::FloatingPointReturnType<T>::Type Floor(const T& x)
2257 {
2258  using RT = typename detail::FloatingPointReturnType<T>::Type;
2259  return viskores::Floor(static_cast<RT>(x));
2260 }
2261 template <typename T, viskores::IdComponent N>
2263  const viskores::Vec<T, N>& x)
2264 {
2266  for (viskores::IdComponent index = 0; index < N; index++)
2267  {
2268  result[index] = viskores::Floor(x[index]);
2269  }
2270  return result;
2271 }
2272 template <typename T>
2274  const viskores::Vec<T, 4>& x)
2275 {
2277  viskores::Floor(x[0]), viskores::Floor(x[1]), viskores::Floor(x[2]), viskores::Floor(x[3]));
2278 }
2279 template <typename T>
2281  const viskores::Vec<T, 3>& x)
2282 {
2284  viskores::Floor(x[0]), viskores::Floor(x[1]), viskores::Floor(x[2]));
2285 }
2286 template <typename T>
2288  const viskores::Vec<T, 2>& x)
2289 {
2291  viskores::Floor(x[1]));
2292 }
2294 
2298 
2300 {
2301 #ifdef VISKORES_CUDA
2302  return VISKORES_CUDA_MATH_FUNCTION_32(round)(x);
2303 #else
2304  return std::round(x);
2305 #endif
2306 }
2307 
2309 {
2310 #ifdef VISKORES_CUDA
2311  return VISKORES_CUDA_MATH_FUNCTION_64(round)(x);
2312 #else
2313  return std::round(x);
2314 #endif
2315 }
2316 template <typename T>
2317 static inline VISKORES_EXEC_CONT typename detail::FloatingPointReturnType<T>::Type Round(const T& x)
2318 {
2319  using RT = typename detail::FloatingPointReturnType<T>::Type;
2320  return viskores::Round(static_cast<RT>(x));
2321 }
2322 template <typename T, viskores::IdComponent N>
2324  const viskores::Vec<T, N>& x)
2325 {
2327  for (viskores::IdComponent index = 0; index < N; index++)
2328  {
2329  result[index] = viskores::Round(x[index]);
2330  }
2331  return result;
2332 }
2333 template <typename T>
2335  const viskores::Vec<T, 4>& x)
2336 {
2338  viskores::Round(x[0]), viskores::Round(x[1]), viskores::Round(x[2]), viskores::Round(x[3]));
2339 }
2340 template <typename T>
2342  const viskores::Vec<T, 3>& x)
2343 {
2345  viskores::Round(x[0]), viskores::Round(x[1]), viskores::Round(x[2]));
2346 }
2347 template <typename T>
2349  const viskores::Vec<T, 2>& x)
2350 {
2352  viskores::Round(x[1]));
2353 }
2355 
2356 //-----------------------------------------------------------------------------
2364 {
2365 #ifdef VISKORES_CUDA
2366  return VISKORES_CUDA_MATH_FUNCTION_32(fmod)(x, y);
2367 #else
2368  return std::fmod(x, y);
2369 #endif
2370 }
2372 {
2373 #ifdef VISKORES_CUDA
2374  return VISKORES_CUDA_MATH_FUNCTION_64(fmod)(x, y);
2375 #else
2376  return std::fmod(x, y);
2377 #endif
2378 }
2380 
2388 #ifdef VISKORES_MSVC
2389 template <typename T>
2390 static inline VISKORES_EXEC_CONT T Remainder(T numerator, T denominator)
2391 {
2392  T quotient = viskores::Round(numerator / denominator);
2393  return numerator - quotient * denominator;
2394 }
2395 #else // !VISKORES_MSVC
2397 {
2398 #ifdef VISKORES_CUDA
2399  return VISKORES_CUDA_MATH_FUNCTION_32(remainder)(x, y);
2400 #else
2401  return std::remainder(x, y);
2402 #endif
2403 }
2405 {
2406 #ifdef VISKORES_CUDA
2407  return VISKORES_CUDA_MATH_FUNCTION_64(remainder)(x, y);
2408 #else
2409  return std::remainder(x, y);
2410 #endif
2411 }
2412 #endif // !VISKORES_MSVC
2413 
2420 template <typename QType>
2421 static inline VISKORES_EXEC_CONT viskores::Float32 RemainderQuotient(viskores::Float32 numerator,
2422  viskores::Float32 denominator,
2423  QType& quotient)
2424 {
2425  int iQuotient;
2426  // See: https://github.com/ROCm-Developer-Tools/HIP/issues/2169
2427 #if defined(VISKORES_CUDA) || defined(VISKORES_HIP)
2428  const viskores::Float32 result =
2429  VISKORES_CUDA_MATH_FUNCTION_32(remquo)(numerator, denominator, &iQuotient);
2430 #else
2431  const viskores::Float32 result = std::remquo(numerator, denominator, &iQuotient);
2432 #endif
2433  quotient = static_cast<QType>(iQuotient);
2434  return result;
2435 }
2436 template <typename QType>
2437 static inline VISKORES_EXEC_CONT viskores::Float64 RemainderQuotient(viskores::Float64 numerator,
2438  viskores::Float64 denominator,
2439  QType& quotient)
2440 {
2441  int iQuotient;
2442 #ifdef VISKORES_CUDA
2443  const viskores::Float64 result =
2444  VISKORES_CUDA_MATH_FUNCTION_64(remquo)(numerator, denominator, &iQuotient);
2445 #else
2446  const viskores::Float64 result = std::remquo(numerator, denominator, &iQuotient);
2447 #endif
2448  quotient = static_cast<QType>(iQuotient);
2449  return result;
2450 }
2452 
2458 {
2459  // See: https://github.com/ROCm-Developer-Tools/HIP/issues/2169
2460 #if defined(VISKORES_CUDA) || defined(VISKORES_HIP)
2461  return VISKORES_CUDA_MATH_FUNCTION_32(modf)(x, &integral);
2462 #else
2463  return std::modf(x, &integral);
2464 #endif
2465 }
2467 {
2468 #if defined(VISKORES_CUDA)
2469  return VISKORES_CUDA_MATH_FUNCTION_64(modf)(x, &integral);
2470 #else
2471  return std::modf(x, &integral);
2472 #endif
2473 }
2475 
2476 //-----------------------------------------------------------------------------
2482 {
2483  return abs(x);
2484 }
2486 {
2487 #if VISKORES_SIZE_LONG == 8
2488  return labs(x);
2489 #elif VISKORES_SIZE_LONG_LONG == 8
2490  return llabs(x);
2491 #else
2492 #error Unknown size of Int64.
2493 #endif
2494 }
2496 {
2497 #ifdef VISKORES_CUDA
2498  return VISKORES_CUDA_MATH_FUNCTION_32(fabs)(x);
2499 #else
2500  return std::fabs(x);
2501 #endif
2502 }
2504 {
2505 #ifdef VISKORES_CUDA
2506  return VISKORES_CUDA_MATH_FUNCTION_64(fabs)(x);
2507 #else
2508  return std::fabs(x);
2509 #endif
2510 }
2511 template <typename T>
2512 static inline VISKORES_EXEC_CONT typename detail::FloatingPointReturnType<T>::Type Abs(T x)
2513 {
2514 #ifdef VISKORES_CUDA
2515  return VISKORES_CUDA_MATH_FUNCTION_64(fabs)(static_cast<viskores::Float64>(x));
2516 #else
2517  return std::fabs(static_cast<viskores::Float64>(x));
2518 #endif
2519 }
2520 template <typename T, viskores::IdComponent N>
2522 {
2523  viskores::Vec<T, N> result;
2524  for (viskores::IdComponent index = 0; index < N; index++)
2525  {
2526  result[index] = viskores::Abs(x[index]);
2527  }
2528  return result;
2529 }
2530 template <typename T>
2532 {
2533  return viskores::Vec<T, 4>(viskores::Abs(x[0]), viskores::Abs(x[1]), viskores::Abs(x[2]), viskores::Abs(x[3]));
2534 }
2535 template <typename T>
2537 {
2538  return viskores::Vec<T, 3>(viskores::Abs(x[0]), viskores::Abs(x[1]), viskores::Abs(x[2]));
2539 }
2540 template <typename T>
2542 {
2543  return viskores::Vec<T, 2>(viskores::Abs(x[0]), viskores::Abs(x[1]));
2544 }
2546 
2550 static inline VISKORES_EXEC_CONT viskores::Int32 SignBit(viskores::Float32 x)
2551 {
2552 #ifndef VISKORES_CUDA
2553  using std::signbit;
2554 #endif
2555  return static_cast<viskores::Int32>(signbit(x));
2556 }
2557 static inline VISKORES_EXEC_CONT viskores::Int32 SignBit(viskores::Float64 x)
2558 {
2559 #ifndef VISKORES_CUDA
2560  using std::signbit;
2561 #endif
2562  return static_cast<viskores::Int32>(signbit(x));
2563 }
2565 
2569 static inline VISKORES_EXEC_CONT bool IsNegative(viskores::Float32 x)
2570 {
2571  return (viskores::SignBit(x) != 0);
2572 }
2573 static inline VISKORES_EXEC_CONT bool IsNegative(viskores::Float64 x)
2574 {
2575  return (viskores::SignBit(x) != 0);
2576 }
2578 
2584 {
2585 #ifdef VISKORES_CUDA
2586  return VISKORES_CUDA_MATH_FUNCTION_32(copysign)(x, y);
2587 #else
2588  return std::copysign(x, y);
2589 #endif
2590 }
2592 {
2593 #ifdef VISKORES_CUDA
2594  return VISKORES_CUDA_MATH_FUNCTION_64(copysign)(x, y);
2595 #else
2596  return std::copysign(x, y);
2597 #endif
2598 }
2599 
2600 template <typename T, viskores::IdComponent N>
2601 static inline VISKORES_EXEC_CONT viskores::Vec<T, N> CopySign(const viskores::Vec<T, N>& x,
2602  const viskores::Vec<T, N>& y)
2603 {
2604  viskores::Vec<T, N> result;
2605  for (viskores::IdComponent index = 0; index < N; index++)
2606  {
2607  result[index] = viskores::CopySign(x[index], y[index]);
2608  }
2609  return result;
2610 }
2612 
2617 {
2618  // See: https://github.com/ROCm-Developer-Tools/HIP/issues/2169
2619 #if defined(VISKORES_CUDA) || defined(VISKORES_HIP)
2620  return VISKORES_CUDA_MATH_FUNCTION_32(frexp)(x, exponent);
2621 #else
2622  return std::frexp(x, exponent);
2623 #endif
2624 }
2625 
2627 {
2628 #ifdef VISKORES_CUDA
2629  return VISKORES_CUDA_MATH_FUNCTION_64(frexp)(x, exponent);
2630 #else
2631  return std::frexp(x, exponent);
2632 #endif
2633 }
2635 
2637 {
2638 #ifdef VISKORES_CUDA
2639  return VISKORES_CUDA_MATH_FUNCTION_32(ldexp)(x, exponent);
2640 #else
2641  return std::ldexp(x, exponent);
2642 #endif
2643 }
2644 
2646 {
2647 #ifdef VISKORES_CUDA
2648  return VISKORES_CUDA_MATH_FUNCTION_64(ldexp)(x, exponent);
2649 #else
2650  return std::ldexp(x, exponent);
2651 #endif
2652 }
2653 
2655 // Float distance.
2656 // See: https://randomascii.wordpress.com/2012/01/23/stupid-float-tricks-2/ for why this works.
2657 
2658 namespace detail
2659 {
2660 
2662 {
2663  VISKORES_ASSERT(x >= 0);
2664  VISKORES_ASSERT(y >= 0);
2665 
2666  // Note that:
2667  // int64_t xi = *reinterpret_cast<int64_t*>(&x);
2668  // int64_t yi = *reinterpret_cast<int64_t*>(&y);
2669  // also works (usually), but generates warnings because it is technically undefined behavior
2670  // according to the C++ standard.
2671  // Good option to have if we get compile errors off memcpy or don't want to #include <cstring> though.
2672  // At least on gcc, both versions generate the same assembly.
2673  viskores::UInt64 xi;
2674  viskores::UInt64 yi;
2675  memcpy(&xi, &x, sizeof(viskores::UInt64));
2676  memcpy(&yi, &y, sizeof(viskores::UInt64));
2677  if (yi > xi) {
2678  return yi - xi;
2679  }
2680  return xi - yi;
2681 }
2682 
2683 
2685 {
2686  VISKORES_ASSERT(x >= 0);
2687  VISKORES_ASSERT(y >= 0);
2688 
2689  viskores::UInt32 xi_32;
2690  viskores::UInt32 yi_32;
2691  memcpy(&xi_32, &x, sizeof(viskores::UInt32));
2692  memcpy(&yi_32, &y, sizeof(viskores::UInt32));
2693  viskores::UInt64 xi = xi_32;
2694  viskores::UInt64 yi = yi_32;
2695  if (yi > xi) {
2696  return yi - xi;
2697  }
2698  return xi - yi;
2699 }
2700 
2701 } // namespace detail
2702 
2707 {
2708  static_assert(sizeof(viskores::Float64) == sizeof(viskores::UInt64), "viskores::Float64 is incorrect size.");
2709  static_assert(std::numeric_limits<viskores::Float64>::has_denorm == std::denorm_present, "FloatDistance presumes the floating-point type has subnormal numbers.");
2710 
2711  if (!viskores::IsFinite(x) || !viskores::IsFinite(y)) {
2712  return 0xFFFFFFFFFFFFFFFFL;
2713  }
2714 
2715  // Signed zero is the sworn enemy of this process.
2716  if (y == 0) {
2717  y = viskores::Abs(y);
2718  }
2719  if (x == 0) {
2720  x = viskores::Abs(x);
2721  }
2722 
2723  if ( (x < 0 && y >= 0) || (x >= 0 && y < 0) )
2724  {
2725  viskores::UInt64 dx, dy;
2726  if (x < 0) {
2727  dy = detail::FloatDistancePositive(0.0, y);
2728  dx = detail::FloatDistancePositive(0.0, -x);
2729  }
2730  else {
2731  dy = detail::FloatDistancePositive(0.0, -y);
2732  dx = detail::FloatDistancePositive(0.0, x);
2733  }
2734 
2735  return dx + dy;
2736  }
2737 
2738  if (x < 0 && y < 0) {
2739  return detail::FloatDistancePositive(-x, -y);
2740  }
2741 
2742  return detail::FloatDistancePositive(x, y);
2743 }
2744 
2747 {
2748  static_assert(sizeof(viskores::Float32) == sizeof(viskores::Int32), "viskores::Float32 is incorrect size.");
2749  static_assert(std::numeric_limits<viskores::Float32>::has_denorm == std::denorm_present, "FloatDistance presumes the floating-point type has subnormal numbers.");
2750 
2751  if (!viskores::IsFinite(x) || !viskores::IsFinite(y)) {
2752  return 0xFFFFFFFFFFFFFFFFL;
2753  }
2754 
2755  if (y == 0) {
2756  y = viskores::Abs(y);
2757  }
2758  if (x == 0) {
2759  x = viskores::Abs(x);
2760  }
2761 
2762  if ( (x < 0 && y >= 0) || (x >= 0 && y < 0) )
2763  {
2764  viskores::UInt64 dx, dy;
2765  if (x < 0) {
2766  dy = detail::FloatDistancePositive(0.0f, y);
2767  dx = detail::FloatDistancePositive(0.0f, -x);
2768  }
2769  else {
2770  dy = detail::FloatDistancePositive(0.0f, -y);
2771  dx = detail::FloatDistancePositive(0.0f, x);
2772  }
2773  return dx + dy;
2774  }
2775 
2776  if (x < 0 && y < 0) {
2777  return detail::FloatDistancePositive(-x, -y);
2778  }
2779 
2780  return detail::FloatDistancePositive(x, y);
2781 }
2782 
2783 // Computes ab - cd.
2784 // See: https://pharr.org/matt/blog/2019/11/03/difference-of-floats.html
2785 template<typename T>
2786 inline VISKORES_EXEC_CONT T DifferenceOfProducts(T a, T b, T c, T d)
2787 {
2788  T cd = c * d;
2789  T err = std::fma(-c, d, cd);
2790  T dop = std::fma(a, b, -cd);
2791  return dop + err;
2792 }
2793 
2802 template<typename T>
2804 {
2805  if (a == 0)
2806  {
2807  if (b == 0)
2808  {
2809  if (c == 0)
2810  {
2811  // A degenerate case. All real numbers are roots; hopefully this arbitrary decision interacts gracefully with use.
2812  return viskores::Vec<T,2>(0,0);
2813  }
2814  else
2815  {
2816  return viskores::Vec<T,2>(viskores::Nan<T>(), viskores::Nan<T>());
2817  }
2818  }
2819  return viskores::Vec<T,2>(-c/b, -c/b);
2820  }
2821  T delta = DifferenceOfProducts(b, b, 4*a, c);
2822  if (delta < 0)
2823  {
2824  return viskores::Vec<T,2>(viskores::Nan<T>(), viskores::Nan<T>());
2825  }
2826 
2827  T q = -(b + viskores::CopySign(viskores::Sqrt(delta), b)) / 2;
2828  T r0 = q / a;
2829  T r1 = c / q;
2830  if (r0 < r1)
2831  {
2832  return viskores::Vec<T,2>(r0, r1);
2833  }
2834  return viskores::Vec<T,2>(r1, r0);
2835 }
2836 
2839 
2842 #ifdef VISKORES_CUDA_DEVICE_PASS
2843 // Need to explicitly mark this as __device__ since __ffs is device only.
2844 inline __device__
2846 {
2847  // Output is [0,32], with ffs(0) == 0
2848  return __ffs(static_cast<int>(word));
2849 }
2850 #else // CUDA_DEVICE_PASS
2851 inline VISKORES_EXEC_CONT
2853 {
2854 # if defined(VISKORES_GCC) || defined(VISKORES_CLANG)
2855 
2856  // Output is [0,32], with ffs(0) == 0
2857  return __builtin_ffs(static_cast<int>(word));
2858 
2859 # elif defined(VISKORES_MSVC)
2860 
2861  // Output is [0, 31], check return code to see if bits are set:
2862  viskores::UInt32 firstSet;
2863  return _BitScanForward(reinterpret_cast<DWORD*>(&firstSet), word) != 0
2864  ? static_cast<viskores::Int32>(firstSet + 1) : 0;
2865 
2866 # elif defined(VISKORES_ICC)
2867 
2868  // Output is [0, 31], undefined if word is 0.
2869  return word != 0 ? _bit_scan_forward(word) + 1 : 0;
2870 
2871 # else
2872 
2873  // Naive implementation:
2874  if (word == 0)
2875  {
2876  return 0;
2877  }
2878 
2879  viskores::Int32 bit = 1;
2880  while ((word & 0x1) == 0)
2881  {
2882  word >>= 1;
2883  ++bit;
2884  }
2885  return bit;
2886 
2887 # endif
2888 }
2889 #endif // CUDA_DEVICE_PASS
2890 
2893 #ifdef VISKORES_CUDA_DEVICE_PASS
2894 // Need to explicitly mark this as __device__ since __ffsll is device only.
2895 inline __device__
2897 {
2898 
2899  // Output is [0,64], with ffs(0) == 0
2900  return __ffsll(static_cast<long long int>(word));
2901 }
2902 #else // CUDA_DEVICE_PASS
2903 inline VISKORES_EXEC_CONT
2905 {
2906 # if defined(VISKORES_GCC) || defined(VISKORES_CLANG) || defined(VISKORES_ICC)
2907 
2908  // Output is [0,64], with ffs(0) == 0
2909  return __builtin_ffsll(static_cast<long long int>(word));
2910 
2911 # elif defined(VISKORES_MSVC)
2912 
2913  // Output is [0, 63], check return code to see if bits are set:
2914  viskores::UInt32 firstSet;
2915  return _BitScanForward64(reinterpret_cast<DWORD*>(&firstSet), word) != 0
2916  ? static_cast<viskores::Int32>(firstSet + 1) : 0;
2917 
2918 # else
2919 
2920  // Naive implementation:
2921  if (word == 0)
2922  {
2923  return 0;
2924  }
2925 
2926  viskores::Int32 bit = 1;
2927  while ((word & 0x1) == 0)
2928  {
2929  word >>= 1;
2930  ++bit;
2931  }
2932  return bit;
2933 
2934 # endif
2935 }
2936 #endif // CUDA_DEVICE_PASS
2937 
2939 #ifdef VISKORES_CUDA_DEVICE_PASS
2940 // Need to explicitly mark this as __device__ since __popc is device only.
2941 inline __device__
2943 {
2944  return __popc(word);
2945 }
2946 #else // CUDA_DEVICE_PASS
2947 inline VISKORES_EXEC_CONT
2949 {
2950 # if defined(VISKORES_GCC) || defined(VISKORES_CLANG)
2951 
2952  return __builtin_popcount(word);
2953 
2954 # elif defined(VISKORES_MSVC) && !defined(_M_ARM64)
2955 
2956  return static_cast<viskores::Int32>(__popcnt(word));
2957 
2958 # elif defined(VISKORES_ICC)
2959 
2960  return _popcnt32(static_cast<int>(word));
2961 
2962 # else
2963 
2964  // Naive implementation:
2965  viskores::Int32 bits = 0;
2966  while (word)
2967  {
2968  if (word & 0x1)
2969  {
2970  ++bits;
2971  }
2972  word >>= 1;
2973  }
2974  return bits;
2975 
2976 # endif
2977 }
2978 #endif // CUDA_DEVICE_PASS
2979 
2981 #ifdef VISKORES_CUDA_DEVICE_PASS
2982 // Need to explicitly mark this as __device__ since __popcll is device only.
2983 inline __device__
2985 {
2986  return __popcll(word);
2987 }
2988 #else // CUDA_DEVICE_PASS
2989 inline VISKORES_EXEC_CONT
2991 {
2992 # if defined(VISKORES_GCC) || defined(VISKORES_CLANG)
2993 
2994  return __builtin_popcountll(word);
2995 
2996 # elif defined(VISKORES_MSVC) && !defined(_M_ARM64)
2997 
2998  return static_cast<viskores::Int32>(__popcnt64(word));
2999 
3000 # elif defined(VISKORES_ICC)
3001 
3002  return _popcnt64(static_cast<viskores::Int64>(word));
3003 
3004 # else
3005 
3006  // Naive implementation:
3007  viskores::Int32 bits = 0;
3008  while (word)
3009  {
3010  if (word & 0x1)
3011  {
3012  ++bits;
3013  }
3014  word >>= 1;
3015  }
3016  return bits;
3017 
3018 # endif
3019 }
3020 #endif // CUDA_DEVICE_PASS
3021 
3022 } // namespace viskores
3023 // clang-format on
3024 
3025 #endif //viskores_Math_h
viskores::Log1P
viskores::Float32 Log1P(viskores::Float32 x)
Definition: Math.h:1647
viskores::QuadraticRoots
viskores::Vec< T, 2 > QuadraticRoots(T a, T b, T c)
Solves ax² + bx + c = 0.
Definition: Math.h:2803
viskores::Exp2
viskores::Float32 Exp2(viskores::Float32 x)
Definition: Math.h:1274
viskores::SinH
viskores::Float32 SinH(viskores::Float32 x)
Definition: Math.h:562
Types.h
viskores::FloatDistance
viskores::UInt64 FloatDistance(viskores::Float64 x, viskores::Float64 y)
Computes the number of representables between two floating point numbers.
Definition: Math.h:2706
viskores::ACos
viskores::Float32 ACos(viskores::Float32 x)
Definition: Math.h:418
viskores::ASin
viskores::Float32 ASin(viskores::Float32 x)
Definition: Math.h:357
viskores::ExpM1
viskores::Float32 ExpM1(viskores::Float32 x)
Definition: Math.h:1336
viskores::Ceil
viskores::Float32 Ceil(viskores::Float32 x)
Definition: Math.h:2177
viskores::IdComponent
viskores::Int32 IdComponent
Base type to use to index small lists.
Definition: Types.h:202
viskores::Sin
viskores::Float32 Sin(viskores::Float32 x)
Definition: Math.h:174
viskores::FindFirstSetBit
viskores::Int32 FindFirstSetBit(viskores::UInt32 word)
Bitwise operations.
Definition: Math.h:2852
viskores::TanH
viskores::Float32 TanH(viskores::Float32 x)
Definition: Math.h:684
VISKORES_EXEC_CONT
#define VISKORES_EXEC_CONT
Definition: ExportMacros.h:60
viskores::ATan
viskores::Float32 ATan(viskores::Float32 x)
Definition: Math.h:479
VISKORES_NEG_INF_BITS_32
#define VISKORES_NEG_INF_BITS_32
Definition: Math.h:1863
viskores::Sqrt
viskores::Float32 Sqrt(viskores::Float32 x)
Definition: Math.h:951
viskores::Vec< T, 3 >
Definition: Types.h:1025
VISKORES_INF_BITS_32
#define VISKORES_INF_BITS_32
Definition: Math.h:1862
viskores::Round
viskores::Float32 Round(viskores::Float32 x)
Definition: Math.h:2299
viskores::Vec< T, 2 >
Definition: Types.h:909
viskores::ASinH
viskores::Float32 ASinH(viskores::Float32 x)
Definition: Math.h:745
viskores::Int64
signed long long Int64
Base type to use for 64-bit signed integer numbers.
Definition: Types.h:212
viskores::TypeTraitsScalarTag
Tag used to identify 0 dimensional types (scalars).
Definition: TypeTraits.h:52
VISKORES_EPSILON_32
#define VISKORES_EPSILON_32
Definition: Math.h:1864
VISKORES_CUDA_MATH_FUNCTION_32
#define VISKORES_CUDA_MATH_FUNCTION_32(func)
Definition: Math.h:50
TypeTraits.h
viskores::Cbrt
viskores::Float32 Cbrt(viskores::Float32 x)
Definition: Math.h:1082
viskores::Exp
viskores::Float32 Exp(viskores::Float32 x)
Definition: Math.h:1213
viskores
Groups connected points that have the same field value.
Definition: Atomic.h:27
viskores::CosH
viskores::Float32 CosH(viskores::Float32 x)
Definition: Math.h:623
viskores::TypeTraitsUnknownTag
Tag used to identify types that aren't Real, Integer, Scalar or Vector.
Definition: TypeTraits.h:28
viskores::ACosH
viskores::Float32 ACosH(viskores::Float32 x)
Definition: Math.h:806
viskores::Float32
float Float32
Base type to use for 32-bit floating-point numbers.
Definition: Types.h:165
viskores::VecTraits
Traits that can be queried to treat any type as a Vec.
Definition: VecTraits.h:69
viskores::DifferenceOfProducts
T DifferenceOfProducts(T a, T b, T c, T d)
Definition: Math.h:2786
viskores::CountSetBits
viskores::Int32 CountSetBits(viskores::UInt32 word)
Count the total number of bits set in word.
Definition: Math.h:2948
viskores::Clamp
viskores::Float32 Clamp(viskores::Float32 x, viskores::Float32 lo, viskores::Float32 hi)
Definition: Math.h:1835
viskores::Frexp
viskores::Float32 Frexp(viskores::Float32 x, viskores::Int32 *exponent)
Definition: Math.h:2616
viskores::Log10
viskores::Float32 Log10(viskores::Float32 x)
Definition: Math.h:1586
VISKORES_NAN_BITS_32
#define VISKORES_NAN_BITS_32
Definition: Math.h:1861
VISKORES_ASSERT
#define VISKORES_ASSERT(condition)
Definition: Assert.h:51
VISKORES_NEG_INF_BITS_64
#define VISKORES_NEG_INF_BITS_64
Definition: Math.h:1872
VISKORES_NAN_BITS_64
#define VISKORES_NAN_BITS_64
Definition: Math.h:1870
viskores::Tan
viskores::Float32 Tan(viskores::Float32 x)
Definition: Math.h:296
viskores::ATanH
viskores::Float32 ATanH(viskores::Float32 x)
Definition: Math.h:867
viskores::Cos
viskores::Float32 Cos(viskores::Float32 x)
Definition: Math.h:235
viskores::UInt64
unsigned long long UInt64
Base type to use for 64-bit signed integer numbers.
Definition: Types.h:215
viskores::Vec< T, 4 >
Definition: Types.h:1143
viskores::Int32
int32_t Int32
Base type to use for 32-bit signed integer numbers.
Definition: Types.h:189
viskores::Log
viskores::Float32 Log(viskores::Float32 x)
Definition: Math.h:1464
viskores::VecTraits::ComponentType
T ComponentType
Type of the components in the vector.
Definition: VecTraits.h:79
viskores::Log2
viskores::Float32 Log2(viskores::Float32 x)
Definition: Math.h:1525
VISKORES_CUDA_MATH_FUNCTION_64
#define VISKORES_CUDA_MATH_FUNCTION_64(func)
Definition: Math.h:51
viskores::Floor
viskores::Float32 Floor(viskores::Float32 x)
Definition: Math.h:2238
VISKORES_INF_BITS_64
#define VISKORES_INF_BITS_64
Definition: Math.h:1871
viskores::Float64
double Float64
Base type to use for 64-bit floating-point numbers.
Definition: Types.h:169
viskores::TypeTraitsVectorTag
Tag used to identify 1 dimensional types (vectors).
Definition: TypeTraits.h:59
viskores::Vec
A short fixed-length array.
Definition: Types.h:365
Windows.h
viskores::UInt32
uint32_t UInt32
Base type to use for 32-bit unsigned integer numbers.
Definition: Types.h:193
VecTraits.h
VISKORES_EPSILON_64
#define VISKORES_EPSILON_64
Definition: Math.h:1873
viskores::Ldexp
viskores::Float32 Ldexp(viskores::Float32 x, viskores::Int32 exponent)
Definition: Math.h:2636