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
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");
62 KOKKOS_DEFAULTED_FUNCTION
66 KOKKOS_DEFAULTED_FUNCTION
69 KOKKOS_DEFAULTED_FUNCTION
75 std::enable_if_t<std::is_convertible<RType, RealType>::value,
int> = 0>
80 : re_(other.real()), im_(other.imag()) {}
87 KOKKOS_INLINE_FUNCTION
88 complex(
const std::complex<RealType>& src) noexcept
95 : re_(
reinterpret_cast<const RealType (&)[2]
>(src)[0]),
96 im_(
reinterpret_cast<const RealType (&)[2]
>(src)[1]) {}
104 operator std::complex<RealType>()
const noexcept {
105 return std::complex<RealType>(re_, im_);
110 KOKKOS_INLINE_FUNCTION
complex(
const RealType& val) noexcept
111 : re_(val), im_(static_cast<RealType>(0)) {}
114 KOKKOS_INLINE_FUNCTION
115 complex(
const RealType& re,
const RealType& im) noexcept : re_(re), im_(im) {}
135 KOKKOS_INLINE_FUNCTION
136 constexpr RealType&
imag() noexcept {
return im_; }
139 KOKKOS_INLINE_FUNCTION
140 constexpr RealType&
real() noexcept {
return re_; }
143 KOKKOS_INLINE_FUNCTION
144 constexpr RealType
imag() const noexcept {
return im_; }
147 KOKKOS_INLINE_FUNCTION
148 constexpr RealType
real() const noexcept {
return re_; }
151 KOKKOS_INLINE_FUNCTION
152 constexpr
void imag(RealType v) noexcept { im_ = v; }
155 KOKKOS_INLINE_FUNCTION
156 constexpr
void real(RealType v) noexcept { re_ = v; }
158 constexpr KOKKOS_INLINE_FUNCTION
complex& operator+=(
165 constexpr KOKKOS_INLINE_FUNCTION complex& operator+=(
166 const RealType& src) noexcept {
171 constexpr KOKKOS_INLINE_FUNCTION complex& operator-=(
172 const complex<RealType>& src) noexcept {
178 constexpr KOKKOS_INLINE_FUNCTION complex& operator-=(
179 const RealType& src) noexcept {
184 constexpr KOKKOS_INLINE_FUNCTION complex& operator*=(
185 const complex<RealType>& src) noexcept {
186 const RealType realPart = re_ * src.re_ - im_ * src.im_;
187 const RealType imagPart = re_ * src.im_ + im_ * src.re_;
193 constexpr KOKKOS_INLINE_FUNCTION complex& operator*=(
194 const RealType& src) noexcept {
201 constexpr KOKKOS_INLINE_FUNCTION complex& operator/=(
202 const complex<RealType>& y) noexcept(noexcept(RealType{} / RealType{})) {
206 const RealType s = fabs(y.real()) + fabs(y.imag());
212 if (s == RealType(0)) {
216 const complex x_scaled(this->re_ / s, this->im_ / s);
217 const complex y_conj_scaled(y.re_ / s, -(y.im_) / s);
218 const RealType y_scaled_abs =
219 y_conj_scaled.re_ * y_conj_scaled.re_ +
220 y_conj_scaled.im_ * y_conj_scaled.im_;
221 *
this = x_scaled * y_conj_scaled;
222 *
this /= y_scaled_abs;
227 constexpr KOKKOS_INLINE_FUNCTION complex& operator/=(
228 const std::complex<RealType>& y) noexcept(noexcept(RealType{} /
233 const RealType s = fabs(y.real()) + fabs(y.imag());
238 if (s == RealType(0)) {
242 const complex x_scaled(this->re_ / s, this->im_ / s);
243 const complex y_conj_scaled(y.re_ / s, -(y.im_) / s);
244 const RealType y_scaled_abs =
245 y_conj_scaled.re_ * y_conj_scaled.re_ +
246 y_conj_scaled.im_ * y_conj_scaled.im_;
247 *
this = x_scaled * y_conj_scaled;
248 *
this /= y_scaled_abs;
253 constexpr KOKKOS_INLINE_FUNCTION complex& operator/=(
254 const RealType& src) noexcept(noexcept(RealType{} / RealType{})) {
260 template <
size_t I,
typename RT>
261 friend constexpr
const RT&
get(
const complex<RT>&) noexcept;
263 template <
size_t I,
typename RT>
264 friend constexpr
const RT&&
get(
const complex<RT>&&) noexcept;
266 #ifdef KOKKOS_ENABLE_DEPRECATED_CODE_4
270 std::enable_if_t<std::is_convertible<RType, RealType>::value,
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<Complex, complex>::value,
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<Complex, complex>::value,
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<Complex, complex>::value,
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)
459 #ifdef KOKKOS_COMPILER_INTEL
460 __builtin_unreachable();
464 template <
size_t I,
typename RealType>
465 KOKKOS_FUNCTION constexpr RealType&&
get(complex<RealType>&& z) noexcept {
466 static_assert(I < 2);
467 if constexpr (I == 0)
468 return std::move(z.real());
470 return std::move(z.imag());
471 #ifdef KOKKOS_COMPILER_INTEL
472 __builtin_unreachable();
476 template <
size_t I,
typename RealType>
477 KOKKOS_FUNCTION constexpr
const RealType&
get(
478 const complex<RealType>& z) noexcept {
479 static_assert(I < 2);
480 if constexpr (I == 0)
484 #ifdef KOKKOS_COMPILER_INTEL
485 __builtin_unreachable();
489 template <
size_t I,
typename RealType>
490 KOKKOS_FUNCTION constexpr
const RealType&&
get(
491 const complex<RealType>&& z) noexcept {
492 static_assert(I < 2);
493 if constexpr (I == 0)
494 return std::move(z.re_);
496 return std::move(z.im_);
497 #ifdef KOKKOS_COMPILER_INTEL
498 __builtin_unreachable();
510 template <
class RealType1,
class RealType2>
511 KOKKOS_INLINE_FUNCTION
bool operator==(complex<RealType1>
const& x,
512 complex<RealType2>
const& y) noexcept {
513 using common_type = std::common_type_t<RealType1, RealType2>;
514 return common_type(x.real()) == common_type(y.real()) &&
515 common_type(x.imag()) == common_type(y.imag());
521 template <
class RealType1,
class RealType2>
522 inline bool operator==(std::complex<RealType1>
const& x,
523 complex<RealType2>
const& y) noexcept {
524 using common_type = std::common_type_t<RealType1, RealType2>;
525 return common_type(x.real()) == common_type(y.real()) &&
526 common_type(x.imag()) == common_type(y.imag());
530 template <
class RealType1,
class RealType2>
531 inline bool operator==(complex<RealType1>
const& x,
532 std::complex<RealType2>
const& y) noexcept {
533 using common_type = std::common_type_t<RealType1, RealType2>;
534 return common_type(x.real()) == common_type(y.real()) &&
535 common_type(x.imag()) == common_type(y.imag());
540 class RealType1,
class RealType2,
542 std::enable_if_t<std::is_convertible<RealType2, RealType1>::value,
int> = 0>
543 KOKKOS_INLINE_FUNCTION
bool operator==(complex<RealType1>
const& x,
544 RealType2
const& y) noexcept {
545 using common_type = std::common_type_t<RealType1, RealType2>;
546 return common_type(x.real()) == common_type(y) &&
547 common_type(x.imag()) == common_type(0);
552 class RealType1,
class RealType2,
554 std::enable_if_t<std::is_convertible<RealType1, RealType2>::value,
int> = 0>
555 KOKKOS_INLINE_FUNCTION
bool operator==(RealType1
const& x,
556 complex<RealType2>
const& y) noexcept {
557 using common_type = std::common_type_t<RealType1, RealType2>;
558 return common_type(x) == common_type(y.real()) &&
559 common_type(0) == common_type(y.imag());
563 template <
class RealType1,
class RealType2>
564 KOKKOS_INLINE_FUNCTION
bool operator!=(complex<RealType1>
const& x,
565 complex<RealType2>
const& y) noexcept {
566 using common_type = std::common_type_t<RealType1, RealType2>;
567 return common_type(x.real()) != common_type(y.real()) ||
568 common_type(x.imag()) != common_type(y.imag());
572 template <
class RealType1,
class RealType2>
573 inline bool operator!=(std::complex<RealType1>
const& x,
574 complex<RealType2>
const& y) noexcept {
575 using common_type = std::common_type_t<RealType1, RealType2>;
576 return common_type(x.real()) != common_type(y.real()) ||
577 common_type(x.imag()) != common_type(y.imag());
581 template <
class RealType1,
class RealType2>
582 inline bool operator!=(complex<RealType1>
const& x,
583 std::complex<RealType2>
const& y) noexcept {
584 using common_type = std::common_type_t<RealType1, RealType2>;
585 return common_type(x.real()) != common_type(y.real()) ||
586 common_type(x.imag()) != common_type(y.imag());
591 class RealType1,
class RealType2,
593 std::enable_if_t<std::is_convertible<RealType2, RealType1>::value,
int> = 0>
594 KOKKOS_INLINE_FUNCTION
bool operator!=(complex<RealType1>
const& x,
595 RealType2
const& y) noexcept {
596 using common_type = std::common_type_t<RealType1, RealType2>;
597 return common_type(x.real()) != common_type(y) ||
598 common_type(x.imag()) != common_type(0);
603 class RealType1,
class RealType2,
605 std::enable_if_t<std::is_convertible<RealType1, RealType2>::value,
int> = 0>
606 KOKKOS_INLINE_FUNCTION
bool operator!=(RealType1
const& x,
607 complex<RealType2>
const& y) noexcept {
608 using common_type = std::common_type_t<RealType1, RealType2>;
609 return common_type(x) != common_type(y.real()) ||
610 common_type(0) != common_type(y.imag());
617 template <
class RealType1,
class RealType2>
618 KOKKOS_INLINE_FUNCTION complex<std::common_type_t<RealType1, RealType2>>
619 operator+(
const complex<RealType1>& x,
const complex<RealType2>& y) noexcept {
620 return complex<std::common_type_t<RealType1, RealType2>>(x.real() + y.real(),
621 x.imag() + y.imag());
625 template <
class RealType1,
class RealType2>
626 KOKKOS_INLINE_FUNCTION complex<std::common_type_t<RealType1, RealType2>>
627 operator+(
const complex<RealType1>& x,
const RealType2& y) noexcept {
628 return complex<std::common_type_t<RealType1, RealType2>>(x.real() + y,
633 template <
class RealType1,
class RealType2>
634 KOKKOS_INLINE_FUNCTION complex<std::common_type_t<RealType1, RealType2>>
635 operator+(
const RealType1& x,
const complex<RealType2>& y) noexcept {
636 return complex<std::common_type_t<RealType1, RealType2>>(x + y.real(),
641 template <
class RealType>
642 KOKKOS_INLINE_FUNCTION complex<RealType> operator+(
643 const complex<RealType>& x) noexcept {
644 return complex<RealType>{+x.real(), +x.imag()};
648 template <
class RealType1,
class RealType2>
649 KOKKOS_INLINE_FUNCTION complex<std::common_type_t<RealType1, RealType2>>
650 operator-(
const complex<RealType1>& x,
const complex<RealType2>& y) noexcept {
651 return complex<std::common_type_t<RealType1, RealType2>>(x.real() - y.real(),
652 x.imag() - y.imag());
656 template <
class RealType1,
class RealType2>
657 KOKKOS_INLINE_FUNCTION complex<std::common_type_t<RealType1, RealType2>>
658 operator-(
const complex<RealType1>& x,
const RealType2& y) noexcept {
659 return complex<std::common_type_t<RealType1, RealType2>>(x.real() - y,
664 template <
class RealType1,
class RealType2>
665 KOKKOS_INLINE_FUNCTION complex<std::common_type_t<RealType1, RealType2>>
666 operator-(
const RealType1& x,
const complex<RealType2>& y) noexcept {
667 return complex<std::common_type_t<RealType1, RealType2>>(x - y.real(),
672 template <
class RealType>
673 KOKKOS_INLINE_FUNCTION complex<RealType> operator-(
674 const complex<RealType>& x) noexcept {
675 return complex<RealType>(-x.real(), -x.imag());
679 template <
class RealType1,
class RealType2>
680 KOKKOS_INLINE_FUNCTION complex<std::common_type_t<RealType1, RealType2>>
681 operator*(
const complex<RealType1>& x,
const complex<RealType2>& y) noexcept {
682 return complex<std::common_type_t<RealType1, RealType2>>(
683 x.real() * y.real() - x.imag() * y.imag(),
684 x.real() * y.imag() + x.imag() * y.real());
695 template <
class RealType1,
class RealType2>
696 inline complex<std::common_type_t<RealType1, RealType2>> operator*(
697 const std::complex<RealType1>& x,
const complex<RealType2>& y) {
698 return complex<std::common_type_t<RealType1, RealType2>>(
699 x.real() * y.real() - x.imag() * y.imag(),
700 x.real() * y.imag() + x.imag() * y.real());
707 template <
class RealType1,
class RealType2>
708 KOKKOS_INLINE_FUNCTION complex<std::common_type_t<RealType1, RealType2>>
709 operator*(
const RealType1& x,
const complex<RealType2>& y) noexcept {
710 return complex<std::common_type_t<RealType1, RealType2>>(x * y.real(),
718 template <
class RealType1,
class RealType2>
719 KOKKOS_INLINE_FUNCTION complex<std::common_type_t<RealType1, RealType2>>
720 operator*(
const complex<RealType1>& y,
const RealType2& x) noexcept {
721 return complex<std::common_type_t<RealType1, RealType2>>(x * y.real(),
726 template <
class RealType>
727 KOKKOS_INLINE_FUNCTION RealType imag(
const complex<RealType>& x) noexcept {
731 template <
class ArithmeticType>
732 KOKKOS_INLINE_FUNCTION constexpr Impl::promote_t<ArithmeticType> imag(
734 return ArithmeticType();
738 template <
class RealType>
739 KOKKOS_INLINE_FUNCTION RealType real(
const complex<RealType>& x) noexcept {
743 template <
class ArithmeticType>
744 KOKKOS_INLINE_FUNCTION constexpr Impl::promote_t<ArithmeticType> real(
751 KOKKOS_INLINE_FUNCTION complex<T> polar(
const T& r,
const T& theta = T()) {
752 KOKKOS_EXPECTS(r >= 0);
753 return complex<T>(r * cos(theta), r * sin(theta));
757 template <
class RealType>
758 KOKKOS_INLINE_FUNCTION RealType abs(
const complex<RealType>& x) {
759 return hypot(x.real(), x.imag());
764 KOKKOS_INLINE_FUNCTION complex<T> pow(
const complex<T>& x,
const T& y) {
766 T theta = atan2(x.imag(), x.real());
767 return polar(pow(r, y), y * theta);
771 KOKKOS_INLINE_FUNCTION complex<T> pow(
const T& x,
const complex<T>& y) {
772 return pow(complex<T>(x), y);
776 KOKKOS_INLINE_FUNCTION complex<T> pow(
const complex<T>& x,
777 const complex<T>& y) {
778 return x == T() ? T() : exp(y * log(x));
781 template <
class T,
class U,
782 class = std::enable_if_t<std::is_arithmetic<T>::value>>
783 KOKKOS_INLINE_FUNCTION complex<Impl::promote_2_t<T, U>> pow(
784 const T& x,
const complex<U>& y) {
785 using type = Impl::promote_2_t<T, U>;
786 return pow(type(x), complex<type>(y));
789 template <
class T,
class U,
790 class = std::enable_if_t<std::is_arithmetic<U>::value>>
791 KOKKOS_INLINE_FUNCTION complex<Impl::promote_2_t<T, U>> pow(
const complex<T>& x,
793 using type = Impl::promote_2_t<T, U>;
794 return pow(complex<type>(x), type(y));
797 template <
class T,
class U>
798 KOKKOS_INLINE_FUNCTION complex<Impl::promote_2_t<T, U>> pow(
799 const complex<T>& x,
const complex<U>& y) {
800 using type = Impl::promote_2_t<T, U>;
801 return pow(complex<type>(x), complex<type>(y));
806 template <
class RealType>
808 const complex<RealType>& x) {
809 RealType r = x.real();
810 RealType i = x.imag();
812 if (r == RealType()) {
813 RealType t = sqrt(fabs(i) / 2);
816 RealType t = sqrt(2 * (abs(x) + fabs(r)));
820 i < RealType() ? -u : u);
825 template <
class RealType>
826 KOKKOS_INLINE_FUNCTION complex<RealType> conj(
827 const complex<RealType>& x) noexcept {
828 return complex<RealType>(real(x), -imag(x));
831 template <
class ArithmeticType>
832 KOKKOS_INLINE_FUNCTION constexpr complex<Impl::promote_t<ArithmeticType>> conj(
834 using type = Impl::promote_t<ArithmeticType>;
835 return complex<type>(x, -type());
839 template <
class RealType>
840 KOKKOS_INLINE_FUNCTION complex<RealType> exp(
const complex<RealType>& x) {
841 return exp(x.real()) * complex<RealType>(cos(x.imag()), sin(x.imag()));
845 template <
class RealType>
847 const complex<RealType>& x) {
848 RealType phi = atan2(x.imag(), x.real());
853 template <
class RealType>
855 const complex<RealType>& x) {
856 return log(x) / log(RealType(10));
860 template <
class RealType>
862 const complex<RealType>& x) {
864 cos(x.real()) * sinh(x.imag()));
868 template <
class RealType>
870 const complex<RealType>& x) {
872 -sin(x.real()) * sinh(x.imag()));
876 template <
class RealType>
878 const complex<RealType>& x) {
879 return sin(x) / cos(x);
883 template <
class RealType>
885 const complex<RealType>& x) {
887 cosh(x.real()) * sin(x.imag()));
891 template <
class RealType>
893 const complex<RealType>& x) {
895 sinh(x.real()) * sin(x.imag()));
899 template <
class RealType>
901 const complex<RealType>& x) {
902 return sinh(x) / cosh(x);
906 template <
class RealType>
908 const complex<RealType>& x) {
909 return log(x + sqrt(x * x + RealType(1.0)));
913 template <
class RealType>
915 const complex<RealType>& x) {
916 return RealType(2.0) * log(sqrt(RealType(0.5) * (x + RealType(1.0))) +
917 sqrt(RealType(0.5) * (x - RealType(1.0))));
921 template <
class RealType>
923 const complex<RealType>& x) {
924 const RealType i2 = x.imag() * x.imag();
925 const RealType r = RealType(1.0) - i2 - x.real() * x.real();
927 RealType p = RealType(1.0) + x.real();
928 RealType m = RealType(1.0) - x.real();
933 RealType phi = atan2(RealType(2.0) * x.imag(), r);
935 RealType(0.5) * phi);
939 template <
class RealType>
941 const complex<RealType>& x) {
948 template <
class RealType>
950 const complex<RealType>& x) {
952 RealType pi_2 = acos(RealType(0.0));
957 template <
class RealType>
959 const complex<RealType>& x) {
960 const RealType r2 = x.real() * x.real();
961 const RealType i = RealType(1.0) - r2 - x.imag() * x.imag();
963 RealType p = x.imag() + RealType(1.0);
964 RealType m = x.imag() - RealType(1.0);
970 RealType(0.5) * atan2(RealType(2.0) * x.real(), i),
971 RealType(0.25) * log(p / m));
977 template <
class RealType>
978 inline complex<RealType> exp(
const std::complex<RealType>& c) {
979 return complex<RealType>(std::exp(c.real()) * std::cos(c.imag()),
980 std::exp(c.real()) * std::sin(c.imag()));
984 template <
class RealType1,
class RealType2>
985 KOKKOS_INLINE_FUNCTION complex<std::common_type_t<RealType1, RealType2>>
986 operator/(
const complex<RealType1>& x,
987 const RealType2& y) noexcept(noexcept(RealType1{} / RealType2{})) {
988 return complex<std::common_type_t<RealType1, RealType2>>(real(x) / y,
993 template <
class RealType1,
class RealType2>
994 KOKKOS_INLINE_FUNCTION complex<std::common_type_t<RealType1, RealType2>>
995 operator/(
const complex<RealType1>& x,
996 const complex<RealType2>& y) noexcept(noexcept(RealType1{} /
1001 using common_real_type = std::common_type_t<RealType1, RealType2>;
1002 const common_real_type s = fabs(real(y)) + fabs(imag(y));
1008 return complex<common_real_type>(real(x) / s, imag(x) / s);
1010 const complex<common_real_type> x_scaled(real(x) / s, imag(x) / s);
1011 const complex<common_real_type> y_conj_scaled(real(y) / s, -imag(y) / s);
1012 const RealType1 y_scaled_abs =
1013 real(y_conj_scaled) * real(y_conj_scaled) +
1014 imag(y_conj_scaled) * imag(y_conj_scaled);
1015 complex<common_real_type> result = x_scaled * y_conj_scaled;
1016 result /= y_scaled_abs;
1022 template <
class RealType1,
class RealType2>
1023 KOKKOS_INLINE_FUNCTION complex<std::common_type_t<RealType1, RealType2>>
1024 operator/(
const RealType1& x,
1025 const complex<RealType2>& y) noexcept(noexcept(RealType1{} /
1027 return complex<std::common_type_t<RealType1, RealType2>>(x) / y;
1030 template <
class RealType>
1031 std::ostream& operator<<(std::ostream& os, const complex<RealType>& x) {
1032 const std::complex<RealType> x_std(Kokkos::real(x), Kokkos::imag(x));
1037 template <
class RealType>
1038 std::istream& operator>>(std::istream& is, complex<RealType>& x) {
1039 std::complex<RealType> x_std;
1046 struct reduction_identity<Kokkos::complex<T>> {
1047 using t_red_ident = reduction_identity<T>;
1060 #ifdef KOKKOS_IMPL_PUBLIC_INCLUDE_NOTDEFINED_COMPLEX
1061 #undef KOKKOS_IMPL_PUBLIC_INCLUDE
1062 #undef KOKKOS_IMPL_PUBLIC_INCLUDE_NOTDEFINED_COMPLEX
1064 #endif // KOKKOS_COMPLEX_HPP
KOKKOS_INLINE_FUNCTION constexpr void real(RealType v) noexcept
Set the real part of this complex number.
KOKKOS_INLINE_FUNCTION constexpr RealType & imag() noexcept
The imaginary part of this complex number.
Partial reimplementation of std::complex that works as the result of a Kokkos::parallel_reduce.
KOKKOS_INLINE_FUNCTION constexpr RealType real() const noexcept
The real part of this complex number.
KOKKOS_INLINE_FUNCTION complex & operator=(const RealType &val) noexcept
Assignment operator (from a real number).
KOKKOS_INLINE_FUNCTION complex(const RealType &val) noexcept
Constructor that takes just the real part, and sets the imaginary part to zero.
complex & operator=(const std::complex< RealType > &src) noexcept
Assignment operator from std::complex.
KOKKOS_INLINE_FUNCTION constexpr RealType & real() noexcept
The real part of this complex number.
KOKKOS_INLINE_FUNCTION complex(const RealType &re, const RealType &im) noexcept
Constructor that takes the real and imaginary parts.
KOKKOS_INLINE_FUNCTION constexpr RealType imag() const noexcept
The imaginary part of this complex number.
KOKKOS_INLINE_FUNCTION constexpr void imag(RealType v) noexcept
Set the imaginary part of this complex number.
KOKKOS_INLINE_FUNCTION complex(const std::complex< RealType > &src) noexcept
Conversion constructor from std::complex.
RealType value_type
The type of the real or imaginary parts of this complex number.