43 #ifndef KOKKOS_COMPLEX_HPP
44 #define KOKKOS_COMPLEX_HPP
47 #include <Kokkos_NumericTraits.hpp>
60 template<
class RealType>
76 re_ (src.re_), im_ (src.im_)
81 re_ (src.re_), im_ (src.im_)
89 template<
class InputRealType>
90 complex (
const std::complex<InputRealType>& src) :
91 re_ (std::
real (src)), im_ (std::
imag (src))
99 operator std::complex<RealType> ()
const {
100 return std::complex<RealType> (re_, im_);
105 template<
class InputRealType>
106 KOKKOS_INLINE_FUNCTION
complex (
const InputRealType& val) :
107 re_ (val), im_ (static_cast<InputRealType>(0.0))
111 KOKKOS_INLINE_FUNCTION
complex(
const RealType& re,
const RealType& im):
116 template<
class RealType1,
class RealType2>
117 KOKKOS_INLINE_FUNCTION
complex (
const RealType1& re,
const RealType2& im) :
122 template<
class InputRealType>
123 KOKKOS_INLINE_FUNCTION
139 template<
class InputRealType>
140 KOKKOS_INLINE_FUNCTION
149 template<
class InputRealType>
150 KOKKOS_INLINE_FUNCTION
158 template<
class InputRealType>
159 KOKKOS_INLINE_FUNCTION
167 template<
class InputRealType>
168 KOKKOS_INLINE_FUNCTION
171 im_ =
static_cast<RealType
> (0.0);
176 template<
class InputRealType>
177 KOKKOS_INLINE_FUNCTION
180 im_ =
static_cast<RealType
> (0.0);
188 template<
class InputRealType>
190 re_ = std::real (src);
191 im_ = std::imag (src);
196 KOKKOS_INLINE_FUNCTION RealType&
imag () {
201 KOKKOS_INLINE_FUNCTION RealType&
real () {
206 KOKKOS_INLINE_FUNCTION
const RealType
imag ()
const {
211 KOKKOS_INLINE_FUNCTION
const RealType
real ()
const {
216 KOKKOS_INLINE_FUNCTION
volatile RealType&
imag ()
volatile {
221 KOKKOS_INLINE_FUNCTION
volatile RealType&
real ()
volatile {
226 KOKKOS_INLINE_FUNCTION
const RealType
imag ()
const volatile {
231 KOKKOS_INLINE_FUNCTION
const RealType
real ()
const volatile {
236 KOKKOS_INLINE_FUNCTION
void imag (RealType v) {
241 KOKKOS_INLINE_FUNCTION
void real (RealType v) {
245 template<
typename InputRealType>
246 KOKKOS_INLINE_FUNCTION
249 static_assert(std::is_convertible<InputRealType,RealType>::value,
250 "InputRealType must be convertible to RealType");
256 template<
typename InputRealType>
257 KOKKOS_INLINE_FUNCTION
259 operator += (
const volatile complex<InputRealType>& src)
volatile {
260 static_assert(std::is_convertible<InputRealType,RealType>::value,
261 "InputRealType must be convertible to RealType");
266 KOKKOS_INLINE_FUNCTION
268 operator += (
const std::complex<RealType>& src) {
274 template<
typename InputRealType>
275 KOKKOS_INLINE_FUNCTION
277 operator += (
const InputRealType& src) {
278 static_assert(std::is_convertible<InputRealType,RealType>::value,
279 "InputRealType must be convertible to RealType");
284 template<
typename InputRealType>
285 KOKKOS_INLINE_FUNCTION
287 operator += (
const volatile InputRealType& src)
volatile {
288 static_assert(std::is_convertible<InputRealType,RealType>::value,
289 "InputRealType must be convertible to RealType");
293 template<
typename InputRealType>
294 KOKKOS_INLINE_FUNCTION
296 operator -= (
const complex<InputRealType>& src) {
297 static_assert(std::is_convertible<InputRealType,RealType>::value,
298 "InputRealType must be convertible to RealType");
304 KOKKOS_INLINE_FUNCTION
306 operator -= (
const std::complex<RealType>& src) {
312 template<
typename InputRealType>
313 KOKKOS_INLINE_FUNCTION
315 operator -= (
const InputRealType& src) {
316 static_assert(std::is_convertible<InputRealType,RealType>::value,
317 "InputRealType must be convertible to RealType");
322 template<
typename InputRealType>
323 KOKKOS_INLINE_FUNCTION
325 operator *= (
const complex<InputRealType>& src) {
326 static_assert(std::is_convertible<InputRealType,RealType>::value,
327 "InputRealType must be convertible to RealType");
328 const RealType realPart = re_ * src.re_ - im_ * src.im_;
329 const RealType imagPart = re_ * src.im_ + im_ * src.re_;
335 template<
typename InputRealType>
336 KOKKOS_INLINE_FUNCTION
338 operator *= (
const volatile complex<InputRealType>& src)
volatile {
339 static_assert(std::is_convertible<InputRealType,RealType>::value,
340 "InputRealType must be convertible to RealType");
341 const RealType realPart = re_ * src.re_ - im_ * src.im_;
342 const RealType imagPart = re_ * src.im_ + im_ * src.re_;
347 KOKKOS_INLINE_FUNCTION
349 operator *= (
const std::complex<RealType>& src) {
350 const RealType realPart = re_ * src.real() - im_ * src.imag();
351 const RealType imagPart = re_ * src.imag() + im_ * src.real();
357 template<
typename InputRealType>
358 KOKKOS_INLINE_FUNCTION
360 operator *= (
const InputRealType& src) {
361 static_assert(std::is_convertible<InputRealType,RealType>::value,
362 "InputRealType must be convertible to RealType");
368 template<
typename InputRealType>
369 KOKKOS_INLINE_FUNCTION
371 operator *= (
const volatile InputRealType& src)
volatile {
372 static_assert(std::is_convertible<InputRealType,RealType>::value,
373 "InputRealType must be convertible to RealType");
378 template<
typename InputRealType>
379 KOKKOS_INLINE_FUNCTION
381 operator /= (
const complex<InputRealType>& y) {
382 static_assert(std::is_convertible<InputRealType,RealType>::value,
383 "InputRealType must be convertible to RealType");
388 const RealType s = std::fabs (y.real ()) + std::fabs (y.imag ());
398 const complex<RealType> x_scaled (this->re_ / s, this->im_ / s);
399 const complex<RealType> y_conj_scaled (y.re_ / s, -(y.im_) / s);
400 const RealType y_scaled_abs = y_conj_scaled.re_ * y_conj_scaled.re_ +
401 y_conj_scaled.im_ * y_conj_scaled.im_;
402 *
this = x_scaled * y_conj_scaled;
403 *
this /= y_scaled_abs;
408 KOKKOS_INLINE_FUNCTION
410 operator /= (
const std::complex<RealType>& y) {
415 const RealType s = std::fabs (y.real ()) + std::fabs (y.imag ());
425 const complex<RealType> x_scaled (this->re_ / s, this->im_ / s);
426 const complex<RealType> y_conj_scaled (y.re_ / s, -(y.im_) / s);
427 const RealType y_scaled_abs = y_conj_scaled.re_ * y_conj_scaled.re_ +
428 y_conj_scaled.im_ * y_conj_scaled.im_;
429 *
this = x_scaled * y_conj_scaled;
430 *
this /= y_scaled_abs;
436 template<
typename InputRealType>
437 KOKKOS_INLINE_FUNCTION
439 operator /= (
const InputRealType& src) {
440 static_assert(std::is_convertible<InputRealType,RealType>::value,
441 "InputRealType must be convertible to RealType");
448 template<
typename InputRealType>
449 KOKKOS_INLINE_FUNCTION
451 operator == (
const complex<InputRealType>& src) {
452 static_assert(std::is_convertible<InputRealType,RealType>::value,
453 "InputRealType must be convertible to RealType");
455 return (re_ == static_cast<RealType>(src.re_)) && (im_ ==
static_cast<RealType
>(src.im_));
458 KOKKOS_INLINE_FUNCTION
460 operator == (
const std::complex<RealType>& src) {
461 return (re_ == src.real()) && (im_ == src.imag());
464 template<
typename InputRealType>
465 KOKKOS_INLINE_FUNCTION
467 operator == (
const InputRealType src) {
468 static_assert(std::is_convertible<InputRealType,RealType>::value,
469 "InputRealType must be convertible to RealType");
471 return (re_ == static_cast<RealType>(src)) && (im_ == RealType(0));
474 template<
typename InputRealType>
475 KOKKOS_INLINE_FUNCTION
477 operator != (
const complex<InputRealType>& src) {
478 static_assert(std::is_convertible<InputRealType,RealType>::value,
479 "InputRealType must be convertible to RealType");
481 return (re_ != static_cast<RealType>(src.re_)) || (im_ !=
static_cast<RealType
>(src.im_));
484 KOKKOS_INLINE_FUNCTION
486 operator != (
const std::complex<RealType>& src) {
487 return (re_ != src.real()) || (im_ != src.imag());
490 template<
typename InputRealType>
491 KOKKOS_INLINE_FUNCTION
493 operator != (
const InputRealType src) {
494 static_assert(std::is_convertible<InputRealType,RealType>::value,
495 "InputRealType must be convertible to RealType");
497 return (re_ != static_cast<RealType>(src)) || (im_ != RealType(0));
504 template<
class RealType1,
class RealType2>
505 KOKKOS_INLINE_FUNCTION
506 complex<typename std::common_type<RealType1,RealType2>::type>
512 template<
class RealType1,
class RealType2>
513 KOKKOS_INLINE_FUNCTION
514 complex<typename std::common_type<RealType1,RealType2>::type>
520 template<
class RealType1,
class RealType2>
521 KOKKOS_INLINE_FUNCTION
522 complex<typename std::common_type<RealType1,RealType2>::type>
528 template<
class RealType>
529 KOKKOS_INLINE_FUNCTION
536 template<
class RealType1,
class RealType2>
537 KOKKOS_INLINE_FUNCTION
538 complex<typename std::common_type<RealType1,RealType2>::type>
544 template<
class RealType1,
class RealType2>
545 KOKKOS_INLINE_FUNCTION
546 complex<typename std::common_type<RealType1,RealType2>::type>
552 template<
class RealType1,
class RealType2>
553 KOKKOS_INLINE_FUNCTION
554 complex<typename std::common_type<RealType1,RealType2>::type>
560 template<
class RealType>
561 KOKKOS_INLINE_FUNCTION
568 template<
class RealType1,
class RealType2>
569 KOKKOS_INLINE_FUNCTION
570 complex<typename std::common_type<RealType1,RealType2>::type>
586 template<
class RealType1,
class RealType2>
588 complex<typename std::common_type<RealType1,RealType2>::type>
591 x.real () * y.
imag () + x.imag () * y.
real ());
598 template<
class RealType1,
class RealType2>
599 KOKKOS_INLINE_FUNCTION
600 complex<typename std::common_type<RealType1,RealType2>::type>
609 template<
class RealType1,
class RealType2>
610 KOKKOS_INLINE_FUNCTION
611 complex<typename std::common_type<RealType1,RealType2>::type>
617 template<
class RealType>
618 KOKKOS_INLINE_FUNCTION
624 template<
class RealType>
625 KOKKOS_INLINE_FUNCTION
631 template<
class RealType>
632 KOKKOS_INLINE_FUNCTION
639 template<
class RealType>
640 KOKKOS_INLINE_FUNCTION
643 RealType phi = std::atan(x.
imag()/x.
real());
648 template<
class RealType>
649 KOKKOS_INLINE_FUNCTION
652 RealType phi = std::atan(x.
imag()/x.
real());
657 template<
class RealType>
658 KOKKOS_INLINE_FUNCTION
664 template<
class RealType>
665 KOKKOS_INLINE_FUNCTION
673 template<
class RealType>
676 exp (
const std::complex<RealType>& c) {
677 return complex<RealType>( std::exp( c.real() )*std::cos( c.imag() ), std::exp( c.real() )*std::sin( c.imag() ) );
681 template<
class RealType1,
class RealType2>
682 KOKKOS_INLINE_FUNCTION
683 complex<typename std::common_type<RealType1,RealType2>::type>
689 template<
class RealType1,
class RealType2>
690 KOKKOS_INLINE_FUNCTION
691 complex<typename std::common_type<RealType1,RealType2>::type>
696 typedef typename std::common_type<RealType1,RealType2>::type common_real_type;
697 const common_real_type s = std::fabs (
real (y)) + std::fabs (
imag (y));
708 const RealType1 y_scaled_abs =
real (y_conj_scaled) *
real (y_conj_scaled) +
709 imag (y_conj_scaled) *
imag (y_conj_scaled);
711 result /= y_scaled_abs;
717 template<
class RealType1,
class RealType2>
718 KOKKOS_INLINE_FUNCTION
719 complex<typename std::common_type<RealType1,RealType2>::type>
725 template<
class RealType1,
class RealType2>
726 KOKKOS_INLINE_FUNCTION
729 typedef typename std::common_type<RealType1,RealType2>::type common_real_type;
730 return ( static_cast<common_real_type>(
real (x)) == static_cast<common_real_type>(
real (y)) &&
731 static_cast<common_real_type>(
imag (x)) == static_cast<common_real_type>(
imag (y)) );
740 template<
class RealType1,
class RealType2>
744 typedef typename std::common_type<RealType1,RealType2>::type common_real_type;
745 return ( static_cast<common_real_type>(std::real (x)) == static_cast<common_real_type>(
real (y)) &&
746 static_cast<common_real_type>(std::imag (x)) == static_cast<common_real_type>(
imag (y)) );
750 template<
class RealType1,
class RealType2>
751 KOKKOS_INLINE_FUNCTION
754 typedef typename std::common_type<RealType1,RealType2>::type common_real_type;
755 return ( static_cast<common_real_type>(
real (x)) == static_cast<common_real_type>(y) &&
756 static_cast<common_real_type>(
imag (x)) == static_cast<common_real_type>(0.0) );
760 template<
class RealType1,
class RealType2>
761 KOKKOS_INLINE_FUNCTION
768 template<
class RealType1,
class RealType2>
769 KOKKOS_INLINE_FUNCTION
772 typedef typename std::common_type<RealType1,RealType2>::type common_real_type;
773 return ( static_cast<common_real_type>(
real (x)) != static_cast<common_real_type>(
real (y)) ||
774 static_cast<common_real_type>(
imag (x)) != static_cast<common_real_type>(
imag (y)) );
778 template<
class RealType1,
class RealType2>
782 typedef typename std::common_type<RealType1,RealType2>::type common_real_type;
783 return ( static_cast<common_real_type>(std::real (x)) != static_cast<common_real_type>(
real (y)) ||
784 static_cast<common_real_type>(std::imag (x)) != static_cast<common_real_type>(
imag (y)) );
788 template<
class RealType1,
class RealType2>
789 KOKKOS_INLINE_FUNCTION
792 typedef typename std::common_type<RealType1,RealType2>::type common_real_type;
793 return ( static_cast<common_real_type>(
real (x)) != static_cast<common_real_type>(y) ||
794 static_cast<common_real_type>(
imag (x)) != static_cast<common_real_type>(0.0) );
798 template<
class RealType1,
class RealType2>
799 KOKKOS_INLINE_FUNCTION
805 template<
class RealType>
806 std::ostream& operator << (std::ostream& os, const complex<RealType>& x) {
812 template<
class RealType>
813 std::ostream& operator >> (std::ostream& os, complex<RealType>& x) {
814 std::complex<RealType> x_std;
822 struct reduction_identity<Kokkos::complex<T> > {
823 typedef reduction_identity<T> t_red_ident;
832 #endif // KOKKOS_COMPLEX_HPP
KOKKOS_INLINE_FUNCTION bool operator==(const complex< RealType1 > &x, const complex< RealType2 > &y)
Equality operator for two complex numbers.
KOKKOS_INLINE_FUNCTION bool operator!=(const complex< RealType1 > &x, const complex< RealType2 > &y)
Inequality operator for two complex numbers.
KOKKOS_INLINE_FUNCTION RealType & imag()
The imaginary part of this complex number.
KOKKOS_INLINE_FUNCTION complex(const RealType1 &re, const RealType2 &im)
Constructor that takes the real and imaginary parts.
Partial reimplementation of std::complex that works as the result of a Kokkos::parallel_reduce.
KOKKOS_INLINE_FUNCTION complex(const InputRealType &val)
Constructor that takes just the real part, and sets the imaginary part to zero.
KOKKOS_INLINE_FUNCTION Kokkos::complex< RealType > pow(const complex< RealType > &x, const RealType &e)
Power of a complex number.
KOKKOS_INLINE_FUNCTION complex(const volatile complex< RealType > &src)
Copy constructor from volatile.
KOKKOS_INLINE_FUNCTION const RealType real() const
The real part of this complex number.
KOKKOS_INLINE_FUNCTION complex(const complex< RealType > &src)
Copy constructor.
KOKKOS_INLINE_FUNCTION complex()
Default constructor (initializes both real and imaginary parts to zero).
KOKKOS_INLINE_FUNCTION RealType abs(const complex< RealType > &x)
Absolute value (magnitude) of a complex number.
KOKKOS_INLINE_FUNCTION RealType & real()
The real part of this complex number.
complex(const std::complex< InputRealType > &src)
Conversion constructor from std::complex.
KOKKOS_INLINE_FUNCTION volatile RealType & imag() volatile
The imaginary part of this complex number (volatile overload).
KOKKOS_INLINE_FUNCTION complex< typename std::common_type< RealType1, RealType2 >::type > operator-(const complex< RealType1 > &x, const complex< RealType2 > &y)
Binary - operator for complex.
KOKKOS_INLINE_FUNCTION const RealType imag() const
The imaginary part of this complex number.
KOKKOS_INLINE_FUNCTION complex< typename std::common_type< RealType1, RealType2 >::type > operator+(const complex< RealType1 > &x, const complex< RealType2 > &y)
Binary + operator for complex complex.
KOKKOS_INLINE_FUNCTION complex< RealType > & operator=(const complex< InputRealType > &src)
Assignment operator.
RealType value_type
The type of the real or imaginary parts of this complex number.
KOKKOS_INLINE_FUNCTION RealType real(const complex< RealType > &x)
Real part of a complex number.
KOKKOS_INLINE_FUNCTION void imag(RealType v)
Set the imaginary part of this complex number.
KOKKOS_INLINE_FUNCTION void real(RealType v)
Set the real part of this complex number.
KOKKOS_INLINE_FUNCTION volatile RealType & real() volatile
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)
Binary operator / for complex and real numbers.
KOKKOS_INLINE_FUNCTION const RealType imag() const volatile
The imaginary part of this complex number (volatile overload).
KOKKOS_INLINE_FUNCTION Kokkos::complex< RealType > sqrt(const complex< RealType > &x)
Square root of a complex number.
KOKKOS_INLINE_FUNCTION const RealType real() const volatile
The real part of this complex number (volatile overload).
KOKKOS_INLINE_FUNCTION complex< RealType > conj(const complex< RealType > &x)
Conjugate of a complex number.
KOKKOS_INLINE_FUNCTION complex< typename std::common_type< RealType1, RealType2 >::type > operator*(const complex< RealType1 > &x, const complex< RealType2 > &y)
Binary * operator for complex.
KOKKOS_INLINE_FUNCTION complex< RealType > exp(const complex< RealType > &x)
Exponential of a complex number.
KOKKOS_INLINE_FUNCTION RealType imag(const complex< RealType > &x)
Imaginary part of a complex number.