00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00025 template<class fieldT>
00026 class Lanczos {
00027 public:
00028 static mdp_complex step(fieldT &psi,
00029 gauge_field &U,
00030 coefficients &coeff,
00031 bool force=false) {
00032 begin_function("Lanczos__step");
00033 static bool init=true;
00034 static fieldT p(psi);
00035 static fieldT q(psi);
00036 static fieldT r(psi);
00037 static double alpha, beta;
00038 static site x(psi.lattice());
00039
00040 if(init || force) {
00041 mdp << "Initializing Lanczos vectors\n";
00042
00043
00044
00045
00046
00047 psi.update();
00048 q=psi;
00049 double norm = sqrt(norm_square(q));
00050 q /= norm;
00051 p = 0.0;
00052 r = 0.0;
00053 beta = 1.0;
00054 init=false;
00055 }
00056
00057
00058
00059
00060
00061 r=p;
00062 q/=beta;
00063 p=q;
00064 r*=-beta;
00065 q=r;
00066
00067 p.update();
00068 mul_Q(r,p,U,coeff);
00069 multiply_by_gamma5(r,r);
00070 q += r;
00071 alpha = real_scalar_product(p,q);
00072 mdp_add_scaled_field(q,-alpha,p);
00073 beta = sqrt(norm_square(q));
00074
00075 if(output_check) {
00076
00077 static fieldT s(psi);
00078 double pp, qq;
00079 mdp_complex pq, qr, ps;
00080 site x(psi.lattice());
00081
00082 pp=norm_square(p);
00083 qq=norm_square(q);
00084 pq=p*q;
00085
00086 mul_Q(s,q,U,coeff);
00087 multiply_by_gamma5(s,s);
00088 s.update();
00089 qr=q*r;
00090
00091 mul_Q(r,p,U,coeff);
00092 multiply_by_gamma5(r,r);
00093 r.update();
00094 ps=p*s;
00095
00096 mdp << "|p|=" << pp << '\n';
00097 mdp << "|q|=" << qq << '\n';
00098 mdp << "<p|q>=" << qp << '\n';
00099 mdp << "<q|Q|p>=" << qr << '\n';
00100 mdp << "<p|Q|q>^*=" << ps << '\n';
00101 mdp << "alpha=" << alpha << '\n';
00102 mdp << "beta=" << beta << '\n';
00103
00104 }
00105 end_function("Lanczos__step");
00106 return mdp_complex(alpha, beta);
00107 }
00108 };
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123