16 #ifndef KOKKOS_COMPLEX_HPP
17 #define KOKKOS_COMPLEX_HPP
18 #ifndef KOKKOS_IMPL_PUBLIC_INCLUDE
19 #define KOKKOS_IMPL_PUBLIC_INCLUDE
20 #define KOKKOS_IMPL_PUBLIC_INCLUDE_NOTDEFINED_COMPLEX
23 #include <Kokkos_Atomic.hpp>
24 #include <Kokkos_MathematicalFunctions.hpp>
25 #include <Kokkos_NumericTraits.hpp>
26 #include <Kokkos_ReductionIdentity.hpp>
27 #include <impl/Kokkos_Error.hpp>
29 #include <type_traits>
42 template <
class RealType>
44 #ifdef KOKKOS_ENABLE_COMPLEX_ALIGN
45 alignas(2 *
sizeof(RealType))
48 static_assert(std::is_floating_point_v<RealType> &&
49 std::is_same_v<RealType, std::remove_cv_t<RealType>>,
50 "Kokkos::complex can only be instantiated for a cv-unqualified "
51 "floating point type");
59 using value_type = RealType;
62 KOKKOS_DEFAULTED_FUNCTION
66 KOKKOS_DEFAULTED_FUNCTION
67 complex(
const complex&) noexcept = default;
69 KOKKOS_DEFAULTED_FUNCTION
70 complex& operator=(const complex&) noexcept = default;
73 template <class RType,
74 std::enable_if_t<std::is_convertible_v<RType, RealType>,
int> = 0>
75 KOKKOS_INLINE_FUNCTION complex(const complex<RType>& other) noexcept
79 : re_(other.real()), im_(other.imag()) {}
86 KOKKOS_INLINE_FUNCTION
87 complex(
const std::complex<RealType>& src) noexcept
94 : re_(
reinterpret_cast<const RealType (&)[2]
>(src)[0]),
95 im_(
reinterpret_cast<const RealType (&)[2]
>(src)[1]) {}
103 operator std::complex<RealType>()
const noexcept {
104 return std::complex<RealType>(re_, im_);
109 KOKKOS_INLINE_FUNCTION complex(
const RealType& val) noexcept
110 : re_(val), im_(static_cast<RealType>(0)) {}
113 KOKKOS_INLINE_FUNCTION
114 complex(
const RealType& re,
const RealType& im) noexcept : re_(re), im_(im) {}
117 KOKKOS_INLINE_FUNCTION complex& operator=(
const RealType& val) noexcept {
128 complex& operator=(
const std::complex<RealType>& src) noexcept {
129 *
this = complex(src);
134 KOKKOS_INLINE_FUNCTION
135 constexpr RealType& imag() noexcept {
return im_; }
138 KOKKOS_INLINE_FUNCTION
139 constexpr RealType& real() noexcept {
return re_; }
142 KOKKOS_INLINE_FUNCTION
143 constexpr RealType imag() const noexcept {
return im_; }
146 KOKKOS_INLINE_FUNCTION
147 constexpr RealType real() const noexcept {
return re_; }
150 KOKKOS_INLINE_FUNCTION
151 constexpr
void imag(RealType v) noexcept { im_ = v; }
154 KOKKOS_INLINE_FUNCTION
155 constexpr
void real(RealType v) noexcept { re_ = v; }
157 constexpr KOKKOS_INLINE_FUNCTION complex& operator+=(
158 const complex<RealType>& src) noexcept {
164 constexpr KOKKOS_INLINE_FUNCTION complex& operator+=(
165 const RealType& src) noexcept {
170 constexpr KOKKOS_INLINE_FUNCTION complex& operator-=(
171 const complex<RealType>& src) noexcept {
177 constexpr KOKKOS_INLINE_FUNCTION complex& operator-=(
178 const RealType& src) noexcept {
183 constexpr KOKKOS_INLINE_FUNCTION complex& operator*=(
184 const complex<RealType>& src) noexcept {
185 const RealType realPart = re_ * src.re_ - im_ * src.im_;
186 const RealType imagPart = re_ * src.im_ + im_ * src.re_;
192 constexpr KOKKOS_INLINE_FUNCTION complex& operator*=(
193 const RealType& src) noexcept {
200 constexpr KOKKOS_INLINE_FUNCTION complex& operator/=(
201 const complex<RealType>& y) noexcept(noexcept(RealType{} / RealType{})) {
205 const RealType s = fabs(y.real()) + fabs(y.imag());
211 if (s == RealType(0)) {
215 const complex x_scaled(this->re_ / s, this->im_ / s);
216 const complex y_conj_scaled(y.re_ / s, -(y.im_) / s);
217 const RealType y_scaled_abs =
218 y_conj_scaled.re_ * y_conj_scaled.re_ +
219 y_conj_scaled.im_ * y_conj_scaled.im_;
220 *
this = x_scaled * y_conj_scaled;
221 *
this /= y_scaled_abs;
226 constexpr KOKKOS_INLINE_FUNCTION complex& operator/=(
227 const std::complex<RealType>& y) noexcept(noexcept(RealType{} /
232 const RealType s = fabs(y.real()) + fabs(y.imag());
237 if (s == RealType(0)) {
241 const complex x_scaled(this->re_ / s, this->im_ / s);
242 const complex y_conj_scaled(y.re_ / s, -(y.im_) / s);
243 const RealType y_scaled_abs =
244 y_conj_scaled.re_ * y_conj_scaled.re_ +
245 y_conj_scaled.im_ * y_conj_scaled.im_;
246 *
this = x_scaled * y_conj_scaled;
247 *
this /= y_scaled_abs;
252 constexpr KOKKOS_INLINE_FUNCTION complex& operator/=(
253 const RealType& src) noexcept(noexcept(RealType{} / RealType{})) {
259 template <
size_t I,
typename RT>
260 friend constexpr
const RT&
get(
const complex<RT>&) noexcept;
262 template <
size_t I,
typename RT>
263 friend constexpr
const RT&&
get(
const complex<RT>&&) noexcept;
265 #ifdef KOKKOS_ENABLE_DEPRECATED_CODE_4
266 template <
class RType,
268 std::enable_if_t<std::is_convertible_v<RType, RealType>,
int> = 0>
269 KOKKOS_DEPRECATED KOKKOS_INLINE_FUNCTION
270 complex(
const volatile complex<RType>& src) noexcept
274 : re_(src.re_), im_(src.im_) {}
296 template <
class Complex,
297 std::enable_if_t<std::is_same_v<Complex, complex>,
int> = 0>
298 KOKKOS_DEPRECATED KOKKOS_INLINE_FUNCTION
void operator=(
299 const Complex& src)
volatile noexcept {
319 template <
class Complex,
320 std::enable_if_t<std::is_same_v<Complex, complex>,
int> = 0>
321 KOKKOS_DEPRECATED KOKKOS_INLINE_FUNCTION
volatile complex& operator=(
322 const volatile Complex& src)
volatile noexcept {
341 template <
class Complex,
342 std::enable_if_t<std::is_same_v<Complex, complex>,
int> = 0>
343 KOKKOS_DEPRECATED KOKKOS_INLINE_FUNCTION complex& operator=(
344 const volatile Complex& src) noexcept {
354 KOKKOS_DEPRECATED KOKKOS_INLINE_FUNCTION
void operator=(
355 const volatile RealType& val) noexcept {
363 KOKKOS_DEPRECATED KOKKOS_INLINE_FUNCTION complex& operator=(
364 const RealType& val)
volatile noexcept {
372 KOKKOS_DEPRECATED KOKKOS_INLINE_FUNCTION complex& operator=(
373 const volatile RealType& val)
volatile noexcept {
380 KOKKOS_DEPRECATED KOKKOS_INLINE_FUNCTION
volatile RealType&
381 imag() volatile noexcept {
386 KOKKOS_DEPRECATED KOKKOS_INLINE_FUNCTION
volatile RealType&
387 real() volatile noexcept {
392 KOKKOS_DEPRECATED KOKKOS_INLINE_FUNCTION RealType imag() const
398 KOKKOS_DEPRECATED KOKKOS_INLINE_FUNCTION RealType real() const
403 KOKKOS_DEPRECATED KOKKOS_INLINE_FUNCTION
void operator+=(
404 const volatile complex<RealType>& src)
volatile noexcept {
409 KOKKOS_DEPRECATED KOKKOS_INLINE_FUNCTION
void operator+=(
410 const volatile RealType& src)
volatile noexcept {
414 KOKKOS_DEPRECATED KOKKOS_INLINE_FUNCTION
void operator*=(
415 const volatile complex<RealType>& src)
volatile noexcept {
416 const RealType realPart = re_ * src.re_ - im_ * src.im_;
417 const RealType imagPart = re_ * src.im_ + im_ * src.re_;
423 KOKKOS_DEPRECATED KOKKOS_INLINE_FUNCTION
void operator*=(
424 const volatile RealType& src)
volatile noexcept {
428 #endif // KOKKOS_ENABLE_DEPRECATED_CODE_4
436 template <
typename RealType>
437 struct std::tuple_size<Kokkos::complex<RealType>>
438 : std::integral_constant<size_t, 2> {};
440 template <
size_t I,
typename RealType>
441 struct std::tuple_element<I, Kokkos::complex<RealType>> {
442 static_assert(I < 2);
443 using type = RealType;
450 template <
size_t I,
typename RealType>
451 KOKKOS_FUNCTION constexpr RealType&
get(complex<RealType>& z) noexcept {
452 static_assert(I < 2);
453 if constexpr (I == 0)
457 #ifdef KOKKOS_COMPILER_INTEL
458 __builtin_unreachable();
462 template <
size_t I,
typename RealType>
463 KOKKOS_FUNCTION constexpr RealType&&
get(complex<RealType>&& z) noexcept {
464 static_assert(I < 2);
465 if constexpr (I == 0)
466 return std::move(z.real());
468 return std::move(z.imag());
469 #ifdef KOKKOS_COMPILER_INTEL
470 __builtin_unreachable();
474 template <
size_t I,
typename RealType>
475 KOKKOS_FUNCTION constexpr
const RealType&
get(
476 const complex<RealType>& z) noexcept {
477 static_assert(I < 2);
478 if constexpr (I == 0)
482 #ifdef KOKKOS_COMPILER_INTEL
483 __builtin_unreachable();
487 template <
size_t I,
typename RealType>
488 KOKKOS_FUNCTION constexpr
const RealType&&
get(
489 const complex<RealType>&& z) noexcept {
490 static_assert(I < 2);
491 if constexpr (I == 0)
492 return std::move(z.re_);
494 return std::move(z.im_);
495 #ifdef KOKKOS_COMPILER_INTEL
496 __builtin_unreachable();
508 template <
class RealType1,
class RealType2>
509 KOKKOS_INLINE_FUNCTION
bool operator==(complex<RealType1>
const& x,
510 complex<RealType2>
const& y) noexcept {
511 using common_type = std::common_type_t<RealType1, RealType2>;
512 return common_type(x.real()) == common_type(y.real()) &&
513 common_type(x.imag()) == common_type(y.imag());
519 template <
class RealType1,
class RealType2>
520 inline bool operator==(std::complex<RealType1>
const& x,
521 complex<RealType2>
const& y) noexcept {
522 using common_type = std::common_type_t<RealType1, RealType2>;
523 return common_type(x.real()) == common_type(y.real()) &&
524 common_type(x.imag()) == common_type(y.imag());
528 template <
class RealType1,
class RealType2>
529 inline bool operator==(complex<RealType1>
const& x,
530 std::complex<RealType2>
const& y) noexcept {
531 using common_type = std::common_type_t<RealType1, RealType2>;
532 return common_type(x.real()) == common_type(y.real()) &&
533 common_type(x.imag()) == common_type(y.imag());
538 class RealType1,
class RealType2,
540 std::enable_if_t<std::is_convertible_v<RealType2, RealType1>,
int> = 0>
541 KOKKOS_INLINE_FUNCTION
bool operator==(complex<RealType1>
const& x,
542 RealType2
const& y) noexcept {
543 using common_type = std::common_type_t<RealType1, RealType2>;
544 return common_type(x.real()) == common_type(y) &&
545 common_type(x.imag()) == common_type(0);
550 class RealType1,
class RealType2,
552 std::enable_if_t<std::is_convertible_v<RealType1, RealType2>,
int> = 0>
553 KOKKOS_INLINE_FUNCTION
bool operator==(RealType1
const& x,
554 complex<RealType2>
const& y) noexcept {
555 using common_type = std::common_type_t<RealType1, RealType2>;
556 return common_type(x) == common_type(y.real()) &&
557 common_type(0) == common_type(y.imag());
561 template <
class RealType1,
class RealType2>
562 KOKKOS_INLINE_FUNCTION
bool operator!=(complex<RealType1>
const& x,
563 complex<RealType2>
const& y) noexcept {
564 using common_type = std::common_type_t<RealType1, RealType2>;
565 return common_type(x.real()) != common_type(y.real()) ||
566 common_type(x.imag()) != common_type(y.imag());
570 template <
class RealType1,
class RealType2>
571 inline bool operator!=(std::complex<RealType1>
const& x,
572 complex<RealType2>
const& y) noexcept {
573 using common_type = std::common_type_t<RealType1, RealType2>;
574 return common_type(x.real()) != common_type(y.real()) ||
575 common_type(x.imag()) != common_type(y.imag());
579 template <
class RealType1,
class RealType2>
580 inline bool operator!=(complex<RealType1>
const& x,
581 std::complex<RealType2>
const& y) noexcept {
582 using common_type = std::common_type_t<RealType1, RealType2>;
583 return common_type(x.real()) != common_type(y.real()) ||
584 common_type(x.imag()) != common_type(y.imag());
589 class RealType1,
class RealType2,
591 std::enable_if_t<std::is_convertible_v<RealType2, RealType1>,
int> = 0>
592 KOKKOS_INLINE_FUNCTION
bool operator!=(complex<RealType1>
const& x,
593 RealType2
const& y) noexcept {
594 using common_type = std::common_type_t<RealType1, RealType2>;
595 return common_type(x.real()) != common_type(y) ||
596 common_type(x.imag()) != common_type(0);
601 class RealType1,
class RealType2,
603 std::enable_if_t<std::is_convertible_v<RealType1, RealType2>,
int> = 0>
604 KOKKOS_INLINE_FUNCTION
bool operator!=(RealType1
const& x,
605 complex<RealType2>
const& y) noexcept {
606 using common_type = std::common_type_t<RealType1, RealType2>;
607 return common_type(x) != common_type(y.real()) ||
608 common_type(0) != common_type(y.imag());
615 template <
class RealType1,
class RealType2>
616 KOKKOS_INLINE_FUNCTION complex<std::common_type_t<RealType1, RealType2>>
617 operator+(
const complex<RealType1>& x,
const complex<RealType2>& y) noexcept {
618 return complex<std::common_type_t<RealType1, RealType2>>(x.real() + y.real(),
619 x.imag() + y.imag());
623 template <
class RealType1,
class RealType2>
624 KOKKOS_INLINE_FUNCTION complex<std::common_type_t<RealType1, RealType2>>
625 operator+(
const complex<RealType1>& x,
const RealType2& y) noexcept {
626 return complex<std::common_type_t<RealType1, RealType2>>(x.real() + y,
631 template <
class RealType1,
class RealType2>
632 KOKKOS_INLINE_FUNCTION complex<std::common_type_t<RealType1, RealType2>>
633 operator+(
const RealType1& x,
const complex<RealType2>& y) noexcept {
634 return complex<std::common_type_t<RealType1, RealType2>>(x + y.real(),
639 template <
class RealType>
640 KOKKOS_INLINE_FUNCTION complex<RealType> operator+(
641 const complex<RealType>& x) noexcept {
642 return complex<RealType>{+x.real(), +x.imag()};
646 template <
class RealType1,
class RealType2>
647 KOKKOS_INLINE_FUNCTION complex<std::common_type_t<RealType1, RealType2>>
648 operator-(
const complex<RealType1>& x,
const complex<RealType2>& y) noexcept {
649 return complex<std::common_type_t<RealType1, RealType2>>(x.real() - y.real(),
650 x.imag() - y.imag());
654 template <
class RealType1,
class RealType2>
655 KOKKOS_INLINE_FUNCTION complex<std::common_type_t<RealType1, RealType2>>
656 operator-(
const complex<RealType1>& x,
const RealType2& y) noexcept {
657 return complex<std::common_type_t<RealType1, RealType2>>(x.real() - y,
662 template <
class RealType1,
class RealType2>
663 KOKKOS_INLINE_FUNCTION complex<std::common_type_t<RealType1, RealType2>>
664 operator-(
const RealType1& x,
const complex<RealType2>& y) noexcept {
665 return complex<std::common_type_t<RealType1, RealType2>>(x - y.real(),
670 template <
class RealType>
671 KOKKOS_INLINE_FUNCTION complex<RealType> operator-(
672 const complex<RealType>& x) noexcept {
673 return complex<RealType>(-x.real(), -x.imag());
677 template <
class RealType1,
class RealType2>
678 KOKKOS_INLINE_FUNCTION complex<std::common_type_t<RealType1, RealType2>>
679 operator*(
const complex<RealType1>& x,
const complex<RealType2>& y) noexcept {
680 return complex<std::common_type_t<RealType1, RealType2>>(
681 x.real() * y.real() - x.imag() * y.imag(),
682 x.real() * y.imag() + x.imag() * y.real());
693 template <
class RealType1,
class RealType2>
694 inline complex<std::common_type_t<RealType1, RealType2>> operator*(
695 const std::complex<RealType1>& x,
const complex<RealType2>& y) {
696 return complex<std::common_type_t<RealType1, RealType2>>(
697 x.real() * y.real() - x.imag() * y.imag(),
698 x.real() * y.imag() + x.imag() * y.real());
705 template <
class RealType1,
class RealType2>
706 KOKKOS_INLINE_FUNCTION complex<std::common_type_t<RealType1, RealType2>>
707 operator*(
const RealType1& x,
const complex<RealType2>& y) noexcept {
708 return complex<std::common_type_t<RealType1, RealType2>>(x * y.real(),
716 template <
class RealType1,
class RealType2>
717 KOKKOS_INLINE_FUNCTION complex<std::common_type_t<RealType1, RealType2>>
718 operator*(
const complex<RealType1>& y,
const RealType2& x) noexcept {
719 return complex<std::common_type_t<RealType1, RealType2>>(x * y.real(),
724 template <
class RealType>
725 KOKKOS_INLINE_FUNCTION RealType imag(
const complex<RealType>& x) noexcept {
729 template <
class ArithmeticType>
730 KOKKOS_INLINE_FUNCTION constexpr Impl::promote_t<ArithmeticType> imag(
732 return ArithmeticType();
736 template <
class RealType>
737 KOKKOS_INLINE_FUNCTION RealType real(
const complex<RealType>& x) noexcept {
741 template <
class ArithmeticType>
742 KOKKOS_INLINE_FUNCTION constexpr Impl::promote_t<ArithmeticType> real(
749 KOKKOS_INLINE_FUNCTION complex<T> polar(
const T& r,
const T& theta = T()) {
750 KOKKOS_EXPECTS(r >= 0);
751 return complex<T>(r * cos(theta), r * sin(theta));
755 template <
class RealType>
756 KOKKOS_INLINE_FUNCTION RealType abs(
const complex<RealType>& x) {
757 return hypot(x.real(), x.imag());
762 KOKKOS_INLINE_FUNCTION complex<T> pow(
const complex<T>& x,
const T& y) {
764 T theta = atan2(x.imag(), x.real());
765 return polar(pow(r, y), y * theta);
769 KOKKOS_INLINE_FUNCTION complex<T> pow(
const T& x,
const complex<T>& y) {
770 return pow(complex<T>(x), y);
774 KOKKOS_INLINE_FUNCTION complex<T> pow(
const complex<T>& x,
775 const complex<T>& y) {
776 return x == T() ? T() : exp(y * log(x));
779 template <
class T,
class U,
class = std::enable_if_t<std::is_arithmetic_v<T>>>
780 KOKKOS_INLINE_FUNCTION complex<Impl::promote_2_t<T, U>> pow(
781 const T& x,
const complex<U>& y) {
782 using type = Impl::promote_2_t<T, U>;
783 return pow(type(x), complex<type>(y));
786 template <
class T,
class U,
class = std::enable_if_t<std::is_arithmetic_v<U>>>
787 KOKKOS_INLINE_FUNCTION complex<Impl::promote_2_t<T, U>> pow(
const complex<T>& x,
789 using type = Impl::promote_2_t<T, U>;
790 return pow(complex<type>(x), type(y));
793 template <
class T,
class U>
794 KOKKOS_INLINE_FUNCTION complex<Impl::promote_2_t<T, U>> pow(
795 const complex<T>& x,
const complex<U>& y) {
796 using type = Impl::promote_2_t<T, U>;
797 return pow(complex<type>(x), complex<type>(y));
802 template <
class RealType>
804 const complex<RealType>& x) {
805 RealType r = x.real();
806 RealType i = x.imag();
808 if (r == RealType()) {
809 RealType t = sqrt(fabs(i) / 2);
812 RealType t = sqrt(2 * (abs(x) + fabs(r)));
816 i < RealType() ? -u : u);
821 template <
class RealType>
822 KOKKOS_INLINE_FUNCTION complex<RealType> conj(
823 const complex<RealType>& x) noexcept {
824 return complex<RealType>(real(x), -imag(x));
827 template <
class ArithmeticType>
828 KOKKOS_INLINE_FUNCTION constexpr complex<Impl::promote_t<ArithmeticType>> conj(
830 using type = Impl::promote_t<ArithmeticType>;
831 return complex<type>(x, -type());
835 template <
class RealType>
836 KOKKOS_INLINE_FUNCTION complex<RealType> exp(
const complex<RealType>& x) {
837 return exp(x.real()) * complex<RealType>(cos(x.imag()), sin(x.imag()));
841 template <
class RealType>
843 const complex<RealType>& x) {
844 RealType phi = atan2(x.imag(), x.real());
849 template <
class RealType>
851 const complex<RealType>& x) {
852 return log(x) / log(RealType(10));
856 template <
class RealType>
858 const complex<RealType>& x) {
860 cos(x.real()) * sinh(x.imag()));
864 template <
class RealType>
866 const complex<RealType>& x) {
868 -sin(x.real()) * sinh(x.imag()));
872 template <
class RealType>
874 const complex<RealType>& x) {
875 return sin(x) / cos(x);
879 template <
class RealType>
881 const complex<RealType>& x) {
883 cosh(x.real()) * sin(x.imag()));
887 template <
class RealType>
889 const complex<RealType>& x) {
891 sinh(x.real()) * sin(x.imag()));
895 template <
class RealType>
897 const complex<RealType>& x) {
898 return sinh(x) / cosh(x);
902 template <
class RealType>
904 const complex<RealType>& x) {
905 return log(x + sqrt(x * x + RealType(1.0)));
909 template <
class RealType>
911 const complex<RealType>& x) {
912 return RealType(2.0) * log(sqrt(RealType(0.5) * (x + RealType(1.0))) +
913 sqrt(RealType(0.5) * (x - RealType(1.0))));
917 template <
class RealType>
919 const complex<RealType>& x) {
920 const RealType i2 = x.imag() * x.imag();
921 const RealType r = RealType(1.0) - i2 - x.real() * x.real();
923 RealType p = RealType(1.0) + x.real();
924 RealType m = RealType(1.0) - x.real();
929 RealType phi = atan2(RealType(2.0) * x.imag(), r);
931 RealType(0.5) * phi);
935 template <
class RealType>
937 const complex<RealType>& x) {
944 template <
class RealType>
946 const complex<RealType>& x) {
948 RealType pi_2 = acos(RealType(0.0));
953 template <
class RealType>
955 const complex<RealType>& x) {
956 const RealType r2 = x.real() * x.real();
957 const RealType i = RealType(1.0) - r2 - x.imag() * x.imag();
959 RealType p = x.imag() + RealType(1.0);
960 RealType m = x.imag() - RealType(1.0);
966 RealType(0.5) * atan2(RealType(2.0) * x.real(), i),
967 RealType(0.25) * log(p / m));
973 template <
class RealType>
974 inline complex<RealType> exp(
const std::complex<RealType>& c) {
975 return complex<RealType>(std::exp(c.real()) * std::cos(c.imag()),
976 std::exp(c.real()) * std::sin(c.imag()));
980 template <
class RealType1,
class RealType2>
981 KOKKOS_INLINE_FUNCTION complex<std::common_type_t<RealType1, RealType2>>
982 operator/(
const complex<RealType1>& x,
983 const RealType2& y) noexcept(noexcept(RealType1{} / RealType2{})) {
984 return complex<std::common_type_t<RealType1, RealType2>>(real(x) / y,
989 template <
class RealType1,
class RealType2>
990 KOKKOS_INLINE_FUNCTION complex<std::common_type_t<RealType1, RealType2>>
991 operator/(
const complex<RealType1>& x,
992 const complex<RealType2>& y) noexcept(noexcept(RealType1{} /
997 using common_real_type = std::common_type_t<RealType1, RealType2>;
998 const common_real_type s = fabs(real(y)) + fabs(imag(y));
1004 return complex<common_real_type>(real(x) / s, imag(x) / s);
1006 const complex<common_real_type> x_scaled(real(x) / s, imag(x) / s);
1007 const complex<common_real_type> y_conj_scaled(real(y) / s, -imag(y) / s);
1008 const RealType1 y_scaled_abs =
1009 real(y_conj_scaled) * real(y_conj_scaled) +
1010 imag(y_conj_scaled) * imag(y_conj_scaled);
1011 complex<common_real_type> result = x_scaled * y_conj_scaled;
1012 result /= y_scaled_abs;
1018 template <
class RealType1,
class RealType2>
1019 KOKKOS_INLINE_FUNCTION complex<std::common_type_t<RealType1, RealType2>>
1020 operator/(
const RealType1& x,
1021 const complex<RealType2>& y) noexcept(noexcept(RealType1{} /
1023 return complex<std::common_type_t<RealType1, RealType2>>(x) / y;
1026 template <
class RealType>
1027 std::ostream& operator<<(std::ostream& os, const complex<RealType>& x) {
1028 const std::complex<RealType> x_std(Kokkos::real(x), Kokkos::imag(x));
1033 template <
class RealType>
1034 std::istream& operator>>(std::istream& is, complex<RealType>& x) {
1035 std::complex<RealType> x_std;
1042 struct reduction_identity<Kokkos::complex<T>> {
1043 using t_red_ident = reduction_identity<T>;
1056 #ifdef KOKKOS_IMPL_PUBLIC_INCLUDE_NOTDEFINED_COMPLEX
1057 #undef KOKKOS_IMPL_PUBLIC_INCLUDE
1058 #undef KOKKOS_IMPL_PUBLIC_INCLUDE_NOTDEFINED_COMPLEX
1060 #endif // KOKKOS_COMPLEX_HPP
KOKKOS_INLINE_FUNCTION constexpr RealType & imag() noexcept
Partial reimplementation of std::complex that works as the result of a Kokkos::parallel_reduce.
KOKKOS_INLINE_FUNCTION constexpr RealType & real() noexcept