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 constexpr complex(
const RealType& val) noexcept
110 : re_(val), im_(static_cast<RealType>(0)) {}
113 KOKKOS_INLINE_FUNCTION
114 constexpr complex(
const RealType& re,
const RealType& im) noexcept
115 : re_(re), im_(im) {}
118 KOKKOS_INLINE_FUNCTION constexpr complex& operator=(
119 const RealType& val) noexcept {
130 complex& operator=(
const std::complex<RealType>& src) noexcept {
131 *
this = complex(src);
136 KOKKOS_INLINE_FUNCTION
137 constexpr RealType& imag() noexcept {
return im_; }
140 KOKKOS_INLINE_FUNCTION
141 constexpr RealType& real() noexcept {
return re_; }
144 KOKKOS_INLINE_FUNCTION
145 constexpr RealType imag() const noexcept {
return im_; }
148 KOKKOS_INLINE_FUNCTION
149 constexpr RealType real() const noexcept {
return re_; }
152 KOKKOS_INLINE_FUNCTION
153 constexpr
void imag(RealType v) noexcept { im_ = v; }
156 KOKKOS_INLINE_FUNCTION
157 constexpr
void real(RealType v) noexcept { re_ = v; }
159 constexpr KOKKOS_INLINE_FUNCTION complex& operator+=(
160 const complex<RealType>& src) noexcept {
166 constexpr KOKKOS_INLINE_FUNCTION complex& operator+=(
167 const RealType& src) noexcept {
172 constexpr KOKKOS_INLINE_FUNCTION complex& operator-=(
173 const complex<RealType>& src) noexcept {
179 constexpr KOKKOS_INLINE_FUNCTION complex& operator-=(
180 const RealType& src) noexcept {
185 constexpr KOKKOS_INLINE_FUNCTION complex& operator*=(
186 const complex<RealType>& src) noexcept {
187 const RealType realPart = re_ * src.re_ - im_ * src.im_;
188 const RealType imagPart = re_ * src.im_ + im_ * src.re_;
194 constexpr KOKKOS_INLINE_FUNCTION complex& operator*=(
195 const RealType& src) noexcept {
202 constexpr KOKKOS_INLINE_FUNCTION complex& operator/=(
203 const complex<RealType>& y) noexcept(noexcept(RealType{} / RealType{})) {
207 const RealType s = fabs(y.real()) + fabs(y.imag());
213 if (s == RealType(0)) {
217 const complex x_scaled(this->re_ / s, this->im_ / s);
218 const complex y_conj_scaled(y.re_ / s, -(y.im_) / s);
219 const RealType y_scaled_abs =
220 y_conj_scaled.re_ * y_conj_scaled.re_ +
221 y_conj_scaled.im_ * y_conj_scaled.im_;
222 *
this = x_scaled * y_conj_scaled;
223 *
this /= y_scaled_abs;
228 constexpr KOKKOS_INLINE_FUNCTION complex& operator/=(
229 const std::complex<RealType>& y) noexcept(noexcept(RealType{} /
234 const RealType s = fabs(y.real()) + fabs(y.imag());
239 if (s == RealType(0)) {
243 const complex x_scaled(this->re_ / s, this->im_ / s);
244 const complex y_conj_scaled(y.re_ / s, -(y.im_) / s);
245 const RealType y_scaled_abs =
246 y_conj_scaled.re_ * y_conj_scaled.re_ +
247 y_conj_scaled.im_ * y_conj_scaled.im_;
248 *
this = x_scaled * y_conj_scaled;
249 *
this /= y_scaled_abs;
254 constexpr KOKKOS_INLINE_FUNCTION complex& operator/=(
255 const RealType& src) noexcept(noexcept(RealType{} / RealType{})) {
261 template <
size_t I,
typename RT>
262 friend constexpr
const RT&
get(
const complex<RT>&) noexcept;
264 template <
size_t I,
typename RT>
265 friend constexpr
const RT&&
get(
const complex<RT>&&) noexcept;
267 #ifdef KOKKOS_ENABLE_DEPRECATED_CODE_4
268 template <
class RType,
270 std::enable_if_t<std::is_convertible_v<RType, RealType>,
int> = 0>
271 KOKKOS_DEPRECATED KOKKOS_INLINE_FUNCTION
272 complex(
const volatile complex<RType>& src) noexcept
276 : re_(src.re_), im_(src.im_) {}
298 template <
class Complex,
299 std::enable_if_t<std::is_same_v<Complex, complex>,
int> = 0>
300 KOKKOS_DEPRECATED KOKKOS_INLINE_FUNCTION
void operator=(
301 const Complex& src)
volatile noexcept {
321 template <
class Complex,
322 std::enable_if_t<std::is_same_v<Complex, complex>,
int> = 0>
323 KOKKOS_DEPRECATED KOKKOS_INLINE_FUNCTION
volatile complex& operator=(
324 const volatile Complex& src)
volatile noexcept {
343 template <
class Complex,
344 std::enable_if_t<std::is_same_v<Complex, complex>,
int> = 0>
345 KOKKOS_DEPRECATED KOKKOS_INLINE_FUNCTION complex& operator=(
346 const volatile Complex& src) noexcept {
356 KOKKOS_DEPRECATED KOKKOS_INLINE_FUNCTION
void operator=(
357 const volatile RealType& val) noexcept {
365 KOKKOS_DEPRECATED KOKKOS_INLINE_FUNCTION complex& operator=(
366 const RealType& val)
volatile noexcept {
374 KOKKOS_DEPRECATED KOKKOS_INLINE_FUNCTION complex& operator=(
375 const volatile RealType& val)
volatile noexcept {
382 KOKKOS_DEPRECATED KOKKOS_INLINE_FUNCTION
volatile RealType&
383 imag() volatile noexcept {
388 KOKKOS_DEPRECATED KOKKOS_INLINE_FUNCTION
volatile RealType&
389 real() volatile noexcept {
394 KOKKOS_DEPRECATED KOKKOS_INLINE_FUNCTION RealType imag() const
400 KOKKOS_DEPRECATED KOKKOS_INLINE_FUNCTION RealType real() const
405 KOKKOS_DEPRECATED KOKKOS_INLINE_FUNCTION
void operator+=(
406 const volatile complex<RealType>& src)
volatile noexcept {
411 KOKKOS_DEPRECATED KOKKOS_INLINE_FUNCTION
void operator+=(
412 const volatile RealType& src)
volatile noexcept {
416 KOKKOS_DEPRECATED KOKKOS_INLINE_FUNCTION
void operator*=(
417 const volatile complex<RealType>& src)
volatile noexcept {
418 const RealType realPart = re_ * src.re_ - im_ * src.im_;
419 const RealType imagPart = re_ * src.im_ + im_ * src.re_;
425 KOKKOS_DEPRECATED KOKKOS_INLINE_FUNCTION
void operator*=(
426 const volatile RealType& src)
volatile noexcept {
430 #endif // KOKKOS_ENABLE_DEPRECATED_CODE_4
438 template <
typename RealType>
439 struct std::tuple_size<Kokkos::complex<RealType>>
440 : std::integral_constant<size_t, 2> {};
442 template <
size_t I,
typename RealType>
443 struct std::tuple_element<I, Kokkos::complex<RealType>> {
444 static_assert(I < 2);
445 using type = RealType;
452 template <
size_t I,
typename RealType>
453 KOKKOS_FUNCTION constexpr RealType&
get(complex<RealType>& z) noexcept {
454 static_assert(I < 2);
455 if constexpr (I == 0)
461 template <
size_t I, typename RealType>
462 KOKKOS_FUNCTION constexpr RealType&& get(complex<RealType>&& z) noexcept {
463 static_assert(I < 2);
464 if constexpr (I == 0)
465 return std::move(z.real());
467 return std::move(z.imag());
470 template <
size_t I, typename RealType>
471 KOKKOS_FUNCTION constexpr const RealType& get(
472 const complex<RealType>& z) noexcept {
473 static_assert(I < 2);
474 if constexpr (I == 0)
480 template <
size_t I, typename RealType>
481 KOKKOS_FUNCTION constexpr const RealType&& get(
482 const complex<RealType>&& z) noexcept {
483 static_assert(I < 2);
484 if constexpr (I == 0)
485 return std::move(z.re_);
487 return std::move(z.im_);
498 template <class RealType1, class RealType2>
499 KOKKOS_INLINE_FUNCTION
bool operator==(complex<RealType1> const& x,
500 complex<RealType2> const& y) noexcept {
501 using common_type = std::common_type_t<RealType1, RealType2>;
502 return common_type(x.real()) == common_type(y.real()) &&
503 common_type(x.imag()) == common_type(y.imag());
509 template <
class RealType1,
class RealType2>
510 inline bool operator==(std::complex<RealType1>
const& x,
511 complex<RealType2>
const& y) noexcept {
512 using common_type = std::common_type_t<RealType1, RealType2>;
513 return common_type(x.real()) == common_type(y.real()) &&
514 common_type(x.imag()) == common_type(y.imag());
518 template <
class RealType1,
class RealType2>
519 inline bool operator==(complex<RealType1>
const& x,
520 std::complex<RealType2>
const& y) noexcept {
521 using common_type = std::common_type_t<RealType1, RealType2>;
522 return common_type(x.real()) == common_type(y.real()) &&
523 common_type(x.imag()) == common_type(y.imag());
528 class RealType1,
class RealType2,
530 std::enable_if_t<std::is_convertible_v<RealType2, RealType1>,
int> = 0>
531 KOKKOS_INLINE_FUNCTION
bool operator==(complex<RealType1>
const& x,
532 RealType2
const& y) noexcept {
533 using common_type = std::common_type_t<RealType1, RealType2>;
534 return common_type(x.real()) == common_type(y) &&
535 common_type(x.imag()) == common_type(0);
540 class RealType1,
class RealType2,
542 std::enable_if_t<std::is_convertible_v<RealType1, RealType2>,
int> = 0>
543 KOKKOS_INLINE_FUNCTION
bool operator==(RealType1
const& x,
544 complex<RealType2>
const& y) noexcept {
545 using common_type = std::common_type_t<RealType1, RealType2>;
546 return common_type(x) == common_type(y.real()) &&
547 common_type(0) == common_type(y.imag());
551 template <
class RealType1,
class RealType2>
552 KOKKOS_INLINE_FUNCTION
bool operator!=(complex<RealType1>
const& x,
553 complex<RealType2>
const& y) noexcept {
554 using common_type = std::common_type_t<RealType1, RealType2>;
555 return common_type(x.real()) != common_type(y.real()) ||
556 common_type(x.imag()) != common_type(y.imag());
560 template <
class RealType1,
class RealType2>
561 inline bool operator!=(std::complex<RealType1>
const& x,
562 complex<RealType2>
const& y) noexcept {
563 using common_type = std::common_type_t<RealType1, RealType2>;
564 return common_type(x.real()) != common_type(y.real()) ||
565 common_type(x.imag()) != common_type(y.imag());
569 template <
class RealType1,
class RealType2>
570 inline bool operator!=(complex<RealType1>
const& x,
571 std::complex<RealType2>
const& y) noexcept {
572 using common_type = std::common_type_t<RealType1, RealType2>;
573 return common_type(x.real()) != common_type(y.real()) ||
574 common_type(x.imag()) != common_type(y.imag());
579 class RealType1,
class RealType2,
581 std::enable_if_t<std::is_convertible_v<RealType2, RealType1>,
int> = 0>
582 KOKKOS_INLINE_FUNCTION
bool operator!=(complex<RealType1>
const& x,
583 RealType2
const& y) noexcept {
584 using common_type = std::common_type_t<RealType1, RealType2>;
585 return common_type(x.real()) != common_type(y) ||
586 common_type(x.imag()) != common_type(0);
591 class RealType1,
class RealType2,
593 std::enable_if_t<std::is_convertible_v<RealType1, RealType2>,
int> = 0>
594 KOKKOS_INLINE_FUNCTION
bool operator!=(RealType1
const& x,
595 complex<RealType2>
const& y) noexcept {
596 using common_type = std::common_type_t<RealType1, RealType2>;
597 return common_type(x) != common_type(y.real()) ||
598 common_type(0) != common_type(y.imag());
605 template <
class RealType1,
class RealType2>
606 KOKKOS_INLINE_FUNCTION complex<std::common_type_t<RealType1, RealType2>>
607 operator+(
const complex<RealType1>& x,
const complex<RealType2>& y) noexcept {
608 return complex<std::common_type_t<RealType1, RealType2>>(x.real() + y.real(),
609 x.imag() + y.imag());
613 template <
class RealType1,
class RealType2>
614 KOKKOS_INLINE_FUNCTION complex<std::common_type_t<RealType1, RealType2>>
615 operator+(
const complex<RealType1>& x,
const RealType2& y) noexcept {
616 return complex<std::common_type_t<RealType1, RealType2>>(x.real() + y,
621 template <
class RealType1,
class RealType2>
622 KOKKOS_INLINE_FUNCTION complex<std::common_type_t<RealType1, RealType2>>
623 operator+(
const RealType1& x,
const complex<RealType2>& y) noexcept {
624 return complex<std::common_type_t<RealType1, RealType2>>(x + y.real(),
629 template <
class RealType>
630 KOKKOS_INLINE_FUNCTION complex<RealType> operator+(
631 const complex<RealType>& x) noexcept {
632 return complex<RealType>{+x.real(), +x.imag()};
636 template <
class RealType1,
class RealType2>
637 KOKKOS_INLINE_FUNCTION complex<std::common_type_t<RealType1, RealType2>>
638 operator-(
const complex<RealType1>& x,
const complex<RealType2>& y) noexcept {
639 return complex<std::common_type_t<RealType1, RealType2>>(x.real() - y.real(),
640 x.imag() - y.imag());
644 template <
class RealType1,
class RealType2>
645 KOKKOS_INLINE_FUNCTION complex<std::common_type_t<RealType1, RealType2>>
646 operator-(
const complex<RealType1>& x,
const RealType2& y) noexcept {
647 return complex<std::common_type_t<RealType1, RealType2>>(x.real() - y,
652 template <
class RealType1,
class RealType2>
653 KOKKOS_INLINE_FUNCTION complex<std::common_type_t<RealType1, RealType2>>
654 operator-(
const RealType1& x,
const complex<RealType2>& y) noexcept {
655 return complex<std::common_type_t<RealType1, RealType2>>(x - y.real(),
660 template <
class RealType>
661 KOKKOS_INLINE_FUNCTION complex<RealType> operator-(
662 const complex<RealType>& x) noexcept {
663 return complex<RealType>(-x.real(), -x.imag());
667 template <
class RealType1,
class RealType2>
668 KOKKOS_INLINE_FUNCTION complex<std::common_type_t<RealType1, RealType2>>
669 operator*(
const complex<RealType1>& x,
const complex<RealType2>& y) noexcept {
670 return complex<std::common_type_t<RealType1, RealType2>>(
671 x.real() * y.real() - x.imag() * y.imag(),
672 x.real() * y.imag() + x.imag() * y.real());
683 template <
class RealType1,
class RealType2>
684 inline complex<std::common_type_t<RealType1, RealType2>> operator*(
685 const std::complex<RealType1>& x,
const complex<RealType2>& y) {
686 return complex<std::common_type_t<RealType1, RealType2>>(
687 x.real() * y.real() - x.imag() * y.imag(),
688 x.real() * y.imag() + x.imag() * y.real());
695 template <
class RealType1,
class RealType2>
696 KOKKOS_INLINE_FUNCTION complex<std::common_type_t<RealType1, RealType2>>
697 operator*(
const RealType1& x,
const complex<RealType2>& y) noexcept {
698 return complex<std::common_type_t<RealType1, RealType2>>(x * y.real(),
706 template <
class RealType1,
class RealType2>
707 KOKKOS_INLINE_FUNCTION complex<std::common_type_t<RealType1, RealType2>>
708 operator*(
const complex<RealType1>& y,
const RealType2& x) noexcept {
709 return complex<std::common_type_t<RealType1, RealType2>>(x * y.real(),
714 template <
class RealType>
715 KOKKOS_INLINE_FUNCTION RealType imag(
const complex<RealType>& x) noexcept {
719 template <
class ArithmeticType>
720 KOKKOS_INLINE_FUNCTION constexpr Impl::promote_t<ArithmeticType> imag(
722 return ArithmeticType();
726 template <
class RealType>
727 KOKKOS_INLINE_FUNCTION RealType real(
const complex<RealType>& x) noexcept {
731 template <
class ArithmeticType>
732 KOKKOS_INLINE_FUNCTION constexpr Impl::promote_t<ArithmeticType> real(
739 KOKKOS_INLINE_FUNCTION complex<T> polar(
const T& r,
const T& theta = T()) {
740 KOKKOS_EXPECTS(r >= 0);
741 return complex<T>(r * cos(theta), r * sin(theta));
745 template <
class RealType>
746 KOKKOS_INLINE_FUNCTION RealType abs(
const complex<RealType>& x) {
747 return hypot(x.real(), x.imag());
752 KOKKOS_INLINE_FUNCTION complex<T> pow(
const complex<T>& x,
const T& y) {
754 T theta = atan2(x.imag(), x.real());
755 return polar(pow(r, y), y * theta);
759 KOKKOS_INLINE_FUNCTION complex<T> pow(
const T& x,
const complex<T>& y) {
760 return pow(complex<T>(x), y);
764 KOKKOS_INLINE_FUNCTION complex<T> pow(
const complex<T>& x,
765 const complex<T>& y) {
766 return x == T() ? T() : exp(y * log(x));
769 template <
class T,
class U,
class = std::enable_if_t<std::is_arithmetic_v<T>>>
770 KOKKOS_INLINE_FUNCTION complex<Impl::promote_2_t<T, U>> pow(
771 const T& x,
const complex<U>& y) {
772 using type = Impl::promote_2_t<T, U>;
773 return pow(type(x), complex<type>(y));
776 template <
class T,
class U,
class = std::enable_if_t<std::is_arithmetic_v<U>>>
777 KOKKOS_INLINE_FUNCTION complex<Impl::promote_2_t<T, U>> pow(
const complex<T>& x,
779 using type = Impl::promote_2_t<T, U>;
780 return pow(complex<type>(x), type(y));
783 template <
class T,
class U>
784 KOKKOS_INLINE_FUNCTION complex<Impl::promote_2_t<T, U>> pow(
785 const complex<T>& x,
const complex<U>& y) {
786 using type = Impl::promote_2_t<T, U>;
787 return pow(complex<type>(x), complex<type>(y));
792 template <
class RealType>
794 const complex<RealType>& x) {
795 RealType r = x.real();
796 RealType i = x.imag();
798 if (r == RealType()) {
799 RealType t = sqrt(fabs(i) / 2);
802 RealType t = sqrt(2 * (abs(x) + fabs(r)));
806 i < RealType() ? -u : u);
811 template <
class RealType>
812 KOKKOS_INLINE_FUNCTION complex<RealType> conj(
813 const complex<RealType>& x) noexcept {
814 return complex<RealType>(real(x), -imag(x));
817 template <
class ArithmeticType>
818 KOKKOS_INLINE_FUNCTION constexpr complex<Impl::promote_t<ArithmeticType>> conj(
820 using type = Impl::promote_t<ArithmeticType>;
821 return complex<type>(x, -type());
825 template <
class RealType>
826 KOKKOS_INLINE_FUNCTION complex<RealType> exp(
const complex<RealType>& x) {
827 return exp(x.real()) * complex<RealType>(cos(x.imag()), sin(x.imag()));
831 template <
class RealType>
833 const complex<RealType>& x) {
834 RealType phi = atan2(x.imag(), x.real());
839 template <
class RealType>
841 const complex<RealType>& x) {
842 return log(x) / log(RealType(10));
846 template <
class RealType>
848 const complex<RealType>& x) {
850 cos(x.real()) * sinh(x.imag()));
854 template <
class RealType>
856 const complex<RealType>& x) {
858 -sin(x.real()) * sinh(x.imag()));
862 template <
class RealType>
864 const complex<RealType>& x) {
865 return sin(x) / cos(x);
869 template <
class RealType>
871 const complex<RealType>& x) {
873 cosh(x.real()) * sin(x.imag()));
877 template <
class RealType>
879 const complex<RealType>& x) {
881 sinh(x.real()) * sin(x.imag()));
885 template <
class RealType>
887 const complex<RealType>& x) {
888 return sinh(x) / cosh(x);
892 template <
class RealType>
894 const complex<RealType>& x) {
895 return log(x + sqrt(x * x + RealType(1.0)));
899 template <
class RealType>
901 const complex<RealType>& x) {
902 return RealType(2.0) * log(sqrt(RealType(0.5) * (x + RealType(1.0))) +
903 sqrt(RealType(0.5) * (x - RealType(1.0))));
907 template <
class RealType>
909 const complex<RealType>& x) {
910 const RealType i2 = x.imag() * x.imag();
911 const RealType r = RealType(1.0) - i2 - x.real() * x.real();
913 RealType p = RealType(1.0) + x.real();
914 RealType m = RealType(1.0) - x.real();
919 RealType phi = atan2(RealType(2.0) * x.imag(), r);
921 RealType(0.5) * phi);
925 template <
class RealType>
927 const complex<RealType>& x) {
934 template <
class RealType>
936 const complex<RealType>& x) {
938 RealType pi_2 = acos(RealType(0.0));
943 template <
class RealType>
945 const complex<RealType>& x) {
946 const RealType r2 = x.real() * x.real();
947 const RealType i = RealType(1.0) - r2 - x.imag() * x.imag();
949 RealType p = x.imag() + RealType(1.0);
950 RealType m = x.imag() - RealType(1.0);
956 RealType(0.5) * atan2(RealType(2.0) * x.real(), i),
957 RealType(0.25) * log(p / m));
963 template <
class RealType>
964 inline complex<RealType> exp(
const std::complex<RealType>& c) {
965 return complex<RealType>(std::exp(c.real()) * std::cos(c.imag()),
966 std::exp(c.real()) * std::sin(c.imag()));
970 template <
class RealType1,
class RealType2>
971 KOKKOS_INLINE_FUNCTION complex<std::common_type_t<RealType1, RealType2>>
972 operator/(
const complex<RealType1>& x,
973 const RealType2& y) noexcept(noexcept(RealType1{} / RealType2{})) {
974 return complex<std::common_type_t<RealType1, RealType2>>(real(x) / y,
979 template <
class RealType1,
class RealType2>
980 KOKKOS_INLINE_FUNCTION complex<std::common_type_t<RealType1, RealType2>>
981 operator/(
const complex<RealType1>& x,
982 const complex<RealType2>& y) noexcept(noexcept(RealType1{} /
987 using common_real_type = std::common_type_t<RealType1, RealType2>;
988 const common_real_type s = fabs(real(y)) + fabs(imag(y));
994 return complex<common_real_type>(real(x) / s, imag(x) / s);
996 const complex<common_real_type> x_scaled(real(x) / s, imag(x) / s);
997 const complex<common_real_type> y_conj_scaled(real(y) / s, -imag(y) / s);
998 const RealType1 y_scaled_abs =
999 real(y_conj_scaled) * real(y_conj_scaled) +
1000 imag(y_conj_scaled) * imag(y_conj_scaled);
1001 complex<common_real_type> result = x_scaled * y_conj_scaled;
1002 result /= y_scaled_abs;
1008 template <
class RealType1,
class RealType2>
1009 KOKKOS_INLINE_FUNCTION complex<std::common_type_t<RealType1, RealType2>>
1010 operator/(
const RealType1& x,
1011 const complex<RealType2>& y) noexcept(noexcept(RealType1{} /
1013 return complex<std::common_type_t<RealType1, RealType2>>(x) / y;
1016 template <
class RealType>
1017 std::ostream& operator<<(std::ostream& os, const complex<RealType>& x) {
1018 const std::complex<RealType> x_std(Kokkos::real(x), Kokkos::imag(x));
1023 template <
class RealType>
1024 std::istream& operator>>(std::istream& is, complex<RealType>& x) {
1025 std::complex<RealType> x_std;
1032 struct reduction_identity<Kokkos::complex<T>> {
1033 using t_red_ident = reduction_identity<T>;
1046 #ifdef KOKKOS_IMPL_PUBLIC_INCLUDE_NOTDEFINED_COMPLEX
1047 #undef KOKKOS_IMPL_PUBLIC_INCLUDE
1048 #undef KOKKOS_IMPL_PUBLIC_INCLUDE_NOTDEFINED_COMPLEX
1050 #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