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
 
   73   template <class RType,
 
   74             std::enable_if_t<std::is_convertible_v<RType, RealType>, 
int> = 0>
 
   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) {}
 
  119       const RealType& val) noexcept {
 
  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+=(
 
  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 constexpr 
bool operator==(
 
  500     complex<RealType1> const& x, 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 constexpr 
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 constexpr 
bool operator==(
 
  544     RealType1 
const& x, 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 constexpr 
bool operator!=(
 
  553     complex<RealType1> 
const& x, 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 constexpr 
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 constexpr 
bool operator!=(
 
  595     RealType1 
const& x, 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 void real(RealType v) noexcept
Set the real part of this complex number. 
 
KOKKOS_INLINE_FUNCTION constexpr complex & operator=(const RealType &val) noexcept
Assignment operator (from a real 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. 
 
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 constexpr 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. 
 
KOKKOS_INLINE_FUNCTION constexpr complex(const RealType &val) noexcept
Constructor that takes just the real part, and sets the imaginary part to zero. 
 
RealType value_type
The type of the real or imaginary parts of this complex number.