CHROMA
one_flavor_ratio_rat_rat_monomial_w.h
Go to the documentation of this file.
1 // -*- C++ -*-
2 
3 /*! @file
4  * @brief One flavor ratio of rational monomials using RHMC
5  */
6 
7 #ifndef __one_flavor_ratio_rat_rat_monomial_w_h__
8 #define __one_flavor_ratio_rat_rat_monomial_w_h__
9 
15 #include <typeinfo>
16 
17 namespace Chroma
18 {
19  //-------------------------------------------------------------------------------------------
20  //! Exact 1 flavor fermact monomial using rational polynomials
21  /*! @ingroup monomial
22  *
23  * Exact 1 flavor fermact monomial using Rational Polynomial.
24  * Preconditioning is not specified yet.
25  * Can supply a default dsdq and pseudoferm refresh algorithm
26  */
27  template<typename P, typename Q, typename Phi>
29  {
30  public:
31  //! virtual destructor:
33 
34  //! Compute the total action
35  virtual Double S(const AbsFieldState<P,Q>& s) = 0;
36 
37  //! Compute dsdq for the system...
38  /*! Actions of the form chi^dag*f_2(A_2)*f_1(A_1)*f_2(A_2)*chi */
39  virtual void dsdq(P& F, const AbsFieldState<P,Q>& s)
40  {
41  START_CODE();
42 
43  // Self Description/Encapsulation Rule
44  XMLWriter& xml_out = TheXMLLogWriter::Instance();
45  push(xml_out, "OneFlavorRatioRatRatExactWilsonTypeFermMonomial");
46 
47  /**** Identical code for unprec and even-odd prec case *****/
48 
49  // S_f = chi^dag*f_2(A_2)*f_1(A_1)*f_2(A_2)^dag*chi
50  // Here, A_1=M_1^dag*M_1 is some 4D operator and A_2=M_2^dag*M_2
51  // is the preconditioning linop. The function
52  // f(A) = norm + \sum_i p_i/(A + q_i)
53  //
54  // We apply f(A)*chi and define the multi-shift solutions
55  // (A+q_i)\hat{chi}_i = chi
56  // (A+q_i)\hat{phi}_i = phi
57  //
58  // A core piece of math is that
59  // S_sample = chi^dag*f(A)*phi
60  //
61  // dS_sample/dU
62  // = chi^dag*df(A)*phi
63  // = - \sum_i p_i * chi^dag* (A+q_i)^{-1} * dA * (A+q_i)^{-1}*phi
64  // = - \sum_i p_i * \hat{chi}_i^dag * dA * \hat{phi}_i
65  // so, two solutions are needed
66  // Also, dA = dM^dag*M + M^dag*dM
67  //
68  // Need
69  // dS_f/dU = chi^dag*df_2(A_2)*f_1(A_1)*f_2(A_2)*chi
70  // + chi^dag*f_2(A_2)*f_1(A_1)*df_2(A_2)*chi
71  // + chi^dag*f_2(A_2)*df_1(A_1)*f_2(A_2)*chi
72  //
73  // Fermion action
75 
76  // Create a state for linop
78 
79  // Need way to get gauge state from AbsFieldState<P,Q>
81 
82  // Get multi-shift system solver
84 
85  // Fermion action
87 
88  // Need way to get gauge state from AbsFieldState<P,Q>
90 
91  // Get multi-shift system solver
93 
94  // Partial Fraction Expansion coeffs for force
95  const RemezCoeff_t& fpfe_num = getNumerFPFE();
96 
97  // Partial Fraction Expansion coeffs for force
98  const RemezCoeff_t& fpfe_den = getDenomFPFE();
99 
100  multi1d<Phi> X;
101  Phi Y;
102 
103  P F_1, F_2, F_tmp(Nd);
104  F.resize(Nd);
105  F = zero;
106 
107  // Loop over all the pseudoferms
108  multi1d<int> n_count(getNPF());
109  QDPIO::cout << "num_pf = " << getNPF() << std::endl;
110 
111  for(int n=0; n < getNPF(); ++n)
112  {
113  // The multi-shift inversion
114  SystemSolverResults_t res = (*invMdagM_num)(X, fpfe_num.pole, getPhi()[n]);
115  n_count[n] = res.n_count;
116 
117  // Loop over solns and accumulate force contributions
118  F_tmp = zero;
119  for(int i=0; i < X.size(); ++i)
120  {
121  (*M_num)(Y, X[i], PLUS);
122 
123  // The d(M^dag)*M term
124  M_num->deriv(F_1, X[i], Y, MINUS);
125 
126  // The M^dag*d(M) term
127  M_num->deriv(F_2, Y, X[i], PLUS);
128  F_1 += F_2;
129 
130  // Reweight each contribution in partial fraction
131  for(int mu=0; mu < F.size(); mu++)
132  F_tmp[mu] -= fpfe_num.res[i] * F_1[mu];
133  }
134 
135  // Concious choice. Don't monitor forces by pole
136  // Just accumulate it
137  F += F_tmp;
138  }
139 
140  state->deriv(F);
141  write(xml_out, "n_count", n_count);
142  monitorForces(xml_out, "Forces", F);
143  pop(xml_out);
144 
145  END_CODE();
146  }
147 
148 
149  //! Refresh pseudofermions
150  /*!
151  * This routine calculates the pseudofermion field (chi) for the case
152  * of rational evolution
153  *
154  * chi = n(Q)*[d(Q)]^(-1) * eta
155  * Where: Q = M^dag*M
156  * d(Q) = (Q+q_1)*(Q+q_2)*...*(Q+q_m)
157  * n(Q) = (Q+p_1)*(Q+p_2)*... *(Q+p_m)
158  * m = HBRatDeg
159  *
160  * The rational function n(x)/d(x) is the optimal rational
161  * approximation to the inverse square root of N(x)/D(x) which in
162  * turn is the optimal rational approximation to x^(-alpha).
163  * Here, alpha = 1/2
164  *
165  * To solve {n(Q)*[d(Q)]^(-1) * eta} the partial fraction expansion is
166  * used in combination with a multishift solver.
167  */
169  {
170  START_CODE();
171 
172  // Heatbath all the fields
173 
174  // Self Description/Encapsulation Rule
175  XMLWriter& xml_out = TheXMLLogWriter::Instance();
176  push(xml_out, "OneFlavorRatioRatRatExactWilsonTypeFermMonomial");
177 
178  // Get at the ferion action for piece i
180 
181  // Create a Connect State, apply fermionic boundaries
182  Handle< FermState<Phi,P,Q> > state(FA_num.createState(s.getQ()));
183 
184  // Create a linear operator
186 
187  // Get multi-shift system solver
189 
190  // Partial Fraction Expansion coeffs for heat-bath
191  const RemezCoeff_t& sipfe_num = getNumerSIPFE();
192 
193  // Partial Fraction Expansion coeffs for heat-bath
194  const RemezCoeff_t& sipfe_den = getDenomSIPFE();
195 
196  // Loop over pseudoferms
197  getPhi().resize(getNPF());
198  multi1d<int> n_count(getNPF());
199  Phi eta;
200 
201  for(int n=0; n < getNPF(); ++n)
202  {
203  // Fill the eta field with gaussian noise
204  eta = zero;
205  gaussian(eta, M_num->subset());
206 
207  // Account for fermion BC by modifying the proposed field
208  FA_num.getFermBC().modifyF(eta);
209 
210  // Temporary: Move to correct normalisation
211  eta *= sqrt(0.5);
212 
213  // The multi-shift inversion
214  multi1d<Phi> X;
215  SystemSolverResults_t res = (*invMdagM_num)(X, sipfe_num.pole, eta);
216  n_count[n] = res.n_count;
217 
218  // Weight solns to make final PF field
219  getPhi()[n][M_num->subset()] = sipfe_num.norm * eta;
220  for(int i=0; i < X.size(); ++i)
221  getPhi()[n][M_num->subset()] += sipfe_num.res[i] * X[i];
222  }
223 
224  write(xml_out, "n_count", n_count);
225  pop(xml_out);
226 
227  END_CODE();
228  }
229 
230  //! Copy pseudofermions if any
231  virtual void setInternalFields(const Monomial<P,Q>& m)
232  {
233  START_CODE();
234 
235  try {
237 
238  getPhi() = fm.getPhi();
239  }
240  catch(std::bad_cast) {
241  QDPIO::cerr << "Failed to cast input Monomial to OneFlavorRatioRatRatExactWilsonTypeFermMonomial " << std::endl;
242  QDP_abort(1);
243  }
244 
245  END_CODE();
246  }
247 
248 
249  //! Compute the action on the appropriate subset
250  /*!
251  * This measures the pseudofermion contribution to the Hamiltonian
252  * for the case of rational evolution (with polynomials n(x) and d(x),
253  * of degree SRatDeg
254  *
255  * S_f = chi_dag * (n(A)*d(A)^(-1))^2* chi
256  *
257  * where A is M^dag*M
258  *
259  * The rational function n(x)/d(x) is the optimal rational
260  * approximation to the square root of N(x)/D(x) which in
261  * turn is the optimal rational approximation to x^(-alpha).
262  * Here, alpha = 1/2
263  */
264  virtual Double S_subset(const AbsFieldState<P,Q>& s) const
265  {
266  START_CODE();
267 
268  XMLWriter& xml_out = TheXMLLogWriter::Instance();
269  push(xml_out, "S_subset");
270 
272 
273  Handle< FermState<Phi,P,Q> > state = FA_num.createState(s.getQ());
274 
275  // Need way to get gauge state from AbsFieldState<P,Q>
277 
278  // Get multi-shift system solver
280 
281  // Partial Fraction Expansion coeffs for action
282  const RemezCoeff_t& spfe_num = getNumerSPFE();
283 
284  // Compute energy
285  // Get X out here via multisolver
286  multi1d<Phi> X;
287 
288  // Loop over all the pseudoferms
289  multi1d<int> n_count(getNPF());
290  Double action = zero;
291  Phi psi;
292 
293  for(int n=0; n < getNPF(); ++n)
294  {
295  // The multi-shift inversion
296  SystemSolverResults_t res = (*invMdagM_num)(X, spfe_num.pole, getPhi()[n]);
297  n_count[n] = res.n_count;
298 
299  // Weight solns to make final PF field
300  psi[M_num->subset()] = spfe_num.norm * getPhi()[n];
301  for(int i=0; i < X.size(); ++i)
302  psi[M_num->subset()] += spfe_num.res[i] * X[i];
303 
304  action += norm2(psi, M_num->subset());
305  }
306 
307  write(xml_out, "n_count", n_count);
308  write(xml_out, "S", action);
309  pop(xml_out);
310 
311  END_CODE();
312 
313  return action;
314  }
315 
316 
317  protected:
318  //! Get at fermion action
319  virtual const WilsonTypeFermAct<Phi,P,Q>& getFermAct() const
320  {return getNumerFermAct();}
321 
322  //! Get at fermion action
323  virtual const WilsonTypeFermAct<Phi,P,Q>& getNumerFermAct() const = 0;
324 
325  //! Get at fermion action
326  virtual const WilsonTypeFermAct<Phi,P,Q>& getDenomFermAct() const = 0;
327 
328  //! Get inverter params
329  virtual const GroupXML_t& getNumerActionInvParams() const = 0;
330 
331  //! Get inverter params
332  virtual const GroupXML_t& getNumerForceInvParams() const = 0;
333 
334  //! Get inverter params
335  virtual const GroupXML_t& getDenomActionInvParams() const = 0;
336 
337  //! Get inverter params
338  virtual const GroupXML_t& getDenomForceInvParams() const = 0;
339 
340  //! Return the partial fraction expansion for the force calc
341  virtual const RemezCoeff_t& getNumerFPFE() const = 0;
342 
343  //! Return the partial fraction expansion for the action calc
344  virtual const RemezCoeff_t& getNumerSPFE() const = 0;
345 
346  //! Return the partial fraction expansion for the heat-bath
347  virtual const RemezCoeff_t& getNumerSIPFE() const = 0;
348 
349  //! Return the partial fraction expansion for the force calc
350  virtual const RemezCoeff_t& getDenomFPFE() const = 0;
351 
352  //! Return the partial fraction expansion for the action calc
353  virtual const RemezCoeff_t& getDenomSPFE() const = 0;
354 
355  //! Return the partial fraction expansion for the heat-bath
356  virtual const RemezCoeff_t& getDenomSIPFE() const = 0;
357 
358  //! Return number of roots in used
359  virtual int getNPF() const = 0;
360 
361  //! Accessor for pseudofermion (read only)
362  virtual const multi1d<Phi>& getPhi() const = 0;
363 
364  //! mutator for pseudofermion
365  virtual multi1d<Phi>& getPhi() = 0;
366 
367  };
368 
369 
370  //-------------------------------------------------------------------------------------------
371  //! Exact 1 flavor unpreconditioned fermact monomial
372  /*! @ingroup monomial
373  *
374  * Exact 1 flavor unpreconditioned fermact monomial.
375  */
376  template<typename P, typename Q, typename Phi>
378  {
379  public:
380  //! virtual destructor:
382 
383  //! Compute the total action
384  virtual Double S(const AbsFieldState<P,Q>& s)
385  {
386  START_CODE();
387 
388  // Self identification/encapsulation Rule
389  XMLWriter& xml_out = TheXMLLogWriter::Instance();
390  push(xml_out, "OneFlavorRatioRatRatExactUnprecWilsonTypeFermMonomial");
391 
392  Double action = this->S_subset(s);
393 
394  write(xml_out, "S", action);
395  pop(xml_out);
396 
397  END_CODE();
398 
399  return action;
400  }
401 
402  protected:
403  //! Get at fermion action
404  virtual const WilsonTypeFermAct<Phi,P,Q>& getNumerFermAct() const = 0;
405 
406  //! Get at fermion action
407  virtual const WilsonTypeFermAct<Phi,P,Q>& getDenomFermAct() const = 0;
408  };
409 
410 
411  //-------------------------------------------------------------------------------------------
412  //! Exact 1 flavor even-odd preconditioned fermact monomial
413  /*! @ingroup monomial
414  *
415  * Exact 1 flavor even-odd preconditioned fermact monomial.
416  * Can supply a default dsdq algorithm
417  */
418  template<typename P, typename Q, typename Phi>
420  {
421  public:
422  //! virtual destructor:
424 
425  //! Even even contribution (eg ln det Clover)
426  virtual Double S_even_even(const AbsFieldState<P,Q>& s) = 0;
427 
428  //! Compute the odd odd contribution (eg
430  {
431  return this->S_subset(s);
432  }
433 
434  //! Compute the total action
436  {
437  START_CODE();
438 
439  XMLWriter& xml_out = TheXMLLogWriter::Instance();
440  push(xml_out, "OneFlavorRatioRatRatExactEvenOddPrecWilsonTypeFermMonomial");
441 
442  Double action_e = S_even_even(s);
443  Double action_o = S_odd_odd(s);
444  Double action = action_e + action_o;
445 
446  write(xml_out, "S_even_even", action_e);
447  write(xml_out, "S_odd_odd", action_o);
448  write(xml_out, "S", action);
449  pop(xml_out);
450 
451  END_CODE();
452 
453  return action;
454  }
455 
456  protected:
457  //! Get at fermion action
459 
460  //! Get at fermion action
462  };
463 
464  //-------------------------------------------------------------------------------------------
465  //! Exact 1 flavor even-odd preconditioned fermact monomial constant determinant
466  // Can fill out the S_odd_odd piece
467 
468  /*! @ingroup monomial
469  *
470  * Exact 1 flavor even-odd preconditioned fermact monomial.
471  * Can supply a default dsdq algorithm
472  */
473  template<typename P, typename Q, typename Phi>
476  {
477  public:
478  //! virtual destructor:
480 
481  //! Even even contribution (eg ln det Clover)
483  return Double(0);
484  }
485 
486  protected:
487  //! Get at fermion action
489 
490  //! Get at fermion action
492  };
493 
494 }
495 
496 
497 #endif
Monomials - gauge action or fermion binlinear contributions for HMC.
Abstract field state.
Definition: field_state.h:27
virtual DiffLinearOperator< T, Q, P > * linOp(Handle< FermState< T, P, Q > > state) const =0
Produce a linear operator for this action.
Even-odd preconditioned Wilson-like fermion actions including derivatives.
Fermionic monomials (binlinears in fermion fields)
Definition: abs_monomial.h:243
virtual const FermBC< T, P, Q > & getFermBC() const
Return the fermion BC object for this action.
Definition: fermact.h:79
virtual FermState< T, P, Q > * createState(const Q &q) const
Given links (coordinates Q) create the state needed for the linear operators.
Definition: fermact.h:59
Class for counted reference semantics.
Definition: handle.h:33
An abstract monomial class, for inexact algorithms.
Definition: abs_monomial.h:43
Exact 1 flavor even-odd preconditioned fermact monomial constant determinant.
virtual Double S_even_even(const AbsFieldState< P, Q > &s)
Even even contribution (eg ln det Clover)
virtual const EvenOddPrecWilsonTypeFermAct< Phi, P, Q > & getDenomFermAct() const =0
Get at fermion action.
virtual const EvenOddPrecWilsonTypeFermAct< Phi, P, Q > & getNumerFermAct() const =0
Get at fermion action.
virtual Double S_odd_odd(const AbsFieldState< P, Q > &s)
Compute the odd odd contribution (eg.
virtual const EvenOddPrecWilsonTypeFermAct< Phi, P, Q > & getDenomFermAct() const =0
Get at fermion action.
Double S(const AbsFieldState< P, Q > &s)
Compute the total action.
virtual const EvenOddPrecWilsonTypeFermAct< Phi, P, Q > & getNumerFermAct() const =0
Get at fermion action.
virtual Double S_even_even(const AbsFieldState< P, Q > &s)=0
Even even contribution (eg ln det Clover)
virtual Double S(const AbsFieldState< P, Q > &s)
Compute the total action.
virtual const WilsonTypeFermAct< Phi, P, Q > & getNumerFermAct() const =0
Get at fermion action.
virtual const WilsonTypeFermAct< Phi, P, Q > & getDenomFermAct() const =0
Get at fermion action.
Exact 1 flavor fermact monomial using rational polynomials.
virtual Double S_subset(const AbsFieldState< P, Q > &s) const
Compute the action on the appropriate subset.
virtual const RemezCoeff_t & getNumerSPFE() const =0
Return the partial fraction expansion for the action calc.
virtual const RemezCoeff_t & getDenomFPFE() const =0
Return the partial fraction expansion for the force calc.
virtual const multi1d< Phi > & getPhi() const =0
Accessor for pseudofermion (read only)
virtual const GroupXML_t & getNumerForceInvParams() const =0
Get inverter params.
virtual const RemezCoeff_t & getNumerFPFE() const =0
Return the partial fraction expansion for the force calc.
virtual void refreshInternalFields(const AbsFieldState< P, Q > &s)
Refresh pseudofermions.
virtual void dsdq(P &F, const AbsFieldState< P, Q > &s)
Compute dsdq for the system...
virtual const RemezCoeff_t & getDenomSIPFE() const =0
Return the partial fraction expansion for the heat-bath.
virtual const WilsonTypeFermAct< Phi, P, Q > & getNumerFermAct() const =0
Get at fermion action.
virtual const WilsonTypeFermAct< Phi, P, Q > & getFermAct() const
Get at fermion action.
virtual const RemezCoeff_t & getNumerSIPFE() const =0
Return the partial fraction expansion for the heat-bath.
virtual int getNPF() const =0
Return number of roots in used.
virtual const GroupXML_t & getDenomActionInvParams() const =0
Get inverter params.
virtual const WilsonTypeFermAct< Phi, P, Q > & getDenomFermAct() const =0
Get at fermion action.
virtual const GroupXML_t & getDenomForceInvParams() const =0
Get inverter params.
virtual void setInternalFields(const Monomial< P, Q > &m)
Copy pseudofermions if any.
virtual Double S(const AbsFieldState< P, Q > &s)=0
Compute the total action.
virtual const RemezCoeff_t & getDenomSPFE() const =0
Return the partial fraction expansion for the action calc.
virtual const GroupXML_t & getNumerActionInvParams() const =0
Get inverter params.
virtual multi1d< Phi > & getPhi()=0
mutator for pseudofermion
static T & Instance()
Definition: singleton.h:432
Wilson-like fermion actions.
Definition: fermact.orig.h:344
virtual MdagMMultiSystemSolver< T > * mInvMdagM(Handle< FermState< T, P, Q > > state, const GroupXML_t &invParam) const
Return a multi-shift linear operator solver for this action to solve (MdagM+shift)*psi=chi.
int mu
Definition: cool.cc:24
Even-odd const determinant Wilson-like fermact.
Helper function for calculating forces.
void write(XMLWriter &xml, const std::string &path, const AsqtadFermActParams &param)
Writer parameters.
void monitorForces(XMLWriter &xml_out, const std::string &path, const multi1d< LatticeColorMatrix > &F)
Calculate and write out forces.
unsigned n
Definition: ldumul_w.cc:36
static int m[4]
Definition: make_seeds.cc:16
Nd
Definition: meslate.cc:74
Asqtad Staggered-Dirac operator.
Definition: klein_gord.cc:10
gaussian(aux)
int n_count
Definition: invbicg.cc:78
push(xml_out,"Condensates")
int i
Definition: pbg5p_w.cc:55
@ MINUS
Definition: chromabase.h:45
@ PLUS
Definition: chromabase.h:45
LatticeFermion psi
Definition: mespbg5p_w.cc:35
pop(xml_out)
LatticeFermion eta
Definition: mespbg5p_w.cc:37
START_CODE()
const WilsonTypeFermAct< multi1d< LatticeFermion > > Handle< const ConnectState > state
Definition: pbg5p_w.cc:28
Double zero
Definition: invbicg.cc:106
multi1d< LatticeFermion > s(Ncb)
FloatingPoint< double > Double
Definition: gtest.h:7351
Remez algorithm coefficients.
Hold group xml and type id.
Convenient structure to package Remez coeffs.
Definition: remez_coeff.h:19
multi1d< Real > pole
Definition: remez_coeff.h:21
multi1d< Real > res
Definition: remez_coeff.h:20
Holds return info from SystemSolver call.
Definition: syssolver.h:17
multi1d< LatticeColorMatrix > P
Definition: t_clover.cc:13
Wilson-like fermion actions.
static INTERNAL_PRECISION F