Bridge++  Version 1.6.1
 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  double traj_length;
223 
224  int err = 0;
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  //- step_size or trajectory_length: either, or both consistently
230  int isset_ssize = params.fetch_double("step_size", Estep);
231  int isset_trajlen = params.fetch_double("trajectory_length", traj_length);
232 
233  if ((isset_ssize != 0) && (isset_trajlen != 0)) {
234  // neither set. error.
235  ++err;
236  } else if ((isset_ssize == 0) && (isset_trajlen != 0)) {
237  // using Estep.
238  } else if ((isset_ssize != 0) && (isset_trajlen == 0)) {
239  // using trajectory_length.
240  Estep = traj_length / Nmdc;
241  } else {
242  // both set. check consistency.
243  double diff = Estep * Nmdc - traj_length;
244 
245  if (fabs(diff) >= CommonParameters::epsilon_criterion()) {
246  ++err;
247  }
248  }
249 
250  if (err) {
251  vout.crucial(m_vl, "Error at %s: input parameter not found or not appropriate.\n", class_name.c_str());
252  exit(EXIT_FAILURE);
253  }
254 
255 
256  set_parameters(Estep, Nmdc, Nprec, Metropolis_test);
257 }
258 
259 
260 //====================================================================
261 void HMC_Leapfrog::set_parameters(const double Estep, const int Nmdc, const int Nprec, const int Metropolis_test)
262 {
263  vout.crucial(m_vl, "%s: warning: integer variable for Metroplis_test is obsolete. use boolean parameter.\n", class_name.c_str());
264 
265  return set_parameters(Estep, Nmdc, Nprec, (Metropolis_test == 0 ? false : true));
266 }
267 
268 
269 //====================================================================
270 void HMC_Leapfrog::set_parameters(const double Estep, const int Nmdc, const int Nprec, const bool Metropolis_test)
271 {
272  //- print input parameters
273  vout.general(m_vl, "%s:\n", class_name.c_str());
274  vout.general(m_vl, " Number of actions: %d\n", m_action.size());
275  vout.general(m_vl, " Estep = %10.6f\n", Estep);
276  vout.general(m_vl, " Nmdc = %d\n", Nmdc);
277  vout.general(m_vl, " Nprec = %d\n", Nprec);
278  vout.general(m_vl, " Metropolis_test = %s\n", Metropolis_test ? "true" : "false");
279 
280  //- range check
281  // NB. Estep,Nmdc,Nprec,Metropolis_test == 0 is allowed.
282 
283  //- store values
284  m_Estep = Estep; // step size (SA)
285  m_Nmdc = Nmdc; // a number of steps (SA)
286  m_Nprec = Nprec; // order of approximation for e^{iP} (SA)
287  m_Metropolis_test = Metropolis_test; // Metropolis test on/off (SA)
288 }
289 
290 
291 //====================================================================
293 {
294  const int Nc = CommonParameters::Nc(); //color (SA)
295 
296  Field_G U(Uorg); // set original gauge conf. to U (SA)
297 
298  for (int i = 0; i < m_action.size(); ++i) {
299  m_action[i]->set_config(&U); // set gauge conf. for each action (SA)
300  }
301 
302  const int Nin = U.nin(); // 2x(complex) 3(color) x 3(color) part (SA)
303  const int Nvol = U.nvol(); // local volume (SA)
304  const int Nex = U.nex(); // direction mu (SA)
305 
306  Field_G iP(Nvol, Nex); // define momentum iP for gauge fields (SA)
307 
308 
309  vout.general(m_vl, "HMC (single leapfrog) start.\n");
310 
311  //- Langevin step
312  const double H_total0 = langevin(iP, U); // calculate initial hamiltonian (SA)
313  // H=p^2/s + S_G + all fermion contributions (SA)
314  vout.general(m_vl, " H_total(init) = %18.8f\n", H_total0);
315 
316  const double plaq0 = m_staple->plaquette(U); // calculate plaquette of old U (SA)
317  vout.general(m_vl, " plaq(init) = %18.8f\n", plaq0);
318 
319  //- initial Hamiltonian
320  // H_total0 = calc_Hamiltonian(iP,U);
321 
322  //- molecular dynamical integration
323  integrate(iP, U); // MD step (SA)
324 
325  //- trial Hamiltonian
326  const double H_total1 = calc_Hamiltonian(iP, U); // calculate final hamiltonian (SA)
327  vout.general(m_vl, " H_total(trial) = %18.8f\n", H_total1);
328 
329  const double plaq1 = m_staple->plaquette(U); // calculate plaquette of new U (SA)
330  vout.general(m_vl, " plaq(trial) = %18.8f\n", plaq1);
331 
332 
333  //- Metropolis test
334  vout.general(m_vl, "Metropolis test.\n");
335 
336  const double diff_H = H_total1 - H_total0; // Delta H (SA)
337  const double exp_minus_diff_H = exp(-diff_H); // e^{-Delta H} (SA)
338 
339  double rand = -1.0;
340  if (m_Metropolis_test) {
341  rand = m_rand->get(); // random number 0 <= rand < 1 (SA)
342  }
343  vout.general(m_vl, " H(diff) = %10.6f\n", diff_H);
344  vout.general(m_vl, " exp(-diff_H) = %10.6f\n", exp_minus_diff_H);
345  vout.general(m_vl, " Random number = %10.6f\n", rand);
346 
347  if (rand <= exp_minus_diff_H) { // accepted
348  vout.general(m_vl, " Accepted\n");
349  Uorg = U; // set new U to gauge conf. (SA)
350  } else { // rejected
351  vout.general(m_vl, " Rejected\n");
352  }
353 
354 
355  const double plaq_final = m_staple->plaquette(Uorg);
356  vout.general(m_vl, " plaq(final) = %18.8f\n", plaq_final);
357 
358  return plaq_final;
359 }
360 
361 
362 //====================================================================
364 {
365  const int Nc = CommonParameters::Nc();
366  const int Ndim = CommonParameters::Ndim();
367  const int NcA = Nc * Nc - 1; // Nc^2-1 (SA)
368 
369  const int Nvol = CommonParameters::Nvol();
370  const int NPE = CommonParameters::NPE();
371 
372  vout.general(m_vl, "Langevin step.\n");
373 
374  // discard caches
375  for (int i = 0; i < m_director.size(); ++i) {
376  m_director[i]->notify_linkv(); // tell director that gauge filed is modified.(SA)
377  }
378 
379  //- kinetic term
380  const double H_iP = m_Langevin_P->set_iP(iP);
381  // calculate hamiltonian of momenta iP. (SA)
382  vout.general(m_vl, " H_kin = %18.8f\n", H_iP);
383  vout.general(m_vl, " H_kin/dof = %18.8f\n", H_iP / NcA / Nvol / NPE / Ndim);
384 
385 
386  double H_actions = 0.0;
387  for (int i = 0; i < m_action.size(); ++i) {
388  H_actions += m_action[i]->langevin(m_rand);
389  // calculate contribution to hamiltonian from each action. (SA)
390  }
391 
392  const double H_total = H_iP + H_actions; // total hamiltonian. (SA)
393  return H_total;
394 }
395 
396 
397 //====================================================================
398 double HMC_Leapfrog::calc_Hamiltonian(const Field_G& iP, const Field_G& U)
399 {
400  const int Nin = U.nin(); // Local volume (SA)
401  const int Nvol = U.nvol();
402  const int Nex = U.nex();
403 
404  const int Nc = CommonParameters::Nc();
405  const int Nd = CommonParameters::Nd();
406  const int NcA = Nc * Nc - 1;
407 
408  const int NPE = CommonParameters::NPE();
409 
410  vout.general(m_vl, "Hamiltonian calculation.\n");
411 
412  // kinetic term
413  const double H_iP = calcH_P(iP); // calculate hamiltonian for iP (SA)
414  vout.general(m_vl, " H_kin = %18.8f\n", H_iP);
415  vout.general(m_vl, " H_kin/dof = %18.8f\n", H_iP / NcA / Nvol / NPE / Nex);
416 
417  double H_actions = 0.0;
418  for (int i = 0; i < m_action.size(); ++i) {
419  // calculate contribution to hamiltonian from each action (SA)
420  H_actions += m_action[i]->calcH();
421  }
422 
423  const double H_total = H_iP + H_actions;
424  return H_total;
425 }
426 
427 
428 //====================================================================
430 {
431  //calculate hamiltonian for iP: |iP|^2/2 (SA)
432  const double hn = iP.norm();
433  const double H_iP = 0.5 * hn * hn;
434 
435  return H_iP;
436 }
437 
438 
439 //====================================================================
441 {
442  vout.general(m_vl, "Integration.\n");
443 
444  const double estep = m_Estep;
445  const double estep2 = 0.5 * m_Estep;
446 
447  // Initial half step of update of h
448  if (m_Nmdc > 0) {
449  const int imdc = 0;
450  vout.general(m_vl, " imdc = %d\n", imdc);
451  update_P(estep2, iP, U); // update momentum iP at first half step (SA)
452  }
453 
454  // Molecular dynamics step
455  for (int imdc = 1; imdc < m_Nmdc + 1; imdc++) {
456  vout.general(m_vl, " imdc = %d\n", imdc);
457 
458  update_U(estep, iP, U); // update gauge field U at full step (SA)
459 
460  if (imdc < m_Nmdc) {
461  update_P(estep, iP, U); // update momentum iP at full step (SA)
462  } else {
463  update_P(estep2, iP, U); // update momentum iP at last half step (SA)
464  }
465  } // here imdc loop ends
466 }
467 
468 
469 //====================================================================
470 void HMC_Leapfrog::update_P(const double estep, Field_G& iP, const Field_G& U)
471 {
472  const int Nin = U.nin();
473  const int Nvol = U.nvol();
474  const int Nex = U.nex();
475  const int Nc = CommonParameters::Nc();
476 
477  Field force(Nin, Nvol, Nex);
478 
479  force.set(0.0);
480 
481  Field force1(Nin, Nvol, Nex);
482  // double H_actions = 0.0;
483  for (int i = 0; i < m_action.size(); ++i) {
484  m_action[i]->force(force1); // calculate force for each action (SA)
485  axpy(force, estep, force1);
486  }
487 
488  // iP = iP + step-size * force (SA)
489  axpy(iP, 1.0, force);
490 }
491 
492 
493 //====================================================================
494 void HMC_Leapfrog::update_U(const double estep, const Field_G& iP, Field_G& U)
495 {
496  const int Nvol = U.nvol();
497  const int Nex = U.nex();
498  const int Nc = CommonParameters::Nc();
499 
500  Mat_SU_N u0(Nc), u1(Nc), u2(Nc);
501  Mat_SU_N h1(Nc);
502 
503  for (int ex = 0; ex < Nex; ++ex) {
504  for (int site = 0; site < Nvol; ++site) {
505  u0 = U.mat(site, ex);
506  u1 = U.mat(site, ex);
507  h1 = iP.mat(site, ex);
508 
509  for (int iprec = 0; iprec < m_Nprec; ++iprec) {
510  double exf = estep / (m_Nprec - iprec); // step_size/(N-k) (SA)
511  u2 = h1 * u1; // iP* u1 (SA)
512  u2 *= exf; // step_size*iP*u1/(N-K) (SA)
513  u1 = u2;
514  u1 += u0; // U + step_size*iP*u1/(N-K) (SA)
515  }
516  // u1 =sum_{k=0}^{N-1} (step_size * iP)^k/k!, N=m_Nprec (SA)
517  u1.reunit(); // reunitarize u1 (SA)
518  U.set_mat(site, ex, u1); // U = u1 (SA)
519  }
520  }
521 
522  for (int i = 0; i < m_director.size(); ++i) {
523  m_director[i]->notify_linkv(); // notify all directors about update of U (SA)
524  }
525 }
526 
527 
528 //====================================================================
529 //============================================================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)
static double epsilon_criterion()
void set(const int jin, const int site, const int jex, double v)
Definition: field.h:176
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:46
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:128
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:72
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:127
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:227
double update(Field_G &)
pointer get() const
int nex() const
Definition: field.h:129
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:320
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)