Bridge++  Version 1.5.4
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
hmc_Leapfrog.cpp
Go to the documentation of this file.
1 
14 #include "hmc_Leapfrog.h"
15 
16 const std::string HMC_Leapfrog::class_name = "HMC_Leapfrog";
17 
18 //====================================================================
20 HMC_Leapfrog::HMC_Leapfrog(std::vector<Action *> action,
21  RandomNumbers *rand)
22  : m_vl(CommonParameters::Vlevel())
23 {
24  m_action.resize(action.size());
25  for (int i = 0; i < action.size(); ++i) {
26  m_action[i] = action[i];
27  }
28  m_staple = new Staple_lex;
29  m_rand = rand;
30  m_Estep = 0.0;
31  m_Nmdc = 0;
32  m_Nprec = 0;
33  m_Metropolis_test = false;
35 }
36 
37 
38 //====================================================================
39 HMC_Leapfrog::HMC_Leapfrog(std::vector<Action *> action,
41  : m_vl(CommonParameters::Vlevel())
42 {
43  m_action.resize(action.size());
44  for (int i = 0; i < action.size(); ++i) {
45  m_action[i] = action[i];
46  }
47  m_staple = new Staple_lex;
48  m_rand = rand.get();
49  m_Estep = 0.0;
50  m_Nmdc = 0;
51  m_Nprec = 0;
52  m_Metropolis_test = false;
54 }
55 
56 
57 //====================================================================
59 HMC_Leapfrog::HMC_Leapfrog(std::vector<Action *> action,
60  std::vector<Director *> director,
61  RandomNumbers *rand)
62  : m_vl(CommonParameters::Vlevel())
63 {
64  m_action.resize(action.size());
65  for (int i = 0; i < action.size(); ++i) {
66  m_action[i] = action[i];
67  }
68  m_director.resize(director.size());
69  for (int i = 0; i < director.size(); ++i) {
70  m_director[i] = director[i];
71  }
72  m_staple = new Staple_lex;
73  m_rand = rand;
74  m_Estep = 0.0;
75  m_Nmdc = 0;
76  m_Nprec = 0;
77  m_Metropolis_test = false;
79 }
80 
81 
82 //====================================================================
83 HMC_Leapfrog::HMC_Leapfrog(std::vector<Action *> action,
84  std::vector<Director *> director,
86  : m_vl(CommonParameters::Vlevel())
87 {
88  m_action.resize(action.size());
89  for (int i = 0; i < action.size(); ++i) {
90  m_action[i] = action[i];
91  }
92  m_director.resize(director.size());
93  for (int i = 0; i < director.size(); ++i) {
94  m_director[i] = director[i];
95  }
96  m_staple = new Staple_lex;
97  m_rand = rand.get();
98  m_Estep = 0.0;
99  m_Nmdc = 0;
100  m_Nprec = 0;
101  m_Metropolis_test = false;
103 }
104 
105 
106 //====================================================================
109  RandomNumbers *rand)
110  : m_vl(CommonParameters::Vlevel())
111 {
112  ActionSet action_set = action_list.get_actions();
113 
114  m_action.resize(action_set.size());
115  for (int i = 0; i < action_set.size(); ++i) {
116  m_action[i] = action_set[i];
117  }
118  m_staple = new Staple_lex;
119  m_rand = rand;
120  m_Estep = 0.0;
121  m_Nmdc = 0;
122  m_Nprec = 0;
123  m_Metropolis_test = false;
125 }
126 
127 
128 //====================================================================
131  : m_vl(CommonParameters::Vlevel())
132 {
133  ActionSet action_set = action_list.get_actions();
134 
135  m_action.resize(action_set.size());
136  for (int i = 0; i < action_set.size(); ++i) {
137  m_action[i] = action_set[i];
138  }
139  m_staple = new Staple_lex;
140  m_rand = rand.get();
141  m_Estep = 0.0;
142  m_Nmdc = 0;
143  m_Nprec = 0;
144  m_Metropolis_test = false;
146 }
147 
148 
149 //====================================================================
152  std::vector<Director *> director,
153  RandomNumbers *rand)
154  : m_vl(CommonParameters::Vlevel())
155 {
156  ActionSet action_set = action_list.get_actions();
157 
158  m_action.resize(action_set.size());
159  for (int i = 0; i < action_set.size(); ++i) {
160  m_action[i] = action_set[i];
161  }
162  m_director.resize(director.size());
163  for (int i = 0; i < director.size(); ++i) {
164  m_director[i] = director[i];
165  }
166  m_staple = new Staple_lex;
167  m_rand = rand;
168  m_Estep = 0.0;
169  m_Nmdc = 0;
170  m_Nprec = 0;
171  m_Metropolis_test = false;
173 }
174 
175 
176 //====================================================================
178  std::vector<Director *> director,
180  : m_vl(CommonParameters::Vlevel())
181 {
182  ActionSet action_set = action_list.get_actions();
183 
184  m_action.resize(action_set.size());
185  for (int i = 0; i < action_set.size(); ++i) {
186  m_action[i] = action_set[i];
187  }
188  m_director.resize(director.size());
189  for (int i = 0; i < director.size(); ++i) {
190  m_director[i] = director[i];
191  }
192  m_staple = new Staple_lex;
193  m_rand = rand.get();
194  m_Estep = 0.0;
195  m_Nmdc = 0;
196  m_Nprec = 0;
197  m_Metropolis_test = false;
199 }
200 
201 
202 //====================================================================
205 {
206  delete m_staple;
207  delete m_Langevin_P;
208 }
209 
210 
211 //====================================================================
213 {
214  const string str_vlevel = params.get_string("verbose_level");
215 
216  m_vl = vout.set_verbose_level(str_vlevel);
217 
218  //- fetch and check input parameters
219  double Estep;
220  int Nmdc, Nprec;
221  bool Metropolis_test;
222 
223  int err = 0;
224  err += params.fetch_double("step_size", Estep);
225  err += params.fetch_int("number_of_steps", Nmdc);
226  err += params.fetch_int("order_of_exp_iP", Nprec);
227  err += params.fetch_bool("Metropolis_test", Metropolis_test);
228 
229  if (err) {
230  vout.crucial(m_vl, "Error at %s: input parameter not found.\n", class_name.c_str());
231  exit(EXIT_FAILURE);
232  }
233 
234 
235  set_parameters(Estep, Nmdc, Nprec, Metropolis_test);
236 }
237 
238 
239 //====================================================================
240 void HMC_Leapfrog::set_parameters(const double Estep, const int Nmdc, const int Nprec, const int Metropolis_test)
241 {
242  vout.crucial(m_vl, "%s: warning: integer variable for Metroplis_test is obsolete. use boolean parameter.\n", class_name.c_str());
243 
244  return set_parameters(Estep, Nmdc, Nprec, (Metropolis_test == 0 ? false : true));
245 }
246 
247 
248 //====================================================================
249 void HMC_Leapfrog::set_parameters(const double Estep, const int Nmdc, const int Nprec, const bool Metropolis_test)
250 {
251  //- print input parameters
252  vout.general(m_vl, "%s:\n", class_name.c_str());
253  vout.general(m_vl, " Number of actions: %d\n", m_action.size());
254  vout.general(m_vl, " Estep = %10.6f\n", Estep);
255  vout.general(m_vl, " Nmdc = %d\n", Nmdc);
256  vout.general(m_vl, " Nprec = %d\n", Nprec);
257  vout.general(m_vl, " Metropolis_test = %s\n", Metropolis_test ? "true" : "false");
258 
259  //- range check
260  // NB. Estep,Nmdc,Nprec,Metropolis_test == 0 is allowed.
261 
262  //- store values
263  m_Estep = Estep; // step size (SA)
264  m_Nmdc = Nmdc; // a number of steps (SA)
265  m_Nprec = Nprec; // order of approximation for e^{iP} (SA)
266  m_Metropolis_test = Metropolis_test; // Metropolis test on/off (SA)
267 }
268 
269 
270 //====================================================================
272 {
273  const int Nc = CommonParameters::Nc(); //color (SA)
274 
275  Field_G U(Uorg); // set original gauge conf. to U (SA)
276 
277  for (int i = 0; i < m_action.size(); ++i) {
278  m_action[i]->set_config(&U); // set gauge conf. for each action (SA)
279  }
280 
281  const int Nin = U.nin(); // 2x(complex) 3(color) x 3(color) part (SA)
282  const int Nvol = U.nvol(); // local volume (SA)
283  const int Nex = U.nex(); // direction mu (SA)
284 
285  Field_G iP(Nvol, Nex); // define momentum iP for gauge fields (SA)
286 
287 
288  vout.general(m_vl, "HMC (single leapfrog) start.\n");
289 
290  //- Langevin step
291  const double H_total0 = langevin(iP, U); // calculate initial hamiltonian (SA)
292  // H=p^2/s + S_G + all fermion contributions (SA)
293  vout.general(m_vl, " H_total(init) = %18.8f\n", H_total0);
294 
295  const double plaq0 = m_staple->plaquette(U); // calculate plaquette of old U (SA)
296  vout.general(m_vl, " plaq(init) = %18.8f\n", plaq0);
297 
298  //- initial Hamiltonian
299  // H_total0 = calc_Hamiltonian(iP,U);
300 
301  //- molecular dynamical integration
302  integrate(iP, U); // MD step (SA)
303 
304  //- trial Hamiltonian
305  const double H_total1 = calc_Hamiltonian(iP, U); // calculate final hamiltonian (SA)
306  vout.general(m_vl, " H_total(trial) = %18.8f\n", H_total1);
307 
308  const double plaq1 = m_staple->plaquette(U); // calculate plaquette of new U (SA)
309  vout.general(m_vl, " plaq(trial) = %18.8f\n", plaq1);
310 
311 
312  //- Metropolis test
313  vout.general(m_vl, "Metropolis test.\n");
314 
315  const double diff_H = H_total1 - H_total0; // Delta H (SA)
316  const double exp_minus_diff_H = exp(-diff_H); // e^{-Delta H} (SA)
317 
318  double rand = -1.0;
319  if (m_Metropolis_test) {
320  rand = m_rand->get(); // random number 0 <= rand < 1 (SA)
321  }
322  vout.general(m_vl, " H(diff) = %10.6f\n", diff_H);
323  vout.general(m_vl, " exp(-diff_H) = %10.6f\n", exp_minus_diff_H);
324  vout.general(m_vl, " Random number = %10.6f\n", rand);
325 
326  if (rand <= exp_minus_diff_H) { // accepted
327  vout.general(m_vl, " Accepted\n");
328  Uorg = U; // set new U to gauge conf. (SA)
329  } else { // rejected
330  vout.general(m_vl, " Rejected\n");
331  }
332 
333 
334  const double plaq_final = m_staple->plaquette(Uorg);
335  vout.general(m_vl, " plaq(final) = %18.8f\n", plaq_final);
336 
337  return plaq_final;
338 }
339 
340 
341 //====================================================================
343 {
344  const int Nc = CommonParameters::Nc();
345  const int Ndim = CommonParameters::Ndim();
346  const int NcA = Nc * Nc - 1; // Nc^2-1 (SA)
347 
348  const int Nvol = CommonParameters::Nvol();
349  const int NPE = CommonParameters::NPE();
350 
351  vout.general(m_vl, "Langevin step.\n");
352 
353  // discard caches
354  for (int i = 0; i < m_director.size(); ++i) {
355  m_director[i]->notify_linkv(); // tell director that gauge filed is modified.(SA)
356  }
357 
358  //- kinetic term
359  const double H_iP = m_Langevin_P->set_iP(iP);
360  // calculate hamiltonian of momenta iP. (SA)
361  vout.general(m_vl, " H_kin = %18.8f\n", H_iP);
362  vout.general(m_vl, " H_kin/dof = %18.8f\n", H_iP / NcA / Nvol / NPE / Ndim);
363 
364 
365  double H_actions = 0.0;
366  for (int i = 0; i < m_action.size(); ++i) {
367  H_actions += m_action[i]->langevin(m_rand);
368  // calculate contribution to hamiltonian from each action. (SA)
369  }
370 
371  const double H_total = H_iP + H_actions; // total hamiltonian. (SA)
372  return H_total;
373 }
374 
375 
376 //====================================================================
377 double HMC_Leapfrog::calc_Hamiltonian(const Field_G& iP, const Field_G& U)
378 {
379  const int Nin = U.nin(); // Local volume (SA)
380  const int Nvol = U.nvol();
381  const int Nex = U.nex();
382 
383  const int Nc = CommonParameters::Nc();
384  const int Nd = CommonParameters::Nd();
385  const int NcA = Nc * Nc - 1;
386 
387  const int NPE = CommonParameters::NPE();
388 
389  vout.general(m_vl, "Hamiltonian calculation.\n");
390 
391  // kinetic term
392  const double H_iP = calcH_P(iP); // calculate hamiltonian for iP (SA)
393  vout.general(m_vl, " H_kin = %18.8f\n", H_iP);
394  vout.general(m_vl, " H_kin/dof = %18.8f\n", H_iP / NcA / Nvol / NPE / Nex);
395 
396  double H_actions = 0.0;
397  for (int i = 0; i < m_action.size(); ++i) {
398  // calculate contribution to hamiltonian from each action (SA)
399  H_actions += m_action[i]->calcH();
400  }
401 
402  const double H_total = H_iP + H_actions;
403  return H_total;
404 }
405 
406 
407 //====================================================================
409 {
410  //calculate hamiltonian for iP: |iP|^2/2 (SA)
411  const double hn = iP.norm();
412  const double H_iP = 0.5 * hn * hn;
413 
414  return H_iP;
415 }
416 
417 
418 //====================================================================
420 {
421  vout.general(m_vl, "Integration.\n");
422 
423  const double estep = m_Estep;
424  const double estep2 = 0.5 * m_Estep;
425 
426  // Initial half step of update of h
427  if (m_Nmdc > 0) {
428  const int imdc = 0;
429  vout.general(m_vl, " imdc = %d\n", imdc);
430  update_P(estep2, iP, U); // update momentum iP at first half step (SA)
431  }
432 
433  // Molecular dynamics step
434  for (int imdc = 1; imdc < m_Nmdc + 1; imdc++) {
435  vout.general(m_vl, " imdc = %d\n", imdc);
436 
437  update_U(estep, iP, U); // update gauge field U at full step (SA)
438 
439  if (imdc < m_Nmdc) {
440  update_P(estep, iP, U); // update momentum iP at full step (SA)
441  } else {
442  update_P(estep2, iP, U); // update momentum iP at last half step (SA)
443  }
444  } // here imdc loop ends
445 }
446 
447 
448 //====================================================================
449 void HMC_Leapfrog::update_P(const double estep, Field_G& iP, const Field_G& U)
450 {
451  const int Nin = U.nin();
452  const int Nvol = U.nvol();
453  const int Nex = U.nex();
454  const int Nc = CommonParameters::Nc();
455 
456  Field force(Nin, Nvol, Nex);
457 
458  force.set(0.0);
459 
460  Field force1(Nin, Nvol, Nex);
461  // double H_actions = 0.0;
462  for (int i = 0; i < m_action.size(); ++i) {
463  m_action[i]->force(force1); // calculate force for each action (SA)
464  axpy(force, estep, force1);
465  }
466 
467  // iP = iP + step-size * force (SA)
468  axpy(iP, 1.0, force);
469 }
470 
471 
472 //====================================================================
473 void HMC_Leapfrog::update_U(const double estep, const Field_G& iP, Field_G& U)
474 {
475  const int Nvol = U.nvol();
476  const int Nex = U.nex();
477  const int Nc = CommonParameters::Nc();
478 
479  Mat_SU_N u0(Nc), u1(Nc), u2(Nc);
480  Mat_SU_N h1(Nc);
481 
482  for (int ex = 0; ex < Nex; ++ex) {
483  for (int site = 0; site < Nvol; ++site) {
484  u0 = U.mat(site, ex);
485  u1 = U.mat(site, ex);
486  h1 = iP.mat(site, ex);
487 
488  for (int iprec = 0; iprec < m_Nprec; ++iprec) {
489  double exf = estep / (m_Nprec - iprec); // step_size/(N-k) (SA)
490  u2 = h1 * u1; // iP* u1 (SA)
491  u2 *= exf; // step_size*iP*u1/(N-K) (SA)
492  u1 = u2;
493  u1 += u0; // U + step_size*iP*u1/(N-K) (SA)
494  }
495  // u1 =sum_{k=0}^{N-1} (step_size * iP)^k/k!, N=m_Nprec (SA)
496  u1.reunit(); // reunitarize u1 (SA)
497  U.set_mat(site, ex, u1); // U = u1 (SA)
498  }
499  }
500 
501  for (int i = 0; i < m_director.size(); ++i) {
502  m_director[i]->notify_linkv(); // notify all directors about update of U (SA)
503  }
504 }
505 
506 
507 //====================================================================
508 //============================================================END=====
bool m_Metropolis_test
Definition: hmc_Leapfrog.h:52
BridgeIO vout
Definition: bridgeIO.cpp:503
int fetch_bool(const string &key, bool &value) const
Definition: parameters.cpp:391
virtual double get()=0
void set_parameters(const Parameters &params)
void set(const int jin, const int site, const int jex, double v)
Definition: field.h:175
double calcH_P(const Field_G &iP)
double m_Estep
Definition: hmc_Leapfrog.h:53
void general(const char *format,...)
Definition: bridgeIO.cpp:197
Container of Field-type object.
Definition: field.h:45
int fetch_double(const string &key, double &value) const
Definition: parameters.cpp:327
double plaquette(const Field_G &)
calculates plaquette value.
Definition: staple_lex.cpp:38
static const std::string class_name
Definition: hmc_Leapfrog.h:47
int nvol() const
Definition: field.h:127
double set_iP(Field_G &iP)
Setting conjugate momenta and returns kinetic part of Hamiltonian.
double calc_Hamiltonian(const Field_G &iP, const Field_G &U)
Class for parameters.
Definition: parameters.h:46
RandomNumbers * m_rand
Definition: hmc_Leapfrog.h:60
Langevin_Momentum * m_Langevin_P
Definition: hmc_Leapfrog.h:55
Mat_SU_N & reunit()
Definition: mat_SU_N.h:71
Bridge::VerboseLevel m_vl
Definition: hmc_Leapfrog.h:61
std::vector< Action * > m_action
Definition: hmc_Leapfrog.h:58
int nin() const
Definition: field.h:126
ActionSet get_actions() const
Definition: action_list.cpp:89
Staple construction.
Definition: staple_lex.h:39
SU(N) gauge field.
Definition: field_G.h:38
int fetch_int(const string &key, int &value) const
Definition: parameters.cpp:346
void integrate(Field_G &iP, Field_G &U)
double norm() const
Definition: field.h:222
double update(Field_G &)
pointer get() const
int nex() const
Definition: field.h:128
Common parameter class: provides parameters as singleton.
double langevin(Field_G &iP, const Field_G &U)
Staple_lex * m_staple
Definition: hmc_Leapfrog.h:56
void axpy(Field &y, const double a, const Field &x)
axpy(y, a, x): y := a * x + y
Definition: field.cpp:319
void update_U(const double estep, const Field_G &iP, Field_G &U)
void crucial(const char *format,...)
Definition: bridgeIO.cpp:178
std::vector< Director * > m_director
Definition: hmc_Leapfrog.h:59
lists of actions at respective integrator levels.
Definition: action_list.h:40
Base class of random number generators.
Definition: randomNumbers.h:43
~HMC_Leapfrog()
destructor
string get_string(const string &key) const
Definition: parameters.cpp:221
void set_mat(const int site, const int mn, const Mat_SU_N &U)
Definition: field_G.h:160
std::vector< Action * > ActionSet
Definition: action_list.h:38
Mat_SU_N mat(const int site, const int mn=0) const
Definition: field_G.h:114
static VerboseLevel set_verbose_level(const std::string &str)
Definition: bridgeIO.cpp:131
HMC_Leapfrog(std::vector< Action * > action, RandomNumbers *rand)
constructor: with array of actions
Langevin part of HMC for conjugate momentum to link variable.
void update_P(const double estep, Field_G &iP, const Field_G &U)