QUDA  v1.1.0
A library for QCD on GPUs
complex_quda.h
Go to the documentation of this file.
1 /*
2  * Copyright 2008-2009 NVIDIA Corporation
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
21 #pragma once
22 
23 //#include <math.h>
24 
25 #include <cmath>
26 #include <complex>
27 #include <sstream>
28 //#include <cuComplex.h>
29 
30 namespace quda {
31  namespace gauge {
32  template<typename Float, typename storeFloat> struct fieldorder_wrapper;
33  }
34 
35  namespace colorspinor {
36  template<typename Float, typename storeFloat> struct fieldorder_wrapper;
37  }
38 }
39 
40 // We need this to make sure code inside quda:: that calls sqrt() using real numbers
41 // doesn't try to call the complex sqrt, but the standard sqrt
42 namespace quda
43 {
44  template <typename ValueType>
45  __host__ __device__
46  inline ValueType cos(ValueType x){
47  return std::cos(x);
48  }
49  template <typename ValueType>
50  __host__ __device__
51  inline ValueType sin(ValueType x){
52  return std::sin(x);
53  }
54  template <typename ValueType>
55  __host__ __device__
56  inline ValueType tan(ValueType x){
57  return std::tan(x);
58  }
59  template <typename ValueType>
60  __host__ __device__
61  inline ValueType acos(ValueType x){
62  return std::acos(x);
63  }
64  template <typename ValueType>
65  __host__ __device__
66  inline ValueType asin(ValueType x){
67  return std::asin(x);
68  }
69  template <typename ValueType>
70  __host__ __device__
71  inline ValueType atan(ValueType x){
72  return std::atan(x);
73  }
74  template <typename ValueType>
75  __host__ __device__
76  inline ValueType atan2(ValueType x,ValueType y){
77  return std::atan2(x,y);
78  }
79  template <typename ValueType>
80  __host__ __device__
81  inline ValueType cosh(ValueType x){
82  return std::cosh(x);
83  }
84  template <typename ValueType>
85  __host__ __device__
86  inline ValueType sinh(ValueType x){
87  return std::sinh(x);
88  }
89  template <typename ValueType>
90  __host__ __device__
91  inline ValueType tanh(ValueType x){
92  return std::tanh(x);
93  }
94  template <typename ValueType>
95  __host__ __device__
96  inline ValueType exp(ValueType x){
97  return std::exp(x);
98  }
99  template <typename ValueType>
100  __host__ __device__
101  inline ValueType log(ValueType x){
102  return std::log(x);
103  }
104  template <typename ValueType>
105  __host__ __device__
106  inline ValueType log10(ValueType x){
107  return std::log10(x);
108  }
109  template <typename ValueType, typename ExponentType>
110  __host__ __device__
111  inline ValueType pow(ValueType x, ExponentType e){
112 #if (CUDA_VERSION < 7050)
113  return std::pow(x,static_cast<ValueType>(e));
114 #else
115  return std::pow(x,e);
116 #endif
117  }
118  template <typename ValueType>
119  __host__ __device__
120  inline ValueType sqrt(ValueType x){
121  return std::sqrt(x);
122  }
123  template <typename ValueType>
124  __host__ __device__
125  inline ValueType abs(ValueType x){
126  return std::abs(x);
127  }
128  template <typename ValueType>
129  __host__ __device__
130  inline ValueType conj(ValueType x){
131  return x;
132  }
133 
134  template <typename ValueType> struct complex;
135  //template <> struct complex<float>;
136  //template <> struct complex<double>;
137 
138 
140  template<typename ValueType>
141  __host__ __device__
142  ValueType abs(const complex<ValueType>& z);
144  template<typename ValueType>
145  __host__ __device__
146  ValueType arg(const complex<ValueType>& z);
148  template<typename ValueType>
149  __host__ __device__
150  ValueType norm(const complex<ValueType>& z);
151 
153  template<typename ValueType>
154  __host__ __device__
155  complex<ValueType> conj(const complex<ValueType>& z);
157 
158  template<typename ValueType>
159  __host__ __device__
160  complex<ValueType> polar(const ValueType& m, const ValueType& theta = 0);
161 
162  // Arithmetic operators:
163  // Multiplication
164  template <typename ValueType>
165  __host__ __device__
166  inline complex<ValueType> operator*(const complex<ValueType>& lhs, const complex<ValueType>& rhs);
167  template <typename ValueType>
168  __host__ __device__
169  inline complex<ValueType> operator*(const complex<ValueType>& lhs, const ValueType & rhs);
170  template <typename ValueType>
171  __host__ __device__
172  inline complex<ValueType> operator*(const ValueType& lhs, const complex<ValueType>& rhs);
173  // Division
174  template <typename ValueType>
175  __host__ __device__
176  inline complex<ValueType> operator/(const complex<ValueType>& lhs, const complex<ValueType>& rhs);
177  template <>
178  __host__ __device__
179  inline complex<float> operator/(const complex<float>& lhs, const complex<float>& rhs);
180  template <>
181  __host__ __device__
182  inline complex<double> operator/(const complex<double>& lhs, const complex<double>& rhs);
183 
184  // Addition
185  template <typename ValueType>
186  __host__ __device__
187  inline complex<ValueType> operator+(const complex<ValueType>& lhs, const complex<ValueType>& rhs);
188  template <typename ValueType>
189  __host__ __device__
190  inline complex<ValueType> operator+(const complex<ValueType>& lhs, const ValueType & rhs);
191  template <typename ValueType>
192  __host__ __device__
193  inline complex<ValueType> operator+(const ValueType& lhs, const complex<ValueType>& rhs);
194  // Subtraction
195  template <typename ValueType>
196  __host__ __device__
197  inline complex<ValueType> operator-(const complex<ValueType>& lhs, const complex<ValueType>& rhs);
198  template <typename ValueType>
199  __host__ __device__
200  inline complex<ValueType> operator-(const complex<ValueType>& lhs, const ValueType & rhs);
201  template <typename ValueType>
202  __host__ __device__
203  inline complex<ValueType> operator-(const ValueType& lhs, const complex<ValueType>& rhs);
204 
205  // Unary plus and minus
206  template <typename ValueType>
207  __host__ __device__
208  inline complex<ValueType> operator+(const complex<ValueType>& rhs);
209  template <typename ValueType>
210  __host__ __device__
211  inline complex<ValueType> operator-(const complex<ValueType>& rhs);
212 
213  // Transcendentals:
214  // Returns the complex cosine of z.
215  template <typename ValueType>
216  __host__ __device__
217  complex<ValueType> cos(const complex<ValueType>& z);
218  // Returns the complex hyperbolic cosine of z.
219  template <typename ValueType>
220  __host__ __device__
221  complex<ValueType> cosh(const complex<ValueType>& z);
222  // Returns the complex base e exponential of z.
223  template <typename ValueType>
224  __host__ __device__
225  complex<ValueType> exp(const complex<ValueType>& z);
226  // Returns the complex natural logarithm of z.
227  template <typename ValueType>
228  __host__ __device__
229  complex<ValueType> log(const complex<ValueType>& z);
230  // Returns the complex base 10 logarithm of z.
231  template <typename ValueType>
232  __host__ __device__
233  complex<ValueType> log10(const complex<ValueType>& z);
234  // Returns z to the n'th power.
235  template <typename ValueType>
236  __host__ __device__
237  complex<ValueType> pow(const complex<ValueType>& z, const int& n);
238  // Returns z to the x'th power.
239  template <typename ValueType>
240  __host__ __device__
241  complex<ValueType> pow(const complex<ValueType>&z, const ValueType&x);
242  // Returns z to the z2'th power.
243  template <typename ValueType>
244  __host__ __device__
245  complex<ValueType> pow(const complex<ValueType>&z, const complex<ValueType>&z2);
246  // Returns x to the z'th power.
247  template <typename ValueType>
248  __host__ __device__
249  complex<ValueType> pow(const ValueType& x, const complex<ValueType>& z);
250  // Returns the complex sine of z.
251  template <typename ValueType>
252  __host__ __device__
253  complex<ValueType> sin(const complex<ValueType>&z);
254  // Returns the complex hyperbolic sine of z.
255  template <typename ValueType>
256  __host__ __device__
257  complex<ValueType> sinh(const complex<ValueType>&z);
258  // Returns the complex square root of z.
259  template <typename ValueType>
260  __host__ __device__
261  complex<ValueType> sqrt(const complex<ValueType>&z);
262  // Returns the complex tangent of z.
263  template <typename ValueType>
264  __host__ __device__
265  complex<ValueType> tan(const complex<ValueType>&z);
266  // Returns the complex hyperbolic tangent of z.
267  template <typename ValueType>
268  __host__ __device__
269  complex<ValueType> tanh(const complex<ValueType>&z);
270 
271 
272  // Inverse Trigonometric:
273  // Returns the complex arc cosine of z.
274  template <typename ValueType>
275  __host__ __device__
276  complex<ValueType> acos(const complex<ValueType>& z);
277  // Returns the complex arc sine of z.
278  template <typename ValueType>
279  __host__ __device__
280  complex<ValueType> asin(const complex<ValueType>& z);
281  // Returns the complex arc tangent of z.
282  template <typename ValueType>
283  __host__ __device__
284  complex<ValueType> atan(const complex<ValueType>& z);
285  // Returns the complex hyperbolic arc cosine of z.
286  template <typename ValueType>
287  __host__ __device__
288  complex<ValueType> acosh(const complex<ValueType>& z);
289  // Returns the complex hyperbolic arc sine of z.
290  template <typename ValueType>
291  __host__ __device__
292  complex<ValueType> asinh(const complex<ValueType>& z);
293  // Returns the complex hyperbolic arc tangent of z.
294  template <typename ValueType>
295  __host__ __device__
296  complex<ValueType> atanh(const complex<ValueType>& z);
297 
298 
299 
300  // Stream operators:
301  template<typename ValueType,class charT, class traits>
302  std::basic_ostream<charT, traits>& operator<<(std::basic_ostream<charT, traits>& os, const complex<ValueType>& z);
303  template<typename ValueType, typename charT, class traits>
304  std::basic_istream<charT, traits>&
305  operator>>(std::basic_istream<charT, traits>& is, complex<ValueType>& z);
306 
307 
308  // Stream operators
309  template<typename ValueType,class charT, class traits>
310  std::basic_ostream<charT, traits>& operator<<(std::basic_ostream<charT, traits>& os, const complex<ValueType>& z)
311  {
312  os << '(' << z.real() << ',' << z.imag() << ')';
313  return os;
314  };
315 
316  template<typename ValueType, typename charT, class traits>
317  std::basic_istream<charT, traits>&
318  operator>>(std::basic_istream<charT, traits>& is, complex<ValueType>& z)
319  {
320  ValueType re, im;
321 
322  charT ch;
323  is >> ch;
324 
325  if(ch == '(')
326  {
327  is >> re >> ch;
328  if (ch == ',')
329  {
330  is >> im >> ch;
331  if (ch == ')')
332  {
333  z = complex<ValueType>(re, im);
334  }
335  else
336  {
337  is.setstate(std::ios_base::failbit);
338  }
339  }
340  else if (ch == ')')
341  {
342  z = re;
343  }
344  else
345  {
346  is.setstate(std::ios_base::failbit);
347  }
348  }
349  else
350  {
351  is.putback(ch);
352  is >> re;
353  z = re;
354  }
355  return is;
356  }
357 
358 template <typename T>
359  struct norm_type {
360  typedef T type;
361  };
362  template <typename T>
363  struct norm_type< complex<T> > {
364  typedef T type;
365  };
366 
367 template <typename ValueType>
368 struct complex
369 {
370 public:
371  typedef ValueType value_type;
372 
373  // Constructors
374  __host__ __device__
375  inline complex<ValueType>(const ValueType & re = ValueType(), const ValueType& im = ValueType())
376  {
377  real(re);
378  imag(im);
379  }
380 
381  template <class X>
382  __host__ __device__
383  inline complex<ValueType>(const complex<X> & z)
384  {
385  real(z.real());
386  imag(z.imag());
387  }
388 
389  template <class X>
390  __host__ __device__
391  inline complex<ValueType>(const std::complex<X> & z)
392  {
393  real(z.real());
394  imag(z.imag());
395  }
396 
397  template <typename T>
398  __host__ __device__
400  {
401  real(z.real());
402  imag(z.imag());
403  return *this;
404  }
405 
406  __host__ __device__
408  {
409  real(real()+z.real());
410  imag(imag()+z.imag());
411  return *this;
412  }
413 
414  __host__ __device__
416  {
417  real(real()-z.real());
418  imag(imag()-z.imag());
419  return *this;
420  }
421 
422  __host__ __device__
424  {
425  *this = *this * z;
426  return *this;
427  }
428 
429  __host__ __device__
431  {
432  *this = *this / z;
433  return *this;
434  }
435 
436  __host__ __device__
437  inline complex<ValueType>& operator*=(const ValueType z)
438  {
439  this->x *= z;
440  this->y *= z;
441  return *this;
442  }
443 
444  __host__ __device__ inline ValueType real() const volatile;
445  __host__ __device__ inline ValueType imag() const volatile;
446  __host__ __device__ inline ValueType real() const;
447  __host__ __device__ inline ValueType imag() const;
448  __host__ __device__ inline void real(ValueType) volatile;
449  __host__ __device__ inline void imag(ValueType) volatile;
450  __host__ __device__ inline void real(ValueType);
451  __host__ __device__ inline void imag(ValueType);
452 };
453 
454 // TODO make cuFloatComplex and cuDoubleComplex protected
455 // TODO see if returning references is a perf hazard
456 
457 template<>
458  struct complex <float> : public float2 //cuFloatComplex
459 {
460 public:
461  typedef float value_type;
462  __host__ __device__ inline complex<float>() {};
463  __host__ __device__
464  inline complex<float>(const float & re, const float& im = float())
465  {
466  real(re);
467  imag(im);
468  }
469 
470  // For some reason having the following constructor
471  // explicitly makes things faster with at least g++
472  __host__ __device__
473  complex<float>(const complex<float> & z)
474  : float2(z){}
475 
476  __host__ __device__
477  complex<float>(float2 z)
478  : float2(z){}
479 
480  template <class X>
481  inline complex<float>(const std::complex<X> & z)
482  {
483  real(z.real());
484  imag(z.imag());
485  }
486 
487  // Member operators
488  template <typename T>
489  __host__ __device__
490  inline volatile complex<float>& operator=(const complex<T> z) volatile
491  {
492  real(z.real());
493  imag(z.imag());
494  return *this;
495  }
496 
497  template <typename T>
498  __host__ __device__
500  {
501  real(z.real());
502  imag(z.imag());
503  return *this;
504  }
505 
506  __host__ __device__
508  {
509  real(real()+z.real());
510  imag(imag()+z.imag());
511  return *this;
512  }
513 
514  __host__ __device__
516  {
517  real(real()-z.real());
518  imag(imag()-z.imag());
519  return *this;
520  }
521 
522  __host__ __device__
524  {
525  *this = *this * z;
526  return *this;
527  }
528 
529  __host__ __device__
531  {
532  *this = *this / z;
533  return *this;
534  }
535 
536  __host__ __device__
537  inline complex<float>& operator*=(const float z)
538  {
539  this->x *= z;
540  this->y *= z;
541  return *this;
542  }
543 
544  // Let the compiler synthesize the copy and assignment operators.
545  __host__ __device__ inline complex<float>(const volatile complex<float> & z)
546  {
547  real(z.real());
548  imag(z.imag());
549  }
550 
551  __host__ __device__ inline float real() const volatile{ return x; }
552  __host__ __device__ inline float imag() const volatile{ return y; }
553  __host__ __device__ inline float real() const{ return x; }
554  __host__ __device__ inline float imag() const{ return y; }
555  __host__ __device__ inline void real(float re)volatile{ x = re; }
556  __host__ __device__ inline void imag(float im)volatile{ y = im; }
557  __host__ __device__ inline void real(float re){ x = re; }
558  __host__ __device__ inline void imag(float im){ y = im; }
559 
560  // cast operators
561  inline operator std::complex<float>() const { return std::complex<float>(real(),imag()); }
562  template <typename T>
563  inline __host__ __device__ operator complex<T>() const { return complex<T>(static_cast<T>(real()),static_cast<T>(imag())); }
564 
565  template<typename otherFloat, typename storeFloat>
566  __host__ __device__ inline void operator=(const gauge::fieldorder_wrapper<otherFloat,storeFloat> &a);
567 
568  template<typename otherFloat, typename storeFloat>
570 
571  template<typename otherFloat, typename storeFloat>
572  __host__ __device__ inline void operator=(const colorspinor::fieldorder_wrapper<otherFloat,storeFloat> &a);
573 
574  template<typename otherFloat, typename storeFloat>
576 };
577 
578 template<>
579  struct complex <double> : public double2 //cuDoubleComplex
580 {
581 public:
582  typedef double value_type;
583  __host__ __device__ inline complex<double>() {};
584  __host__ __device__
585  inline complex<double>(const double & re, const double& im = double())
586  {
587  real(re);
588  imag(im);
589  }
590 
591  // For some reason having the following constructor
592  // explicitly makes things faster with at least g++
593  __host__ __device__
594  inline complex<double>(const complex<double> & z)
595  : double2(z) {}
596 
597  __host__ __device__
598  inline complex<double>(double2 z)
599  : double2(z) {}
600 
601  template <class X>
602  inline complex<double>(const std::complex<X> & z)
603  {
604  real(z.real());
605  imag(z.imag());
606  }
607 
608  // Member operators
609  template <typename T>
610  __host__ __device__
611  inline volatile complex<double>& operator=(const complex<T> z) volatile
612  {
613  real(z.real());
614  imag(z.imag());
615  return *this;
616  }
617 
618  template <typename T>
619  __host__ __device__
621  {
622  real(z.real());
623  imag(z.imag());
624  return *this;
625  }
626 
627  __host__ __device__
629  {
630  real(real()+z.real());
631  imag(imag()+z.imag());
632  return *this;
633  }
634 
635  __host__ __device__
637  {
638  real(real()+z.real());
639  imag(imag()+z.imag());
640  return *this;
641  }
642 
643  __host__ __device__
645  {
646  real(real()-z.real());
647  imag(imag()-z.imag());
648  return *this;
649  }
650 
651  __host__ __device__
653  {
654  *this = *this * z;
655  return *this;
656  }
657 
658  __host__ __device__
660  {
661  *this = *this / z;
662  return *this;
663  }
664 
665  __host__ __device__
666  inline complex<double>& operator*=(const double z)
667  {
668  this->x *= z;
669  this->y *= z;
670  return *this;
671  }
672 
673  __host__ __device__ inline complex<double>(const volatile complex<double> & z)
674  {
675  real(z.real());
676  imag(z.imag());
677  }
678 
679  // Let the compiler synthesize the copy and assignment operators.
680  __host__ __device__ inline double real() const volatile { return x; }
681  __host__ __device__ inline double imag() const volatile { return y; }
682  __host__ __device__ inline double real() const { return x; }
683  __host__ __device__ inline double imag() const { return y; }
684  __host__ __device__ inline void real(double re)volatile{ x = re; }
685  __host__ __device__ inline void imag(double im)volatile{ y = im; }
686  __host__ __device__ inline void real(double re){ x = re; }
687  __host__ __device__ inline void imag(double im){ y = im; }
688 
689  // cast operators
690  inline operator std::complex<double>() const { return std::complex<double>(real(),imag()); }
691  template <typename T>
692  inline __host__ __device__ operator complex<T>() const { return complex<T>(static_cast<T>(real()),static_cast<T>(imag())); }
693 
694  template<typename otherFloat, typename storeFloat>
695  __host__ __device__ inline void operator=(const gauge::fieldorder_wrapper<otherFloat,storeFloat> &a);
696 
697  template<typename otherFloat, typename storeFloat>
699 
700  template<typename otherFloat, typename storeFloat>
701  __host__ __device__ inline void operator=(const colorspinor::fieldorder_wrapper<otherFloat,storeFloat> &a);
702 
703  template<typename otherFloat, typename storeFloat>
705 };
706 
707 template <> struct complex<int8_t> : public char2 {
708 public:
709  typedef int8_t value_type;
710 
711  __host__ __device__ inline complex<int8_t>() : char2() {};
712 
713  __host__ __device__ inline complex<int8_t>(const int8_t &re, const int8_t &im = float())
714  {
715  real(re);
716  imag(im);
717  }
718 
719  __host__ __device__ inline complex<int8_t>(const complex<int8_t> &z) : char2(z) {}
720 
721  __host__ __device__ inline complex<int8_t> &operator+=(const complex<int8_t> z)
722  {
723  real(real() + z.real());
724  imag(imag() + z.imag());
725  return *this;
726  }
727 
728  __host__ __device__ inline complex<int8_t> &operator-=(const complex<int8_t> z)
729  {
730  real(real() - z.real());
731  imag(imag() - z.imag());
732  return *this;
733  }
734 
735  __host__ __device__ inline int8_t real() const volatile { return x; }
736  __host__ __device__ inline int8_t imag() const volatile { return y; }
737  __host__ __device__ inline int8_t real() const { return x; }
738  __host__ __device__ inline int8_t imag() const { return y; }
739  __host__ __device__ inline void real(int8_t re) volatile { x = re; }
740  __host__ __device__ inline void imag(int8_t im) volatile { y = im; }
741  __host__ __device__ inline void real(int8_t re) { x = re; }
742  __host__ __device__ inline void imag(int8_t im) { y = im; }
743 
744  // cast operators
745  inline operator std::complex<int8_t>() const { return std::complex<int8_t>(real(), imag()); }
746  template <typename T> inline __host__ __device__ operator complex<T>() const
747  {
748  return complex<T>(static_cast<T>(real()), static_cast<T>(imag()));
749  }
750 };
751 
752 template<>
753 struct complex <short> : public short2
754 {
755 public:
756  typedef short value_type;
757 
758  __host__ __device__ inline complex<short>() {};
759 
760  __host__ __device__ inline complex<short>(const short & re, const short& im = float())
761  {
762  real(re);
763  imag(im);
764  }
765 
766  __host__ __device__ inline complex<short>(const complex<short> & z) : short2(z){}
767 
768  __host__ __device__ inline complex<short>& operator+=(const complex<short> z)
769  {
770  real(real()+z.real());
771  imag(imag()+z.imag());
772  return *this;
773  }
774 
775  __host__ __device__ inline complex<short>& operator-=(const complex<short> z)
776  {
777  real(real()-z.real());
778  imag(imag()-z.imag());
779  return *this;
780  }
781 
782  __host__ __device__ inline short real() const volatile{ return x; }
783  __host__ __device__ inline short imag() const volatile{ return y; }
784  __host__ __device__ inline short real() const{ return x; }
785  __host__ __device__ inline short imag() const{ return y; }
786  __host__ __device__ inline void real(short re)volatile{ x = re; }
787  __host__ __device__ inline void imag(short im)volatile{ y = im; }
788  __host__ __device__ inline void real(short re){ x = re; }
789  __host__ __device__ inline void imag(short im){ y = im; }
790 
791  // cast operators
792  inline operator std::complex<short>() const { return std::complex<short>(real(),imag()); }
793  template <typename T>
794  inline __host__ __device__ operator complex<T>() const { return complex<T>(static_cast<T>(real()),static_cast<T>(imag())); }
795 
796 };
797 
798 template<>
799 struct complex <int> : public int2
800 {
801 public:
802  typedef int value_type;
803 
804  __host__ __device__ inline complex<int>() {};
805 
806  __host__ __device__ inline complex<int>(const int& re, const int& im = float())
807  {
808  real(re);
809  imag(im);
810  }
811 
812  __host__ __device__ inline complex<int>(const complex<int> & z) : int2(z){}
813 
814  __host__ __device__ inline complex<int>& operator+=(const complex<int> z)
815  {
816  real(real()+z.real());
817  imag(imag()+z.imag());
818  return *this;
819  }
820 
821  __host__ __device__ inline complex<int>& operator-=(const complex<int> z)
822  {
823  real(real()-z.real());
824  imag(imag()-z.imag());
825  return *this;
826  }
827 
828  __host__ __device__ inline int real() const volatile{ return x; }
829  __host__ __device__ inline int imag() const volatile{ return y; }
830  __host__ __device__ inline int real() const{ return x; }
831  __host__ __device__ inline int imag() const{ return y; }
832  __host__ __device__ inline void real(int re)volatile{ x = re; }
833  __host__ __device__ inline void imag(int im)volatile{ y = im; }
834  __host__ __device__ inline void real(int re){ x = re; }
835  __host__ __device__ inline void imag(int im){ y = im; }
836 
837  // cast operators
838  inline operator std::complex<int>() const { return std::complex<int>(real(),imag()); }
839  template <typename T>
840  inline __host__ __device__ operator complex<T>() const { return complex<T>(static_cast<T>(real()),static_cast<T>(imag())); }
841 
842 };
843 
844  // Binary arithmetic operations
845  // At the moment I'm implementing the basic functions, and the
846  // corresponding cuComplex calls are commented.
847 
848  template<typename ValueType>
849  __host__ __device__
851 const complex<ValueType>& rhs){
852  return complex<ValueType>(lhs.real()+rhs.real(),lhs.imag()+rhs.imag());
853  // return cuCaddf(lhs,rhs);
854  }
855 
856  template<typename ValueType>
857  __host__ __device__
858  inline complex<ValueType> operator+(const volatile complex<ValueType>& lhs,
859 const volatile complex<ValueType>& rhs){
860  return complex<ValueType>(lhs.real()+rhs.real(),lhs.imag()+rhs.imag());
861  // return cuCaddf(lhs,rhs);
862  }
863 
864  template <typename ValueType>
865  __host__ __device__
866  inline complex<ValueType> operator+(const complex<ValueType>& lhs, const ValueType & rhs){
867  return complex<ValueType>(lhs.real()+rhs,lhs.imag());
868  // return cuCaddf(lhs,complex<ValueType>(rhs));
869  }
870  template <typename ValueType>
871  __host__ __device__
872  inline complex<ValueType> operator+(const ValueType& lhs, const complex<ValueType>& rhs){
873  return complex<ValueType>(rhs.real()+lhs,rhs.imag());
874  // return cuCaddf(complex<float>(lhs),rhs);
875  }
876 
877  template <typename ValueType>
878  __host__ __device__
880  return complex<ValueType>(lhs.real()-rhs.real(),lhs.imag()-rhs.imag());
881  // return cuCsubf(lhs,rhs);
882  }
883  template <typename ValueType>
884  __host__ __device__
885  inline complex<ValueType> operator-(const complex<ValueType>& lhs, const ValueType & rhs){
886  return complex<ValueType>(lhs.real()-rhs,lhs.imag());
887  // return cuCsubf(lhs,complex<float>(rhs));
888  }
889  template <typename ValueType>
890  __host__ __device__
891  inline complex<ValueType> operator-(const ValueType& lhs, const complex<ValueType>& rhs){
892  return complex<ValueType>(lhs-rhs.real(),-rhs.imag());
893  // return cuCsubf(complex<float>(lhs),rhs);
894  }
895 
896  template <typename ValueType>
897  __host__ __device__
899 const complex<ValueType>& rhs){
900  return complex<ValueType>(lhs.real()*rhs.real()-lhs.imag()*rhs.imag(),
901 lhs.real()*rhs.imag()+lhs.imag()*rhs.real());
902  // return cuCmulf(lhs,rhs);
903  }
904 
905  template <typename ValueType>
906  __host__ __device__
907  inline complex<ValueType> operator*(const complex<ValueType>& lhs, const ValueType & rhs){
908  return complex<ValueType>(lhs.real()*rhs,lhs.imag()*rhs);
909  // return cuCmulf(lhs,complex<float>(rhs));
910  }
911 
912  template <typename ValueType>
913  __host__ __device__
914  inline complex<ValueType> operator*(const ValueType& lhs, const complex<ValueType>& rhs){
915  return complex<ValueType>(rhs.real()*lhs,rhs.imag()*lhs);
916  // return cuCmulf(complex<float>(lhs),rhs);
917  }
918 
919 
920  template <typename ValueType>
921  __host__ __device__
923  const ValueType cross_norm = lhs.real() * rhs.real() + lhs.imag() * rhs.imag();
924  const ValueType rhs_norm = norm(rhs);
925  return complex<ValueType>(cross_norm/rhs_norm,
926 (lhs.imag() * rhs.real() - lhs.real() * rhs.imag()) / rhs_norm);
927  }
928 
929  template <>
930  __host__ __device__
931  inline complex<float> operator/(const complex<float>& lhs, const complex<float>& rhs){
932 
933  complex<float> quot;
934  float s = fabsf(rhs.real()) + fabsf(rhs.imag());
935  float oos = 1.0f / s;
936  float ars = lhs.real() * oos;
937  float ais = lhs.imag() * oos;
938  float brs = rhs.real() * oos;
939  float bis = rhs.imag() * oos;
940  s = (brs * brs) + (bis * bis);
941  oos = 1.0f / s;
942  return complex<float>(((ars * brs) + (ais * bis)) * oos,
943  ((ais * brs) - (ars * bis)) * oos);
944  }
945 
946  template <>
947  __host__ __device__
949 
950  complex<double> quot;
951  double s = fabs(rhs.real()) + fabs(rhs.imag());
952  double oos = 1.0 / s;
953  double ars = lhs.real() * oos;
954  double ais = lhs.imag() * oos;
955  double brs = rhs.real() * oos;
956  double bis = rhs.imag() * oos;
957  s = (brs * brs) + (bis * bis);
958  oos = 1.0 / s;
959  return complex<double>(((ars * brs) + (ais * bis)) * oos,
960  ((ais * brs) - (ars * bis)) * oos);
961  }
962 
963  template <typename ValueType>
964  __host__ __device__
965  inline complex<ValueType> operator/(const complex<ValueType>& lhs, const ValueType & rhs){
966  return complex<ValueType>(lhs.real()/rhs,lhs.imag()/rhs);
967  // return cuCdivf(lhs,complex<float>(rhs));
968  }
969 
970  template <typename ValueType>
971  __host__ __device__
972  inline complex<ValueType> operator/(const ValueType& lhs, const complex<ValueType>& rhs){
973  const ValueType cross_norm = lhs * rhs.real();
974  const ValueType rhs_norm = norm(rhs);
975  return complex<ValueType>(cross_norm/rhs_norm,(-lhs.real() * rhs.imag()) / rhs_norm);
976  }
977 
978  template <>
979  __host__ __device__
980  inline complex<float> operator/(const float& lhs, const complex<float>& rhs){
981  return complex<float>(lhs) / rhs;
982  }
983  template <>
984  __host__ __device__
985  inline complex<double> operator/(const double& lhs, const complex<double>& rhs){
986  return complex<double>(lhs) / rhs;
987  }
988 
989  // Unary arithmetic operations
990  template <typename ValueType>
991  __host__ __device__
993  return rhs;
994  }
995  template <typename ValueType>
996  __host__ __device__
998  return rhs*-ValueType(1);
999  }
1000 
1001  // Equality operators
1002  template <typename ValueType>
1003  __host__ __device__
1004  inline bool operator==(const complex<ValueType>& lhs, const complex<ValueType>& rhs){
1005  if(lhs.real() == rhs.real() && lhs.imag() == rhs.imag()){
1006  return true;
1007  }
1008  return false;
1009  }
1010 
1011  template <typename ValueType>
1012  __host__ __device__
1013  inline bool operator==(const ValueType & lhs, const complex<ValueType>& rhs){
1014  if(lhs == rhs.real() && rhs.imag() == 0){
1015  return true;
1016  }
1017  return false;
1018  }
1019  template <typename ValueType>
1020  __host__ __device__
1021  inline bool operator==(const complex<ValueType> & lhs, const ValueType& rhs){
1022  if(lhs.real() == rhs && lhs.imag() == 0){
1023  return true;
1024  }
1025  return false;
1026  }
1027 
1028 
1029  template <typename ValueType>
1030  __host__ __device__
1031  inline bool operator!=(const complex<ValueType>& lhs, const complex<ValueType>& rhs){
1032  return !(lhs == rhs);
1033  }
1034 
1035  template <typename ValueType>
1036  __host__ __device__
1037  inline bool operator!=(const ValueType & lhs, const complex<ValueType>& rhs){
1038  return !(lhs == rhs);
1039  }
1040 
1041  template <typename ValueType>
1042  __host__ __device__
1043  inline bool operator!=(const complex<ValueType> & lhs, const ValueType& rhs){
1044  return !(lhs == rhs);
1045  }
1046 
1047 
1048  template <typename ValueType>
1049  __host__ __device__
1051  return complex<ValueType>(z.real(),-z.imag());
1052  }
1053 
1054  template <typename ValueType>
1055  __host__ __device__
1056  inline ValueType abs(const complex<ValueType>& z){
1057  return ::hypot(z.real(),z.imag());
1058  }
1059  template <>
1060  __host__ __device__
1061  inline float abs(const complex<float>& z){
1062  return ::hypotf(z.real(),z.imag());
1063  }
1064  template<>
1065  __host__ __device__
1066  inline double abs(const complex<double>& z){
1067  return ::hypot(z.real(),z.imag());
1068  }
1069 
1070  template <typename ValueType>
1071  __host__ __device__
1072  inline ValueType arg(const complex<ValueType>& z){
1073  return atan2(z.imag(),z.real());
1074  }
1075  template<>
1076  __host__ __device__
1077  inline float arg(const complex<float>& z){
1078  return atan2f(z.imag(),z.real());
1079  }
1080  template<>
1081  __host__ __device__
1082  inline double arg(const complex<double>& z){
1083  return atan2(z.imag(),z.real());
1084  }
1085 
1086  template <typename ValueType>
1087  __host__ __device__
1088  inline ValueType norm(const complex<ValueType>& z){
1089  return z.real()*z.real() + z.imag()*z.imag();
1090  }
1091 
1092  template <typename ValueType>
1093  __host__ __device__
1094  inline complex<ValueType> polar(const ValueType & m, const ValueType & theta){
1095  return complex<ValueType>(m * ::cos(theta),m * ::sin(theta));
1096  }
1097 
1098  template <>
1099  __host__ __device__
1100  inline complex<float> polar(const float & magnitude, const float & angle){
1101  return complex<float>(magnitude * ::cosf(angle),magnitude * ::sinf(angle));
1102  }
1103 
1104  template <>
1105  __host__ __device__
1106  inline complex<double> polar(const double & magnitude, const double & angle){
1107  return complex<double>(magnitude * ::cos(angle),magnitude * ::sin(angle));
1108  }
1109 
1110  // Transcendental functions implementation
1111  template <typename ValueType>
1112  __host__ __device__
1114  const ValueType re = z.real();
1115  const ValueType im = z.imag();
1116  return complex<ValueType>(::cos(re) * ::cosh(im), -::sin(re) * ::sinh(im));
1117  }
1118 
1119  template <>
1120  __host__ __device__
1122  const float re = z.real();
1123  const float im = z.imag();
1124  return complex<float>(cosf(re) * coshf(im), -sinf(re) * sinhf(im));
1125  }
1126 
1127  template <typename ValueType>
1128  __host__ __device__
1130  const ValueType re = z.real();
1131  const ValueType im = z.imag();
1132  return complex<ValueType>(::cosh(re) * ::cos(im), ::sinh(re) * ::sin(im));
1133  }
1134 
1135  template <>
1136  __host__ __device__
1138  const float re = z.real();
1139  const float im = z.imag();
1140  return complex<float>(::coshf(re) * ::cosf(im), ::sinhf(re) * ::sinf(im));
1141  }
1142 
1143 
1144  template <typename ValueType>
1145  __host__ __device__
1147  return polar(::exp(z.real()),z.imag());
1148  }
1149 
1150  template <>
1151  __host__ __device__
1153  return polar(::expf(z.real()),z.imag());
1154  }
1155 
1156  template <typename ValueType>
1157  __host__ __device__
1159  return complex<ValueType>(::log(abs(z)),arg(z));
1160  }
1161 
1162  template <>
1163  __host__ __device__
1165  return complex<float>(::logf(abs(z)),arg(z));
1166  }
1167 
1168 
1169  template <typename ValueType>
1170  __host__ __device__
1172  // Using the explicit literal prevents compile time warnings in
1173  // devices that don't support doubles
1174  return log(z)/ValueType(2.30258509299404568402);
1175  // return log(z)/ValueType(::log(10.0));
1176  }
1177 
1178  template <typename ValueType>
1179  __host__ __device__
1180  inline complex<ValueType> pow(const complex<ValueType>& z, const ValueType & exponent){
1181  return exp(log(z)*exponent);
1182  }
1183 
1184  template <typename ValueType>
1185  __host__ __device__
1186  inline complex<ValueType> pow(const complex<ValueType>& z, const complex<ValueType> & exponent){
1187  return exp(log(z)*exponent);
1188  }
1189 
1190  template <typename ValueType>
1191  __host__ __device__
1192  inline complex<ValueType> pow(const ValueType & x, const complex<ValueType> & exponent){
1193  return exp(::log(x)*exponent);
1194  }
1195 
1196  template <>
1197  __host__ __device__
1198  inline complex<float> pow(const float & x, const complex<float> & exponent){
1199  return exp(::logf(x)*exponent);
1200  }
1201 
1202  template <typename ValueType>
1203  __host__ __device__
1204  inline complex<ValueType> pow(const complex<ValueType>& z,const int & exponent){
1205  return exp(log(z)*ValueType(exponent));
1206  }
1207 
1208  template <typename ValueType>
1209  __host__ __device__
1211  const ValueType re = z.real();
1212  const ValueType im = z.imag();
1213  return complex<ValueType>(::sin(re) * ::cosh(im), ::cos(re) * ::sinh(im));
1214  }
1215 
1216  template <>
1217  __host__ __device__
1219  const float re = z.real();
1220  const float im = z.imag();
1221  return complex<float>(::sinf(re) * ::coshf(im), ::cosf(re) * ::sinhf(im));
1222  }
1223 
1224  template <typename ValueType>
1225  __host__ __device__
1227  const ValueType re = z.real();
1228  const ValueType im = z.imag();
1229  return complex<ValueType>(::sinh(re) * ::cos(im), ::cosh(re) * ::sin(im));
1230  }
1231 
1232  template <>
1233  __host__ __device__
1235  const float re = z.real();
1236  const float im = z.imag();
1237  return complex<float>(::sinhf(re) * ::cosf(im), ::coshf(re) * ::sinf(im));
1238  }
1239 
1240  template <typename ValueType>
1241  __host__ __device__
1243  return polar(::sqrt(abs(z)),arg(z)/ValueType(2));
1244  }
1245 
1246  template <>
1247  __host__ __device__
1249  return polar(::sqrtf(abs(z)),arg(z)/float(2));
1250  }
1251 
1252  template <typename ValueType>
1253  __host__ __device__
1255  return sin(z)/cos(z);
1256  }
1257 
1258  template <typename ValueType>
1259  __host__ __device__
1261  // This implementation seems better than the simple sin/cos
1262  return (exp(ValueType(2)*z)-ValueType(1))/(exp(ValueType(2)*z)+ValueType(1));
1263  // return sinh(z)/cosh(z);
1264  }
1265 
1266  // Inverse trigonometric functions implementation
1267 
1268  template <typename ValueType>
1269  __host__ __device__
1271  const complex<ValueType> ret = asin(z);
1272  return complex<ValueType>(ValueType(M_PI/2.0) - ret.real(),-ret.imag());
1273  }
1274 
1275  template <typename ValueType>
1276  __host__ __device__
1278  const complex<ValueType> i(0,1);
1279  return -i*asinh(i*z);
1280  }
1281 
1282  template <typename ValueType>
1283  __host__ __device__
1285  const complex<ValueType> i(0,1);
1286  return -i*atanh(i*z);
1287  }
1288 
1289  template <typename ValueType>
1290  __host__ __device__
1292  quda::complex<ValueType> ret((z.real() - z.imag()) * (z.real() + z.imag()) - ValueType(1.0),
1293  ValueType(2.0) * z.real() * z.imag());
1294  ret = sqrt(ret);
1295  if (z.real() < ValueType(0.0)){
1296  ret = -ret;
1297  }
1298  ret += z;
1299  ret = log(ret);
1300  if (ret.real() < ValueType(0.0)){
1301  ret = -ret;
1302  }
1303  return ret;
1304 
1305  /*
1306  quda::complex<ValueType> ret = log(sqrt(z*z-ValueType(1))+z);
1307  if(ret.real() < 0){
1308  ret.real(-ret.real());
1309  }
1310  return ret;
1311  */
1312  }
1313 
1314  template <typename ValueType>
1315  __host__ __device__
1317  return log(sqrt(z*z+ValueType(1))+z);
1318  }
1319 
1320  template <typename ValueType>
1321  __host__ __device__
1323  ValueType imag2 = z.imag() * z.imag();
1324  ValueType n = ValueType(1.0) + z.real();
1325  n = imag2 + n * n;
1326 
1327  ValueType d = ValueType(1.0) - z.real();
1328  d = imag2 + d * d;
1329  complex<ValueType> ret(ValueType(0.25) * (::log(n) - ::log(d)),0);
1330 
1331  d = ValueType(1.0) - z.real() * z.real() - imag2;
1332 
1333  ret.imag(ValueType(0.5) * ::atan2(ValueType(2.0) * z.imag(), d));
1334  return ret;
1335  //return (log(ValueType(1)+z)-log(ValueType(1)-z))/ValueType(2);
1336  }
1337 
1338  template <typename ValueType>
1339  __host__ __device__
1341  float imag2 = z.imag() * z.imag();
1342  float n = float(1.0) + z.real();
1343  n = imag2 + n * n;
1344 
1345  float d = float(1.0) - z.real();
1346  d = imag2 + d * d;
1347  complex<float> ret(float(0.25) * (::logf(n) - ::logf(d)),0);
1348 
1349  d = float(1.0) - z.real() * z.real() - imag2;
1350 
1351  ret.imag(float(0.5) * ::atan2f(float(2.0) * z.imag(), d));
1352  return ret;
1353  //return (log(ValueType(1)+z)-log(ValueType(1)-z))/ValueType(2);
1354 
1355  }
1356 
1357  template <typename real> __host__ __device__ inline complex<real> cmul(const complex<real> &x, const complex<real> &y)
1358  {
1359  complex<real> w;
1360  w.x = x.real() * y.real();
1361  w.x -= x.imag() * y.imag();
1362  w.y = x.imag() * y.real();
1363  w.y += x.real() * y.imag();
1364  return w;
1365  }
1366 
1367  template <typename real>
1368  __host__ __device__ inline complex<real> cmac(const complex<real> &x, const complex<real> &y, const complex<real> &z)
1369  {
1370  complex<real> w = z;
1371  w.x += x.real() * y.real();
1372  w.x -= x.imag() * y.imag();
1373  w.y += x.imag() * y.real();
1374  w.y += x.real() * y.imag();
1375  return w;
1376  }
1377 
1378  template <typename real> __host__ __device__ inline complex<real> i_(const complex<real> &a)
1379  {
1380  // FIXME compiler generates worse code with "optimal" code
1381 #if 1
1382  return complex<real>(0.0, 1.0) * a;
1383 #else
1384  return complex<real>(-a.imag(), a.real());
1385 #endif
1386  }
1387 
1388 } // end namespace quda
__host__ __device__ ValueType conj(ValueType x)
Definition: complex_quda.h:130
__host__ __device__ complex< real > cmul(const complex< real > &x, const complex< real > &y)
__host__ __device__ complex< ValueType > polar(const ValueType &m, const ValueType &theta=0)
Returns the complex with magnitude m and angle theta in radians.
__host__ __device__ complex< ValueType > acos(const complex< ValueType > &z)
__host__ __device__ ValueType tanh(ValueType x)
Definition: complex_quda.h:91
__host__ __device__ complex< ValueType > asinh(const complex< ValueType > &z)
__host__ __device__ ValueType log10(ValueType x)
Definition: complex_quda.h:106
__device__ __host__ ColorSpinor< Float, Nc, Ns > operator*(const S &a, const ColorSpinor< Float, Nc, Ns > &x)
Compute the scalar-vector product y = a * x.
__host__ __device__ ValueType cos(ValueType x)
Definition: complex_quda.h:46
__host__ __device__ ValueType atan(ValueType x)
Definition: complex_quda.h:71
__host__ __device__ ValueType acos(ValueType x)
Definition: complex_quda.h:61
__host__ __device__ complex< ValueType > tan(const complex< ValueType > &z)
__host__ __device__ complex< real > cmac(const complex< real > &x, const complex< real > &y, const complex< real > &z)
__host__ __device__ ValueType atan2(ValueType x, ValueType y)
Definition: complex_quda.h:76
__host__ __device__ complex< float > log(const complex< float > &z)
__host__ __device__ double abs(const complex< double > &z)
__host__ __device__ complex< ValueType > acosh(const complex< ValueType > &z)
__host__ __device__ ValueType arg(const complex< ValueType > &z)
Returns the phase angle of z.
__host__ __device__ ValueType sin(ValueType x)
Definition: complex_quda.h:51
__host__ __device__ complex< float > cos(const complex< float > &z)
__host__ __device__ ValueType log(ValueType x)
Definition: complex_quda.h:101
__host__ __device__ ValueType sqrt(ValueType x)
Definition: complex_quda.h:120
__host__ __device__ complex< ValueType > log10(const complex< ValueType > &z)
__host__ __device__ complex< ValueType > atanh(const complex< ValueType > &z)
std::basic_istream< charT, traits > & operator>>(std::basic_istream< charT, traits > &is, complex< ValueType > &z)
Definition: complex_quda.h:318
__host__ __device__ complex< float > sqrt(const complex< float > &z)
__host__ __device__ complex< ValueType > asin(const complex< ValueType > &z)
__host__ __device__ ValueType sinh(ValueType x)
Definition: complex_quda.h:86
__host__ __device__ complex< float > sinh(const complex< float > &z)
__host__ __device__ complex< float > pow(const float &x, const complex< float > &exponent)
__host__ __device__ complex< float > cosh(const complex< float > &z)
__host__ __device__ complex< ValueType > tanh(const complex< ValueType > &z)
__device__ __host__ ColorSpinor< Float, Nc, Ns > operator+(const ColorSpinor< Float, Nc, Ns > &x, const ColorSpinor< Float, Nc, Ns > &y)
ColorSpinor addition operator.
__host__ __device__ ValueType pow(ValueType x, ExponentType e)
Definition: complex_quda.h:111
__host__ __device__ ValueType exp(ValueType x)
Definition: complex_quda.h:96
__host__ __device__ ValueType norm(const complex< ValueType > &z)
Returns the magnitude of z squared.
__host__ __device__ complex< ValueType > atan(const complex< ValueType > &z)
__host__ __device__ ValueType cosh(ValueType x)
Definition: complex_quda.h:81
__host__ __device__ bool operator==(const complex< ValueType > &lhs, const complex< ValueType > &rhs)
__host__ __device__ ValueType tan(ValueType x)
Definition: complex_quda.h:56
__host__ __device__ complex< real > i_(const complex< real > &a)
__host__ __device__ bool operator!=(const complex< ValueType > &lhs, const complex< ValueType > &rhs)
__host__ __device__ ValueType asin(ValueType x)
Definition: complex_quda.h:66
constexpr CommKey operator/(const CommKey &lhs, const CommKey &rhs)
Definition: comm_key.h:44
__device__ __host__ ColorSpinor< Float, Nc, Ns > operator-(const ColorSpinor< Float, Nc, Ns > &x, const ColorSpinor< Float, Nc, Ns > &y)
ColorSpinor subtraction operator.
__host__ __device__ complex< float > sin(const complex< float > &z)
__host__ __device__ complex< float > exp(const complex< float > &z)
__host__ __device__ ValueType abs(ValueType x)
Definition: complex_quda.h:125
std::ostream & operator<<(std::ostream &output, const CloverFieldParam &param)
fieldorder_wrapper is an internal class that is used to wrap instances of FieldOrder accessors,...
__host__ __device__ void real(double re)
Definition: complex_quda.h:686
__host__ __device__ void imag(double im) volatile
Definition: complex_quda.h:685
__host__ __device__ complex< double > & operator+=(const complex< float > z)
Definition: complex_quda.h:636
__host__ __device__ double imag() const
Definition: complex_quda.h:683
__host__ __device__ double real() const
Definition: complex_quda.h:682
__host__ __device__ complex< double > & operator+=(const complex< double > z)
Definition: complex_quda.h:628
__host__ __device__ double imag() const volatile
Definition: complex_quda.h:681
__host__ __device__ volatile complex< double > & operator=(const complex< T > z) volatile
Definition: complex_quda.h:611
__host__ __device__ complex< double > & operator*=(const double z)
Definition: complex_quda.h:666
__host__ __device__ void operator=(const colorspinor::fieldorder_wrapper< otherFloat, storeFloat > &a)
__host__ __device__ complex< double > & operator*=(const complex< double > z)
Definition: complex_quda.h:652
__host__ __device__ void imag(double im)
Definition: complex_quda.h:687
__host__ __device__ complex< double > & operator=(const complex< T > z)
Definition: complex_quda.h:620
__host__ __device__ complex< double > & operator/=(const complex< double > z)
Definition: complex_quda.h:659
__host__ __device__ complex< double > & operator-=(const complex< double > z)
Definition: complex_quda.h:644
__host__ __device__ void operator=(const gauge::fieldorder_wrapper< otherFloat, storeFloat > &a)
__host__ __device__ double real() const volatile
Definition: complex_quda.h:680
__host__ __device__ void real(double re) volatile
Definition: complex_quda.h:684
__host__ __device__ float real() const
Definition: complex_quda.h:553
__host__ __device__ complex< float > & operator*=(const float z)
Definition: complex_quda.h:537
__host__ __device__ void real(float re) volatile
Definition: complex_quda.h:555
__host__ __device__ float imag() const
Definition: complex_quda.h:554
__host__ __device__ float imag() const volatile
Definition: complex_quda.h:552
__host__ __device__ complex< float > & operator-=(const complex< float > z)
Definition: complex_quda.h:515
__host__ __device__ complex< float > & operator=(const complex< T > z)
Definition: complex_quda.h:499
__host__ __device__ complex< float > & operator+=(const complex< float > z)
Definition: complex_quda.h:507
__host__ __device__ complex< float > & operator/=(const complex< float > z)
Definition: complex_quda.h:530
__host__ __device__ void imag(float im)
Definition: complex_quda.h:558
__host__ __device__ volatile complex< float > & operator=(const complex< T > z) volatile
Definition: complex_quda.h:490
__host__ __device__ float real() const volatile
Definition: complex_quda.h:551
__host__ __device__ complex< float > & operator*=(const complex< float > z)
Definition: complex_quda.h:523
__host__ __device__ void operator=(const colorspinor::fieldorder_wrapper< otherFloat, storeFloat > &a)
__host__ __device__ void imag(float im) volatile
Definition: complex_quda.h:556
__host__ __device__ void real(float re)
Definition: complex_quda.h:557
__host__ __device__ void operator=(const gauge::fieldorder_wrapper< otherFloat, storeFloat > &a)
__host__ __device__ void real(int8_t re) volatile
Definition: complex_quda.h:739
__host__ __device__ int8_t imag() const volatile
Definition: complex_quda.h:736
__host__ __device__ int8_t imag() const
Definition: complex_quda.h:738
__host__ __device__ void imag(int8_t im) volatile
Definition: complex_quda.h:740
__host__ __device__ void real(int8_t re)
Definition: complex_quda.h:741
__host__ __device__ complex< int8_t > & operator-=(const complex< int8_t > z)
Definition: complex_quda.h:728
__host__ __device__ complex< int8_t > & operator+=(const complex< int8_t > z)
Definition: complex_quda.h:721
__host__ __device__ void imag(int8_t im)
Definition: complex_quda.h:742
__host__ __device__ int8_t real() const volatile
Definition: complex_quda.h:735
__host__ __device__ int8_t real() const
Definition: complex_quda.h:737
__host__ __device__ int imag() const
Definition: complex_quda.h:831
__host__ __device__ void real(int re)
Definition: complex_quda.h:834
__host__ __device__ void real(int re) volatile
Definition: complex_quda.h:832
__host__ __device__ int real() const
Definition: complex_quda.h:830
__host__ __device__ void imag(int im)
Definition: complex_quda.h:835
__host__ __device__ complex< int > & operator+=(const complex< int > z)
Definition: complex_quda.h:814
__host__ __device__ int imag() const volatile
Definition: complex_quda.h:829
__host__ __device__ int real() const volatile
Definition: complex_quda.h:828
__host__ __device__ void imag(int im) volatile
Definition: complex_quda.h:833
__host__ __device__ complex< int > & operator-=(const complex< int > z)
Definition: complex_quda.h:821
__host__ __device__ short imag() const
Definition: complex_quda.h:785
__host__ __device__ void imag(short im)
Definition: complex_quda.h:789
__host__ __device__ short real() const
Definition: complex_quda.h:784
__host__ __device__ void imag(short im) volatile
Definition: complex_quda.h:787
__host__ __device__ complex< short > & operator+=(const complex< short > z)
Definition: complex_quda.h:768
__host__ __device__ complex< short > & operator-=(const complex< short > z)
Definition: complex_quda.h:775
__host__ __device__ short real() const volatile
Definition: complex_quda.h:782
__host__ __device__ short imag() const volatile
Definition: complex_quda.h:783
__host__ __device__ void real(short re)
Definition: complex_quda.h:788
__host__ __device__ void real(short re) volatile
Definition: complex_quda.h:786
__host__ __device__ ValueType imag() const volatile
__host__ __device__ complex< ValueType > & operator*=(const ValueType z)
Definition: complex_quda.h:437
__host__ __device__ ValueType real() const volatile
__host__ __device__ void real(ValueType) volatile
__host__ __device__ ValueType real() const
__host__ __device__ complex< ValueType > & operator=(const complex< T > z)
Definition: complex_quda.h:399
__host__ __device__ complex< ValueType > & operator-=(const complex< ValueType > z)
Definition: complex_quda.h:415
ValueType value_type
Definition: complex_quda.h:371
__host__ __device__ void imag(ValueType) volatile
__host__ __device__ complex< ValueType > & operator/=(const complex< ValueType > z)
Definition: complex_quda.h:430
__host__ __device__ void imag(ValueType)
__host__ __device__ ValueType imag() const
__host__ __device__ complex< ValueType > & operator*=(const complex< ValueType > z)
Definition: complex_quda.h:423
__host__ __device__ void real(ValueType)
__host__ __device__ complex< ValueType > & operator+=(const complex< ValueType > z)
Definition: complex_quda.h:407
fieldorder_wrapper is an internal class that is used to wrap instances of FieldOrder accessors,...