Kokkos Core Kernels Package  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
Kokkos_Complex.hpp
1 /*
2 //@HEADER
3 // ************************************************************************
4 //
5 // Kokkos v. 2.0
6 // Copyright (2014) Sandia Corporation
7 //
8 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
9 // the U.S. Government retains certain rights in this software.
10 //
11 // Redistribution and use in source and binary forms, with or without
12 // modification, are permitted provided that the following conditions are
13 // met:
14 //
15 // 1. Redistributions of source code must retain the above copyright
16 // notice, this list of conditions and the following disclaimer.
17 //
18 // 2. Redistributions in binary form must reproduce the above copyright
19 // notice, this list of conditions and the following disclaimer in the
20 // documentation and/or other materials provided with the distribution.
21 //
22 // 3. Neither the name of the Corporation nor the names of the
23 // contributors may be used to endorse or promote products derived from
24 // this software without specific prior written permission.
25 //
26 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
27 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
30 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
31 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
32 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
33 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
34 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
35 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
36 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37 //
38 // Questions? Contact Christian R. Trott (crtrott@sandia.gov)
39 //
40 // ************************************************************************
41 //@HEADER
42 */
43 #ifndef KOKKOS_COMPLEX_HPP
44 #define KOKKOS_COMPLEX_HPP
45 
46 #include <Kokkos_Atomic.hpp>
47 #include <Kokkos_NumericTraits.hpp>
48 #include <complex>
49 #include <iostream>
50 
51 namespace Kokkos {
52 
60 template<class RealType>
61 class complex {
62 private:
63  RealType re_, im_;
64 
65 public:
67  typedef RealType value_type;
68 
70  KOKKOS_INLINE_FUNCTION complex () :
71  re_ (0.0), im_ (0.0)
72  {}
73 
75  KOKKOS_INLINE_FUNCTION complex (const complex<RealType>& src) :
76  re_ (src.re_), im_ (src.im_)
77  {}
78 
80  KOKKOS_INLINE_FUNCTION complex (const volatile complex<RealType>& src) :
81  re_ (src.re_), im_ (src.im_)
82  {}
83 
89  template<class InputRealType>
90  complex (const std::complex<InputRealType>& src) :
91  re_ (std::real (src)), im_ (std::imag (src))
92  {}
93 
99  operator std::complex<RealType> () const {
100  return std::complex<RealType> (re_, im_);
101  }
102 
105  template<class InputRealType>
106  KOKKOS_INLINE_FUNCTION complex (const InputRealType& val) :
107  re_ (val), im_ (static_cast<InputRealType>(0.0))
108  {}
109 
110  // BUG HCC WORKAROUND
111  KOKKOS_INLINE_FUNCTION complex( const RealType& re, const RealType& im):
112  re_ (re), im_ (im)
113  {}
114 
116  template<class RealType1, class RealType2>
117  KOKKOS_INLINE_FUNCTION complex (const RealType1& re, const RealType2& im) :
118  re_ (re), im_ (im)
119  {}
120 
122  template<class InputRealType>
123  KOKKOS_INLINE_FUNCTION
125  re_ = src.re_;
126  im_ = src.im_;
127  return *this;
128  }
129 
139  template<class InputRealType>
140  KOKKOS_INLINE_FUNCTION
141  void operator= (const complex<InputRealType>& src) volatile {
142  re_ = src.re_;
143  im_ = src.im_;
144  // We deliberately do not return anything here. See explanation
145  // in public documentation above.
146  }
147 
149  template<class InputRealType>
150  KOKKOS_INLINE_FUNCTION
151  volatile complex<RealType>& operator= (const volatile complex<InputRealType>& src) volatile {
152  re_ = src.re_;
153  im_ = src.im_;
154  return *this;
155  }
156 
158  template<class InputRealType>
159  KOKKOS_INLINE_FUNCTION
161  re_ = src.re_;
162  im_ = src.im_;
163  return *this;
164  }
165 
167  template<class InputRealType>
168  KOKKOS_INLINE_FUNCTION
169  complex<RealType>& operator= (const InputRealType& val) {
170  re_ = val;
171  im_ = static_cast<RealType> (0.0);
172  return *this;
173  }
174 
176  template<class InputRealType>
177  KOKKOS_INLINE_FUNCTION
178  void operator= (const InputRealType& val) volatile {
179  re_ = val;
180  im_ = static_cast<RealType> (0.0);
181  }
182 
188  template<class InputRealType>
189  complex<RealType>& operator= (const std::complex<InputRealType>& src) {
190  re_ = std::real (src);
191  im_ = std::imag (src);
192  return *this;
193  }
194 
196  KOKKOS_INLINE_FUNCTION RealType& imag () {
197  return im_;
198  }
199 
201  KOKKOS_INLINE_FUNCTION RealType& real () {
202  return re_;
203  }
204 
206  KOKKOS_INLINE_FUNCTION const RealType imag () const {
207  return im_;
208  }
209 
211  KOKKOS_INLINE_FUNCTION const RealType real () const {
212  return re_;
213  }
214 
216  KOKKOS_INLINE_FUNCTION volatile RealType& imag () volatile {
217  return im_;
218  }
219 
221  KOKKOS_INLINE_FUNCTION volatile RealType& real () volatile {
222  return re_;
223  }
224 
226  KOKKOS_INLINE_FUNCTION const RealType imag () const volatile {
227  return im_;
228  }
229 
231  KOKKOS_INLINE_FUNCTION const RealType real () const volatile {
232  return re_;
233  }
234 
236  KOKKOS_INLINE_FUNCTION void imag (RealType v) {
237  im_ = v;
238  }
239 
241  KOKKOS_INLINE_FUNCTION void real (RealType v) {
242  re_ = v;
243  }
244 
245  template<typename InputRealType>
246  KOKKOS_INLINE_FUNCTION
248  operator += (const complex<InputRealType>& src) {
249  static_assert(std::is_convertible<InputRealType,RealType>::value,
250  "InputRealType must be convertible to RealType");
251  re_ += src.re_;
252  im_ += src.im_;
253  return *this;
254  }
255 
256  template<typename InputRealType>
257  KOKKOS_INLINE_FUNCTION
258  void
259  operator += (const volatile complex<InputRealType>& src) volatile {
260  static_assert(std::is_convertible<InputRealType,RealType>::value,
261  "InputRealType must be convertible to RealType");
262  re_ += src.re_;
263  im_ += src.im_;
264  }
265 
266  KOKKOS_INLINE_FUNCTION
267  complex<RealType>&
268  operator += (const std::complex<RealType>& src) {
269  re_ += src.real();
270  im_ += src.imag();
271  return *this;
272  }
273 
274  template<typename InputRealType>
275  KOKKOS_INLINE_FUNCTION
276  complex<RealType>&
277  operator += (const InputRealType& src) {
278  static_assert(std::is_convertible<InputRealType,RealType>::value,
279  "InputRealType must be convertible to RealType");
280  re_ += src;
281  return *this;
282  }
283 
284  template<typename InputRealType>
285  KOKKOS_INLINE_FUNCTION
286  void
287  operator += (const volatile InputRealType& src) volatile {
288  static_assert(std::is_convertible<InputRealType,RealType>::value,
289  "InputRealType must be convertible to RealType");
290  re_ += src;
291  }
292 
293  template<typename InputRealType>
294  KOKKOS_INLINE_FUNCTION
295  complex<RealType>&
296  operator -= (const complex<InputRealType>& src) {
297  static_assert(std::is_convertible<InputRealType,RealType>::value,
298  "InputRealType must be convertible to RealType");
299  re_ -= src.re_;
300  im_ -= src.im_;
301  return *this;
302  }
303 
304  KOKKOS_INLINE_FUNCTION
305  complex<RealType>&
306  operator -= (const std::complex<RealType>& src) {
307  re_ -= src.real();
308  im_ -= src.imag();
309  return *this;
310  }
311 
312  template<typename InputRealType>
313  KOKKOS_INLINE_FUNCTION
314  complex<RealType>&
315  operator -= (const InputRealType& src) {
316  static_assert(std::is_convertible<InputRealType,RealType>::value,
317  "InputRealType must be convertible to RealType");
318  re_ -= src;
319  return *this;
320  }
321 
322  template<typename InputRealType>
323  KOKKOS_INLINE_FUNCTION
324  complex<RealType>&
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_;
330  re_ = realPart;
331  im_ = imagPart;
332  return *this;
333  }
334 
335  template<typename InputRealType>
336  KOKKOS_INLINE_FUNCTION
337  void
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_;
343  re_ = realPart;
344  im_ = imagPart;
345  }
346 
347  KOKKOS_INLINE_FUNCTION
348  complex<RealType>&
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();
352  re_ = realPart;
353  im_ = imagPart;
354  return *this;
355  }
356 
357  template<typename InputRealType>
358  KOKKOS_INLINE_FUNCTION
359  complex<RealType>&
360  operator *= (const InputRealType& src) {
361  static_assert(std::is_convertible<InputRealType,RealType>::value,
362  "InputRealType must be convertible to RealType");
363  re_ *= src;
364  im_ *= src;
365  return *this;
366  }
367 
368  template<typename InputRealType>
369  KOKKOS_INLINE_FUNCTION
370  void
371  operator *= (const volatile InputRealType& src) volatile {
372  static_assert(std::is_convertible<InputRealType,RealType>::value,
373  "InputRealType must be convertible to RealType");
374  re_ *= src;
375  im_ *= src;
376  }
377 
378  template<typename InputRealType>
379  KOKKOS_INLINE_FUNCTION
380  complex<RealType>&
381  operator /= (const complex<InputRealType>& y) {
382  static_assert(std::is_convertible<InputRealType,RealType>::value,
383  "InputRealType must be convertible to RealType");
384 
385  // Scale (by the "1-norm" of y) to avoid unwarranted overflow.
386  // If the real part is +/-Inf and the imaginary part is -/+Inf,
387  // this won't change the result.
388  const RealType s = std::fabs (y.real ()) + std::fabs (y.imag ());
389 
390  // If s is 0, then y is zero, so x/y == real(x)/0 + i*imag(x)/0.
391  // In that case, the relation x/y == (x/s) / (y/s) doesn't hold,
392  // because y/s is NaN.
393  if (s == 0.0) {
394  this->re_ /= s;
395  this->im_ /= s;
396  }
397  else {
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_; // abs(y) == abs(conj(y))
402  *this = x_scaled * y_conj_scaled;
403  *this /= y_scaled_abs;
404  }
405  return *this;
406  }
407 
408  KOKKOS_INLINE_FUNCTION
409  complex<RealType>&
410  operator /= (const std::complex<RealType>& y) {
411 
412  // Scale (by the "1-norm" of y) to avoid unwarranted overflow.
413  // If the real part is +/-Inf and the imaginary part is -/+Inf,
414  // this won't change the result.
415  const RealType s = std::fabs (y.real ()) + std::fabs (y.imag ());
416 
417  // If s is 0, then y is zero, so x/y == real(x)/0 + i*imag(x)/0.
418  // In that case, the relation x/y == (x/s) / (y/s) doesn't hold,
419  // because y/s is NaN.
420  if (s == 0.0) {
421  this->re_ /= s;
422  this->im_ /= s;
423  }
424  else {
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_; // abs(y) == abs(conj(y))
429  *this = x_scaled * y_conj_scaled;
430  *this /= y_scaled_abs;
431  }
432  return *this;
433  }
434 
435 
436  template<typename InputRealType>
437  KOKKOS_INLINE_FUNCTION
438  complex<RealType>&
439  operator /= (const InputRealType& src) {
440  static_assert(std::is_convertible<InputRealType,RealType>::value,
441  "InputRealType must be convertible to RealType");
442 
443  re_ /= src;
444  im_ /= src;
445  return *this;
446  }
447 
448  template<typename InputRealType>
449  KOKKOS_INLINE_FUNCTION
450  bool
451  operator == (const complex<InputRealType>& src) {
452  static_assert(std::is_convertible<InputRealType,RealType>::value,
453  "InputRealType must be convertible to RealType");
454 
455  return (re_ == static_cast<RealType>(src.re_)) && (im_ == static_cast<RealType>(src.im_));
456  }
457 
458  KOKKOS_INLINE_FUNCTION
459  bool
460  operator == (const std::complex<RealType>& src) {
461  return (re_ == src.real()) && (im_ == src.imag());
462  }
463 
464  template<typename InputRealType>
465  KOKKOS_INLINE_FUNCTION
466  bool
467  operator == (const InputRealType src) {
468  static_assert(std::is_convertible<InputRealType,RealType>::value,
469  "InputRealType must be convertible to RealType");
470 
471  return (re_ == static_cast<RealType>(src)) && (im_ == RealType(0));
472  }
473 
474  template<typename InputRealType>
475  KOKKOS_INLINE_FUNCTION
476  bool
477  operator != (const complex<InputRealType>& src) {
478  static_assert(std::is_convertible<InputRealType,RealType>::value,
479  "InputRealType must be convertible to RealType");
480 
481  return (re_ != static_cast<RealType>(src.re_)) || (im_ != static_cast<RealType>(src.im_));
482  }
483 
484  KOKKOS_INLINE_FUNCTION
485  bool
486  operator != (const std::complex<RealType>& src) {
487  return (re_ != src.real()) || (im_ != src.imag());
488  }
489 
490  template<typename InputRealType>
491  KOKKOS_INLINE_FUNCTION
492  bool
493  operator != (const InputRealType src) {
494  static_assert(std::is_convertible<InputRealType,RealType>::value,
495  "InputRealType must be convertible to RealType");
496 
497  return (re_ != static_cast<RealType>(src)) || (im_ != RealType(0));
498  }
499 
500 };
501 
502 
504 template<class RealType1, class RealType2>
505 KOKKOS_INLINE_FUNCTION
506 complex<typename std::common_type<RealType1,RealType2>::type>
509 }
510 
512 template<class RealType1, class RealType2>
513 KOKKOS_INLINE_FUNCTION
514 complex<typename std::common_type<RealType1,RealType2>::type>
515 operator + (const complex<RealType1>& x, const RealType2& y) {
517 }
518 
520 template<class RealType1, class RealType2>
521 KOKKOS_INLINE_FUNCTION
522 complex<typename std::common_type<RealType1,RealType2>::type>
523 operator + (const RealType1& x, const complex<RealType2>& y) {
525 }
526 
528 template<class RealType>
529 KOKKOS_INLINE_FUNCTION
530 complex<RealType>
532  return x;
533 }
534 
536 template<class RealType1, class RealType2>
537 KOKKOS_INLINE_FUNCTION
538 complex<typename std::common_type<RealType1,RealType2>::type>
541 }
542 
544 template<class RealType1, class RealType2>
545 KOKKOS_INLINE_FUNCTION
546 complex<typename std::common_type<RealType1,RealType2>::type>
547 operator - (const complex<RealType1>& x, const RealType2& y) {
549 }
550 
552 template<class RealType1, class RealType2>
553 KOKKOS_INLINE_FUNCTION
554 complex<typename std::common_type<RealType1,RealType2>::type>
555 operator - (const RealType1& x, const complex<RealType2>& y) {
557 }
558 
560 template<class RealType>
561 KOKKOS_INLINE_FUNCTION
562 complex<RealType>
564  return complex<RealType> (-x.real (), -x.imag ());
565 }
566 
568 template<class RealType1, class RealType2>
569 KOKKOS_INLINE_FUNCTION
570 complex<typename std::common_type<RealType1,RealType2>::type>
573  x.real () * y.imag () + x.imag () * y.real ());
574 }
575 
586 template<class RealType1, class RealType2>
587 inline
588 complex<typename std::common_type<RealType1,RealType2>::type>
589 operator * (const std::complex<RealType1>& x, const complex<RealType2>& y) {
590  return complex<typename std::common_type<RealType1,RealType2>::type> (x.real () * y.real () - x.imag () * y.imag (),
591  x.real () * y.imag () + x.imag () * y.real ());
592 }
593 
598 template<class RealType1, class RealType2>
599 KOKKOS_INLINE_FUNCTION
600 complex<typename std::common_type<RealType1,RealType2>::type>
601 operator * (const RealType1& x, const complex<RealType2>& y) {
603 }
604 
609 template<class RealType1, class RealType2>
610 KOKKOS_INLINE_FUNCTION
611 complex<typename std::common_type<RealType1,RealType2>::type>
612 operator * (const complex<RealType1>& y, const RealType2& x) {
614 }
615 
617 template<class RealType>
618 KOKKOS_INLINE_FUNCTION
619 RealType imag (const complex<RealType>& x) {
620  return x.imag ();
621 }
622 
624 template<class RealType>
625 KOKKOS_INLINE_FUNCTION
626 RealType real (const complex<RealType>& x) {
627  return x.real ();
628 }
629 
631 template<class RealType>
632 KOKKOS_INLINE_FUNCTION
633 RealType abs (const complex<RealType>& x) {
634  // FIXME (mfh 31 Oct 2014) Scale to avoid unwarranted overflow.
635  return std::sqrt (real (x) * real (x) + imag (x) * imag (x));
636 }
637 
639 template<class RealType>
640 KOKKOS_INLINE_FUNCTION
641 Kokkos::complex<RealType> pow (const complex<RealType>& x, const RealType& e) {
642  RealType r = abs(x);
643  RealType phi = std::atan(x.imag()/x.real());
644  return std::pow(r,e) * Kokkos::complex<RealType>(std::cos(phi*e),std::sin(phi*e));
645 }
646 
648 template<class RealType>
649 KOKKOS_INLINE_FUNCTION
651  RealType r = abs(x);
652  RealType phi = std::atan(x.imag()/x.real());
653  return std::sqrt(r) * Kokkos::complex<RealType>(std::cos(phi*0.5),std::sin(phi*0.5));
654 }
655 
657 template<class RealType>
658 KOKKOS_INLINE_FUNCTION
660  return complex<RealType> (real (x), -imag (x));
661 }
662 
664 template<class RealType>
665 KOKKOS_INLINE_FUNCTION
667  return std::exp(x.real()) * complex<RealType> (std::cos (x.imag()), std::sin(x.imag()));
668 }
669 
673 template<class RealType>
674 inline
675 complex<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() ) );
678 }
679 
681 template<class RealType1, class RealType2>
682 KOKKOS_INLINE_FUNCTION
683 complex<typename std::common_type<RealType1,RealType2>::type>
684 operator / (const complex<RealType1>& x, const RealType2& y) {
686 }
687 
689 template<class RealType1, class RealType2>
690 KOKKOS_INLINE_FUNCTION
691 complex<typename std::common_type<RealType1,RealType2>::type>
693  // Scale (by the "1-norm" of y) to avoid unwarranted overflow.
694  // If the real part is +/-Inf and the imaginary part is -/+Inf,
695  // this won't change the result.
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));
698 
699  // If s is 0, then y is zero, so x/y == real(x)/0 + i*imag(x)/0.
700  // In that case, the relation x/y == (x/s) / (y/s) doesn't hold,
701  // because y/s is NaN.
702  if (s == 0.0) {
703  return complex<common_real_type> (real (x) / s, imag (x) / s);
704  }
705  else {
706  const complex<common_real_type> x_scaled (real (x) / s, imag (x) / s);
707  const complex<common_real_type> y_conj_scaled (real (y) / s, -imag (y) / s);
708  const RealType1 y_scaled_abs = real (y_conj_scaled) * real (y_conj_scaled) +
709  imag (y_conj_scaled) * imag (y_conj_scaled); // abs(y) == abs(conj(y))
710  complex<common_real_type> result = x_scaled * y_conj_scaled;
711  result /= y_scaled_abs;
712  return result;
713  }
714 }
715 
717 template<class RealType1, class RealType2>
718 KOKKOS_INLINE_FUNCTION
719 complex<typename std::common_type<RealType1,RealType2>::type>
720 operator / (const RealType1& x, const complex<RealType2>& y) {
722 }
723 
725 template<class RealType1, class RealType2>
726 KOKKOS_INLINE_FUNCTION
727 bool
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)) );
732 }
733 
740 template<class RealType1, class RealType2>
741 inline
742 bool
743 operator == (const std::complex<RealType1>& x, const complex<RealType2>& y) {
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)) );
747 }
748 
750 template<class RealType1, class RealType2>
751 KOKKOS_INLINE_FUNCTION
752 bool
753 operator == (const complex<RealType1>& x, const RealType2& y) {
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) );
757 }
758 
760 template<class RealType1, class RealType2>
761 KOKKOS_INLINE_FUNCTION
762 bool
763 operator == (const RealType1& x, const complex<RealType2>& y) {
764  return y == x;
765 }
766 
768 template<class RealType1, class RealType2>
769 KOKKOS_INLINE_FUNCTION
770 bool
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)) );
775 }
776 
778 template<class RealType1, class RealType2>
779 inline
780 bool
781 operator != (const std::complex<RealType1>& x, const complex<RealType2>& y) {
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)) );
785 }
786 
788 template<class RealType1, class RealType2>
789 KOKKOS_INLINE_FUNCTION
790 bool
791 operator != (const complex<RealType1>& x, const RealType2& y) {
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) );
795 }
796 
798 template<class RealType1, class RealType2>
799 KOKKOS_INLINE_FUNCTION
800 bool
801 operator != (const RealType1& x, const complex<RealType2>& y) {
802  return y != x;
803 }
804 
805 template<class RealType>
806 std::ostream& operator << (std::ostream& os, const complex<RealType>& x) {
807  const std::complex<RealType> x_std (Kokkos::real (x), Kokkos::imag (x));
808  os << x_std;
809  return os;
810 }
811 
812 template<class RealType>
813 std::ostream& operator >> (std::ostream& os, complex<RealType>& x) {
814  std::complex<RealType> x_std;
815  os >> x_std;
816  x = x_std; // only assigns on success of above
817  return os;
818 }
819 
820 
821 template<class T>
822 struct reduction_identity<Kokkos::complex<T> > {
823  typedef reduction_identity<T> t_red_ident;
824  KOKKOS_FORCEINLINE_FUNCTION constexpr static Kokkos::complex<T> sum()
825  {return Kokkos::complex<T>(t_red_ident::sum(),t_red_ident::sum());}
826  KOKKOS_FORCEINLINE_FUNCTION constexpr static Kokkos::complex<T> prod()
827  {return Kokkos::complex<T>(t_red_ident::prod(),t_red_ident::sum());}
828 };
829 
830 } // namespace Kokkos
831 
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.
Atomic functions.
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.