Bridge++  Ver. 1.1.x
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
projection_Maximum_SU_N.cpp
Go to the documentation of this file.
1 
15 
16 #ifdef USE_PARAMETERS_FACTORY
17 #include "parameters_factory.h"
18 #endif
19 
20 #ifdef USE_FACTORY
21 namespace {
22  Projection *create_object()
23  {
24  return new Projection_Maximum_SU_N();
25  }
26 
27 
28  bool init = Projection::Factory::Register("Maximum_SU_N", create_object);
29 }
30 #endif
31 
32 //- parameter entries
33 namespace {
34  void append_entry(Parameters& param)
35  {
36  param.Register_int("maximum_number_of_iteration", 0);
37  param.Register_double("convergence_criterion", 0.0);
38 
39  param.Register_string("verbose_level", "NULL");
40  }
41 
42 
43 #ifdef USE_PARAMETERS_FACTORY
44  bool init_param = ParametersFactory::Register("Projection.Maximum_SU_N", append_entry);
45 #endif
46 }
47 //- end
48 
49 //- parameters class
51 //- end
52 
53 //====================================================================
55 {
56  const string str_vlevel = params.get_string("verbose_level");
57 
58  m_vl = vout.set_verbose_level(str_vlevel);
59 
60  //- fetch and check input parameters
61  int Niter;
62  double Enorm;
63 
64  int err = 0;
65  err += params.fetch_int("maximum_number_of_iteration", Niter);
66  err += params.fetch_double("convergence_criterion", Enorm);
67 
68  if (err) {
69  vout.crucial(m_vl, "Projection_Maximum_SU_N: fetch error, input parameter not found.\n");
70  abort();
71  }
72 
73 
74  set_parameters(Niter, Enorm);
75 }
76 
77 
78 //====================================================================
79 void Projection_Maximum_SU_N::set_parameters(const int Niter, const double Enorm)
80 {
81  //- print input parameters
82  vout.general(m_vl, "Projection_Maximum_SU_N:\n");
83  vout.general(m_vl, " Niter = %d\n", Niter);
84  vout.general(m_vl, " Enorm = %12.4e\n", Enorm);
85 
86  //- range check
87  int err = 0;
88  err += ParameterCheck::non_negative(Niter);
89  err += ParameterCheck::non_zero(Enorm);
90 
91  if (err) {
92  vout.crucial(m_vl, "Projection_Maximum_SU_N: parameter range check failed.\n");
93  abort();
94  }
95 
96  //- store values
97  m_Niter = Niter;
98  m_Enorm = Enorm;
99 }
100 
101 
102 //====================================================================
104  double alpha,
105  const Field_G& Cst, const Field_G& Uorg)
106 {
107  int Nex = Uorg.nex();
108  int Nvol = Uorg.nvol();
109  int Nc = CommonParameters::Nc();
110 
111  assert(Cst.nex() == Nex);
112  assert(Cst.nvol() == Nvol);
113  assert(U.nex() == Nex);
114  assert(U.nvol() == Nvol);
115 
116  Field_G u_tmp(Nvol, Nex);
117  for (int ex = 0; ex < Nex; ++ex) {
118  u_tmp.setpart_ex(ex, Cst, ex);
119  u_tmp.addpart_ex(ex, Uorg, ex, 1.0 - alpha);
120  }
121 
122  maxTr(U, u_tmp);
123 }
124 
125 
126 //====================================================================
128  double alpha, const Field_G& Sigmap,
129  const Field_G& Cst, const Field_G& Uorg)
130 {
131  vout.crucial(m_vl, "Projection_Maximum_SU_N: force_recursive() is not available.\n");
132  abort();
133 }
134 
135 
136 //====================================================================
138 {
139  int Nc = CommonParameters::Nc();
140  int Nvol = Cst.nvol();
141  int Nex = Cst.nex();
142 
143  assert(Nvol == G0.nvol());
144  assert(Nex == G0.nex());
145 
146  int Nmt = 1; // number of subgroup maximization loop:
147  // seems not important because of outer iter-loop.
148 
149  Mat_SU_N unity(Nc);
150  unity.unit();
151 
152  Field_G Udelta(Nvol, Nex), A(Nvol, Nex);
153  A = Cst;
154 
155  vout.detailed(m_vl, "Maximum projection start.\n");
156 
157  for (int ex = 0; ex < Nex; ++ex) {
158  for (int site = 0; site < Nvol; ++site) {
159  G0.set_mat(site, ex, unity);
160  }
161  }
162 
163  for (int iter = 0; iter < m_Niter; ++iter) {
164  for (int ex = 0; ex < Nex; ++ex) {
165  for (int site = 0; site < Nvol; ++site) {
166  Udelta.set_mat(site, ex, unity);
167  }
168  }
169 
170  for (int imt = 0; imt < Nmt; ++imt) {
171  for (int i1 = 0; i1 < Nc; ++i1) {
172  int i2 = (i1 + 1) % Nc;
173  maxTr_SU2(i1, i2, G0, A, Udelta);
174  }
175  }
176  // for exact check with Fortran version (passed).
177 
178  /*
179  for(int imt = 0; imt < Nmt; ++imt){
180  for(int i = Nc; i > 0; --i){
181  int i1 = i % Nc;
182  int i2 = (i1 + 1) % Nc;
183  maxTr_SU2(i1, i2, G0, A, Udelta);
184  }
185  }
186  */
187 
188  //- convergence test
189  double retr1 = 0.0;
190  for (int ex = 0; ex < Nex; ++ex) {
191  for (int site = 0; site < Nvol; ++site) {
192  for (int cc = 0; cc < Nc; ++cc) {
193  retr1 += Udelta.cmp_r(cc * (1 + Nc), site, ex);
194  }
195  }
196  }
197 
198  double retr = Communicator::reduce_sum(retr1);
199  int Npe = Communicator::size();
200  double deltaV = 1.0 - retr / (Nc * Nvol * Nex * Npe);
201  vout.detailed(m_vl, " iter = %d deltaV = %12.4e\n", iter, deltaV);
202 
203  if (deltaV < m_Enorm) {
204  Mat_SU_N ut(Nc);
205  for (int ex = 0; ex < Nex; ++ex) {
206  for (int site = 0; site < Nvol; ++site) {
207  G0.mat_dag(ut, site, ex);
208  G0.set_mat(site, ex, ut);
209  }
210  }
211 
212  vout.detailed(m_vl, "Maximum projection converged.\n");
213 
214  return;
215  }
216  }
217 
218 
219  vout.crucial(m_vl, "Maximum projection not converged.\n");
220  abort();
221 }
222 
223 
224 //====================================================================
225 void Projection_Maximum_SU_N::maxTr_SU2(int i1, int i2, Field_G& Gmax,
226  Field_G& A, Field_G& Udelta)
227 {
228  int Nc = CommonParameters::Nc();
229  int Nvol = A.nvol();
230  int Nex = A.nex();
231 
232  assert(i1 < Nc);
233  assert(i2 < Nc);
234 
235  int j1 = mindex(i1, i1, Nc);
236  int j2 = mindex(i2, i2, Nc);
237  int k1 = mindex(i1, i2, Nc);
238  int k2 = mindex(i2, i1, Nc);
239 
240  Mat_SU_N at(Nc), vt(Nc);
241  Field_G v(Nvol, Nex), w(Nvol, Nex);
242 
243  //----------[ | # # 0 | <i1 ]--------------------------
244  //----------[ V = | # # 0 | <i2 ]--------------------------
245  //----------[ | 0 0 1 | ]--------------------------
246 
247  for (int ex = 0; ex < Nex; ++ex) {
248  for (int site = 0; site < Nvol; ++site) {
249  at = A.mat(site, ex);
250 
251  double xlamd =
252  at.r(j1) * at.r(j1) + at.i(j1) * at.i(j1) + 2.0 * at.r(j1) * at.r(j2)
253  + at.r(k1) * at.r(k1) + at.i(k1) * at.i(k1) - 2.0 * at.i(j1) * at.i(j2)
254  + at.r(k2) * at.r(k2) + at.i(k2) * at.i(k2) - 2.0 * at.r(k1) * at.r(k2)
255  + at.r(j2) * at.r(j2) + at.i(j2) * at.i(j2) + 2.0 * at.i(k1) * at.i(k2);
256  xlamd = 1.0 / sqrt(xlamd);
257 
258  vt.unit();
259  vt.set(j1, (at.r(j1) + at.r(j2)) * xlamd, (-at.i(j1) + at.i(j2)) * xlamd);
260  vt.set(k1, (at.r(k2) - at.r(k1)) * xlamd, (-at.i(k2) - at.i(k1)) * xlamd);
261  vt.set(k2, (at.r(k1) - at.r(k2)) * xlamd, (-at.i(k1) - at.i(k2)) * xlamd);
262  vt.set(j2, (at.r(j1) + at.r(j2)) * xlamd, (at.i(j1) - at.i(j2)) * xlamd);
263 
264  v.set_mat(site, ex, vt);
265  }
266  }
267 
268  for (int ex = 0; ex < Nex; ++ex) {
269  w.mult_Field_Gnn(ex, A, ex, v, ex);
270  }
271  A = w;
272 
273  for (int ex = 0; ex < Nex; ++ex) {
274  w.mult_Field_Gnn(ex, Gmax, ex, v, ex);
275  }
276  Gmax = w;
277 
278  for (int ex = 0; ex < Nex; ++ex) {
279  w.mult_Field_Gnn(ex, Udelta, ex, v, ex);
280  }
281  Udelta = w;
282 }
283 
284 
285 //====================================================================
286 //============================================================END=====