19 using namespace QDP::Hints;
25 template<
typename T,
typename P,
typename Q>
47 multi1d<int> bits(maxBits);
48 multi1d<int> br_bits(maxBits);
51 for(
int i(0);
i<maxBits;
i++){
54 int br_i = maxBits-
i-1 ;
55 br_bits[br_i] = bits[
i] ;
56 br = br + (br_bits[br_i]<<br_i) ;
61 void GetRoots(multi1d<DComplex>&
r, multi1d<DComplex>& ic){
65 Double www = 6.28318530717958647696/(degree+1.0) ;
68 for(
int i(0);
i<degree;
i++){
71 r[
i] = UpperBound*cmplx(0.5*(1.0+
eps)*(1.0-cos(www*ii)) , -sqrt(
eps)*sin(www*ii));
72 ic[
i] = 1.0/(UpperBound*0.5*(1.0+
eps) -
r[
i]) ;
74 c_Zero = 2.0/(UpperBound+LowerBound) ;
86 const Real& lower_bound_,
87 const Real& upper_bound_,
88 int ord) : M(m_), LowerBound(lower_bound_), UpperBound(upper_bound_), degree(degree_)
97 QDPIO::cout<<
"lpoly: Polynomium degree must be even.\n" ;
100 QDPIO::cout<<
"lpoly: Using degree:" << degree<<std::endl ;
103 root.resize(degree_);
104 inv_c.resize(degree_);
107 multi1d<DComplex>
r(degree);
108 multi1d<DComplex> ic(degree);
114 for(
int k(1);
k<=ord;
k++){
116 for(
int i(
k-1);
i<degree/2;
i+=ord){
120 root [degree-1-
j] = conj(root[
j] ) ;
121 inv_c[degree-1-
j] = conj(inv_c[
j]) ;
132 const Real& lower_bound_,
133 const Real& upper_bound_) : M(m_), LowerBound(lower_bound_), UpperBound(upper_bound_), degree(degree_){
148 QDPIO::cout<<
"tlpoly: Polynomium degree must be power of two.\n" ;
150 degree_ = degree + 1 ;
152 QDPIO::cout<<
"tlpoly: Using degree: " << degree<<std::endl ;
160 QDPIO::cout<<
"tlpoly: Using degree: " << degree<<std::endl ;
166 inv_c.resize(degree);
169 multi1d<DComplex>
r(degree);
170 multi1d<DComplex> ic(degree);
174 for(
int i(0);
i<degree;
i++){
176 int ii = bitrevers(
i,maxBits) ;
189 inline const Subset&
subset()
const {
return M->subset();}
204 T t ; moveToFastMemoryHint(
t);
213 Real
a = 2/(UpperBound-LowerBound) ;
214 Real
d = (UpperBound+LowerBound)/(UpperBound-LowerBound) ;
223 Real sigma_m_minus_one(1.0) ;
224 Real sigma_m_plus_one ;
233 sigma_m_plus_one = 2.0*
d*sigma_m - sigma_m_minus_one ;
234 p = 2.0*sigma_m/sigma_m_plus_one *(
d*
x+
a*
r) -
235 sigma_m_minus_one/sigma_m_plus_one*
y ;
242 sigma_m_minus_one = sigma_m ;
243 sigma_m = sigma_m_plus_one ;
245 QDPIO::cout<<
"applyChebInv: 1/sigma("<<
m<<
"): "<<1.0/sigma_m<<std::endl ;
254 applyChebInv(
chi,
b) ;
277 Real c0 = sqrt(c_Zero) ;
281 for(
int i(start);
i<end;
i++){
311 multi1d<T> chi_products(degree+1);
312 multi1d<T> psi_products(degree+1);
314 multi1d<T> M_chi_products(degree+1);
315 multi1d<T> M_psi_products(degree+1);
322 chi_products[degree] = sqrt(c_Zero)*
chi;
323 for(
int n(degree-1);
n >= 0; --
n){
324 Qsq(chi_products[
n], chi_products[
n+1]);
325 chi_products[
n] -= conj(root [
n]) * chi_products[
n+1];
326 chi_products[
n] *= conj(inv_c[
n]) ;
329 psi_products[0] = sqrt(c_Zero)*
psi;
330 for(
int n(0);
n < degree; ++
n){
331 Qsq(psi_products[
n+1], psi_products[
n]);
332 psi_products[
n+1] -= root[
n] * psi_products[
n];
333 psi_products[
n+1] *= inv_c[
n] ;
336 for(
int n(0);
n < degree+1; ++
n)
338 (*M)(M_chi_products[
n],chi_products[
n],
PLUS);
339 (*M)(M_psi_products[
n],psi_products[
n],
PLUS);
344 for(
int n(0);
n < degree; ++
n)
346 M->deriv(ds_tmp, M_chi_products[
n+1], psi_products[
n],
PLUS);
347 for(
int d(0);
d<
Nd;
d++)
348 ds_tmp[
d] *= inv_c[
n] ;
351 M->deriv(ds_tmp, chi_products[
n+1], M_psi_products[
n],
MINUS);
352 for(
int d(0);
d<
Nd;
d++)
353 ds_tmp[
d] *= inv_c[
n] ;
Differentiable Linear Operator.
Base class for all fermion action boundary conditions.
Class for counted reference semantics.
Polynomial linear operator including derivatives.
void deriv(P &ds_u, const T &chi, const T &psi, PlusMinus isign) const
Apply the derivative of the linop.
multi1d< DComplex > MonomialNorm() const
Returns the roots.
multi1d< DComplex > Roots() const
Returns the roots.
lpoly(Handle< DiffLinearOperator< T, P, Q > > m_, int degree_, const Real &lower_bound_, const Real &upper_bound_)
void operator()(T &chi, const T &b, PlusMinus isign) const
Here is your apply function.
void applyChebInv(T &x, const T &b) const
void applyA(T &chi, const T &b, PlusMinus isign) const
Apply the A or A_dagger piece: P(Qsq) = A_dagger(Qsq) * A(Qsq)
lpoly(Handle< DiffLinearOperator< T, P, Q > > m_, int degree_, const Real &lower_bound_, const Real &upper_bound_, int ord)
int bitrevers(int n, int maxBits)
const Subset & subset() const
Subset comes from underlying operator.
multi1d< DComplex > inv_c
void Qsq(T &y, const T &x) const
Apply the underlying (Mdagger M) operator.
const FermBC< T, P, Q > & getFermBC() const
Return the fermion BC object for this linear operator.
void GetRoots(multi1d< DComplex > &r, multi1d< DComplex > &ic)
Handle< DiffLinearOperator< T, P, Q > > M
Class for counted reference semantics.
Asqtad Staggered-Dirac operator.
LinOpSysSolverMGProtoClover::T T
FloatingPoint< double > Double
multi1d< LatticeFermion > r(Ncb)
Polynomial Linear Operators.
multi1d< LatticeColorMatrix > P