44 #ifndef KOKKOS_COMPLEX_HPP
45 #define KOKKOS_COMPLEX_HPP
48 #include <Kokkos_NumericTraits.hpp>
61 template <
class RealType>
63 #ifdef KOKKOS_ENABLE_COMPLEX_ALIGN
64 alignas(2 *
sizeof(RealType))
76 KOKKOS_DEFAULTED_FUNCTION
80 KOKKOS_DEFAULTED_FUNCTION
83 KOKKOS_DEFAULTED_FUNCTION
87 template <class RType,
88 typename std::enable_if<std::is_convertible<RType, RealType>::value,
94 : re_(other.
real()), im_(other.
imag()) {}
101 KOKKOS_INLINE_FUNCTION
102 complex(
const std::complex<RealType>& src) noexcept
109 : re_(
reinterpret_cast<const RealType (&)[2]
>(src)[0]),
110 im_(
reinterpret_cast<const RealType (&)[2]
>(src)[1]) {}
118 operator std::complex<RealType>()
const noexcept {
119 return std::complex<RealType>(re_, im_);
124 KOKKOS_INLINE_FUNCTION
complex(
const RealType& val) noexcept
125 : re_(val), im_(static_cast<RealType>(0)) {}
128 KOKKOS_INLINE_FUNCTION
129 complex(
const RealType& re,
const RealType& im) noexcept : re_(re), im_(im) {}
149 KOKKOS_INLINE_FUNCTION
150 KOKKOS_CONSTEXPR_14 RealType&
imag() noexcept {
return im_; }
153 KOKKOS_INLINE_FUNCTION
154 KOKKOS_CONSTEXPR_14 RealType&
real() noexcept {
return re_; }
157 KOKKOS_INLINE_FUNCTION
158 constexpr RealType
imag() const noexcept {
return im_; }
161 KOKKOS_INLINE_FUNCTION
162 constexpr RealType
real() const noexcept {
return re_; }
165 KOKKOS_INLINE_FUNCTION
167 void imag(RealType v) noexcept { im_ = v; }
170 KOKKOS_INLINE_FUNCTION
172 void real(RealType v) noexcept { re_ = v; }
174 KOKKOS_CONSTEXPR_14 KOKKOS_INLINE_FUNCTION
complex& operator+=(
181 KOKKOS_CONSTEXPR_14 KOKKOS_INLINE_FUNCTION complex& operator+=(
182 const RealType& src) noexcept {
187 KOKKOS_CONSTEXPR_14 KOKKOS_INLINE_FUNCTION complex& operator-=(
188 const complex<RealType>& src) noexcept {
194 KOKKOS_CONSTEXPR_14 KOKKOS_INLINE_FUNCTION complex& operator-=(
195 const RealType& src) noexcept {
200 KOKKOS_CONSTEXPR_14 KOKKOS_INLINE_FUNCTION complex& operator*=(
201 const complex<RealType>& src) noexcept {
202 const RealType realPart = re_ * src.re_ - im_ * src.im_;
203 const RealType imagPart = re_ * src.im_ + im_ * src.re_;
209 KOKKOS_CONSTEXPR_14 KOKKOS_INLINE_FUNCTION complex& operator*=(
210 const RealType& src) noexcept {
217 KOKKOS_CONSTEXPR_14 KOKKOS_INLINE_FUNCTION complex& operator/=(
218 const complex<RealType>& y) noexcept(noexcept(RealType{} / RealType{})) {
222 #if !defined(__HIP_DEVICE_COMPILE__) // FIXME_HIP
225 const RealType s = fabs(y.real()) + fabs(y.imag());
231 if (s == RealType(0)) {
235 const complex x_scaled(this->re_ / s, this->im_ / s);
236 const complex y_conj_scaled(y.re_ / s, -(y.im_) / s);
237 const RealType y_scaled_abs =
238 y_conj_scaled.re_ * y_conj_scaled.re_ +
239 y_conj_scaled.im_ * y_conj_scaled.im_;
240 *
this = x_scaled * y_conj_scaled;
241 *
this /= y_scaled_abs;
247 KOKKOS_INLINE_FUNCTION complex& operator/=(
248 const std::complex<RealType>& y) noexcept(noexcept(RealType{} /
253 #if !defined(__HIP_DEVICE_COMPILE__) // FIXME_HIP
256 const RealType s = fabs(y.real()) + fabs(y.imag());
261 if (s == RealType(0)) {
265 const complex x_scaled(this->re_ / s, this->im_ / s);
266 const complex y_conj_scaled(y.re_ / s, -(y.im_) / s);
267 const RealType y_scaled_abs =
268 y_conj_scaled.re_ * y_conj_scaled.re_ +
269 y_conj_scaled.im_ * y_conj_scaled.im_;
270 *
this = x_scaled * y_conj_scaled;
271 *
this /= y_scaled_abs;
276 KOKKOS_CONSTEXPR_14 KOKKOS_INLINE_FUNCTION complex& operator/=(
277 const RealType& src) noexcept(noexcept(RealType{} / RealType{})) {
289 template <
class RType,
290 typename std::enable_if<std::is_convertible<RType, RealType>::value,
296 : re_(src.re_), im_(src.im_) {}
318 template <
class Complex,
319 typename std::enable_if<std::is_same<Complex, complex>::value,
321 KOKKOS_INLINE_FUNCTION
void operator=(
const Complex& src)
volatile noexcept {
341 template <
class Complex,
342 typename std::enable_if<std::is_same<Complex, complex>::value,
345 const volatile Complex& src)
volatile noexcept {
364 template <
class Complex,
365 typename std::enable_if<std::is_same<Complex, complex>::value,
368 const volatile Complex& src) noexcept {
378 KOKKOS_INLINE_FUNCTION
void operator=(
const volatile RealType& val) noexcept {
387 const RealType& val)
volatile noexcept {
396 const volatile RealType& val)
volatile noexcept {
403 KOKKOS_INLINE_FUNCTION
404 volatile RealType&
imag() volatile noexcept {
return im_; }
407 KOKKOS_INLINE_FUNCTION
408 volatile RealType&
real() volatile noexcept {
return re_; }
411 KOKKOS_INLINE_FUNCTION
412 RealType
imag() const volatile noexcept {
return im_; }
415 KOKKOS_INLINE_FUNCTION
416 RealType
real() const volatile noexcept {
return re_; }
418 KOKKOS_INLINE_FUNCTION
void operator+=(
424 KOKKOS_INLINE_FUNCTION
void operator+=(
425 const volatile RealType& src)
volatile noexcept {
429 KOKKOS_INLINE_FUNCTION
void operator*=(
430 const volatile complex<RealType>& src)
volatile noexcept {
431 const RealType realPart = re_ * src.re_ - im_ * src.im_;
432 const RealType imagPart = re_ * src.im_ + im_ * src.re_;
438 KOKKOS_INLINE_FUNCTION
void operator*=(
439 const volatile RealType& src)
volatile noexcept {
455 template <
class RealType1,
class RealType2>
458 using common_type =
typename std::common_type<RealType1, RealType2>::type;
459 return common_type(x.real()) == common_type(y.real()) &&
460 common_type(x.imag()) == common_type(y.imag());
466 template <
class RealType1,
class RealType2>
469 using common_type =
typename std::common_type<RealType1, RealType2>::type;
470 return common_type(x.real()) == common_type(y.real()) &&
471 common_type(x.imag()) == common_type(y.imag());
475 template <
class RealType1,
class RealType2>
477 std::complex<RealType2>
const& y) noexcept {
478 using common_type =
typename std::common_type<RealType1, RealType2>::type;
479 return common_type(x.real()) == common_type(y.real()) &&
480 common_type(x.imag()) == common_type(y.imag());
485 class RealType1,
class RealType2,
487 typename std::enable_if<std::is_convertible<RealType2, RealType1>::value,
490 RealType2
const& y) noexcept {
491 using common_type =
typename std::common_type<RealType1, RealType2>::type;
492 return common_type(x.real()) == common_type(y) &&
493 common_type(x.imag()) == common_type(0);
498 class RealType1,
class RealType2,
500 typename std::enable_if<std::is_convertible<RealType1, RealType2>::value,
504 using common_type =
typename std::common_type<RealType1, RealType2>::type;
505 return common_type(x) == common_type(y.real()) &&
506 common_type(0) == common_type(y.imag());
510 template <
class RealType1,
class RealType2>
513 using common_type =
typename std::common_type<RealType1, RealType2>::type;
514 return common_type(x.real()) != common_type(y.real()) ||
515 common_type(x.imag()) != common_type(y.imag());
519 template <
class RealType1,
class RealType2>
522 using common_type =
typename std::common_type<RealType1, RealType2>::type;
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>
530 std::complex<RealType2>
const& y) noexcept {
531 using common_type =
typename std::common_type<RealType1, RealType2>::type;
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 typename std::enable_if<std::is_convertible<RealType2, RealType1>::value,
543 RealType2
const& y) noexcept {
544 using common_type =
typename std::common_type<RealType1, RealType2>::type;
545 return common_type(x.real()) != common_type(y) ||
546 common_type(x.imag()) != common_type(0);
551 class RealType1,
class RealType2,
553 typename std::enable_if<std::is_convertible<RealType1, RealType2>::value,
557 using common_type =
typename std::common_type<RealType1, RealType2>::type;
558 return common_type(x) != common_type(y.real()) ||
559 common_type(0) != common_type(y.imag());
566 template <
class RealType1,
class RealType2>
567 KOKKOS_INLINE_FUNCTION
568 complex<typename std::common_type<RealType1, RealType2>::type>
572 x.real() + y.real(), x.imag() + y.imag());
576 template <
class RealType1,
class RealType2>
577 KOKKOS_INLINE_FUNCTION
578 complex<typename std::common_type<RealType1, RealType2>::type>
581 x.real() + y, x.imag());
585 template <
class RealType1,
class RealType2>
586 KOKKOS_INLINE_FUNCTION
587 complex<typename std::common_type<RealType1, RealType2>::type>
590 x + y.real(), y.imag());
594 template <
class RealType>
601 template <
class RealType1,
class RealType2>
602 KOKKOS_INLINE_FUNCTION
603 complex<typename std::common_type<RealType1, RealType2>::type>
607 x.real() - y.real(), x.imag() - y.imag());
611 template <
class RealType1,
class RealType2>
612 KOKKOS_INLINE_FUNCTION
613 complex<typename std::common_type<RealType1, RealType2>::type>
616 x.real() - y, x.imag());
620 template <
class RealType1,
class RealType2>
621 KOKKOS_INLINE_FUNCTION
622 complex<typename std::common_type<RealType1, RealType2>::type>
625 x - y.real(), -y.imag());
629 template <
class RealType>
636 template <
class RealType1,
class RealType2>
637 KOKKOS_INLINE_FUNCTION
638 complex<typename std::common_type<RealType1, RealType2>::type>
642 x.real() * y.real() - x.imag() * y.imag(),
643 x.real() * y.imag() + x.imag() * y.real());
654 template <
class RealType1,
class RealType2>
658 x.real() * y.
real() - x.imag() * y.
imag(),
659 x.real() * y.
imag() + x.imag() * y.
real());
666 template <
class RealType1,
class RealType2>
667 KOKKOS_INLINE_FUNCTION
668 complex<typename std::common_type<RealType1, RealType2>::type>
671 x * y.real(), x * y.imag());
678 template <
class RealType1,
class RealType2>
679 KOKKOS_INLINE_FUNCTION
680 complex<typename std::common_type<RealType1, RealType2>::type>
683 x * y.real(), x * y.imag());
687 template <
class RealType>
693 template <
class RealType>
699 template <
class RealType>
701 #if !defined(__CUDA_ARCH__) && \
702 !defined(__HIP_DEVICE_COMPILE__) // FIXME_CUDA FIXME_HIP
709 template <
class RealType>
713 #if !defined(__HIP_DEVICE_COMPILE__) // FIXME_HIP
720 RealType phi = atan(x.
imag() / x.
real());
725 template <
class RealType>
729 #if !defined(__HIP_DEVICE_COMPILE__) // FIXME_HIP
736 RealType phi = atan(x.
imag() / x.
real());
741 template <
class RealType>
748 template <
class RealType>
750 #if !defined(__HIP_DEVICE_COMPILE__) // FIXME_HIP
763 template <
class RealType>
766 std::exp(c.real()) * std::sin(c.imag()));
770 template <
class RealType1,
class RealType2>
771 KOKKOS_INLINE_FUNCTION
772 complex<typename std::common_type<RealType1, RealType2>::type>
774 const RealType2& y) noexcept(noexcept(RealType1{} /
776 return complex<typename std::common_type<RealType1, RealType2>::type>(
781 template <
class RealType1,
class RealType2>
782 KOKKOS_INLINE_FUNCTION
783 complex<typename std::common_type<RealType1, RealType2>::type>
790 #if !defined(__HIP_DEVICE_COMPILE__) // FIXME_HIP
794 typename std::common_type<RealType1, RealType2>::type common_real_type;
795 const common_real_type s = fabs(
real(y)) + fabs(
imag(y));
801 return complex<common_real_type>(
real(x) / s,
imag(x) / s);
803 const complex<common_real_type> x_scaled(
real(x) / s,
imag(x) / s);
804 const complex<common_real_type> y_conj_scaled(
real(y) / s, -
imag(y) / s);
805 const RealType1 y_scaled_abs =
806 real(y_conj_scaled) *
real(y_conj_scaled) +
807 imag(y_conj_scaled) *
imag(y_conj_scaled);
808 complex<common_real_type> result = x_scaled * y_conj_scaled;
809 result /= y_scaled_abs;
815 template <
class RealType1,
class RealType2>
816 KOKKOS_INLINE_FUNCTION
817 complex<typename std::common_type<RealType1, RealType2>::type>
821 return complex<typename std::common_type<RealType1, RealType2>::type>(x) / y;
824 template <
class RealType>
825 std::ostream& operator<<(std::ostream& os, const complex<RealType>& x) {
831 template <
class RealType>
832 std::istream& operator>>(std::istream& is, complex<RealType>& x) {
833 std::complex<RealType> x_std;
840 struct reduction_identity<Kokkos::complex<T> > {
841 typedef reduction_identity<T> t_red_ident;
854 #endif // KOKKOS_COMPLEX_HPP
KOKKOS_INLINE_FUNCTION volatile RealType & imag() volatilenoexcept
The imaginary part of this complex number (volatile overload).
KOKKOS_INLINE_FUNCTION RealType real(const complex< RealType > &x) noexcept
Real part of a complex number.
KOKKOS_INLINE_FUNCTION KOKKOS_CONSTEXPR_14 RealType & real() noexcept
The real part of this complex number.
KOKKOS_INLINE_FUNCTION complex< RealType > conj(const complex< RealType > &x) noexcept
Conjugate of a complex number.
KOKKOS_INLINE_FUNCTION bool operator==(complex< RealType1 > const &x, complex< RealType2 > const &y) noexcept
Binary == operator for complex complex.
KOKKOS_INLINE_FUNCTION KOKKOS_CONSTEXPR_14 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 RealType imag() const volatilenoexcept
The imaginary part of this complex number (volatile overload).
KOKKOS_INLINE_FUNCTION Kokkos::complex< RealType > pow(const complex< RealType > &x, const RealType &e)
Power of a complex 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 complex< typename std::common_type< RealType1, RealType2 >::type > operator+(const complex< RealType1 > &x, const complex< RealType2 > &y) noexcept
Binary + operator for complex complex.
KOKKOS_INLINE_FUNCTION RealType abs(const complex< RealType > &x)
Absolute value (magnitude) of a complex number.
KOKKOS_INLINE_FUNCTION RealType imag(const complex< RealType > &x) noexcept
Imaginary part of a complex number.
KOKKOS_INLINE_FUNCTION complex(const RealType &re, const RealType &im) noexcept
Constructor that takes the real and imaginary parts.
KOKKOS_INLINE_FUNCTION RealType real() const volatilenoexcept
The real part of this complex number (volatile overload).
KOKKOS_INLINE_FUNCTION complex< typename std::common_type< RealType1, RealType2 >::type > operator/(const complex< RealType1 > &x, const RealType2 &y) noexcept(noexcept(RealType1{}/RealType2{}))
Binary operator / for complex and real numbers.
KOKKOS_INLINE_FUNCTION constexpr RealType imag() const noexcept
The imaginary part of this complex number.
KOKKOS_INLINE_FUNCTION complex & operator=(const volatile RealType &val) volatilenoexcept
Assignment operator volatile LHS and volatile RHS.
KOKKOS_INLINE_FUNCTION complex(const std::complex< RealType > &src) noexcept
Conversion constructor from std::complex.
KOKKOS_INLINE_FUNCTION volatile complex & operator=(const volatile Complex &src) volatilenoexcept
Assignment operator, volatile LHS and volatile RHS.
KOKKOS_INLINE_FUNCTION KOKKOS_CONSTEXPR_14 void imag(RealType v) noexcept
Set the imaginary part of this complex number.
KOKKOS_INLINE_FUNCTION Kokkos::complex< RealType > sqrt(const complex< RealType > &x)
Square root of a complex number.
KOKKOS_INLINE_FUNCTION complex & operator=(const RealType &val) volatilenoexcept
Assignment operator volatile LHS and non-volatile RHS.
KOKKOS_INLINE_FUNCTION complex(const volatile complex< RType > &src) noexcept
Copy constructor from volatile.
KOKKOS_INLINE_FUNCTION volatile RealType & real() volatilenoexcept
The real part of this complex number (volatile overload).
KOKKOS_INLINE_FUNCTION bool operator!=(complex< RealType1 > const &x, complex< RealType2 > const &y) noexcept
Binary != operator for complex complex.
RealType value_type
The type of the real or imaginary parts of this complex number.
KOKKOS_INLINE_FUNCTION complex< RealType > exp(const complex< RealType > &x)
Exponential of a complex number.
KOKKOS_INLINE_FUNCTION void operator=(const volatile RealType &val) noexcept
Assignment operator (from a volatile real number).
KOKKOS_INLINE_FUNCTION complex< typename std::common_type< RealType1, RealType2 >::type > operator-(const complex< RealType1 > &x, const complex< RealType2 > &y) noexcept
Binary - operator for complex.
KOKKOS_INLINE_FUNCTION void operator=(const Complex &src) volatilenoexcept
Assignment operator, for volatile *this and nonvolatile input.
KOKKOS_INLINE_FUNCTION KOKKOS_CONSTEXPR_14 void real(RealType v) noexcept
Set the real part of this complex number.
KOKKOS_INLINE_FUNCTION complex & operator=(const volatile Complex &src) noexcept
Assignment operator, volatile RHS and non-volatile LHS.
KOKKOS_INLINE_FUNCTION complex< typename std::common_type< RealType1, RealType2 >::type > operator*(const complex< RealType1 > &x, const complex< RealType2 > &y) noexcept
Binary * operator for complex.