QUDA  0.9.0
eig_lanczos_quda.cpp
Go to the documentation of this file.
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <math.h>
4 
5 #include <quda_internal.h>
6 #include <color_spinor_field.h>
7 #include <blas_quda.h>
8 #include <dslash_quda.h>
9 #include <invert_quda.h>
10 #include <util_quda.h>
11 #include <sys/time.h>
12 #include <lanczos_quda.h>
13 
14 #include <iostream>
15 
16 namespace quda {
17 
18  Lanczos::Lanczos(RitzMat &ritz_mat, QudaEigParam &eigParam, TimeProfile &profile) :
19  Eig_Solver(eigParam, profile), ritz_mat(ritz_mat)
20  {
21 
22  }
23 
25  {
26 
27  }
28 
29  void Lanczos::operator()(double *alpha, double *beta, cudaColorSpinorField **Eig_Vec, cudaColorSpinorField &r, cudaColorSpinorField &Apsi, int k0, int m)
30  {
31  using namespace blas;
32 
34 
35  // Check to see that we'reV not trying to invert on a zero-field source
36  const double b2 = norm2(r);
37  if(b2 == 0){
39  printfQuda("Warning: initial residual is already zero\n");
40  return;
41  }
42 
43  double ff;
44  ff = sqrt(norm2(r));
45  zero(*(Eig_Vec[k0]));
46  axpy(1.0/ff, r, *(Eig_Vec[k0]));
47 
48  for (int k = k0; k < m; ++k)
49  {
50  if( k == 0 )
51  {
52  // r_k = A*v_k , r_k is used for temporary buffer.
53  ritz_mat(r, *(Eig_Vec[0]));
54  // alpha_k = ( v_k , r_k )
55  alpha[0] = reDotProduct(*(Eig_Vec[0]), r);
56  // r_k = (A - alpha_k)v_k - beta_{k-1}*v_{k-1} = r_k - alpha_k*v_k
57  // k = 1 case, beta_0 is defined to 0, so we don`t need beta related term.
58  axpy(-alpha[0],*(Eig_Vec[0]), r);
59  // beta_k = ||r_k||
60  beta[0] = sqrt(norm2(r));
61 
62 
63  zero(*(Eig_Vec[1]));
64  axpy(1.0/beta[0], r, *(Eig_Vec[1]));
65 
66  }
67  else
68  {
69  // r_k = A*v_k , r_k is used for temporary buffer.
70  ritz_mat(r, *(Eig_Vec[k]));
71  // r_k = (A - alpha_k)v_k - beta_{k-1}*v_{k-1} = r_k - alpha_k*v_k
72  // 1st: r_k = r_k - beta_{k-1}*v_{k-1}
73  // 2nd: alpha = (v_k, A*v_k) = (v_k , r_k)
74  // 3rd: r_k = r_k - alpha_k*v_k
75  axpy(-beta[k-1],*(Eig_Vec[k-1]), r);
76  alpha[k] = reDotProduct(*(Eig_Vec[k]), r);
77  axpy(-alpha[k],*(Eig_Vec[k]), r);
78  // beta_k = ||r_k||
79  beta[k] = sqrt(norm2(r));
80 
81  GrandSchm_test(r, Eig_Vec, k+1, 0);
82 
83  if(k+1 < m)
84  {
85  zero(*(Eig_Vec[k+1]));
86  axpy(1.0/beta[k], r, *(Eig_Vec[k+1]));
87  }
88  }
89  }
91  return;
92  }
93 
94 #if 0
95  ImpRstLanczos::ImpRstLanczos(RitzMat &ritz_mat, QudaEigParam &eigParam, TimeProfile &profile) :
97  { }
98 
99  ImpRstLanczos::~ImpRstLanczos()
100  { }
101 
102  void ImpRstLanczos::operator()(double *alpha, double *beta, cudaColorSpinorField **Eig_Vec,
103  cudaColorSpinorField &r, cudaColorSpinorField &Apsi, int k0, int m)
104  { }
105 #endif
106 
107 } // namespace quda
void operator()(double *alpha, double *beta, cudaColorSpinorField **Eig_Vec, cudaColorSpinorField &r, cudaColorSpinorField &Apsi, int k0, int m)
__host__ __device__ ValueType sqrt(ValueType x)
Definition: complex_quda.h:105
double reDotProduct(ColorSpinorField &x, ColorSpinorField &y)
Definition: reduce_quda.cu:277
QudaEigParam & eigParam
Definition: lanczos_quda.h:19
double norm2(const CloverField &a, bool inverse=false)
const RitzMat & ritz_mat
Definition: lanczos_quda.h:63
void GrandSchm_test(cudaColorSpinorField &psi, cudaColorSpinorField **Eig_Vec, int Nvec, double *delta)
Definition: eig_solver.cpp:47
TimeProfile & profile
Definition: lanczos_quda.h:20
Lanczos(RitzMat &ritz_mat, QudaEigParam &eigParam, TimeProfile &profile)
#define printfQuda(...)
Definition: util_quda.h:84
__device__ void axpy(real a, const real *x, Link &y)
__device__ __host__ void zero(vector_type< scalar, n > &v)
Definition: cub_helper.cuh:82