QUDA  0.9.0
su3_project.cuh
Go to the documentation of this file.
1 #pragma once
2 
11 #include <quda_matrix.h>
12 
13 namespace quda {
14 
23  template <typename Float2, typename Float>
24  __host__ __device__ int checkUnitary(Matrix<Float2,3> &inv, Matrix<Float2,3> in, const Float tol)
25  {
26  computeMatrixInverse(in, &inv);
27 
28  for (int i=0;i<3;i++)
29  for (int j=0;j<3;j++)
30  {
31  if (fabs(in(i,j).x - inv(j,i).x) > tol)
32  return 1;
33  if (fabs(in(i,j).y + inv(j,i).y) > tol)
34  return 1;
35  }
36  return 0;
37  }
38  template <typename Float2>
47  __host__ __device__ int checkUnitaryPrint(Matrix<Float2,3> &inv, Matrix<Float2,3> in)
48  {
49  computeMatrixInverse(in, &inv);
50  for (int i=0;i<3;i++)
51  for (int j=0;j<3;j++)
52  {
53  printf("TESTR: %+.3le %+.3le %+.3le\n", in(i,j).x, (*inv)(j,i).x, fabs(in(i,j).x - (*inv)(j,i).x));
54  printf("TESTI: %+.3le %+.3le %+.3le\n", in(i,j).y, (*inv)(j,i).y, fabs(in(i,j).y + (*inv)(j,i).y));
55  cudaDeviceSynchronize();
56  if (fabs(in(i,j).x - inv(j,i).x) > 1e-14)
57  return 1;
58  if (fabs(in(i,j).y + inv(j,i).y) > 1e-14)
59  return 1;
60  }
61  return 0;
62  }
63 
70  template <typename Float>
71  __host__ __device__ void polarSu3(Matrix<complex<Float>,3> &in, Float tol)
72  {
73  Matrix<complex<Float>,3> inv, out;
74 
75  out = in;
77 
78  // iterate until matrix is unitary
79  do {
80  out = out + conj(inv);
81  out = out*0.5;
82  } while(checkUnitary(inv, out, tol));
83 
84 
85  // now project onto special unitary group
86  complex<Float> det = getDeterminant(out);
87  double mod = det.x*det.x + det.y*det.y;
88  mod = pow(mod, (1./6.));
89  double angle = atan2(det.y, det.x);
90  angle /= -3.;
91 
92  complex<Float> cTemp;
93 
94  cTemp.x = cos(angle)/mod;
95  cTemp.y = sin(angle)/mod;
96 
97  in = out*cTemp;
98 /* if (checkUnitary(inv, out))
99  {
100  cTemp = getDeterminant(out);
101  printf ("DetX: %+.3lf %+.3lfi, %.3lf %.3lf\nDetN: %+.3lf %+.3lfi", det.x, det.y, mod, angle, cTemp.x, cTemp.y);
102  cudaDeviceSynchronize();
103  checkUnitaryPrint(out, &inv);
104  setIdentity(in);
105  *in = *in * 0.5;
106  }
107  else
108  {
109  cTemp = getDeterminant(out);
110 // printf("Det: %+.3lf %+.3lf\n", cTemp.x, cTemp.y);
111  cudaDeviceSynchronize();
112 
113  if (fabs(cTemp.x - 1.0) > 1e-8)
114  setIdentity(in);
115  else if (fabs(cTemp.y) > 1e-8)
116  {
117  setIdentity(in);
118  printf("DadadaUnitary failed\n");
119  *in = *in * 0.1;
120  }
121  else
122  *in = out;
123  }*/
124  }
125 
126 
127 } // namespace quda
__host__ __device__ void polarSu3(Matrix< complex< Float >, 3 > &in, Float tol)
Project the input matrix on the SU(3) group. First unitarize the matrix and then project onto the spe...
Definition: su3_project.cuh:71
double tol
Definition: test_util.cpp:1647
int printf(const char *,...) __attribute__((__format__(__printf__
__host__ __device__ ValueType sin(ValueType x)
Definition: complex_quda.h:40
cpuColorSpinorField * in
__host__ __device__ ValueType atan2(ValueType x, ValueType y)
Definition: complex_quda.h:65
__host__ __device__ ValueType pow(ValueType x, ExponentType e)
Definition: complex_quda.h:100
__host__ __device__ int checkUnitaryPrint(Matrix< Float2, 3 > &inv, Matrix< Float2, 3 > in)
Check the unitarity of the input matrix to a given tolerance (1e-14) and print out deviation for each...
Definition: su3_project.cuh:47
cpuColorSpinorField * out
__host__ __device__ int checkUnitary(Matrix< Float2, 3 > &inv, Matrix< Float2, 3 > in, const Float tol)
Check the unitarity of the input matrix to a given tolerance.
Definition: su3_project.cuh:24
double fabs(double)
__device__ __host__ void computeMatrixInverse(const Matrix< T, 3 > &u, Matrix< T, 3 > *uinv)
Definition: quda_matrix.h:501
__host__ __device__ ValueType cos(ValueType x)
Definition: complex_quda.h:35
static int mod(int a, int b)
__device__ __host__ T getDeterminant(const Mat< T, 3 > &a)
Definition: quda_matrix.h:312
__host__ __device__ ValueType conj(ValueType x)
Definition: complex_quda.h:115