ParGeMSLR
complex.hpp
Go to the documentation of this file.
1 #ifndef PARGEMSLR_COMPLEX_H
2 #define PARGEMSLR_COMPLEX_H
3 
9 #include <complex>
10 #ifdef PARGEMSLR_CUDA
11 #include <cuda_runtime.h>
12 #endif
13 //#include <iostream>
14 
15 namespace pargemslr
16 {
17 
22  template <typename T>
24  {
25  private:
26 
31  T _real;
32 
37  T _imag;
38 
39  public:
40  /* constructor */
46  {
47  _real = T();
48  _imag = T();
49  }
50 
57  {
58  _real = real;
59  _imag = T();
60  }
61 
68  ComplexValueClass(T real, T imag)
69  {
70  _real = real;
71  _imag = imag;
72  }
73 
79 #ifdef PARGEMSLR_CUDA
80 __host__ __device__
81 #endif
82  T& Real()
83  {
84  return _real;
85  }
86 
92 #ifdef PARGEMSLR_CUDA
93 __host__ __device__
94 #endif
95  const T& Real() const
96  {
97  return _real;
98  }
99 
105 #ifdef PARGEMSLR_CUDA
106 __host__ __device__
107 #endif
108  T& Imag()
109  {
110  return _imag;
111  }
112 
118 #ifdef PARGEMSLR_CUDA
119 __host__ __device__
120 #endif
121  const T& Imag() const
122  {
123  return _imag;
124  }
125 
131  T Norm() const
132  {
133  return _real * _real + _imag * _imag;
134  }
135 
141  T Norm2() const
142  {
143  return std::sqrt(_real * _real + _imag * _imag);
144  }
145 
151  T Abs() const
152  {
153  return std::sqrt(_real * _real + _imag * _imag);
154  }
155 
162  {
163  return ComplexValueClass<T>(_real, -_imag);
164  }
165 
173  /*
174  operator T() const
175  {
176  if(_imag != T())
177  {
178  std::cout<<"Error: converting complex type to real type with nonzero imag part, imag part lost."<<std::endl;
179  std::cout<<"This message should never be printed from a correct program."<<std::endl;
180  std::cout<<"Possible cause: operating real value with complex value."<<std::endl;
181  }
182  return _real;
183  }
184  */
185 
192 #ifdef PARGEMSLR_CUDA
193 __host__ __device__
194 #endif
196  {
197  _real = real;
198  _imag = T();
199  return *this;
200  }
201 
209  {
210  _real += real;
211  return *this;
212  }
213 
221  {
222  _real -= real;
223  return *this;
224  }
225 
233  {
234  _real *= real;
235  _imag *= real;
236  return *this;
237  }
238 
246  {
247  _real /= real;
248  _imag /= real;
249  return *this;
250  }
251 
258 #ifdef PARGEMSLR_CUDA
259 __host__ __device__
260 #endif
262  {
263  _real = val.Real();
264  _imag = val.Imag();
265  return *this;
266  }
267 
275  {
276  _real += val.Real();
277  _imag += val.Imag();
278  return *this;
279  }
280 
288  {
289  _real -= val.Real();
290  _imag -= val.Imag();
291  return *this;
292  }
293 
301  {
302  /* (a+bi)*(c+di) = ac-bd + (ad+bc)i */
303  const T new_real = _real * val.Real() - _imag * val.Imag();
304  _imag = _real * val.Imag() + _imag * val.Real();
305  _real = new_real;
306  return *this;
307  }
308 
316  {
317  /* (a+bi)/(c+di) is slightly more complex
318  * [(a+bi)*(c-di)]/[(c+di)*(c-di)] =
319  * [ ac+bd + (bc-ad)i ]/(c*c+d*d)
320  */
321  const T new_lower = val.Norm();
322  const T new_real = _real * val.Real() + _imag * val.Imag();
323  _imag = (val.Real() * _imag - val.Imag() * _real) / new_lower;
324  _real = new_real / new_lower;
325  return *this;
326  }
327 
328  };
329 
337  template <typename T>
338  inline ComplexValueClass<T> operator+(const ComplexValueClass<T> &val, const T& real)
339  {
340  ComplexValueClass<T> val1 = val;
341  val1 += real;
342  return val1;
343  }
344 
352  template <typename T>
353  inline ComplexValueClass<T> operator+( const T& real, const ComplexValueClass<T> &val)
354  {
355  ComplexValueClass<T> val1 = val;
356  val1 += real;
357  return val1;
358  }
359 
367  template <typename T>
369  {
370  ComplexValueClass<T> val = val1;
371  val += val2;
372  return val;
373  }
374 
381  template <typename T>
383  {
384  return ComplexValueClass<T>( val.Real(), val.Imag());
385  }
386 
394  template <typename T>
395  inline ComplexValueClass<T> operator-(const ComplexValueClass<T> &val, const T& real)
396  {
397  ComplexValueClass<T> val1 = val;
398  val1 -= real;
399  return val1;
400  }
401 
409  template <typename T>
410  inline ComplexValueClass<T> operator-( const T& real, const ComplexValueClass<T> &val)
411  {
412  ComplexValueClass<T> val1 = ComplexValueClass<T>(real, T());
413  val1 -= val;
414  return val1;
415  }
416 
424  template <typename T>
426  {
427  ComplexValueClass<T> val = val1;
428  val -= val2;
429  return val;
430  }
431 
438  template <typename T>
440  {
441  return ComplexValueClass<T>( -val.Real(), -val.Imag());
442  }
443 
451  template <typename T>
452  inline ComplexValueClass<T> operator*(const ComplexValueClass<T> &val, const T& real)
453  {
454  ComplexValueClass<T> val1 = val;
455  val1 *= real;
456  return val1;
457  }
458 
466  template <typename T>
467  inline ComplexValueClass<T> operator*( const T& real, const ComplexValueClass<T> &val)
468  {
469  ComplexValueClass<T> val1 = val;
470  val1 *= real;
471  return val1;
472  }
473 
481  template <typename T>
483  {
484  ComplexValueClass<T> val = val1;
485  val *= val2;
486  return val;
487  }
488 
496  template <typename T>
497  inline ComplexValueClass<T> operator/(const ComplexValueClass<T> &val, const T& real)
498  {
499  ComplexValueClass<T> val1 = val;
500  val1 /= real;
501  return val1;
502  }
503 
511  template <typename T>
512  inline ComplexValueClass<T> operator/( const T& real, const ComplexValueClass<T> &val)
513  {
514  ComplexValueClass<T> val1 = ComplexValueClass<T>(real, T());
515  val1 /= val;
516  return val1;
517  }
518 
526  template <typename T>
528  {
529  ComplexValueClass<T> val = val1;
530  val /= val2;
531  return val;
532  }
533 
541  template <typename T>
542  inline bool operator==( const ComplexValueClass<T> &val1, const T &val2)
543  {
544  return (val1.Real() == val2) && (val1.Imag() == T());
545  }
546 
554  template <typename T>
555  inline bool operator==( const T &val1, const ComplexValueClass<T> &val2)
556  {
557  return (val1 == val2.Real()) && (T() == val2.Imag());
558  }
559 
567  template <typename T>
568  inline bool operator==( const ComplexValueClass<T> &val1, const ComplexValueClass<T> &val2)
569  {
570  return (val1.Real() == val2.Real()) && (val1.Imag() == val2.Imag());
571  }
572 
580  template <typename T>
581  inline bool operator!=( const ComplexValueClass<T> &val1, const T &val2)
582  {
583  return (val1.Real() != val2) || (val1.Imag() != T());
584  }
585 
593  template <typename T>
594  inline bool operator!=( const T &val1, const ComplexValueClass<T> &val2)
595  {
596  return (val1 != val2.Real()) || (T() != val2.Imag());
597  }
598 
606  template <typename T>
607  inline bool operator!=( const ComplexValueClass<T> &val1, const ComplexValueClass<T> &val2)
608  {
609  return (val1.Real() != val2.Real()) || (val1.Imag() != val2.Imag());
610  }
611 
619  template<typename T, typename CharT, class Traits>
620  std::basic_ostream<CharT, Traits>&
621  operator<<(std::basic_ostream<CharT, Traits>& basic_os, const ComplexValueClass<T>& val)
622  {
623  std::basic_ostringstream<CharT, Traits> basic_ostr;
624  basic_ostr.flags(basic_os.flags());
625  basic_ostr.imbue(basic_os.getloc());
626  basic_ostr.precision(basic_os.precision());
627 
628  T val_r = val.Real();
629  T val_i = val.Imag();
630 
631  if(val_r < 0)
632  {
633  basic_ostr<<"-";
634  }
635  else
636  {
637  basic_ostr<<"+";
638  }
639  basic_ostr<<std::abs(val_r);
640  if(val_i < 0)
641  {
642  basic_ostr<<"-";
643  }
644  else
645  {
646  basic_ostr<<"+";
647  }
648  basic_ostr<<std::abs(val_i)<<"i";
649  return basic_os << basic_ostr.str();
650  }
651 
652  typedef ComplexValueClass<float> complexs;
653  typedef ComplexValueClass<double> complexd;
654 
655 #ifdef PARGEMSLR_OPENMP
656 
657 #pragma omp declare reduction(+:complexs:omp_out += omp_in) initializer (omp_priv=complexs())
658 #pragma omp declare reduction(+:complexd:omp_out += omp_in) initializer (omp_priv=complexd())
659 
660 #endif
661 
666  typedef struct CComplexSingleStruct
667  {
668  float real, imag;
669  }ccomplexs;
670 
675  typedef struct CComplexDoubleStruct
676  {
677  double real, imag;
678  }ccomplexd;
679 
684  template <class T> struct PargemslrIsComplex : public std::false_type {};
685  template <class T> struct PargemslrIsComplex<const T> : public PargemslrIsComplex<T> {};
686  template <class T> struct PargemslrIsComplex<volatile const T> : public PargemslrIsComplex<T>{};
687  template <class T> struct PargemslrIsComplex<volatile T> : public PargemslrIsComplex<T>{};
688  template<> struct PargemslrIsComplex<complexs> : public std::true_type {};
689  template<> struct PargemslrIsComplex<complexd> : public std::true_type {};
690 
695  template <class T> struct PargemslrIsReal : public std::false_type {};
696  template <class T> struct PargemslrIsReal<const T> : public PargemslrIsReal<T> {};
697  template <class T> struct PargemslrIsReal<volatile const T> : public PargemslrIsReal<T>{};
698  template <class T> struct PargemslrIsReal<volatile T> : public PargemslrIsReal<T>{};
699  template<> struct PargemslrIsReal<float> : public std::true_type {};
700  template<> struct PargemslrIsReal<double> : public std::true_type {};
701 
702 }
703 
704 #endif
pargemslr::operator/
ComplexValueClass< T > operator/(const ComplexValueClass< T > &val, const T &real)
/ operator.
Definition: complex.hpp:497
pargemslr::operator==
bool operator==(const ComplexValueClass< T > &val1, const T &val2)
== operator.
Definition: complex.hpp:542
pargemslr::ComplexValueClass::Conj
ComplexValueClass< T > Conj() const
Get the conjugate.
Definition: complex.hpp:161
pargemslr::ComplexValueClass::operator+=
ComplexValueClass< T > & operator+=(const ComplexValueClass< T > &val)
+= operator with real value.
Definition: complex.hpp:274
pargemslr::PargemslrIsReal
Tell if a value is a real value.
Definition: complex.hpp:695
pargemslr::operator!=
bool operator!=(const ComplexValueClass< T > &val1, const T &val2)
!= operator.
Definition: complex.hpp:581
pargemslr::ComplexValueClass::ComplexValueClass
ComplexValueClass(T real)
The constructor of complex value class.
Definition: complex.hpp:56
pargemslr::ComplexValueClass::ComplexValueClass
ComplexValueClass()
The constructor of complex value class.
Definition: complex.hpp:45
pargemslr::CComplexSingleStruct
The c style struct of single complex.
Definition: complex.hpp:667
pargemslr::ComplexValueClass::operator-=
ComplexValueClass< T > & operator-=(const T &real)
-= operator with real value.
Definition: complex.hpp:220
pargemslr::ComplexValueClass::operator*=
ComplexValueClass< T > & operator*=(const ComplexValueClass< T > &val)
*= operator with real value.
Definition: complex.hpp:300
pargemslr::ComplexValueClass::operator*=
ComplexValueClass< T > & operator*=(const T &real)
*= operator with real value.
Definition: complex.hpp:232
pargemslr::ComplexValueClass::operator+=
ComplexValueClass< T > & operator+=(const T &real)
+= operator with real value.
Definition: complex.hpp:208
pargemslr::ComplexValueClass::ComplexValueClass
ComplexValueClass(T real, T imag)
The constructor of complex value class.
Definition: complex.hpp:68
pargemslr::ComplexValueClass::Imag
T & Imag()
Get the imag part.
Definition: complex.hpp:108
pargemslr::ComplexValueClass::Real
const T & Real() const
Get the real part.
Definition: complex.hpp:95
pargemslr::operator-
ComplexValueClass< T > operator-(const ComplexValueClass< T > &val, const T &real)
operator.
Definition: complex.hpp:395
pargemslr::ComplexValueClass
The template class complex.
Definition: complex.hpp:24
pargemslr::ComplexValueClass::operator/=
ComplexValueClass< T > & operator/=(const T &real)
/= operator with real value.
Definition: complex.hpp:245
pargemslr::ComplexValueClass::Imag
const T & Imag() const
Get the imag part.
Definition: complex.hpp:121
pargemslr::ComplexValueClass::Real
T & Real()
Get the real part.
Definition: complex.hpp:82
pargemslr::ComplexValueClass::Norm
T Norm() const
Get the square of 2-norm. Note that std::complex use the this value as norm.
Definition: complex.hpp:131
pargemslr::ComplexValueClass::operator/=
ComplexValueClass< T > & operator/=(const ComplexValueClass< T > &val)
/= operator with real value.
Definition: complex.hpp:315
pargemslr::operator*
ComplexValueClass< T > operator*(const ComplexValueClass< T > &val, const T &real)
operator.
Definition: complex.hpp:452
pargemslr::ComplexValueClass::operator-=
ComplexValueClass< T > & operator-=(const ComplexValueClass< T > &val)
-= operator with real value.
Definition: complex.hpp:287
pargemslr::ComplexValueClass::operator=
ComplexValueClass< T > & operator=(const ComplexValueClass< T > &val)
= operator with real value.
Definition: complex.hpp:261
pargemslr::PargemslrIsComplex
Tell if a value is a complex value.
Definition: complex.hpp:684
pargemslr::CComplexDoubleStruct
The c style struct of double complex.
Definition: complex.hpp:676
pargemslr::ComplexValueClass::Abs
T Abs() const
Get the 2-norm as absolute value.
Definition: complex.hpp:151
pargemslr::ComplexValueClass::operator=
ComplexValueClass< T > & operator=(const T &real)
Conver to real value, only keep the real part.
Definition: complex.hpp:195
pargemslr::operator+
ComplexValueClass< T > operator+(const ComplexValueClass< T > &val, const T &real)
operator.
Definition: complex.hpp:338
pargemslr::ComplexValueClass::Norm2
T Norm2() const
Get the 2-norm. Note that std::complex use the square of this value as norm.
Definition: complex.hpp:141