Browse Source

Clean up sources up to (before) src/SCAN.

master
J.-S. Caux 6 years ago
parent
commit
e7dd24d337

+ 18
- 1
ABACUS.org View File

1
 #+TODO: TODO(t@) | DONE(d@)
1
 #+TODO: TODO(t@) | DONE(d@)
2
-#+TODO: BUGREPORT(b@) CRITICAL(#@) | SOLVED(s@)
2
+#+TODO: BUGREPORT(b@) BUGRISK(?@) CRITICAL(#@) | SOLVED(s@)
3
 #+TODO: CONCEPT(c@) UPDATED(u@) | REJECTED(r@)
3
 #+TODO: CONCEPT(c@) UPDATED(u@) | REJECTED(r@)
4
 #+TODO: PICKEDUP(p@) | ABANDONED(k@) IMPLEMENTED(i@)
4
 #+TODO: PICKEDUP(p@) | ABANDONED(k@) IMPLEMENTED(i@)
5
 
5
 
24
   :END:
24
   :END:
25
 
25
 
26
 
26
 
27
+* Bugrisks						:ABACUS:Dev:Bugrisks:
28
+  :PROPERTIES:
29
+  :ARCHIVE:  %s_archive::* Bugrisks
30
+  :CUSTOM_ID: Bugrisks
31
+  :END:
32
+
33
+TIP: Search for the string BUGRISK in the codebase
34
+
35
+** BUGRISK Value of LiebLin ln_Density_ME
36
+   - State "BUGRISK"    from ""           [2018-02-11 Sun 09:11]
37
+
38
+File: ln_Density_ME.cc
39
+line 66
40
+
41
+Why real?
42
+
43
+
27
 * Priority 					       :ABACUS:Dev:Priority:
44
 * Priority 					       :ABACUS:Dev:Priority:
28
   :PROPERTIES:
45
   :PROPERTIES:
29
   :ARCHIVE:  %s_archive::* Priority
46
   :ARCHIVE:  %s_archive::* Priority

+ 6
- 1
README.md View File

25
 ```
25
 ```
26
 This will produce all executables, together with a library `ABACUS_[vn]` where vn is of the form [digit][character].
26
 This will produce all executables, together with a library `ABACUS_[vn]` where vn is of the form [digit][character].
27
 
27
 
28
+## Warnings
29
+* The ODSLF part (for one-dimensional spinless fermions) is not functional: it is based on the old Young Tableaux ids, and must be upgraded to `State_Label`s.
30
+* The Richardson part is not implemented; what exists is old and long deprecated.
28
 
31
 
29
 ## Acknowledgements
32
 ## Acknowledgements
30
 __Antoine Klauser__ provided functions for computing neighbour-operator-product matrix elements in XXX: `ln_Szz_ME`, `ln_Szm_p_Smz_ME` and `ln_Smm_ME`.
33
 __Antoine Klauser__ provided functions for computing neighbour-operator-product matrix elements in XXX: `ln_Szz_ME`, `ln_Szm_p_Smz_ME` and `ln_Smm_ME`.
31
 
34
 
32
-__Jacopo De Nardis__ provided the code for the `ln_g2_ME` function for Lieb-Liniger.
35
+__Miłosz Panfil__ contributed to code to help in the calculation of finite-temperature correlations of Lieb-Liniger.
36
+
37
+__Jacopo De Nardis__ contributed code for the `ln_g2_ME` function for Lieb-Liniger.
33
 
38
 
34
 __Teun Zwart__ has given much useful advice concerning C++ code organization.
39
 __Teun Zwart__ has given much useful advice concerning C++ code organization.
35
 
40
 

+ 45
- 164
src/LIEBLIN/LiebLin_Bethe_State.cc View File

24
 
24
 
25
   LiebLin_Bethe_State::LiebLin_Bethe_State ()
25
   LiebLin_Bethe_State::LiebLin_Bethe_State ()
26
     : c_int (0.0), L(0.0), cxL(0.0), N(0),
26
     : c_int (0.0), L(0.0), cxL(0.0), N(0),
27
-      //OriginStateIxe(Vect<int>(0,1)),
28
       Ix2_available(Vect<int>(0, 1)), index_first_hole_to_right (Vect<int>(0,1)), displacement (Vect<int>(0,1)),
27
       Ix2_available(Vect<int>(0, 1)), index_first_hole_to_right (Vect<int>(0,1)), displacement (Vect<int>(0,1)),
29
-      Ix2(Vect<int>(0, 1)), lambdaoc(Vect<DP>(0.0, 1)), //BE(Vect<DP>(0.0, 1)),
28
+      Ix2(Vect<int>(0, 1)), lambdaoc(Vect<DP>(0.0, 1)),
30
       S(Vect<DP>(0.0, 1)), dSdlambdaoc(Vect<DP>(0.0, 1)),
29
       S(Vect<DP>(0.0, 1)), dSdlambdaoc(Vect<DP>(0.0, 1)),
31
       diffsq(0.0), prec(ITER_REQ_PREC_LIEBLIN), conv(0), iter_Newton(0), E(0.0), iK(0), K(0.0), lnnorm(-100.0)
30
       diffsq(0.0), prec(ITER_REQ_PREC_LIEBLIN), conv(0), iter_Newton(0), E(0.0), iK(0), K(0.0), lnnorm(-100.0)
32
   {
31
   {
33
-    stringstream Nout; Nout << N; label = Nout.str() + LABELSEP + ABACUScoding[0] + LABELSEP;//"_0_";
32
+    stringstream Nout; Nout << N; label = Nout.str() + LABELSEP + ABACUScoding[0] + LABELSEP;
34
   }
33
   }
35
 
34
 
36
   LiebLin_Bethe_State::LiebLin_Bethe_State (DP c_int_ref, DP L_ref, int N_ref)
35
   LiebLin_Bethe_State::LiebLin_Bethe_State (DP c_int_ref, DP L_ref, int N_ref)
37
     : c_int(c_int_ref), L(L_ref), cxL(c_int_ref * L_ref), N(N_ref),
36
     : c_int(c_int_ref), L(L_ref), cxL(c_int_ref * L_ref), N(N_ref),
38
-      //OriginStateIx2(Vect<int>(0,N),
39
       Ix2_available(Vect<int>(0, 2)), index_first_hole_to_right (Vect<int>(0,N)), displacement (Vect<int>(0,N)),
37
       Ix2_available(Vect<int>(0, 2)), index_first_hole_to_right (Vect<int>(0,N)), displacement (Vect<int>(0,N)),
40
-      Ix2(Vect<int>(0, N)), lambdaoc(Vect<DP>(0.0, N)), //BE(Vect<DP>(0.0, N)),
38
+      Ix2(Vect<int>(0, N)), lambdaoc(Vect<DP>(0.0, N)),
41
       S(Vect<DP>(0.0, N)), dSdlambdaoc(Vect<DP>(0.0, N)),
39
       S(Vect<DP>(0.0, N)), dSdlambdaoc(Vect<DP>(0.0, N)),
42
-      diffsq(0.0), prec(ABACUS::max(1.0, 1.0/(c_int * c_int)) * ITER_REQ_PREC_LIEBLIN), conv(0), iter_Newton(0), E(0.0), iK(0), K(0.0), lnnorm(-100.0)
40
+      diffsq(0.0), prec(ABACUS::max(1.0, 1.0/(c_int * c_int)) * ITER_REQ_PREC_LIEBLIN),
41
+      conv(0), iter_Newton(0), E(0.0), iK(0), K(0.0), lnnorm(-100.0)
43
   {
42
   {
44
     if (c_int < 0.0) ABACUSerror("You must use a positive interaction parameter !");
43
     if (c_int < 0.0) ABACUSerror("You must use a positive interaction parameter !");
45
     if (N < 0) ABACUSerror("Particle number must be strictly positive.");
44
     if (N < 0) ABACUSerror("Particle number must be strictly positive.");
46
 
45
 
47
-    stringstream Nout; Nout << N; label = Nout.str() + LABELSEP + ABACUScoding[0] + LABELSEP;//+ "_0_";
46
+    stringstream Nout; Nout << N; label = Nout.str() + LABELSEP + ABACUScoding[0] + LABELSEP;
48
 
47
 
49
     // Set quantum numbers to ground-state configuration:
48
     // Set quantum numbers to ground-state configuration:
50
     for (int i = 0; i < N; ++i) Ix2[i] = -(N-1) + 2*i;
49
     for (int i = 0; i < N; ++i) Ix2[i] = -(N-1) + 2*i;
52
     Vect<int> OriginIx2 = Ix2;
51
     Vect<int> OriginIx2 = Ix2;
53
 
52
 
54
     (*this).Set_Label_from_Ix2 (OriginIx2);
53
     (*this).Set_Label_from_Ix2 (OriginIx2);
55
-    //(*this).Set_Label_Internals_from_Ix2 (OriginIx2);
56
   }
54
   }
57
 
55
 
58
 
56
 
69
       displacement = RefState.displacement;
67
       displacement = RefState.displacement;
70
       Ix2 = RefState.Ix2;
68
       Ix2 = RefState.Ix2;
71
       lambdaoc = RefState.lambdaoc;
69
       lambdaoc = RefState.lambdaoc;
72
-      //BE = RefState.BE;
73
       S = RefState.S;
70
       S = RefState.S;
74
       dSdlambdaoc = RefState.dSdlambdaoc;
71
       dSdlambdaoc = RefState.dSdlambdaoc;
75
       diffsq = RefState.diffsq;
72
       diffsq = RefState.diffsq;
114
     // Now reorder the Ix2 to follow convention:
111
     // Now reorder the Ix2 to follow convention:
115
     Ix2.QuickSort();
112
     Ix2.QuickSort();
116
 
113
 
117
-    //cout << "Setting label:" << label_ref << endl << "Ix2old = " << labeldata.Ix2old[0] << endl << "Ix2exc = " << labeldata.Ix2exc[0] << endl;
118
-    //cout << "on " << OriginStateIx2ordered << endl << "giving " << Ix2 << endl;
119
-
120
     (*this).Set_Label_from_Ix2 (OriginStateIx2ordered);
114
     (*this).Set_Label_from_Ix2 (OriginStateIx2ordered);
121
-    //(*this).Set_Label_Internals_from_Ix2 (OriginStateIx2ordered);
122
   }
115
   }
123
 
116
 
124
   void LiebLin_Bethe_State::Set_to_Label (string label_ref)
117
   void LiebLin_Bethe_State::Set_to_Label (string label_ref)
138
 
131
 
139
     if (N != OriginStateIx2.size()) ABACUSerror("N != OriginStateIx2.size() in Set_Label_from_Ix2.");
132
     if (N != OriginStateIx2.size()) ABACUSerror("N != OriginStateIx2.size() in Set_Label_from_Ix2.");
140
 
133
 
141
-    //cout << "Setting label on Ix2 " << endl << Ix2 << endl;
142
 
134
 
143
     // Set the state label:
135
     // Set the state label:
144
     Vect<int> type_ref(0,1);
136
     Vect<int> type_ref(0,1);
173
     label = Return_State_Label (labeldata, OriginStateIx2);
165
     label = Return_State_Label (labeldata, OriginStateIx2);
174
   }
166
   }
175
 
167
 
176
-  /*
177
-  void LiebLin_Bethe_State::Set_Label_from_Ix2 (const Vect<int>& OriginStateIx2)
178
-  {
179
-    // This function was deprecated since it assumed that the Ix2 of the state were
180
-    // in a particular order mirroring the indices of OriginStateIx2.
181
-
182
-    if (N != OriginStateIx2.size()) ABACUSerror("N != OriginStateIx2.size() in Set_Label_from_Ix2.");
183
-
184
-    Vect<int> OriginStateIx2ordered = OriginStateIx2;
185
-    OriginStateIx2ordered.QuickSort();
186
-
187
-    // Set the state label:
188
-    Vect<int> type_ref(0,1);
189
-    Vect<int> M_ref(N, 1);
190
-    Vect<int> nexc_ref(0, 1);
191
-    // Count nr of particle-holes:
192
-    for (int i = 0; i < N; ++i) if (Ix2[i] != OriginStateIx2ordered[i]) nexc_ref[0] += 1;
193
-    Vect<Vect<int> > Ix2old_ref(1);
194
-    Vect<Vect<int> > Ix2exc_ref(1);
195
-    Ix2old_ref[0] = Vect<int>(ABACUS::max(nexc_ref[0],1));
196
-    Ix2exc_ref[0] = Vect<int>(ABACUS::max(nexc_ref[0],1));
197
-    int nexccheck = 0;
198
-    for (int i = 0; i < N; ++i)
199
-      if (Ix2[i] != OriginStateIx2ordered[i]) {
200
-	Ix2old_ref[0][nexccheck] = OriginStateIx2ordered[i];
201
-	Ix2exc_ref[0][nexccheck++] = Ix2[i];
202
-      }
203
-
204
-    State_Label_Data labeldata(type_ref, M_ref, nexc_ref, Ix2old_ref, Ix2exc_ref);
205
-
206
-    label = Return_State_Label (labeldata);
207
-  }
208
-  */
209
-
210
   void LiebLin_Bethe_State::Set_Label_Internals_from_Ix2 (const Vect<int>& OriginStateIx2)
168
   void LiebLin_Bethe_State::Set_Label_Internals_from_Ix2 (const Vect<int>& OriginStateIx2)
211
   {
169
   {
212
-    //ABACUSerror("LiebLin_Bethe_State::Set_Label_Internals_from_Ix2 deprecated 20110604");
213
-
214
     if (N != OriginStateIx2.size()) ABACUSerror("N != OriginStateIx2.size() in Set_Label_Internals_from_Ix2.");
170
     if (N != OriginStateIx2.size()) ABACUSerror("N != OriginStateIx2.size() in Set_Label_Internals_from_Ix2.");
215
 
171
 
216
     Vect<int> OriginStateIx2ordered = OriginStateIx2;
172
     Vect<int> OriginStateIx2ordered = OriginStateIx2;
238
     label = Return_State_Label (labeldata, OriginStateIx2);
194
     label = Return_State_Label (labeldata, OriginStateIx2);
239
 
195
 
240
     // Construct the Ix2_available vector: we give one more quantum number on left and right:
196
     // Construct the Ix2_available vector: we give one more quantum number on left and right:
241
-    int navailable = 2 + (ABACUS::max(Ix2.max(), OriginStateIx2.max()) - ABACUS::min(Ix2.min(), OriginStateIx2.min()))/2 - N + 1;
197
+    int navailable = 2 + (ABACUS::max(Ix2.max(), OriginStateIx2.max())
198
+			  - ABACUS::min(Ix2.min(), OriginStateIx2.min()))/2 - N + 1;
242
     Ix2_available = Vect<int>(navailable);
199
     Ix2_available = Vect<int>(navailable);
243
     index_first_hole_to_right = Vect<int>(N);
200
     index_first_hole_to_right = Vect<int>(N);
244
 
201
 
245
     // First set Ix2_available to all holes from left
202
     // First set Ix2_available to all holes from left
246
-    for (int i = 0; i < Ix2_available.size(); ++i) Ix2_available[i] = ABACUS::min(Ix2.min(), OriginStateIx2.min()) - 2 + 2*i;
203
+    for (int i = 0; i < Ix2_available.size(); ++i)
204
+      Ix2_available[i] = ABACUS::min(Ix2.min(), OriginStateIx2.min()) - 2 + 2*i;
247
 
205
 
248
     // Now shift according to Ix2 of OriginState:
206
     // Now shift according to Ix2 of OriginState:
249
     for (int j = 0; j < N; ++j) {
207
     for (int j = 0; j < N; ++j) {
261
     for (int j = 0; j < N; ++j) {
219
     for (int j = 0; j < N; ++j) {
262
       if (Ix2[j] < OriginStateIx2ordered[j]) {
220
       if (Ix2[j] < OriginStateIx2ordered[j]) {
263
 	// Ix2[j] must be equal to some OriginState_Ix2_available[i] for i < OriginState_index_first_hole_to_right[j]
221
 	// Ix2[j] must be equal to some OriginState_Ix2_available[i] for i < OriginState_index_first_hole_to_right[j]
264
-	//cout << "Going down\t" << Ix2[j] << "\t" << index_first_hole_to_right[j] << "\t" << displacement[j] << endl;
265
 	while (Ix2[j] != Ix2_available[index_first_hole_to_right[j] + displacement[j] ]) {
222
 	while (Ix2[j] != Ix2_available[index_first_hole_to_right[j] + displacement[j] ]) {
266
-	  //cout << j << "\t" << index_first_hole_to_right[j] << "\t" << displacement[j] << "\t" << Ix2_available[index_first_hole_to_right[j] + displacement[j] ] << endl;
267
 	  if (index_first_hole_to_right[j] + displacement[j] == 0) {
223
 	  if (index_first_hole_to_right[j] + displacement[j] == 0) {
268
-	    cout << label << endl << j << endl << OriginStateIx2 << endl << Ix2 << endl << Ix2_available << endl << index_first_hole_to_right << endl << displacement << endl;
224
+	    cout << label << endl << j << endl << OriginStateIx2 << endl << Ix2 << endl << Ix2_available
225
+		 << endl << index_first_hole_to_right << endl << displacement << endl;
269
 	    ABACUSerror("Going down too far in Set_Label_Internals...");
226
 	    ABACUSerror("Going down too far in Set_Label_Internals...");
270
 	  }
227
 	  }
271
 	  displacement[j]--;
228
 	  displacement[j]--;
273
       }
230
       }
274
       if (Ix2[j] > OriginStateIx2ordered[j]) {
231
       if (Ix2[j] > OriginStateIx2ordered[j]) {
275
 	// Ix2[j] must be equal to some Ix2_available[i] for i >= index_first_hole_to_right[j]
232
 	// Ix2[j] must be equal to some Ix2_available[i] for i >= index_first_hole_to_right[j]
276
-	//cout << "Going up\t" << Ix2[j] << "\t" << index_first_hole_to_right[j] << "\t" << displacement[j] << endl;
277
 	displacement[j] = 1; // start with this value to prevent segfault
233
 	displacement[j] = 1; // start with this value to prevent segfault
278
 	while (Ix2[j] != Ix2_available[index_first_hole_to_right[j] - 1 + displacement[j] ]) {
234
 	while (Ix2[j] != Ix2_available[index_first_hole_to_right[j] - 1 + displacement[j] ]) {
279
-	  //cout << j << "\t" << index_first_hole_to_right[j] << "\t" << displacement[j] << "\t" << Ix2_available[index_first_hole_to_right[j] + displacement[j] ] << endl;
280
 	  if (index_first_hole_to_right[j] + displacement[j] == Ix2_available.size() - 1) {
235
 	  if (index_first_hole_to_right[j] + displacement[j] == Ix2_available.size() - 1) {
281
-	    cout << label << endl << j << endl << OriginStateIx2 << endl << Ix2 << endl << Ix2_available << endl << index_first_hole_to_right << endl << displacement << endl;
236
+	    cout << label << endl << j << endl << OriginStateIx2 << endl << Ix2 << endl << Ix2_available
237
+		 << endl << index_first_hole_to_right << endl << displacement << endl;
282
 	    ABACUSerror("Going up too far in Set_Label_Internals...");
238
 	    ABACUSerror("Going up too far in Set_Label_Internals...");
283
 	  }
239
 	  }
284
 	  displacement[j]++;
240
 	  displacement[j]++;
285
 	}
241
 	}
286
       }
242
       }
287
     }
243
     }
288
-    //cout << "label " << label << endl;
289
-    //cout << "Ix2: " << Ix2 << endl << "Ix2_available: " << Ix2_available << endl << "index...: " << index_first_hole_to_right << endl << "displacement: " << displacement << endl;
290
-    //char a; cin >> a;
291
-
292
-
293
   }
244
   }
294
 
245
 
295
   bool LiebLin_Bethe_State::Check_Admissibility (char whichDSF)
246
   bool LiebLin_Bethe_State::Check_Admissibility (char whichDSF)
307
     diffsq = 1.0;
258
     diffsq = 1.0;
308
 
259
 
309
     if (reset_rapidities) (*this).Set_Free_lambdaocs();
260
     if (reset_rapidities) (*this).Set_Free_lambdaocs();
310
-    /*
311
-    // Start with normal iterations:
312
-    //for (int niternormal = 0; niternormal < 10; ++niternormal) {
313
-    for (int niternormal = 0; niternormal < N; ++niternormal) {
314
-      //(*this).Iterate_BAE(0.99);
315
-      (*this).Iterate_BAE(0.9);
316
-      cout << "Normal: " << niternormal << "\t" << diffsq << endl;
317
-      cout << (*this).lambdaoc << endl;
318
-      if (diffsq < sqrt(prec)) break;
319
-    }
320
-    */
261
+
321
     iter_Newton = 0;
262
     iter_Newton = 0;
322
 
263
 
323
     DP damping = 1.0;
264
     DP damping = 1.0;
324
     DP diffsq_prev = 1.0e+6;
265
     DP diffsq_prev = 1.0e+6;
325
-    //while (diffsq > prec && !is_nan(diffsq) && iter_Newton < 40) {
326
     while (diffsq > prec && !is_nan(diffsq) && iter_Newton < 100) {
266
     while (diffsq > prec && !is_nan(diffsq) && iter_Newton < 100) {
327
-    //while (diffsq > prec && !is_nan(diffsq) && iter_Newton < 400) {
328
       (*this).Iterate_BAE_Newton(damping);
267
       (*this).Iterate_BAE_Newton(damping);
329
-      //(*this).Iterate_BAE_S(damping); // Not as fast as Newton for N up to ~ 256
330
-      //if (diffsq > diffsq_prev) damping /= 2.0;
331
       if (diffsq > diffsq_prev && damping > 0.5) damping /= 2.0;
268
       if (diffsq > diffsq_prev && damping > 0.5) damping /= 2.0;
332
       else if (diffsq < diffsq_prev) damping = 1.0;
269
       else if (diffsq < diffsq_prev) damping = 1.0;
333
       diffsq_prev = diffsq;
270
       diffsq_prev = diffsq;
334
-      //cout << iter_Newton << "\t" << diffsq << "\t" << damping << endl;
335
-      //cout << (*this).lambdaoc << endl;
336
     }
271
     }
337
 
272
 
338
     conv = ((diffsq < prec) && (*this).Check_Rapidities()) ? 1 : 0;
273
     conv = ((diffsq < prec) && (*this).Check_Rapidities()) ? 1 : 0;
339
 
274
 
340
     if (!conv) {
275
     if (!conv) {
341
-      cout << "Alert! State " << label << " did not converge... diffsq " << diffsq << "\titer_Newton " << iter_Newton << (*this) << endl;
342
-      //char a; cin >> a;
276
+      cout << "Alert! State " << label << " did not converge... diffsq " << diffsq
277
+	   << "\titer_Newton " << iter_Newton << (*this) << endl;
343
     }
278
     }
344
 
279
 
345
-    //cout << (*this) << endl;
346
-
347
     return;
280
     return;
348
   }
281
   }
349
 
282
 
388
 
321
 
389
       // Add the pieces outside of Gaudin determinant
322
       // Add the pieces outside of Gaudin determinant
390
 
323
 
391
-      for (int j = 0; j < N - 1; ++j) for (int k = j+1; k < N; ++k) lnnorm += log(1.0 + 1.0/pow(lambdaoc[j] - lambdaoc[k], 2.0));
324
+      for (int j = 0; j < N - 1; ++j) for (int k = j+1; k < N; ++k)
325
+					lnnorm += log(1.0 + 1.0/pow(lambdaoc[j] - lambdaoc[k], 2.0));
392
 
326
 
393
     }
327
     }
394
 
328
 
409
   void LiebLin_Bethe_State::Set_Free_lambdaocs()
343
   void LiebLin_Bethe_State::Set_Free_lambdaocs()
410
   {
344
   {
411
     if (cxL >= 1.0)
345
     if (cxL >= 1.0)
412
-    for (int a = 0; a < N; ++a) lambdaoc[a] = PI * Ix2[a]/cxL;
346
+      for (int a = 0; a < N; ++a) lambdaoc[a] = PI * Ix2[a]/cxL;
413
 
347
 
414
     // For small values of c, use better approximation using approximate zeroes of Hermite polynomials: see Gaudin eqn 4.71.
348
     // For small values of c, use better approximation using approximate zeroes of Hermite polynomials: see Gaudin eqn 4.71.
415
     if (cxL < 1.0) {
349
     if (cxL < 1.0) {
416
-      //DP sqrtcL = pow(cxL, 0.5);
417
       DP oneoversqrtcLN = 1.0/pow(cxL * N, 0.5);
350
       DP oneoversqrtcLN = 1.0/pow(cxL * N, 0.5);
418
       for (int a = 0; a < N; ++a) lambdaoc[a] = oneoversqrtcLN * PI * Ix2[a];
351
       for (int a = 0; a < N; ++a) lambdaoc[a] = oneoversqrtcLN * PI * Ix2[a];
419
-
420
-      //for (int a = 0; a < N; ++a) lambdaoc[a] = sqrtcL * PI * Ix2[a];  // wrong values, correct scaling with c
421
-      //for (int a = 0; a < N; ++a) lambdaoc[a] = PI * Ix2[a]/(cxL + 2.0 * N);  // set to minimal distance lattice
422
     }
352
     }
423
 
353
 
424
-    //cout << "Set free lambdaocs to: " << endl << lambdaoc << endl;
425
     return;
354
     return;
426
   }
355
   }
427
 
356
 
443
     }
372
     }
444
 
373
 
445
     diffsq = 0.0;
374
     diffsq = 0.0;
446
-    //DP sumsq = 0.0;
447
     for (int i = 0; i < N; ++i) {
375
     for (int i = 0; i < N; ++i) {
448
       lambdaoc[i] += dlambdaoc[i];
376
       lambdaoc[i] += dlambdaoc[i];
449
-      //sumsq += lambdaoc[i] * lambdaoc[i];
450
-      //diffsq += dlambdaoc[i] * dlambdaoc[i];
451
-      //if (cxL > 1.0) diffsq += dlambdaoc[i] * dlambdaoc[i];
452
-      //else diffsq += cxL * cxL * dlambdaoc[i] * dlambdaoc[i];
453
       // Normalize the diffsq by the typical value of the rapidities:
377
       // Normalize the diffsq by the typical value of the rapidities:
454
       if (cxL > 1.0) diffsq += dlambdaoc[i] * dlambdaoc[i]/(lambdaoc[i] * lambdaoc[i] + 1.0e-6);
378
       if (cxL > 1.0) diffsq += dlambdaoc[i] * dlambdaoc[i]/(lambdaoc[i] * lambdaoc[i] + 1.0e-6);
455
       else diffsq += cxL * cxL * dlambdaoc[i] * dlambdaoc[i]/(lambdaoc[i] * lambdaoc[i] + 1.0e-6);
379
       else diffsq += cxL * cxL * dlambdaoc[i] * dlambdaoc[i]/(lambdaoc[i] * lambdaoc[i] + 1.0e-6);
456
     }
380
     }
457
     diffsq /= DP(N);
381
     diffsq /= DP(N);
458
-    //diffsq /= sqrt(sumsq) * DP(N);
459
 
382
 
460
     return;
383
     return;
461
   }
384
   }
463
   void LiebLin_Bethe_State::Iterate_BAE_S (DP damping)
386
   void LiebLin_Bethe_State::Iterate_BAE_S (DP damping)
464
   {
387
   {
465
     // This is essentially Newton's method but only in one variable.
388
     // This is essentially Newton's method but only in one variable.
466
-    // The logic is that the derivative of the LHS of the BE_j w/r to lambdaoc_j is much larger than with respect to lambdaoc_l with l != j.
389
+    // The logic is that the derivative of the LHS of the BE_j w/r to lambdaoc_j is much larger
390
+    // than with respect to lambdaoc_l with l != j.
467
 
391
 
468
     Vect_DP dlambdaoc (0.0, N);
392
     Vect_DP dlambdaoc (0.0, N);
469
 
393
 
475
       S[j] *= 2.0/cxL;
399
       S[j] *= 2.0/cxL;
476
 
400
 
477
       dSdlambdaoc[j] = 0.0;
401
       dSdlambdaoc[j] = 0.0;
478
-      for (int k = 0; k < N; ++k) dSdlambdaoc[j] += 1.0/((lambdaoc[j] - lambdaoc[k]) * (lambdaoc[j] - lambdaoc[k]) + 1.0);
402
+      for (int k = 0; k < N; ++k)
403
+	dSdlambdaoc[j] += 1.0/((lambdaoc[j] - lambdaoc[k]) * (lambdaoc[j] - lambdaoc[k]) + 1.0);
479
       dSdlambdaoc[j] *= 2.0/(PI * cxL);
404
       dSdlambdaoc[j] *= 2.0/(PI * cxL);
480
 
405
 
481
       dlambdaoc[j] = (PI*Ix2[j]/cxL - S[j] + lambdaoc[j] * dSdlambdaoc[j])/(1.0 + dSdlambdaoc[j]) - lambdaoc[j];
406
       dlambdaoc[j] = (PI*Ix2[j]/cxL - S[j] + lambdaoc[j] * dSdlambdaoc[j])/(1.0 + dSdlambdaoc[j]) - lambdaoc[j];
526
 	}
451
 	}
527
       sumtheta *= 2.0;
452
       sumtheta *= 2.0;
528
 
453
 
529
-      //cout << j << "\t" << Ix2[j] << "\t" << atanintshift << endl;
530
-
531
       RHSBAE[j] = cxL * lambdaoc[j] + sumtheta - PI*(Ix2[j] - atanintshift);
454
       RHSBAE[j] = cxL * lambdaoc[j] + sumtheta - PI*(Ix2[j] - atanintshift);
532
     }
455
     }
533
 
456
 
535
 
458
 
536
     for (int j = 0; j < N; ++j) dlambdaoc[j] = - RHSBAE[j];
459
     for (int j = 0; j < N; ++j) dlambdaoc[j] = - RHSBAE[j];
537
 
460
 
538
-    //cout << "dlambdaoc pre lubksb = " << dlambdaoc << endl;
539
-
540
     DP d;
461
     DP d;
541
     ludcmp (Gaudin, indx, d);
462
     ludcmp (Gaudin, indx, d);
542
     lubksb (Gaudin, indx, dlambdaoc);
463
     lubksb (Gaudin, indx, dlambdaoc);
543
 
464
 
544
-    //cout << "dlambdaoc post lubksb = " << dlambdaoc << endl;
545
-
546
     bool ordering_changed = false;
465
     bool ordering_changed = false;
547
     for (int j = 0; j < N-1; ++j) if (lambdaoc[j] + dlambdaoc[j] > lambdaoc[j+1] + dlambdaoc[j+1]) ordering_changed = true;
466
     for (int j = 0; j < N-1; ++j) if (lambdaoc[j] + dlambdaoc[j] > lambdaoc[j+1] + dlambdaoc[j+1]) ordering_changed = true;
548
 
467
 
553
       DP maxdlambdaoc = 0.0;
472
       DP maxdlambdaoc = 0.0;
554
       do {
473
       do {
555
 	ordering_still_changed = false;
474
 	ordering_still_changed = false;
556
-	if (dlambdaoc[0] < 0.0 && fabs(dlambdaoc[0]) > (maxdlambdaoc = 10.0*ABACUS::max(fabs(lambdaoc[0]), fabs(lambdaoc[N-1]))))
475
+	if (dlambdaoc[0] < 0.0 && fabs(dlambdaoc[0])
476
+	    > (maxdlambdaoc = 10.0*ABACUS::max(fabs(lambdaoc[0]), fabs(lambdaoc[N-1]))))
557
 	  dlambdaoc[0] = -maxdlambdaoc;
477
 	  dlambdaoc[0] = -maxdlambdaoc;
558
 	if (lambdaoc[0] + dlambdaoc[0] > lambdaoc[1] + dlambdaoc[1]) {
478
 	if (lambdaoc[0] + dlambdaoc[0] > lambdaoc[1] + dlambdaoc[1]) {
559
 	  dlambdaoc[0] = 0.25 * (lambdaoc[1] + dlambdaoc[1] - lambdaoc[0] ); // max quarter distance
479
 	  dlambdaoc[0] = 0.25 * (lambdaoc[1] + dlambdaoc[1] - lambdaoc[0] ); // max quarter distance
560
 	  ordering_still_changed = true;
480
 	  ordering_still_changed = true;
561
-	  //cout << "reason 1" << endl;
562
 	}
481
 	}
563
-	if (dlambdaoc[N-1] > 0.0 && fabs(dlambdaoc[N-1]) > (maxdlambdaoc = 10.0*ABACUS::max(fabs(lambdaoc[0]), fabs(lambdaoc[N-1]))))
482
+	if (dlambdaoc[N-1] > 0.0 && fabs(dlambdaoc[N-1])
483
+	    > (maxdlambdaoc = 10.0*ABACUS::max(fabs(lambdaoc[0]), fabs(lambdaoc[N-1]))))
564
 	  dlambdaoc[N-1] = maxdlambdaoc;
484
 	  dlambdaoc[N-1] = maxdlambdaoc;
565
 	if (lambdaoc[N-1] + dlambdaoc[N-1] < lambdaoc[N-2] + dlambdaoc[N-2]) {
485
 	if (lambdaoc[N-1] + dlambdaoc[N-1] < lambdaoc[N-2] + dlambdaoc[N-2]) {
566
 	  dlambdaoc[N-1] = 0.25 * (lambdaoc[N-2] + dlambdaoc[N-2] - lambdaoc[N-1]);
486
 	  dlambdaoc[N-1] = 0.25 * (lambdaoc[N-2] + dlambdaoc[N-2] - lambdaoc[N-1]);
567
 	  ordering_still_changed = true;
487
 	  ordering_still_changed = true;
568
-	  //cout << "reason 2" << endl;
569
 	}
488
 	}
570
 	for (int j = 1; j < N-1; ++j) {
489
 	for (int j = 1; j < N-1; ++j) {
571
 	  if (lambdaoc[j] + dlambdaoc[j] > lambdaoc[j+1] + dlambdaoc[j+1]) {
490
 	  if (lambdaoc[j] + dlambdaoc[j] > lambdaoc[j+1] + dlambdaoc[j+1]) {
572
 	    dlambdaoc[j] = 0.25 * (lambdaoc[j+1] + dlambdaoc[j+1] - lambdaoc[j]);
491
 	    dlambdaoc[j] = 0.25 * (lambdaoc[j+1] + dlambdaoc[j+1] - lambdaoc[j]);
573
 	    ordering_still_changed = true;
492
 	    ordering_still_changed = true;
574
-	    //cout << "reason 3" << endl;
575
 	  }
493
 	  }
576
 	  if (lambdaoc[j] + dlambdaoc[j] < lambdaoc[j-1] + dlambdaoc[j-1]) {
494
 	  if (lambdaoc[j] + dlambdaoc[j] < lambdaoc[j-1] + dlambdaoc[j-1]) {
577
 	    dlambdaoc[j] = 0.25 * (lambdaoc[j-1] + dlambdaoc[j-1] - lambdaoc[j]);
495
 	    dlambdaoc[j] = 0.25 * (lambdaoc[j-1] + dlambdaoc[j-1] - lambdaoc[j]);
578
 	    ordering_still_changed = true;
496
 	    ordering_still_changed = true;
579
-	    //cout << "reason 4" << endl;
580
 	  }
497
 	  }
581
 	}
498
 	}
582
       } while (ordering_still_changed);
499
       } while (ordering_still_changed);
583
     }
500
     }
584
 
501
 
585
-    //if (ordering_changed) cout << "dlambdaoc post checking = " << dlambdaoc << endl;
586
-
587
-    /*
588
-    bool orderingchanged = false;
589
-    //bool dlambdaexceedsmaxrapdiff = false;
590
-    DP damping_to_use = damping;
591
-    for (int j = 0; j < N-1; ++j) {
592
-      if (lambdaoc[j] + dlambdaoc[j] > lambdaoc[j+1] + dlambdaoc[j+1]) // unacceptable, order changed!
593
-	orderingchanged = true;
594
-      // We must damp the dlambda such that the ordering is unchanged:
595
-      // the condition is lambdaoc[j] + damping*dlambdaoc[j] < lambdaoc[j+1] + damping*dlambdaoc[j+1]
596
-      damping_to_use = ABACUS::min(damping_to_use, 0.5 * (lambdaoc[j+1] - lambdaoc[j])/(dlambdaoc[j] - dlambdaoc[j+1]));
597
-    }
598
-    */
599
-    //for (int j = 0; j < N; ++j)
600
-    //if (fabs(dlambdaoc[j]) > maxrapdiff) dlambdaexceedsmaxrapdiff = true;
601
-    /*
602
-    // The dlambdaoc must be smaller than the distance to neighbouring rapidities:
603
-    // If any dlambdaoc is greater than half the distance, set all to half the previous distance:
604
-    if (orderingchanged || dlambdaexceedsmaxrapdiff) {
605
-      if (dlambdaoc[0] > 0.0) dlambdaoc[0] = 0.25 * (lambdaoc[1] - lambdaoc[0]);
606
-      //else dlambdaoc[0] = 0.25 * (lambdaoc[0] - lambdaoc[1]);
607
-      else dlambdaoc[0] = -fabs(lambdaoc[0]);  // strictly limit the growth of lambdaoc[0]
608
-      //if (dlambdaoc[N-1] > 0.0) dlambdaoc[N-1] = 0.25 * (lambdaoc[N-1] - lambdaoc[N-2]);
609
-      if (dlambdaoc[N-1] > 0.0) dlambdaoc[N-1] = fabs(lambdaoc[N-1]); // strictly limit the growth of lambdaoc[N-1]
610
-      else dlambdaoc[N-1] = 0.25 * (lambdaoc[N-2] - lambdaoc[N-1]);
611
-      for (int j = 1; j < N-1; ++j) {
612
-	if (dlambdaoc[j] > 0.0) dlambdaoc[j] = 0.25 * (lambdaoc[j+1] - lambdaoc[j]);
613
-	if (dlambdaoc[j] < 0.0) dlambdaoc[j] = 0.25 * (lambdaoc[j-1] - lambdaoc[j]);
614
-      }
615
-      //cout << "Corrected dlambdaoc = " << dlambdaoc << endl;
616
-    }
617
-    */
618
     diffsq = 0.0;
502
     diffsq = 0.0;
619
     for (int i = 0; i < N; ++i) {
503
     for (int i = 0; i < N; ++i) {
620
-      //diffsq += dlambdaoc[i] * dlambdaoc[i];
621
       // Normalize the diffsq by the typical value of the rapidities:
504
       // Normalize the diffsq by the typical value of the rapidities:
622
       if (cxL > 1.0) diffsq += dlambdaoc[i] * dlambdaoc[i]/(lambdaoc[i] * lambdaoc[i] + 1.0e-6);
505
       if (cxL > 1.0) diffsq += dlambdaoc[i] * dlambdaoc[i]/(lambdaoc[i] * lambdaoc[i] + 1.0e-6);
623
       else diffsq += cxL * cxL * dlambdaoc[i] * dlambdaoc[i]/(lambdaoc[i] * lambdaoc[i] + 1.0e-6);
506
       else diffsq += cxL * cxL * dlambdaoc[i] * dlambdaoc[i]/(lambdaoc[i] * lambdaoc[i] + 1.0e-6);
627
     if (ordering_changed) diffsq = 1.0; // reset if Newton wanted to change ordering
510
     if (ordering_changed) diffsq = 1.0; // reset if Newton wanted to change ordering
628
 
511
 
629
     for (int j = 0; j < N; ++j) lambdaoc[j] += damping * dlambdaoc[j];
512
     for (int j = 0; j < N; ++j) lambdaoc[j] += damping * dlambdaoc[j];
630
-    //for (int j = 0; j < N; ++j) lambdaoc[j] += damping_to_use * dlambdaoc[j];
631
 
513
 
632
     iter_Newton++;
514
     iter_Newton++;
633
 
515
 
634
     // if we've converged, calculate the norm here, since the work has been done...
516
     // if we've converged, calculate the norm here, since the work has been done...
635
 
517
 
636
-    //if (diffsq < prec && !orderingchanged && !dlambdaexceedsmaxrapdiff) {
637
     if (diffsq < prec && !ordering_changed) {
518
     if (diffsq < prec && !ordering_changed) {
638
 
519
 
639
       lnnorm = 0.0;
520
       lnnorm = 0.0;
640
       for (int j = 0; j < N; j++) lnnorm += log(fabs(Gaudin[j][j]));
521
       for (int j = 0; j < N; j++) lnnorm += log(fabs(Gaudin[j][j]));
641
 
522
 
642
       // Add the pieces outside of Gaudin determinant
523
       // Add the pieces outside of Gaudin determinant
643
-      for (int j = 0; j < N - 1; ++j) for (int k = j+1; k < N; ++k) lnnorm += log(1.0 + 1.0/pow(lambdaoc[j] - lambdaoc[k], 2.0));
524
+      for (int j = 0; j < N - 1; ++j)
525
+	for (int k = j+1; k < N; ++k)
526
+	  lnnorm += log(1.0 + 1.0/pow(lambdaoc[j] - lambdaoc[k], 2.0));
644
     }
527
     }
645
 
528
 
646
     return;
529
     return;
657
   {
540
   {
658
     iK = 0;
541
     iK = 0;
659
     for (int j = 0; j < N; ++j) {
542
     for (int j = 0; j < N; ++j) {
660
-      //cout << j << "\t" << iK << "\t" << Ix2[j] << endl;
661
       iK += Ix2[j];
543
       iK += Ix2[j];
662
     }
544
     }
663
     if (iK % 2) {
545
     if (iK % 2) {
683
   void LiebLin_Bethe_State::Build_Reduced_Gaudin_Matrix (SQMat<DP>& Gaudin_Red)
565
   void LiebLin_Bethe_State::Build_Reduced_Gaudin_Matrix (SQMat<DP>& Gaudin_Red)
684
   {
566
   {
685
 
567
 
686
-    if (Gaudin_Red.size() != N) ABACUSerror("Passing matrix of wrong size in Build_Reduced_Gaudin_Matrix.");
568
+    if (Gaudin_Red.size() != N)
569
+      ABACUSerror("Passing matrix of wrong size in Build_Reduced_Gaudin_Matrix.");
687
 
570
 
688
     DP sum_Kernel = 0.0;
571
     DP sum_Kernel = 0.0;
689
 
572
 
717
 
600
 
718
     if (!ck) ABACUSerror("Choose a parity invariant state please");
601
     if (!ck) ABACUSerror("Choose a parity invariant state please");
719
 
602
 
720
-    if (Gaudin_Red.size() != N/2) ABACUSerror("Passing matrix of wrong size in Build_Reduced_Gaudin_Matrix.");
603
+    if (Gaudin_Red.size() != N/2)
604
+      ABACUSerror("Passing matrix of wrong size in Build_Reduced_Gaudin_Matrix.");
721
 
605
 
722
     DP sum_Kernel = 0.0;
606
     DP sum_Kernel = 0.0;
723
 
607
 
726
 
610
 
727
 	if (j == k) {
611
 	if (j == k) {
728
 	  sum_Kernel = 0.0;
612
 	  sum_Kernel = 0.0;
729
-	  for (int kp = N/2; kp < N; ++kp) if (j + N/2 != kp) sum_Kernel += Kernel (lambdaoc[j+N/2] - lambdaoc[kp]) + Kernel (lambdaoc[j+N/2] + lambdaoc[kp]);
613
+	  for (int kp = N/2; kp < N; ++kp)
614
+	    if (j + N/2 != kp)
615
+	      sum_Kernel += Kernel (lambdaoc[j+N/2] - lambdaoc[kp]) + Kernel (lambdaoc[j+N/2] + lambdaoc[kp]);
730
 	  Gaudin_Red[j][k] = cxL + sum_Kernel;
616
 	  Gaudin_Red[j][k] = cxL + sum_Kernel;
731
 	}
617
 	}
732
 
618
 
733
-	else Gaudin_Red[j][k] = - (Kernel (lambdaoc[j+ N/2] - lambdaoc[k+ N/2]) + Kernel (lambdaoc[j+ N/2] + lambdaoc[k+ N/2])   );
619
+	else Gaudin_Red[j][k] = - (Kernel (lambdaoc[j+ N/2] - lambdaoc[k+ N/2])
620
+				   + Kernel (lambdaoc[j+ N/2] + lambdaoc[k+ N/2]) );
734
 
621
 
735
       }
622
       }
736
 
623
 
743
     // This function changes the Ix2 of a given state by annihilating a particle and hole
630
     // This function changes the Ix2 of a given state by annihilating a particle and hole
744
     // pair specified by ipart and ihole (counting from the left, starting with index 0).
631
     // pair specified by ipart and ihole (counting from the left, starting with index 0).
745
 
632
 
746
-    //cout << "Annihilating ipart " << ipart << " and ihole " << ihole << " of state with label " << (*this).label << endl;
747
-
748
     State_Label_Data currentdata = Read_State_Label ((*this).label, OriginStateIx2);
633
     State_Label_Data currentdata = Read_State_Label ((*this).label, OriginStateIx2);
749
-    //cout << "current Ix2old " << currentdata.Ix2old[0] << endl;
750
-    //cout << "current Ix2exc " << currentdata.Ix2exc[0] << endl;
751
 
634
 
752
-    if (ipart >= currentdata.nexc[0]) ABACUSerror("Particle label too large in LiebLin_Bethe_State::Annihilate_ph_pair.");
753
-    if (ihole >= currentdata.nexc[0]) ABACUSerror("Hole label too large in LiebLin_Bethe_State::Annihilate_ph_pair.");
635
+    if (ipart >= currentdata.nexc[0])
636
+      ABACUSerror("Particle label too large in LiebLin_Bethe_State::Annihilate_ph_pair.");
637
+    if (ihole >= currentdata.nexc[0])
638
+      ABACUSerror("Hole label too large in LiebLin_Bethe_State::Annihilate_ph_pair.");
754
 
639
 
755
     // Simply remove the given pair:
640
     // Simply remove the given pair:
756
     Vect<int> type_new = currentdata.type;
641
     Vect<int> type_new = currentdata.type;
768
       for (int i = 0; i < nexc_new[it]; ++i) {
653
       for (int i = 0; i < nexc_new[it]; ++i) {
769
 	Ix2old_new[it][i] = currentdata.Ix2old[it][i + (i >= ihole)];
654
 	Ix2old_new[it][i] = currentdata.Ix2old[it][i + (i >= ihole)];
770
 	Ix2exc_new[it][i] = currentdata.Ix2exc[it][i + (i >= ipart)];
655
 	Ix2exc_new[it][i] = currentdata.Ix2exc[it][i + (i >= ipart)];
771
-	}
772
       }
656
       }
773
-    //cout << "Ix2old_new " << Ix2old_new[0] << endl;
774
-    //cout << "Ix2exc_new " << Ix2exc_new[0] << endl;
657
+    }
775
 
658
 
776
     State_Label_Data newdata (type_new, M_new, nexc_new, Ix2old_new, Ix2exc_new);
659
     State_Label_Data newdata (type_new, M_new, nexc_new, Ix2old_new, Ix2exc_new);
777
 
660
 
778
     (*this).Set_to_Label (Return_State_Label(newdata, OriginStateIx2));
661
     (*this).Set_to_Label (Return_State_Label(newdata, OriginStateIx2));
779
-
780
-    //cout << "Obtained label " << (*this).label << endl;
781
   }
662
   }
782
 
663
 
783
   void LiebLin_Bethe_State::Parity_Flip ()
664
   void LiebLin_Bethe_State::Parity_Flip ()

+ 0
- 3
src/LIEBLIN/LiebLin_Chem_Pot.cc View File

24
     // RefState is used here to provide the c_int, L and N parameters.
24
     // RefState is used here to provide the c_int, L and N parameters.
25
 
25
 
26
     LiebLin_Bethe_State Nplus1State(RefState.c_int, RefState.L, RefState.N + 1);
26
     LiebLin_Bethe_State Nplus1State(RefState.c_int, RefState.L, RefState.N + 1);
27
-    //LiebLin_Bethe_State NState(RefState.c_int, RefState.L, RefState.N);
28
     LiebLin_Bethe_State Nmin1State(RefState.c_int, RefState.L, RefState.N - 1);
27
     LiebLin_Bethe_State Nmin1State(RefState.c_int, RefState.L, RefState.N - 1);
29
 
28
 
30
     Nplus1State.Compute_All(true);
29
     Nplus1State.Compute_All(true);
31
-    //NState.Compute_All(true);
32
     Nmin1State.Compute_All(true);
30
     Nmin1State.Compute_All(true);
33
 
31
 
34
-    //return(NState.E - Nmin1State.E);
35
     return(0.5 * (Nplus1State.E - Nmin1State.E));
32
     return(0.5 * (Nplus1State.E - Nmin1State.E));
36
   }
33
   }
37
 
34
 

+ 8
- 48
src/LIEBLIN/LiebLin_Matrix_Element_Contrib.cc View File

19
 
19
 
20
 namespace ABACUS {
20
 namespace ABACUS {
21
 
21
 
22
-  //DP Compute_Matrix_Element_Contrib (char whichDSF, bool fixed_iK, LiebLin_Bethe_State& LeftState,
23
-  //				     LiebLin_Bethe_State& RefState, DP Chem_Pot, fstream& DAT_outfile)
24
-  //DP Compute_Matrix_Element_Contrib (char whichDSF, int iKmin, int iKmax, LiebLin_Bethe_State& LeftState,
25
-  //				     LiebLin_Bethe_State& RefState, DP Chem_Pot, fstream& DAT_outfile)
26
   DP Compute_Matrix_Element_Contrib (char whichDSF, int iKmin, int iKmax, LiebLin_Bethe_State& LeftState,
22
   DP Compute_Matrix_Element_Contrib (char whichDSF, int iKmin, int iKmax, LiebLin_Bethe_State& LeftState,
27
 				     LiebLin_Bethe_State& RefState, DP Chem_Pot, stringstream& DAT_outfile)
23
 				     LiebLin_Bethe_State& RefState, DP Chem_Pot, stringstream& DAT_outfile)
28
   {
24
   {
45
     else if (whichDSF == 'g')
41
     else if (whichDSF == 'g')
46
       ME = real(exp(ln_Psi_ME (RefState, LeftState)));
42
       ME = real(exp(ln_Psi_ME (RefState, LeftState)));
47
     else if (whichDSF == 'q') // geometrical quench
43
     else if (whichDSF == 'q') // geometrical quench
48
-      //ME_CX = (LiebLin_Twisted_ln_Overlap(1.0, RefState.lambdaoc, RefState.lnnorm, LeftState));
49
-      //ME_CX = (LiebLin_ln_Overlap(RefState.lambdaoc, RefState.lnnorm, LeftState));
50
       ME_CX = LiebLin_ln_Overlap(LeftState.lambdaoc, LeftState.lnnorm, RefState);
44
       ME_CX = LiebLin_ln_Overlap(LeftState.lambdaoc, LeftState.lnnorm, RefState);
51
     else if (whichDSF == 'B') { // BEC to finite c quench: g2(x=0)
45
     else if (whichDSF == 'B') { // BEC to finite c quench: g2(x=0)
52
-      //ME_CX = exp(ln_Overlap_with_BEC (LeftState)); // overlap part
53
-      ME_CX = exp(ln_Overlap_with_BEC (LeftState) - ln_Overlap_with_BEC (RefState)); // overlap part, relative to saddle-point state
54
-      ME = real(exp(ln_g2_ME (RefState, LeftState))); // matrix element part
46
+      // overlap part, relative to saddle-point state
47
+      ME_CX = exp(ln_Overlap_with_BEC (LeftState) - ln_Overlap_with_BEC (RefState));
48
+      // matrix element part
49
+      ME = real(exp(ln_g2_ME (RefState, LeftState)));
55
       // The product is ME_CX * ME = e^{-\delta S_e} \langle \rho_{sp} | g2 (x=0) | \rho_{sp} + e \rangle
50
       // The product is ME_CX * ME = e^{-\delta S_e} \langle \rho_{sp} | g2 (x=0) | \rho_{sp} + e \rangle
56
       // and is the first half of the t-dep expectation value formula coming from the Quench Action formalism
51
       // and is the first half of the t-dep expectation value formula coming from the Quench Action formalism
57
     }
52
     }
71
       if (whichDSF == 'Z') {
66
       if (whichDSF == 'Z') {
72
 	DAT_outfile << endl << LeftState.E - RefState.E - (LeftState.N - RefState.N) * Chem_Pot << "\t"
67
 	DAT_outfile << endl << LeftState.E - RefState.E - (LeftState.N - RefState.N) * Chem_Pot << "\t"
73
 		    << LeftState.iK - RefState.iK
68
 		    << LeftState.iK - RefState.iK
74
-	  //<< "\t" << LeftState.conv
75
 		    << 0 << "\t" // This is the deviation, here always 0
69
 		    << 0 << "\t" // This is the deviation, here always 0
76
 		    << "\t" << LeftState.label;
70
 		    << "\t" << LeftState.label;
77
       }
71
       }
79
 	DAT_outfile << endl << LeftState.E - RefState.E - (LeftState.N - RefState.N) * Chem_Pot << "\t"
73
 	DAT_outfile << endl << LeftState.E - RefState.E - (LeftState.N - RefState.N) * Chem_Pot << "\t"
80
 		    << LeftState.iK - RefState.iK << "\t"
74
 		    << LeftState.iK - RefState.iK << "\t"
81
 		    << real(ME_CX) << "\t" << imag(ME_CX) - twoPI * int(imag(ME_CX)/twoPI + 1.0e-10) << "\t"
75
 		    << real(ME_CX) << "\t" << imag(ME_CX) - twoPI * int(imag(ME_CX)/twoPI + 1.0e-10) << "\t"
82
-	  //<< LeftState.conv << "\t"
83
 		    << 0 << "\t" // This is the deviation, here always 0
76
 		    << 0 << "\t" // This is the deviation, here always 0
84
 		    << LeftState.label;
77
 		    << LeftState.label;
85
       }
78
       }
87
 	DAT_outfile << endl << LeftState.E - RefState.E - (LeftState.N - RefState.N) * Chem_Pot << "\t"
80
 	DAT_outfile << endl << LeftState.E - RefState.E - (LeftState.N - RefState.N) * Chem_Pot << "\t"
88
 		    << LeftState.iK - RefState.iK << "\t"
81
 		    << LeftState.iK - RefState.iK << "\t"
89
 		    << ME << "\t"
82
 		    << ME << "\t"
90
-	  //<< LeftState.conv << "\t"
91
 		    << 0 << "\t" // This is the deviation, here always 0
83
 		    << 0 << "\t" // This is the deviation, here always 0
92
 		    << LeftState.label;
84
 		    << LeftState.label;
93
 	DAT_outfile << "\t" << Momentum_Right_Excitations(LeftState) << "\t" << Momentum_Left_Excitations(LeftState);
85
 	DAT_outfile << "\t" << Momentum_Right_Excitations(LeftState) << "\t" << Momentum_Left_Excitations(LeftState);
94
-	//cout << Momentum_Right_Excitations(LeftState) << "\t" << Momentum_Left_Excitations(LeftState);
95
       }
86
       }
96
       else if (whichDSF == 'B') { // BEC to finite c > 0 quench; g2 (x=0)
87
       else if (whichDSF == 'B') { // BEC to finite c > 0 quench; g2 (x=0)
97
 	if (fabs(real(ME_CX) * ME) > 1.0e-100)
88
 	if (fabs(real(ME_CX) * ME) > 1.0e-100)
99
 		      << LeftState.iK - RefState.iK << "\t"
90
 		      << LeftState.iK - RefState.iK << "\t"
100
 		      << real(ME_CX) << "\t" // the overlap is always real
91
 		      << real(ME_CX) << "\t" // the overlap is always real
101
 		      << ME << "\t"
92
 		      << ME << "\t"
102
-	    //<< 0 << "\t" // This is the deviation, here always 0 // omit this here
103
 		      << LeftState.label;
93
 		      << LeftState.label;
104
       }
94
       }
105
       else if (whichDSF == 'C') { // BEC to finite c, overlap sq
95
       else if (whichDSF == 'C') { // BEC to finite c, overlap sq
108
 		      << LeftState.iK - RefState.iK << "\t"
98
 		      << LeftState.iK - RefState.iK << "\t"
109
 		      << real(ME_CX) << "\t" // the overlap is always real
99
 		      << real(ME_CX) << "\t" // the overlap is always real
110
 		      << ME << "\t"
100
 		      << ME << "\t"
111
-	    //<< 0 << "\t" // This is the deviation, here always 0 // omit this here
112
 		      << LeftState.label;
101
 		      << LeftState.label;
113
       }
102
       }
114
       else {
103
       else {
115
 	DAT_outfile << endl << LeftState.E - RefState.E - (LeftState.N - RefState.N) * Chem_Pot << "\t"
104
 	DAT_outfile << endl << LeftState.E - RefState.E - (LeftState.N - RefState.N) * Chem_Pot << "\t"
116
 		    << LeftState.iK - RefState.iK << "\t"
105
 		    << LeftState.iK - RefState.iK << "\t"
117
 		    << ME << "\t"
106
 		    << ME << "\t"
118
-	  //<< LeftState.conv << "\t"
119
 		    << 0 << "\t" // This is the deviation, here always 0
107
 		    << 0 << "\t" // This is the deviation, here always 0
120
 		    << LeftState.label;
108
 		    << LeftState.label;
121
       }
109
       }
127
       data_value = 1.0/(1.0 + LeftState.E - RefState.E - (LeftState.N - RefState.N) * Chem_Pot);
115
       data_value = 1.0/(1.0 + LeftState.E - RefState.E - (LeftState.N - RefState.N) * Chem_Pot);
128
     else if (whichDSF == 'd' || whichDSF == '1') {
116
     else if (whichDSF == 'd' || whichDSF == '1') {
129
       if (fixed_iK)
117
       if (fixed_iK)
130
-	/*
131
-	// use omega * MEsq/iK^2
132
-	//data_value = (LeftState.E - RefState.E - (LeftState.N - RefState.N) * Chem_Pot)
133
-      // MEsq/ABACUS::max(1, (LeftState.iK - RefState.iK) * (LeftState.iK - RefState.iK))
134
-	//: 0.0;
135
-	*/
136
-	// Careful: use fabs(E) since this must also work with Tgt0 or arbitrary RefState DEPRECATED ++G_1, USE abs_data_value
137
 	data_value = (LeftState.E - RefState.E - (LeftState.N - RefState.N) * Chem_Pot) * ME * ME;
118
 	data_value = (LeftState.E - RefState.E - (LeftState.N - RefState.N) * Chem_Pot) * ME * ME;
138
-      else if (!fixed_iK) // use ME if momentum in fundamental window -iK_UL <= iK <= iK_UL
139
-	//data_value = abs(LeftState.iK - RefState.iK) <= RefState.Tableau[0].Ncols ?  // this last nr is iK_UL
140
-	    //MEsq : 0.0;
141
-	//data_value = (LeftState.iK - RefState.iK == 0 ? 1.0 : 2.0) * MEsq;
142
-	//data_value = ME * ME;
143
-	// use omega * MEsq/iK^2
144
-	// Careful: use fabs(E) since this must also work with Tgt0 or arbitrary RefState DEPRECATED ++G_1, USE abs_data_value
145
-	data_value = (LeftState.E - RefState.E - (LeftState.N - RefState.N) * Chem_Pot) * ME * ME/ABACUS::max(1, (LeftState.iK - RefState.iK) * (LeftState.iK - RefState.iK));
119
+      else if (!fixed_iK)
120
+	data_value = (LeftState.E - RefState.E - (LeftState.N - RefState.N) * Chem_Pot) * ME * ME
121
+	  /ABACUS::max(1, (LeftState.iK - RefState.iK) * (LeftState.iK - RefState.iK));
146
     }
122
     }
147
     else if (whichDSF == 'g' || whichDSF == 'o') {
123
     else if (whichDSF == 'g' || whichDSF == 'o') {
148
       if (fixed_iK)
124
       if (fixed_iK)
149
-	/*
150
-	// use omega * MEsq/((k^2 - mu + 4 c N/L)/L)
151
-	data_value = (LeftState.E - RefState.E - (LeftState.N - RefState.N) * Chem_Pot)
152
-	* MEsq/((((LeftState.K - RefState.K) * (LeftState.K - RefState.K) - Chem_Pot) + 4.0 * RefState.c_int * RefState.N/RefState.L)/RefState.L)
153
-	: 0.0;
154
-	*/
155
-	// Careful: use fabs(E) since this must also work with Tgt0 or arbitrary RefState
156
 	data_value = (LeftState.E - RefState.E - (LeftState.N - RefState.N) * Chem_Pot) * ME * ME;
125
 	data_value = (LeftState.E - RefState.E - (LeftState.N - RefState.N) * Chem_Pot) * ME * ME;
157
-      else if (!fixed_iK) { // simply use MEsq if momentum in fundamental window -iK_UL <= iK <= iK_UL
158
-	//data_value = abs(LeftState.iK - RefState.iK) <= RefState.Tableau[0].Ncols ?  // this last nr is iK_UL
159
-	//MEsq : 0.0;
160
-	//data_value = (LeftState.iK - RefState.iK == 0 ? 1.0 : 2.0) * MEsq;
126
+      else if (!fixed_iK) {
161
 	data_value = ME * ME;
127
 	data_value = ME * ME;
162
-	//data_value = fabs(LeftState.E - RefState.E - (LeftState.N - RefState.N) * Chem_Pot) * ME * ME;
163
-	// In the case of whichDSF == 'o', the state with label (N-1)_0_ gives zero data_value. Force to 1.
164
-	//if (whichDSF == 'o' && fabs(LeftState.E - RefState.E - (LeftState.N - RefState.N) * Chem_Pot) < 1.0e-10) data_value = 1.0;
165
       }
128
       }
166
     }
129
     }
167
-    //else if (whichDSF == 'o')
168
-    //data_value = abs(LeftState.iK - RefState.iK) <= RefState.Tableau[0].Ncols ?  // this last nr is iK_UL
169
-    //MEsq : 0.0;
170
     else if (whichDSF == 'q')
130
     else if (whichDSF == 'q')
171
       data_value = exp(2.0 * real(ME_CX));
131
       data_value = exp(2.0 * real(ME_CX));
172
     else if (whichDSF == 'B')
132
     else if (whichDSF == 'B')

+ 49
- 697
src/LIEBLIN/LiebLin_State_Ensemble.cc View File

30
     : nstates(nstates_req), state(Vect<LiebLin_Bethe_State>(RefState, nstates_req)), weight(1.0/nstates_req, nstates_req)
30
     : nstates(nstates_req), state(Vect<LiebLin_Bethe_State>(RefState, nstates_req)), weight(1.0/nstates_req, nstates_req)
31
   {
31
   {
32
   }
32
   }
33
-  /*
34
-  LiebLin_Diagonal_State_Ensemble::LiebLin_Diagonal_State_Ensemble (const LiebLin_Bethe_State& RefState, int nstates_req, const Vect<DP>& weight_ref)
35
-    : nstates(nstates_req), state(Vect<LiebLin_Bethe_State>(RefState, nstates_req)), weight(weight_ref)
36
-  {
37
-    if (weight_ref.size() != nstates_req) ABACUSerror("Incompatible vector size in LiebLin_Diagonal_State_Ensemble constructor.");
38
-  }
39
-  */
40
 
33
 
41
   // Recursively go through all arbitrary-order type 2 descendents
34
   // Recursively go through all arbitrary-order type 2 descendents
42
   void Generate_type_2_descendents (LiebLin_Bethe_State& ActualState, int* ndesc_ptr, const LiebLin_Bethe_State& OriginState)
35
   void Generate_type_2_descendents (LiebLin_Bethe_State& ActualState, int* ndesc_ptr, const LiebLin_Bethe_State& OriginState)
65
   }
58
   }
66
 
59
 
67
 
60
 
68
-
69
-
70
-  //LiebLin_Diagonal_State_Ensemble::LiebLin_Diagonal_State_Ensemble (DP c_int, DP L, int N, const Root_Density& rho, int nstates_req)
71
-  //: nstates(nstates_req)
72
   LiebLin_Diagonal_State_Ensemble::LiebLin_Diagonal_State_Ensemble (DP c_int, DP L, int N, const Root_Density& rho)
61
   LiebLin_Diagonal_State_Ensemble::LiebLin_Diagonal_State_Ensemble (DP c_int, DP L, int N, const Root_Density& rho)
73
   {
62
   {
63
+    // This function returns a state ensemble matching the continuous density rho.
64
+    // The logic closely resembles the one used in Discretized_LiebLin_Bethe_State.
65
+
74
     //version with 4 states in ensemble
66
     //version with 4 states in ensemble
75
 
67
 
76
     Root_Density x(rho.Npts, rho.lambdamax);
68
     Root_Density x(rho.Npts, rho.lambdamax);
81
 	x.value[ix] += 2.0 * rho.value[ip] * rho.dlambda[ip] * atan ((x.lambda[ix] - rho.lambda[ip])/c_int);
73
 	x.value[ix] += 2.0 * rho.value[ip] * rho.dlambda[ip] * atan ((x.lambda[ix] - rho.lambda[ip])/c_int);
82
       }
74
       }
83
       x.value[ix] /= 2.0*PI; //normalization
75
       x.value[ix] /= 2.0*PI; //normalization
84
-
85
-      //cout << x.lambda[ix] << "\t" << x.value[ix] << "\t" << rho.lambda[ix] "\t" << rho.value[ix] <<endl;
86
     }
76
     }
87
 
77
 
88
     // Now carry on as per Discretized_LiebLin_Bethe_State:
78
     // Now carry on as per Discretized_LiebLin_Bethe_State:
111
     for (int i = 0; i < rho.Npts; ++i) {
101
     for (int i = 0; i < rho.Npts; ++i) {
112
       integral_prev = integral;
102
       integral_prev = integral;
113
       integral += L * rho.value[i] * rho.dlambda[i];
103
       integral += L * rho.value[i] * rho.dlambda[i];
114
-      //cout << x.value[i] << "\t" << integral << endl;
115
       if (integral > Nfound + 0.5) {
104
       if (integral > Nfound + 0.5) {
116
 	// Subtle error: if the rho is too discontinuous, i.e. if more than one rapidity is found, must correct for this.
105
 	// Subtle error: if the rho is too discontinuous, i.e. if more than one rapidity is found, must correct for this.
117
-		if (integral > Nfound + 1.5 && integral < Nfound + 2.5) { // found two rapidities
118
-		  ABACUSerror("The distribution of particles is too discontinous for discretisation");
119
-		}
120
-
121
-		else {
122
-		  // few variables to clarify the computations, they do not need to be vectors, not used outside this loop
123
-		  //Ix2_found[Nfound] = 2.0 * L *  (x.value[i] * (integral - Nfound - 0.5) + x.value[i-1] * (Nfound + 0.5 - integral_prev))/(integral - integral_prev);
124
-		  Ix2_found[Nfound] = 2.0 * L * x.Return_Value(rho.lambda[i]);
125
-
126
-		  Ix2_left = floor(Ix2_found[Nfound]);
127
-		  Ix2_left -= (Ix2_left + N + 1)%2 ? 1 : 0;	//adjust parity
128
-
129
-		  Ix2_right = ceil(Ix2_found[Nfound]);
130
-		  Ix2_right += (Ix2_right + N + 1)%2 ? 1 : 0;	//adjust parity
131
-
132
-		  int Ix2_in = (Ix2_found[Nfound] > 0 ? Ix2_left : Ix2_right);
133
-		  int Ix2_out = (Ix2_found[Nfound] > 0 ? Ix2_right : Ix2_left);
134
-		  cout << rho.lambda[i] << "\t" << x.Return_Value(rho.lambda[i]) << "\t" << Ix2_found[Nfound] << endl;
135
-
136
-		  //choose the saddle point state and remember the uncertain choices
137
-		  if(Ix2_found[Nfound] - Ix2_left < 0.5) {
138
-			state[0].Ix2[Nfound] = Ix2_left;
139
-			state[1].Ix2[Nfound] = Ix2_left;
140
-			state[2].Ix2[Nfound] = Ix2_left;
141
-			state[3].Ix2[Nfound] = Ix2_left;
142
-		  }
143
-		  else if (Ix2_right - Ix2_found[Nfound] < 0.5) {
144
-			state[0].Ix2[Nfound] = Ix2_right;
145
-			state[1].Ix2[Nfound] = Ix2_right;
146
-			state[2].Ix2[Nfound] = Ix2_right;
147
-			state[3].Ix2[Nfound] = Ix2_right;
148
-		  }
149
-		  else { //it's a kind of magic: the zeroth goes in whle the first goes out, the second goes left if the third goes right
150
-		  	state[0].Ix2[Nfound] = Ix2_in;
151
-		  	state[1].Ix2[Nfound] = Ix2_out;
152
-		  	state[2+change].Ix2[Nfound] = Ix2_left;
153
-		  	state[2+!change].Ix2[Nfound] = Ix2_right;
154
-		  	change = !change;
155
-		  	++n_moves;
156
-		  }
157
-		  Nfound++;
158
-		}
106
+	if (integral > Nfound + 1.5 && integral < Nfound + 2.5) { // found two rapidities
107
+	  ABACUSerror("The distribution of particles is too discontinous for discretisation");
108
+	}
109
+
110
+	else {
111
+	  // few variables to clarify the computations, they do not need to be vectors, not used outside this loop
112
+	  Ix2_found[Nfound] = 2.0 * L * x.Return_Value(rho.lambda[i]);
113
+
114
+	  Ix2_left = floor(Ix2_found[Nfound]);
115
+	  Ix2_left -= (Ix2_left + N + 1)%2 ? 1 : 0;	//adjust parity
116
+
117
+	  Ix2_right = ceil(Ix2_found[Nfound]);
118
+	  Ix2_right += (Ix2_right + N + 1)%2 ? 1 : 0;	//adjust parity
119
+
120
+	  int Ix2_in = (Ix2_found[Nfound] > 0 ? Ix2_left : Ix2_right);
121
+	  int Ix2_out = (Ix2_found[Nfound] > 0 ? Ix2_right : Ix2_left);
122
+	  cout << rho.lambda[i] << "\t" << x.Return_Value(rho.lambda[i]) << "\t" << Ix2_found[Nfound] << endl;
123
+
124
+	  //choose the saddle point state and remember the uncertain choices
125
+	  if(Ix2_found[Nfound] - Ix2_left < 0.5) {
126
+	    state[0].Ix2[Nfound] = Ix2_left;
127
+	    state[1].Ix2[Nfound] = Ix2_left;
128
+	    state[2].Ix2[Nfound] = Ix2_left;
129
+	    state[3].Ix2[Nfound] = Ix2_left;
130
+	  }
131
+	  else if (Ix2_right - Ix2_found[Nfound] < 0.5) {
132
+	    state[0].Ix2[Nfound] = Ix2_right;
133
+	    state[1].Ix2[Nfound] = Ix2_right;
134
+	    state[2].Ix2[Nfound] = Ix2_right;
135
+	    state[3].Ix2[Nfound] = Ix2_right;
136
+	  }
137
+	  else {
138
+	    //it's a kind of magic: the zeroth goes in whle the first goes out,
139
+	    //the second goes left if the third goes right
140
+	    state[0].Ix2[Nfound] = Ix2_in;
141
+	    state[1].Ix2[Nfound] = Ix2_out;
142
+	    state[2+change].Ix2[Nfound] = Ix2_left;
143
+	    state[2+!change].Ix2[Nfound] = Ix2_right;
144
+	    change = !change;
145
+	    ++n_moves;
146
+	  }
147
+	  Nfound++;
148
+	}
159
       }
149
       }
160
-      //cout << "\ti = " << i << "\tintegral = " << integral << "\tNfound = " << Nfound << endl;
161
     }
150
     }
162
-    //cout << endl;
163
 
151
 
164
     //fix state[3] and state[4]
152
     //fix state[3] and state[4]
165
     for(int i=0; i<N-1; ++i) {
153
     for(int i=0; i<N-1; ++i) {
184
     if(!all_Diff) {
172
     if(!all_Diff) {
185
       //check if the first two states are different
173
       //check if the first two states are different
186
       if(state[0].Ix2 == state[1].Ix2)
174
       if(state[0].Ix2 == state[1].Ix2)
187
-	ABACUSerror("Cannot create 4 (nor 2) different states in LiebLin_Diagonal_State_Ensemble. Consider increasing system size");
175
+	ABACUSerror("Cannot create 4 (nor 2) different states in LiebLin_Diagonal_State_Ensemble. "
176
+		    "Consider increasing system size");
188
       else {
177
       else {
189
 	nstates = 2;
178
 	nstates = 2;
190
 	weight[0] = 0.5;
179
 	weight[0] = 0.5;
191
 	weight[1] = 0.5;
180
 	weight[1] = 0.5;
192
       }
181
       }
193
     }
182
     }
194
-    //set the weights accordingly to the distance between the states.
195
-//   	int n_moves_2 = 0, n_moves_3 = 0;
196
-//   	for(int i=0; i < N; ++i) {
197
-//   		if (!state[0].Ix2.is_in(state[2].Ix2[i])) ++n_moves_2;
198
-//   		if (!state[0].Ix2.is_in(state[3].Ix2[i])) ++n_moves_3;
199
-//   	}
200
-//
201
-//   	n_moves_2 = min(n_moves_2, n_moves - n_moves_2);
202
-//   	n_moves_3 = min(n_moves_3, n_moves - n_moves_3);
203
-//
204
-//   	weight[2] *= 2.0*n_moves_2/n_moves;
205
-//   	weight[3] *= 2.0*n_moves_3/n_moves;
206
-//
207
-//   	DP sum_weight = weight[0] + weight[1] + weight[2] + weight[3];
208
 
183
 
209
     for(int i=0; i<nstates; ++i) {
184
     for(int i=0; i<nstates; ++i) {
210
-      //weight[i] /= sum_weight;
211
       state[i].Set_Label_from_Ix2(state[0].Ix2);
185
       state[i].Set_Label_from_Ix2(state[0].Ix2);
212
       state[i].Compute_All(true);
186
       state[i].Compute_All(true);
213
     }
187
     }
214
 
188
 
215
 
189
 
216
-    cout << weight[0] << "\t" << state[0].Ix2 << endl << weight[0] << "\t" << state[1].Ix2 << endl;// << state[2].Ix2 << endl << state[3].Ix2 << endl;
190
+    cout << weight[0] << "\t" << state[0].Ix2 << endl << weight[0] << "\t" << state[1].Ix2 << endl;
217
 
191
 
218
     return;
192
     return;
219
-
220
-
221
-    //old working version but not enough to saturate +fsumrule
222
-/*
223
-  	Root_Density x = rho;
224
-  	for(int ix=0; ix<x.Npts; ++ix) {
225
-  		x.value[ix] = x.lambda[ix];
226
-  		for( int ip=0; ip<rho.Npts; ++ip) {
227
-  			x.value[ix] += 2.0 * rho.value[ip] * rho.dlambda[ip] * atan ((x.lambda[ix] - rho.lambda[ip])/c_int);
228
-  		}
229
-  		x.value[ix] /= 2.0*PI; //normalization
230
-  	}
231
-
232
-    // Now carry on as per Discretized_LiebLin_Bethe_State:
233
-    // Each time N \int_{-\infty}^\lambda d\lambda' \rho(\lambda') crosses a half integer, add a particle:
234
-    DP integral = 0.0;
235
-    DP integral_prev = 0.0;
236
-    int Nfound = 0;
237
-    Vect<DP> Ix2_found(0.0, N);
238
-    int Ix2_left, Ix2_right;
239
-    Vect<int> Ix2(N);
240
-    Vect<int> Ix2_uncertain(0, N);
241
-    Vect<int> index_uncertain(0, N);
242
-    int n_uncertain = 0, n_states_raw = 1;
243
-
244
-    for (int i = 0; i < rho.Npts; ++i) {
245
-      integral_prev = integral;
246
-      integral += L * rho.value[i] * rho.dlambda[i];
247
-      //cout << x.value[i] << "\t" << integral << endl;
248
-      if (integral > Nfound + 0.5) {
249
-	// Subtle error: if the rho is too discontinuous, i.e. if more than one rapidity is found, must correct for this.
250
-		if (integral > Nfound + 1.5 && integral < Nfound + 2.5) { // found two rapidities
251
-		  ABACUSerror("The distribution of particles is too discontinous for discretisation");
252
-		}
253
-
254
-		else {
255
-		  // few variables to clarify the computations, they do not need to be vectors, not used outside this loop
256
-		  Ix2_found[Nfound] = 2.0 * L *  (x.value[i] * (integral - Nfound - 0.5) + x.value[i-1] * (Nfound + 0.5 - integral_prev))/(integral - integral_prev);
257
-
258
-		  Ix2_left = floor(Ix2_found[Nfound]);
259
-		  Ix2_left -= (Ix2_left + N + 1)%2 ? 1 : 0;	//adjust parity
260
-
261
-		  Ix2_right = ceil(Ix2_found[Nfound]);
262
-		  Ix2_right += (Ix2_right + N + 1)%2 ? 1 : 0;	//adjust parity
263
-
264
-		  //cout << Ix2_found[Nfound] << "\t";
265
-
266
-		  //choose the saddle point state and remember the uncertain choices
267
-		  if(Ix2_found[Nfound] - Ix2_left < 1) {
268
-			Ix2[Nfound] = Ix2_left;
269
-			if(Ix2_found[Nfound] - Ix2_left > 0.75) {
270
-				Ix2_uncertain[n_uncertain] = -1;
271
-				index_uncertain[n_uncertain] = Nfound;
272
-				++n_uncertain;
273
-				n_states_raw *= 2;
274
-			}
275
-		  }
276
-		  else if (Ix2_right - Ix2_found[Nfound] < 1) {
277
-			Ix2[Nfound] = Ix2_right;
278
-			if(Ix2_right - Ix2_found[Nfound] > 0.75) {
279
-				Ix2_uncertain[n_uncertain] = 1;
280
-				index_uncertain[n_uncertain] = Nfound;
281
-				++n_uncertain;
282
-				n_states_raw *= 2;
283
-			}
284
-		  }
285
-		  else ABACUSerror("Cannot deduce a quantum number from x(lambda)");
286
-		  Nfound++;
287
-		}
288
-      }
289
-      //cout << "\ti = " << i << "\tintegral = " << integral << "\tNfound = " << Nfound << endl;
290
-    }
291
-  	//cout << endl;
292
-
293
-  	//cout << Ix2 << endl;
294
-
295
-  	// create ensamble of states and compute its weights with respect to exact Ix2 saddle point
296
-  	Vect<Vect<int> > Ix2states(Ix2, n_states_raw);
297
-  	Vect<DP> Ix2weight(0.0, n_states_raw);
298
-
299
-// 	Ix2states[0] = Ix2;
300
-//	Ix2weight[0] = ;
301
-  	int n_states_proper = 0;
302
-	for(int i=0; i < n_states_raw; ++i) {
303
-		//only symmetric modifications
304
-		for(int mod_index = 0; mod_index<n_uncertain; ++mod_index) {
305
-			if((i & (1 << mod_index)) >> mod_index != 0) {
306
-				Ix2states[n_states_proper][index_uncertain[mod_index]] += (-2)*Ix2_uncertain[mod_index];
307
-				////Ix2states[state_index][N - 1 - hole_position[mod_index]] += (2)*holes[hole_position[mod_index]];
308
-			}
309
-		}
310
-		//check if it's a proper set of quantum numbers
311
-		bool OK = true;
312
-		for(int j=0; j<N-1; ++j) if(Ix2states[n_states_proper][j] == Ix2states[n_states_proper][j+1]) OK = false;
313
-
314
-		if(OK) {
315
-			DP sum = 0;
316
-			for(int j=0; j<N; ++j) sum += abs(Ix2_found[j] - Ix2states[n_states_proper][j]);
317
-			Ix2weight[n_states_proper] = exp(-sum);
318
-			n_states_proper++;
319
-		}
320
-		else Ix2states[n_states_proper] = Ix2;
321
-	}
322
-
323
-
324
-
325
-	//sort the states in increasing weight order;
326
-	Vect<int> index(0, n_states_raw);
327
-    for (int nrs = 0; nrs < n_states_raw; ++nrs) index[nrs] = nrs;
328
-    Ix2weight.QuickSort(index);
329
-
330
-    //cut the number of states if above 21 <- arbitrary number for now
331
-    nstates = min(n_states_proper, 21);
332
-    cout << n_states_raw << "\t" << n_states_proper << "\t" << nstates << endl;
333
-
334
-    //create ensamble of states with normalised weights and ordered accordingly
335
-	LiebLin_Bethe_State rhostate(c_int, N, L);
336
-    rhostate.Ix2 = Ix2;
337
-    rhostate.Compute_All(true);
338
-
339
-	state = Vect<LiebLin_Bethe_State>(rhostate, nstates);
340
-    weight = Vect<DP>(nstates);
341
-
342
-    DP sum_weight = 0.0;
343
-    for(int i=0; i<nstates; ++i) {
344
-    	state[i].Ix2 = Ix2states[index[n_states_raw - i - 1]];
345
-    	state[i].Set_Label_from_Ix2 (state[0].Ix2);
346
-    	weight[i] = Ix2weight[n_states_raw - i - 1];
347
-    	sum_weight += weight[i];
348
-    }
349
-
350
-    //renormalise
351
-    for(int i=0; i<nstates; ++i) weight[i] /= sum_weight;
352
-
353
-//    for(int i=0; i<nstates; ++i) {
354
-//    	cout << weight[i] << "\t" << state[i].Ix2 << endl;
355
-//    }
356
-
357
-    return;
358
-*/
359
-  	//cout << rho_t.value << endl;
360
-
361
-  	// different attempts - to delete soon
362
-//  	ABACUSerror("Stop here.");
363
-/*
364
-
365
-    // This function returns a state ensemble matching the continuous density rho.
366
-    // The logic closely resembles the one used in Discretized_LiebLin_Bethe_State.
367
-
368
-    // Now carry on as per Discretized_LiebLin_Bethe_State:
369
-    // Each time N \int_{-\infty}^\lambda d\lambda' \rho(\lambda') crosses a half integer, add a particle:
370
-    DP integral = 0.0;
371
-    DP integral_prev = 0.0;
372
-    int Nfound = 0;
373
-    Vect<DP> lambda_found(0.0, 2*N);
374
-
375
-    for (int i = 0; i < rho.Npts; ++i) {
376
-      integral_prev = integral;
377
-      integral += L * rho.value[i] * rho.dlambda[i];
378
-      //cout << x.value[i] << "\t" << integral << endl;
379
-      if (integral > Nfound + 0.5) {
380
-      cout << L*x.value[i] << "\t" << integral << endl;
381
-	// Subtle error: if the rho is too discontinuous, i.e. if more than one rapidity is found, must correct for this.
382
-	if (integral > Nfound + 1.5 && integral < Nfound + 2.5) { // found two rapidities
383
-	  lambda_found[Nfound++] = 0.25 * (3.0 * rho.lambda[i-1] + rho.lambda[i]);
384
-	  lambda_found[Nfound++] = 0.25 * (rho.lambda[i-1] + 3.0 * rho.lambda[i]);
385
-	}
386
-	else {
387
-	  //lambda_found[Nfound] = rho.lambda[i];
388
-	  // Better: center the lambda_found between these points:
389
-	  //lambda_found[Nfound] = rho.lambda[i-1] + (rho.lambda[i] - rho.lambda[i-1]) * ((Nfound + 1.0) - integral_prev)/(integral - integral_prev);
390
-	  lambda_found[Nfound] = 0.5 * (rho.lambda[i-1] + rho.lambda[i]);
391
-	  Nfound++;
392
-	}
393
-      }
394
-      //cout << "\ti = " << i << "\tintegral = " << integral << "\tNfound = " << Nfound << endl;
395
-    }
396
-    //cout << "rho: " << rho.Npts << " points" << endl << rho.value << endl;
397
-    //cout << "sym: " << rho.value[0] << " " << rho.value[rho.value.size() - 1]
398
-    // << "\t" << rho.value[rho.value.size()/2] << " " << rho.value[rho.value.size()/2 + 1] << endl;
399
-    //cout << "Found " << Nfound << " particles." << endl;
400
-    //cout << "lambda_found = " << lambda_found << endl;
401
-
402
-    Vect<DP> lambda(N);
403
-    // Fill up the found rapidities:
404
-    for (int il = 0; il < ABACUS::min(N, Nfound); ++il) lambda[il] = lambda_found[il];
405
-    // If there are missing ones, put them at the end; ideally, this should never be called
406
-    for (int il = Nfound; il < N; ++il) lambda[il] = lambda_found[Nfound-1] + (il - Nfound + 1) * (lambda_found[Nfound-1] - lambda_found[Nfound-2]);
407
-
408
-	//cout << lambda << endl;
409
-*/
410
-	//try a different method
411
-	//first determine bins, that is intervals in lambda which contain a single rapidity
412
-/*
413
-	Vect<int> lambda_bin(0.0, N+1);
414
-	integral = 0.0;
415
-	Nfound = 0;
416
-
417
-	lambda_bin[0] = 0;
418
-	lambda_bin[N] = rho.Npts-1;
419
-	for(int i=0; i<rho.Npts; ++i) {
420
-		integral += L * rho.value[i] * rho.dlambda[i];
421
-		if (integral > Nfound + 1.0) lambda_bin[++Nfound] = i - (rho.lambda[i]>0);
422
-	}
423
-
424
-	//put rapidity at the mean value of the distribution inside the bin
425
-	for(int ib=0; ib < N; ++ib) {
426
-		lambda_found[ib] = 0.0;
427
-		for(int i=lambda_bin[ib]; i<lambda_bin[ib+1]; ++i) lambda_found[ib] += L * rho.value[i] * rho.lambda[i] * rho.dlambda[i];
428
-	}
429
-
430
-	//cout << lambda_found << endl;
431
-
432
-	for(int i=0; i<N; ++i) cout << L*lambda[i]/PI << "\t" << L*lambda_found[i]/PI << endl;
433
-
434
-
435
-	ABACUSerror("Stop here.");
436
-*/
437
-/*
438
-    // Calculate quantum numbers: 2\pi * (L lambda + \sum_j 2 atan((lambda - lambda_j)/c)) = I_j
439
-    // Use rounding.
440
-    Vect<DP> Ix2_exact(N);
441
-    for (int i = 0; i < N; ++i) {
442
-      DP sum = 0.0;
443
-      for (int j = 0; j < N; ++j) sum += 2.0 * atan((lambda[i] - lambda[j])/c_int);
444
-      Ix2_exact[i] = (L * lambda[i] + sum)/PI;
445
-	  Ix2_left[i] = floor(Ix2_exact[i]);
446
-	  Ix2_left[i] -= (Ix2_left[i] + N + 1)%2 ? 1 : 0;
447
-	  Ix2_right[i] = ceil(Ix2_exact[i]);
448
-	  Ix2_right[i] += (Ix2_right[i] + N + 1)%2 ? 1 : 0;
449
-
450
-	  //cout << Ix2_left[i] << "\t" << Ix2_exact[i] << "\t" << Ix2_right[i] << endl;
451
-      //Ix2[i] = 2.0* int((L * lambda[i] + sum)/twoPI) + (N % 2) - 1;
452
-      // For N is even/odd, we want to round off to the nearest odd/even integer.
453
-      //Ix2[i] = 2.0 * floor((L* lambda[i] + sum)/twoPI + 0.5 * (N%2 ? 1 : 2)) + (N%2) - 1;
454
-    }
455
-    //cout << "Found quantum numbers " << endl << Ix2 << endl;
456
-*/
457
-
458
-/*
459
-	//create the reference state and mark possible hole positions
460
-	Vect<int> Ix2(N);
461
-	Vect<float> holes(0.0, N);
462
-	for(int i=0; i < N; ++i) {
463
-		if(Ix2_found[i] - Ix2_left[i] < 1) {
464
-			Ix2[i] = Ix2_left[i];
465
-				if(Ix2_found[i] - Ix2_left[i] > 0.75) holes[i] = -1;
466
-		}
467
-		else {
468
-			Ix2[i] = Ix2_right[i];
469
-			if(Ix2_right[i] - Ix2_found[i] > 0.75) holes[i] = 1;
470
-		}
471
-	}
472
-*/
473
-//	cout << endl << Ix2 << endl;
474
-//	cout << endl << holes << endl;
475
-/*
476
-	//count number of possible states
477
-	int n = 0;
478
-	for(int i=0; i < N; ++i) {
479
-		if(holes[i] != 0) ++n;
480
-	}
481
-	int n_states_raw = 1;
482
-*/
483
-/* only symmetric modifications
484
-	for(int i=0; i<0.5*n; ++i) n_states_raw *= 2.0; //we count only symmetric modiications
485
-
486
-	Vect<Vect<int> > Ix2states(Ix2, n_states_raw);
487
-
488
-	Vect<int> hole_position(0, 0.5*n);
489
-	int hole_index = 0;
490
-	for(int i=N/2 + N%2; i<N; ++i) {
491
-		if(holes[i] != 0) hole_position[hole_index++] = i;
492
-	}
493
-
494
-
495
-	//create modifications, we use bit representation of integers between 0 and n_states-1 treating zero as no change and 1 as mutltiplication by -1
496
-	int state_index = 1;
497
-	for(int i=1; i < n_states_raw; ++i) {
498
-		//only symmetric modifications
499
-		for(int mod_index = 0; mod_index<0.5*n; ++mod_index) {
500
-			if((i & (1 << mod_index)) >> mod_index != 0) {
501
-				Ix2states[state_index][hole_position[mod_index]] += (-2)*holes[hole_position[mod_index]];
502
-				Ix2states[state_index][N - 1 - hole_position[mod_index]] += (2)*holes[hole_position[mod_index]];
503
-			}
504
-		}
505
-		//check if it's a proper set of quantum numbers
506
-		bool OK = true;
507
-		for(int j=0; j<N-1; ++j) if(Ix2states[state_index][j] == Ix2states[state_index][j+1]) OK = false;
508
-
509
-		if(OK) state_index++;
510
-		else Ix2states[state_index] = Ix2;
511
-	}
512
-*/
513
-/*
514
-	for(int i=0; i<n; ++i) n_states_raw *= 2.0; //we count all posibilities
515
-
516
-	Vect<Vect<int> > Ix2states(Ix2, n_states_raw);
517
-
518
-	Vect<int> hole_position(0, n);
519
-	int hole_index = 0;
520
-	for(int i=0; i<N; ++i) {
521
-		if(holes[i] != 0) hole_position[hole_index++] = i;
522
-	}
523
-
524
-
525
-	//create modifications, we use bit representation of integers between 0 and n_states-1 treating zero as no change and 1 as mutltiplication by -1
526
-	int state_index = 1;
527
-	for(int i=1; i < n_states_raw; ++i) {
528
-		//only symmetric modifications
529
-		for(int mod_index = 0; mod_index<n; ++mod_index) {
530
-			if((i & (1 << mod_index)) >> mod_index != 0) {
531
-				Ix2states[state_index][hole_position[mod_index]] += (-2)*holes[hole_position[mod_index]];
532
-				//Ix2states[state_index][N - 1 - hole_position[mod_index]] += (2)*holes[hole_position[mod_index]];
533
-			}
534
-		}
535
-		//check if it's a proper set of quantum numbers
536
-		bool OK = true;
537
-		for(int j=0; j<N-1; ++j) if(Ix2states[state_index][j] == Ix2states[state_index][j+1]) OK = false;
538
-
539
-		if(OK) state_index++;
540
-		else Ix2states[state_index] = Ix2;
541
-	}
542
-
543
-*/
544
-/*
545
-	n_states_raw = state_index;
546
-//	for(int i=0; i<n_states; ++i) cout << Ix2states[i] << endl;
547
-
548
-	LiebLin_Bethe_State rhostate(c_int, N, L);
549
-    rhostate.Ix2 = Ix2;
550
-    rhostate.Compute_All(true);
551
-
552
-	Vect<LiebLin_Bethe_State> state_raw = Vect<LiebLin_Bethe_State>(rhostate, n_states_raw);
553
-    Vect<DP> weight_raw(0.0, n_states_raw);
554
-*/
555
-
556
-/*
557
-    DP energy_rho = 0;
558
-    for (int i = 0; i < rho.Npts; ++i) {
559
-		energy_rho += L * rho.value[i] * rho.dlambda[i] * rho.lambda[i] * rho.lambda[i];
560
-    }
561
-
562
-    cout << energy_rho << endl;
563
-
564
-    DP energy_discrete = 0;
565
-    for (int i=0; i < N; ++i) {
566
-    	energy_discrete += lambda[i] * lambda[i];
567
-    }
568
-    energy_discrete /= N;
569
-    cout << energy_discrete;
570
-*/
571
-/*
572
-	DP sum_weight_raw = 0.0;
573
-    for(int i=0; i<n_states_raw; ++i) {
574
-    	//state_raw[i].Ix2 = Ix2states[i];
575
-    	//state_raw[i].Set_Label_from_Ix2 (state_raw[0].Ix2);
576
-    	//state_raw[i].Compute_All(true);
577
-    	DP sum = 0;
578
-    	for(int j=0; j<N; ++j) sum += fabs(Ix2states[i][j] - Ix2_found[j]);
579
-    	weight_raw[i] = exp(sum)/L;
580
-
581
-    	sum_weight_raw += weight_raw[i];
582
-    }
583
-
584
-    for(int i=0; i<n_states_raw; ++i) weight_raw[i] /= sum_weight_raw;
585
-
586
-    // Order the weights in decreasing value:
587
-    Vect<int> index(n_states_raw);
588
-    for (int nrs = 0; nrs < n_states_raw; ++nrs) index[nrs] = nrs;
589
-    weight_raw.QuickSort(index);
590
-
591
-    //nstates = 0;
592
-    //for(int i=0; i<n_states_raw; ++i) if (weight_raw[i] > 0.01) ++nstates;
593
-
594
-    nstates = ABACUS::min(n_states_raw, 21);
595
-
596
-    cout << nstates << endl;
597
-
598
-	state = Vect<LiebLin_Bethe_State>(rhostate, nstates);
599
-    weight = Vect<DP>(nstates);
600
-
601
-    DP sum_weight = 0.0;
602
-    for(int i=0; i<nstates; ++i) {
603
-    	state[i].Ix2 = Ix2states[index[i]];
604
-    	state[i].Set_Label_from_Ix2 (state[0].Ix2);
605
-    	weight[i] = weight_raw[index[i]];
606
-    	sum_weight += weight[i];
607
-    }
608
-
609
-    //renormalise
610
-    for(int i=0; i<nstates; ++i) weight[i] /= sum_weight;
611
-
612
-    for(int i=0; i<nstates; ++i) {
613
-    	cout << weight[i] << "\t" << state[i].Ix2 << endl;
614
-    }
615
-*/
616
-	//ABACUSerror("Stop here.");
617
-
618
-	// end of different attempts
619
-/*
620
-    // Check that the quantum numbers are all distinct:
621
-    bool allOK = false;
622
-    while (!allOK) {
623
-      for (int i = 0; i < N-1; ++i) if (Ix2[i] == Ix2[i+1] && Ix2[i] < 0) Ix2[i] -= 2;
624
-      for (int i = 1; i < N; ++i) if (Ix2[i] == Ix2[i-1] && Ix2[i] > 0) Ix2[i] += 2;
625
-      allOK = true;
626
-      for (int i = 0; i < N-1; ++i) if (Ix2[i] == Ix2[i+1]) allOK = false;
627
-    }
628
-    //cout << "Found modified quantum numbers " << endl << Ix2 << endl;
629
-
630
-    LiebLin_Bethe_State rhostate(c_int, N, L);
631
-    rhostate.Ix2 = Ix2;
632
-    rhostate.Compute_All(true);
633
-    //cout << "rapidities of state found: " << rhostate.lambda << endl;
634
-
635
-    // Until here, the code is identical to that in Discretized_LiebLin_Bethe_State.
636
-    // Construct states in the vicinity by going through type 2 descendents recursively:
637
-    int ndesc_type2 = 0;
638
-    int* ndesc_type2_ptr = &ndesc_type2;
639
-    Generate_type_2_descendents (rhostate, ndesc_type2_ptr, rhostate);
640
-
641
-
642
-    cout << "Found " << ndesc_type2 << " descendents for state " << rhostate << endl;
643
-    //ABACUSerror("Stop here...");
644
-
645
-    // Now try to construct states in the vicinity.
646
-    int nrstates1mod = 1;
647
-    for (int i = 0; i < N; ++i) {
648
-      if (i == 0 || Ix2[i-1] < Ix2[i] - 2) nrstates1mod++;
649
-      if (i == N-1 || Ix2[i+1] > Ix2[i] + 2) nrstates1mod++;
650
-    }
651
-    //if (nrstates1mod < nstates_req) ABACUSerror("nrstates1mod < nstates_req in LiebLin_Diagonal_State_Ensemble.");
652
-    nstates = nrstates1mod;
653
-
654
-    Vect<Vect<int> > Ix2states1mod(nrstates1mod);
655
-    for (int nrs = 0; nrs < nrstates1mod; ++nrs) Ix2states1mod[nrs] = Vect<int> (N);
656
-
657
-    int nfound = 0;
658
-    Ix2states1mod[nfound++] = Ix2; // this is the sp state
659
-    for (int i = 0; i < N; ++i) {
660
-      if (i == 0 || Ix2[i-1] < Ix2[i] - 2) {
661
-	Ix2states1mod[nfound] = Ix2;
662
-	Ix2states1mod[nfound++][i] -= 2;
663
-      }
664
-      if (i == N-1 || Ix2[i+1] > Ix2[i] + 2) {
665
-	Ix2states1mod[nfound] = Ix2;
666
-	Ix2states1mod[nfound++][i] += 2;
667
-      }
668
-    }
669
-
670
-    // Evaluate the weight of all found states:
671
-    Vect<DP> rawweight(nrstates1mod);
672
-
673
-    for (int nrs = 0; nrs < nrstates1mod; ++nrs) {
674
-      DP sumweight = 0.0;
675
-      for (int i = 0; i < N; ++i) sumweight += fabs(Ix2states1mod[nrs][i] - Ix2_exact[i]);
676
-      rawweight[nrs] = exp(-sumweight/log(L));
677
-    }
678
-
679
-    // Order the weights in decreasing value:
680
-    Vect<int> index(nrstates1mod);
681
-    for (int nrs = 0; nrs < nrstates1mod; ++nrs) index[nrs] = nrs;
682
-    rawweight.QuickSort(index);
683
-
684
-    // Calculate weight normalization:
685
-    DP weightnorm = 0.0;
686
-    //for (int ns = 0; ns < nstates_req; ++ns) weightnorm += rawweight[nrstates1mod - 1 - ns];
687
-    for (int ns = 0; ns < nstates; ++ns) weightnorm += rawweight[nrstates1mod - 1 - ns];
688
-
689
-    state = Vect<LiebLin_Bethe_State>(rhostate, nstates);
690
-    weight = Vect<DP> (nstates);
691
-
692
-    for (int ns = 0; ns < nstates; ++ns) {
693
-      weight[ns] = rawweight[nrstates1mod - 1 - ns]/weightnorm;
694
-      state[ns].Ix2 = Ix2states1mod[index[nrstates1mod - 1 - ns] ];
695
-      state[ns].Set_Label_from_Ix2 (rhostate.Ix2);
696
-      state[ns].Compute_All(true);
697
-    }
698
-*/
699
-
700
-
701
-  }
702
-
703
-  /*
704
-  LiebLin_Diagonal_State_Ensemble::LiebLin_Diagonal_State_Ensemble (DP c_int, DP L, int N, const Root_Density& rho, int nstates_req)
705
-    : nstates(nstates_req)
706
-  {
707
-    // This function returns a state ensemble matching the continuous density rho.
708
-    // The logic closely resembles the one used in Discretized_LiebLin_Bethe_State.
709
-
710
-    // Each `exact' (from rho) quantum number is matched to its two possible values,
711
-    // assigning a probability to each according to the proximity of the quantum number values.
712
-
713
-    // The set is then ordered in energy, and split into nstates_req boxes from which one
714
-    // representative is selected, and given the probability = sum of probabilities in the box.
715
-
716
-
717
-    // Begin as per Discretized_LiebLin_Bethe_State, to find the saddle-point state.
718
-    // Each time N \int_{-\infty}^\lambda d\lambda' \rho(\lambda') crosses a half integer, add a particle:
719
-    DP integral = 0.0;
720
-    DP integral_prev = 0.0;
721
-    int Nfound = 0;
722
-    Vect<DP> lambda_found(0.0, 2*N);
723
-
724
-    for (int i = 0; i < rho.Npts; ++i) {
725
-      integral_prev = integral;
726
-      integral += L * rho.value[i] * rho.dlambda[i];
727
-      if (integral > Nfound + 0.5) {
728
-	// Subtle error: if the rho is too discontinuous, i.e. if more than one rapidity is found, must correct for this.
729
-	if (integral > Nfound + 1.5 && integral < Nfound + 2.5) { // found two rapidities
730
-	  lambda_found[Nfound++] = 0.25 * (3.0 * rho.lambda[i-1] + rho.lambda[i]);
731
-	  lambda_found[Nfound++] = 0.25 * (rho.lambda[i-1] + 3.0 * rho.lambda[i]);
732
-	}
733
-	else {
734
-	  //lambda_found[Nfound] = rho.lambda[i];
735
-	  // Better: center the lambda_found between these points:
736
-	  //lambda_found[Nfound] = rho.lambda[i-1] + (rho.lambda[i] - rho.lambda[i-1]) * ((Nfound + 1.0) - integral_prev)/(integral - integral_prev);
737
-	  lambda_found[Nfound] = 0.5 * (rho.lambda[i-1] + rho.lambda[i]);
738
-	  Nfound++;
739
-	}
740
-      }
741
-      //cout << "\ti = " << i << "\tintegral = " << integral << "\tNfound = " << Nfound << endl;
742
-    }
743
-    //cout << "rho: " << rho.Npts << " points" << endl << rho.value << endl;
744
-    //cout << "sym: " << rho.value[0] << " " << rho.value[rho.value.size() - 1]
745
-    // << "\t" << rho.value[rho.value.size()/2] << " " << rho.value[rho.value.size()/2 + 1] << endl;
746
-    //cout << "Found " << Nfound << " particles." << endl;
747
-    //cout << "lambda_found = " << lambda_found << endl;
748
-
749
-    Vect<DP> lambda(N);
750
-    // Fill up the found rapidities:
751
-    for (int il = 0; il < ABACUS::min(N, Nfound); ++il) lambda[il] = lambda_found[il];
752
-    // If there are missing ones, put them at the end; ideally, this should never be called
753
-    for (int il = Nfound; il < N; ++il) lambda[il] = lambda_found[Nfound-1] + (il - Nfound + 1) * (lambda_found[Nfound-1] - lambda_found[Nfound-2]);
754
-
755
-    // Calculate quantum numbers: 2\pi * (L lambda + \sum_j 2 atan((lambda - lambda_j)/c)) = I_j
756
-    // Use rounding.
757
-    Vect<DP> Ix2_exact(N);
758
-    Vect<int> Ix2(N);
759
-    for (int i = 0; i < N; ++i) {
760
-      DP sum = 0.0;
761
-      for (int j = 0; j < N; ++j) sum += 2.0 * atan((lambda[i] - lambda[j])/c_int);
762
-      Ix2_exact[i] = (L * lambda[i] + sum)/PI;
763
-      //Ix2[i] = 2.0* int((L * lambda[i] + sum)/twoPI) + (N % 2) - 1;
764
-      // For N is even/odd, we want to round off to the nearest odd/even integer.
765
-      Ix2[i] = 2.0 * floor((L* lambda[i] + sum)/twoPI + 0.5 * (N%2 ? 1 : 2)) + (N%2) - 1;
766
-    }
767
-    //cout << "Found quantum numbers " << endl << Ix2 << endl;
768
-
769
-    // Check that the quantum numbers are all distinct:
770
-    bool allOK = false;
771
-    while (!allOK) {
772
-      for (int i = 0; i < N-1; ++i) if (Ix2[i] == Ix2[i+1] && Ix2[i] < 0) Ix2[i] -= 2;
773
-      for (int i = 1; i < N; ++i) if (Ix2[i] == Ix2[i-1] && Ix2[i] > 0) Ix2[i] += 2;
774
-      allOK = true;
775
-      for (int i = 0; i < N-1; ++i) if (Ix2[i] == Ix2[i+1]) allOK = false;
776
-    }
777
-    //cout << "Found modified quantum numbers " << endl << Ix2 << endl;
778
-
779
-    LiebLin_Bethe_State rhostate(c_int, N, L);
780
-    rhostate.Ix2 = Ix2;
781
-    rhostate.Compute_All(true);
782
-    //cout << "rapidities of state found: " << rhostate.lambda << endl;
783
-
784
-    // Until here, the code is identical to that in Discretized_LiebLin_Bethe_State.
785
-
786
-    // Now try to construct states in the vicinity.
787
-    int nrstates1mod = 1;
788
-    for (int i = 0; i < N; ++i) {
789
-      if (i == 0 || Ix2[i-1] < Ix2[i] - 2) nrstates1mod++;
790
-      if (i == N-1 || Ix2[i+1] > Ix2[i] + 2) nrstates1mod++;
791
-    }
792
-    if (nrstates1mod < nstates_req) ABACUSerror("nrstates1mod < nstates_req in LiebLin_Diagonal_State_Ensemble.");
793
-
794
-    Vect<Vect<int> > Ix2states1mod(nrstates1mod);
795
-    for (int nrs = 0; nrs < nrstates1mod; ++nrs) Ix2states1mod[nrs] = Vect<int> (N);
796
-
797
-    int nfound = 0;
798
-    Ix2states1mod[nfound++] = Ix2; // this is the sp state
799
-    for (int i = 0; i < N; ++i) {
800
-      if (i == 0 || Ix2[i-1] < Ix2[i] - 2) {
801
-	Ix2states1mod[nfound] = Ix2;
802
-	Ix2states1mod[nfound++][i] -= 2;
803
-      }
804
-      if (i == N-1 || Ix2[i+1] > Ix2[i] + 2) {
805
-	Ix2states1mod[nfound] = Ix2;
806
-	Ix2states1mod[nfound++][i] += 2;
807
-      }
808
-    }
809
-
810
-    // Evaluate the weight of all found states:
811
-    Vect<DP> rawweight(nrstates1mod);
812
-
813
-    for (int nrs = 0; nrs < nrstates1mod; ++nrs) {
814
-      DP sumweight = 0.0;
815
-      for (int i = 0; i < N; ++i) sumweight += fabs(Ix2states1mod[nrs][i] - Ix2_exact[i]);
816
-      rawweight[nrs] = exp(-sumweight/log(L));
817
-    }
818
-
819
-    // Order the weights in decreasing value:
820
-    Vect<int> index(nrstates1mod);
821
-    for (int nrs = 0; nrs < nrstates1mod; ++nrs) index[nrs] = nrs;
822
-    rawweight.QuickSort(index);
823
-
824
-    // Calculate weight normalization:
825
-    DP weightnorm = 0.0;
826
-    for (int ns = 0; ns < nstates_req; ++ns) weightnorm += rawweight[nrstates1mod - 1 - ns];
827
-
828
-    state = Vect<LiebLin_Bethe_State>(rhostate, nstates_req);
829
-    weight = Vect<DP> (nstates_req);
830
-
831
-    for (int ns = 0; ns < nstates_req; ++ns) {
832
-      weight[ns] = rawweight[nrstates1mod - 1 - ns]/weightnorm;
833
-      state[ns].Ix2 = Ix2states1mod[index[nrstates1mod - 1 - ns] ];
834
-      state[ns].Set_Label_from_Ix2 (rhostate.Ix2);
835
-      state[ns].Compute_All(true);
836
-    }
837
   }
193
   }
838
-  */
839
 
194
 
840
   LiebLin_Diagonal_State_Ensemble& LiebLin_Diagonal_State_Ensemble::operator= (const LiebLin_Diagonal_State_Ensemble& rhs)
195
   LiebLin_Diagonal_State_Ensemble& LiebLin_Diagonal_State_Ensemble::operator= (const LiebLin_Diagonal_State_Ensemble& rhs)
841
   {
196
   {
858
     while (getline(infile, dummy))  ++nrlines;
213
     while (getline(infile, dummy))  ++nrlines;
859
     infile.close();
214
     infile.close();
860
 
215
 
861
-    //cout << "Found " << nrlines << " lines in ens file." << endl;
862
     nstates = nrlines;
216
     nstates = nrlines;
863
     LiebLin_Bethe_State examplestate (c_int, L, N);
217
     LiebLin_Bethe_State examplestate (c_int, L, N);
864
     state = Vect<LiebLin_Bethe_State> (examplestate, nstates);
218
     state = Vect<LiebLin_Bethe_State> (examplestate, nstates);
893
   }
247
   }
894
 
248
 
895
 
249
 
896
-  //LiebLin_Diagonal_State_Ensemble LiebLin_Thermal_Saddle_Point_Ensemble (DP c_int, DP L, int N, DP kBT, int nstates_req)
897
   LiebLin_Diagonal_State_Ensemble LiebLin_Thermal_Saddle_Point_Ensemble (DP c_int, DP L, int N, DP kBT)
250
   LiebLin_Diagonal_State_Ensemble LiebLin_Thermal_Saddle_Point_Ensemble (DP c_int, DP L, int N, DP kBT)
898
   {
251
   {
899
     // This function constructs a manifold of states around the thermal saddle-point.
252
     // This function constructs a manifold of states around the thermal saddle-point.
915
     cout << "ebar: " << TBAsol.ebar << endl;
268
     cout << "ebar: " << TBAsol.ebar << endl;
916
 
269
 
917
     cout << ensemble.state[0].E << endl;
270
     cout << ensemble.state[0].E << endl;
918
-    //return(LiebLin_Diagonal_State_Ensemble (c_int, L, N, TBAsol.rho, nstates_req));
919
     return(ensemble);
271
     return(ensemble);
920
   }
272
   }
921
 
273
 

+ 21
- 73
src/LIEBLIN/LiebLin_Sumrules.cc View File

20
 
20
 
21
 namespace ABACUS {
21
 namespace ABACUS {
22
 
22
 
23
-  //DP Sumrule_Factor (char whichDSF, LiebLin_Bethe_State& RefState, DP Chem_Pot, bool fixed_iK, int iKneeded)
24
   DP Sumrule_Factor (char whichDSF, LiebLin_Bethe_State& RefState, DP Chem_Pot, int iKmin, int iKmax)
23
   DP Sumrule_Factor (char whichDSF, LiebLin_Bethe_State& RefState, DP Chem_Pot, int iKmin, int iKmax)
25
   {
24
   {
26
     DP sumrule_factor = 1.0;
25
     DP sumrule_factor = 1.0;
27
 
26
 
28
-    //if (!fixed_iK) {
29
     if (iKmin != iKmax) {
27
     if (iKmin != iKmax) {
30
       if (whichDSF == 'Z') sumrule_factor = 1.0;
28
       if (whichDSF == 'Z') sumrule_factor = 1.0;
31
       else if (whichDSF == 'd' || whichDSF == '1') {
29
       else if (whichDSF == 'd' || whichDSF == '1') {
33
 	// Here, we use a measure decreasing in K with K^2.
31
 	// Here, we use a measure decreasing in K with K^2.
34
 	// We sum up omega * MEsq/(iK^2) for all values of iKmin <= iK <= iKmax, discounting iK == 0 (where DSF vanishes)
32
 	// We sum up omega * MEsq/(iK^2) for all values of iKmin <= iK <= iKmax, discounting iK == 0 (where DSF vanishes)
35
 	// We therefore have (N/L) x L^{-1} x (2\pi/L)^2 x (iKmax - iKmin + 1) = 4 \pi^2 x N x (iKmax - iKmin + 1)/L^4
33
 	// We therefore have (N/L) x L^{-1} x (2\pi/L)^2 x (iKmax - iKmin + 1) = 4 \pi^2 x N x (iKmax - iKmin + 1)/L^4
36
-	// Discounting iK == 0 (where DSF vanishes), if iKmin <= 0 && iKmax >= 0 (in which case 0 is containted in [iKmin, iKmax])
34
+	// Discounting iK == 0 (where DSF vanishes),
35
+	// if iKmin <= 0 && iKmax >= 0 (in which case 0 is containted in [iKmin, iKmax])
37
 	sumrule_factor = (iKmin <= 0 && iKmax >= 0) ?
36
 	sumrule_factor = (iKmin <= 0 && iKmax >= 0) ?
38
 	  (RefState.L * RefState.L * RefState.L * RefState.L)/(4.0 * PI * PI * RefState.N * (iKmax - iKmin))
37
 	  (RefState.L * RefState.L * RefState.L * RefState.L)/(4.0 * PI * PI * RefState.N * (iKmax - iKmin))
39
 	  : (RefState.L * RefState.L * RefState.L * RefState.L)/(4.0 * PI * PI * RefState.N * (iKmax - iKmin + 1));
38
 	  : (RefState.L * RefState.L * RefState.L * RefState.L)/(4.0 * PI * PI * RefState.N * (iKmax - iKmin + 1));
40
-
41
-	/*
42
-	// Measure using the g2(0) + delta function:  // DOES NOT WORK VERY WELL
43
-	DP dE0_dc = LiebLin_dE0_dc (RefState.c_int, RefState.L, RefState.N);
44
-	//sumrule_factor = 1.0/((dE0_dc + (2.0 * RefState.Tableau[0].Ncols + 1.0)*RefState.N/RefState.L)/RefState.L);
45
-	// Assume that iKmin == 0 here:
46
-	//sumrule_factor = 1.0/((dE0_dc + (2*iKmax + 1)*RefState.N/RefState.L)/RefState.L);
47
-	// For iKmin != 0:
48
-	sumrule_factor = 1.0/((dE0_dc + (iKmax - iKmin + 1)*RefState.N/RefState.L)/RefState.L);
49
-	*/
50
       }
39
       }
51
       // For the Green's function, it's the delta function \delta(x = 0) plus the density:
40
       // For the Green's function, it's the delta function \delta(x = 0) plus the density:
52
-      //else if (whichDSF == 'g') sumrule_factor = 1.0/((2.0 * RefState.Tableau[0].Ncols + 1.0)/RefState.L + RefState.N/RefState.L);
53
-      // Assume that iKmin == 0 here:
54
-      //else if (whichDSF == 'g') sumrule_factor = 1.0/(2.0* iKmax + 1.0)/RefState.L + RefState.N/RefState.L);
55
       else if (whichDSF == 'g')
41
       else if (whichDSF == 'g')
56
 	sumrule_factor = 1.0/((abs(iKmax - iKmin) + 1.0)/RefState.L + RefState.N/RefState.L);
42
 	sumrule_factor = 1.0/((abs(iKmax - iKmin) + 1.0)/RefState.L + RefState.N/RefState.L);
57
-	//sumrule_factor = 1.0/((pow(twoPI * iKmax/RefState.L, 2.0) - Chem_Pot + 4.0 * RefState.c_int * RefState.N/RefState.L)/RefState.L);
58
       // For the one-body function, it's just the density:
43
       // For the one-body function, it's just the density:
59
       else if (whichDSF == 'o') sumrule_factor = RefState.L/RefState.N;
44
       else if (whichDSF == 'o') sumrule_factor = RefState.L/RefState.N;
60
       else if (whichDSF == 'q') sumrule_factor = 1.0;
45
       else if (whichDSF == 'q') sumrule_factor = 1.0;
63
       else ABACUSerror("whichDSF option not consistent in Sumrule_Factor");
48
       else ABACUSerror("whichDSF option not consistent in Sumrule_Factor");
64
     }
49
     }
65
 
50
 
66
-    //else if (fixed_iK) {
67
     else if (iKmin == iKmax) {
51
     else if (iKmin == iKmax) {
68
       if (whichDSF == 'Z') sumrule_factor = 1.0;
52
       if (whichDSF == 'Z') sumrule_factor = 1.0;
69
       else if (whichDSF == 'd' || whichDSF == '1')
53
       else if (whichDSF == 'd' || whichDSF == '1')
70
-	//// We sum up omega * MEsq/(iK^2):  this should give (1/L) x (N/L) x k^2 = N x (2\pi)^2/L^4
71
-	//sumrule_factor = pow(RefState.L, 4.0)/(4.0 * PI * PI * RefState.N);
72
 	// We sum up omega * MEsq
54
 	// We sum up omega * MEsq
73
-	//sumrule_factor = pow(RefState.L, 4.0)/(4.0 * PI * PI * iKneeded * iKneeded * RefState.N);
74
 	sumrule_factor = pow(RefState.L, 4.0)/(4.0 * PI * PI * iKmax * iKmax * RefState.N);
55
 	sumrule_factor = pow(RefState.L, 4.0)/(4.0 * PI * PI * iKmax * iKmax * RefState.N);
75
       else if (whichDSF == 'g' || whichDSF == 'o') {
56
       else if (whichDSF == 'g' || whichDSF == 'o') {
76
 	// We sum up omega * MEsq
57
 	// We sum up omega * MEsq
77
-	//sumrule_factor = 1.0/((pow(twoPI * iKneeded/RefState.L, 2.0) - Chem_Pot + 4.0 * RefState.c_int * RefState.N/RefState.L)/RefState.L);
78
-	sumrule_factor = 1.0/((pow(twoPI * iKmax/RefState.L, 2.0) - Chem_Pot + 4.0 * RefState.c_int * RefState.N/RefState.L)/RefState.L);
58
+	sumrule_factor = 1.0/((pow(twoPI * iKmax/RefState.L, 2.0) - Chem_Pot
59
+			       + 4.0 * RefState.c_int * RefState.N/RefState.L)/RefState.L);
79
       }
60
       }
80
-      //else if (whichDSF == 'o') sumrule_factor = RefState.L/RefState.N;
81
       else if (whichDSF == 'q') sumrule_factor = 1.0;
61
       else if (whichDSF == 'q') sumrule_factor = 1.0;
82
       else if (whichDSF == 'B') sumrule_factor = 1.0;
62
       else if (whichDSF == 'B') sumrule_factor = 1.0;
83
       else if (whichDSF == 'C') sumrule_factor = 1.0;
63
       else if (whichDSF == 'C') sumrule_factor = 1.0;
87
     return(sumrule_factor);
67
     return(sumrule_factor);
88
   }
68
   }
89
 
69
 
90
-  void Evaluate_F_Sumrule (char whichDSF, const LiebLin_Bethe_State& RefState, DP Chem_Pot, int iKmin, int iKmax, const char* RAW_Cstr, const char* FSR_Cstr)
70
+  void Evaluate_F_Sumrule (char whichDSF, const LiebLin_Bethe_State& RefState, DP Chem_Pot,
71
+			   int iKmin, int iKmax, const char* RAW_Cstr, const char* FSR_Cstr)
91
   {
72
   {
92
 
73
 
93
     ifstream infile;
74
     ifstream infile;
98
     }
79
     }
99
 
80
 
100
     // We run through the data file to check the f sumrule at each positive momenta:
81
     // We run through the data file to check the f sumrule at each positive momenta:
101
-    //int iK_UL = RefState.Tableau[0].Ncols;  // this is iK_UL
102
-    //Vect<DP> Sum_omega_MEsq(0.0, iK_UL + 1);
103
     Vect_DP Sum_omega_MEsq (0.0, iKmax - iKmin + 1);
82
     Vect_DP Sum_omega_MEsq (0.0, iKmax - iKmin + 1);
104
     Vect_DP Sum_abs_omega_MEsq (0.0, iKmax - iKmin + 1);
83
     Vect_DP Sum_abs_omega_MEsq (0.0, iKmax - iKmin + 1);
105
 
84
 
107
 
86
 
108
     DP omega, ME;
87
     DP omega, ME;
109
     int iK;
88
     int iK;
110
-    //int conv;
111
     DP dev;
89
     DP dev;
112
     string label;
90
     string label;
113
     int nr, nl;
91
     int nr, nl;
118
       nraw++;
96
       nraw++;
119
       infile >> omega >> iK >> ME >> dev >> label;
97
       infile >> omega >> iK >> ME >> dev >> label;
120
       if (whichDSF == '1') infile >> nr >> nl;
98
       if (whichDSF == '1') infile >> nr >> nl;
121
-      //if (iK > 0 && iK <= iK_UL) Sum_omega_MEsq[iK] += omega * MEsq;
122
       if (iK >= iKmin && iK <= iKmax) Sum_omega_MEsq[iK - iKmin] += omega * ME * ME;
99
       if (iK >= iKmin && iK <= iKmax) Sum_omega_MEsq[iK - iKmin] += omega * ME * ME;
123
       if (iK >= iKmin && iK <= iKmax) Sum_abs_omega_MEsq[iK - iKmin] += fabs(omega * ME * ME);
100
       if (iK >= iKmin && iK <= iKmax) Sum_abs_omega_MEsq[iK - iKmin] += fabs(omega * ME * ME);
124
       Sum_MEsq += ME * ME;
101
       Sum_MEsq += ME * ME;
126
 
103
 
127
     infile.close();
104
     infile.close();
128
 
105
 
129
-    //cout << "Read " << nraw << " entries in raw file." << endl;
130
-
131
     ofstream outfile;
106
     ofstream outfile;
132
     outfile.open(FSR_Cstr);
107
     outfile.open(FSR_Cstr);
133
     outfile.precision(16);
108
     outfile.precision(16);
134
 
109
 
135
     if (whichDSF == 'd' || whichDSF == '1') {
110
     if (whichDSF == 'd' || whichDSF == '1') {
136
-      /*
137
-      outfile << 0 << "\t" << 1;  // full saturation at k = 0 !
138
-      for (int i = 1; i <= iK_UL; ++i)
139
-	outfile << endl << i << "\t" << Sum_omega_MEsq[i] * RefState.L * RefState.L
140
-	  * RefState.L * RefState.L/(4.0 * PI * PI * i * i * RefState.N);
141
-	  */
142
 
111
 
143
       for (int i = iKmin; i <= iKmax; ++i) {
112
       for (int i = iKmin; i <= iKmax; ++i) {
144
 
113
 
145
 	if (i > iKmin) outfile << endl;
114
 	if (i > iKmin) outfile << endl;
146
-	//outfile << i << "\t" << Sum_omega_MEsq[i - iKmin] * pow(RefState.L, 4.0)/(pow(2.0 * PI * ABACUS::max(abs(i), 1), 2.0) * RefState.N);
147
-	outfile << i << "\t" << Sum_omega_MEsq[i - iKmin] * pow(RefState.L, 4.0)/(pow(2.0 * PI * ABACUS::max(abs(i), 1), 2.0) * RefState.N)
115
+
116
+	outfile << i << "\t" << Sum_omega_MEsq[i - iKmin] * pow(RefState.L, 4.0)
117
+	  /(pow(2.0 * PI * ABACUS::max(abs(i), 1), 2.0) * RefState.N)
148
 	  // Include average of result at +iK and -iK in a third column: iK is at index index(iK) = iK - iKmin
118
 	  // Include average of result at +iK and -iK in a third column: iK is at index index(iK) = iK - iKmin
149
 	  // so -iK is at index index(-iK) = -iK - iKmin
119
 	  // so -iK is at index index(-iK) = -iK - iKmin
150
 	  // We can only use this index if it is >= 0 and < iKmax - iKmin + 1, otherwise third column is copy of second:
120
 	  // We can only use this index if it is >= 0 and < iKmax - iKmin + 1, otherwise third column is copy of second:
155
       }
125
       }
156
     }
126
     }
157
     else if (whichDSF == 'g' || whichDSF == 'o') {
127
     else if (whichDSF == 'g' || whichDSF == 'o') {
158
-      /*
159
-      for (int i = 0; i <= iK_UL; ++i)
160
-	outfile << endl << i << "\t" << Sum_omega_MEsq[i] * RefState.L
161
-	  /((4.0 * PI * PI * i * i)/(RefState.L * RefState.L) - Chem_Pot + 4.0 * RefState.c_int * RefState.N/RefState.L);
162
-      //cout << "Sum_MEsq = " << Sum_MEsq << "\tN/L = " << RefState.N/RefState.L << endl;
163
-      */
164
       for (int i = iKmin; i <= iKmax; ++i) {
128
       for (int i = iKmin; i <= iKmax; ++i) {
165
 	if (i > iKmin) outfile << endl;
129
 	if (i > iKmin) outfile << endl;
166
-	//outfile << i << "\t" << Sum_omega_MEsq[i - iKmin] * RefState.L
167
-	///((4.0 * PI * PI * i * i)/(RefState.L * RefState.L) - Chem_Pot + 4.0 * RefState.c_int * RefState.N/RefState.L);
168
 	outfile << i << "\t" << Sum_omega_MEsq[i - iKmin] * RefState.L
130
 	outfile << i << "\t" << Sum_omega_MEsq[i - iKmin] * RefState.L
169
 	  /((4.0 * PI * PI * i * i)/(RefState.L * RefState.L) - Chem_Pot + 4.0 * RefState.c_int * RefState.N/RefState.L)
131
 	  /((4.0 * PI * PI * i * i)/(RefState.L * RefState.L) - Chem_Pot + 4.0 * RefState.c_int * RefState.N/RefState.L)
170
 		<< "\t" << ((i + iKmin <= 0 && -i < iKmax + 1) ?
132
 		<< "\t" << ((i + iKmin <= 0 && -i < iKmax + 1) ?
171
 			    0.5 * (Sum_omega_MEsq[i - iKmin] + Sum_omega_MEsq[-i - iKmin]) : Sum_omega_MEsq[i - iKmin])
133
 			    0.5 * (Sum_omega_MEsq[i - iKmin] + Sum_omega_MEsq[-i - iKmin]) : Sum_omega_MEsq[i - iKmin])
172
-			    * RefState.L/((4.0 * PI * PI * i * i)/(RefState.L * RefState.L) - Chem_Pot + 4.0 * RefState.c_int * RefState.N/RefState.L);
134
+	  * RefState.L/((4.0 * PI * PI * i * i)/(RefState.L * RefState.L) - Chem_Pot + 4.0 * RefState.c_int * RefState.N/RefState.L);
173
       }
135
       }
174
     }
136
     }
175
 
137
 
177
 
139
 
178
   }
140
   }
179
 
141
 
180
-  void Evaluate_F_Sumrule (string prefix, char whichDSF, const LiebLin_Bethe_State& RefState, DP Chem_Pot, int iKmin, int iKmax)
142
+  void Evaluate_F_Sumrule (string prefix, char whichDSF, const LiebLin_Bethe_State& RefState,
143
+			   DP Chem_Pot, int iKmin, int iKmax)
181
   {
144
   {
182
 
145
 
183
     stringstream RAW_stringstream;    string RAW_string;
146
     stringstream RAW_stringstream;    string RAW_string;
193
   }
156
   }
194
 
157
 
195
   // Using diagonal state ensemble:
158
   // Using diagonal state ensemble:
196
-  void Evaluate_F_Sumrule (char whichDSF, DP c_int, DP L, int N, DP kBT, int nstates_req, DP Chem_Pot, int iKmin, int iKmax, const char* FSR_Cstr)
159
+  void Evaluate_F_Sumrule (char whichDSF, DP c_int, DP L, int N, DP kBT, int nstates_req,
160
+			   DP Chem_Pot, int iKmin, int iKmax, const char* FSR_Cstr)
197
   {
161
   {
198
 
162
 
199
     // We run through the data file to check the f sumrule at each positive momenta:
163
     // We run through the data file to check the f sumrule at each positive momenta:
203
 
167
 
204
     DP omega, ME;
168
     DP omega, ME;
205
     int iK;
169
     int iK;
206
-    //int conv;
207
     DP dev;
170
     DP dev;
208
     string label;
171
     string label;
209
     int nr, nl;
172
     int nr, nl;
212
     LiebLin_Diagonal_State_Ensemble ensemble;
175
     LiebLin_Diagonal_State_Ensemble ensemble;
213
 
176
 
214
     stringstream ensfilestrstream;
177
     stringstream ensfilestrstream;
215
-    //ensfilestrstream << "LiebLin_c_int_" << c_int << "_L_" << L << "_N_" << N << "_kBT_" << kBT << "_ns_" << nstates_req << ".ens";
216
     ensfilestrstream << "LiebLin_c_int_" << c_int << "_L_" << L << "_N_" << N << "_kBT_" << kBT << ".ens";
178
     ensfilestrstream << "LiebLin_c_int_" << c_int << "_L_" << L << "_N_" << N << "_kBT_" << kBT << ".ens";
217
     string ensfilestr = ensfilestrstream.str();
179
     string ensfilestr = ensfilestrstream.str();
218
     const char* ensfile_Cstr = ensfilestr.c_str();
180
     const char* ensfile_Cstr = ensfilestr.c_str();
223
 
185
 
224
       // Define the raw input file name:
186
       // Define the raw input file name:
225
       stringstream filenameprefix;
187
       stringstream filenameprefix;
226
-      //Data_File_Name (filenameprefix, whichDSF, iKmin, iKmax, kBT, ensemble.state[ns], ensemble.state[ns], ensemble.state[ns].label);
227
-      Data_File_Name (filenameprefix, whichDSF, iKmin, iKmax, 0.0, ensemble.state[ns], ensemble.state[ns], ensemble.state[ns].label);
188
+      Data_File_Name (filenameprefix, whichDSF, iKmin, iKmax, 0.0, ensemble.state[ns],
189
+		      ensemble.state[ns], ensemble.state[ns].label);
228
       string prefix = filenameprefix.str();
190
       string prefix = filenameprefix.str();
229
       stringstream RAW_stringstream;    string RAW_string;
191
       stringstream RAW_stringstream;    string RAW_string;
230
       RAW_stringstream << prefix << ".raw";
192
       RAW_stringstream << prefix << ".raw";
240
       while (infile.peek() != EOF) {
202
       while (infile.peek() != EOF) {
241
 	infile >> omega >> iK >> ME >> dev >> label;
203
 	infile >> omega >> iK >> ME >> dev >> label;
242
 	if (whichDSF == '1') infile >> nr >> nl;
204
 	if (whichDSF == '1') infile >> nr >> nl;
243
-	//if (iK > 0 && iK <= iK_UL) Sum_omega_MEsq[iK] += omega * MEsq;
244
 	if (iK >= iKmin && iK <= iKmax) Sum_omega_MEsq[iK - iKmin] += ensemble.weight[ns] * omega * ME * ME;
205
 	if (iK >= iKmin && iK <= iKmax) Sum_omega_MEsq[iK - iKmin] += ensemble.weight[ns] * omega * ME * ME;
245
 	Sum_MEsq += ensemble.weight[ns] * ME * ME;
206
 	Sum_MEsq += ensemble.weight[ns] * ME * ME;
246
       }
207
       }
255
     outfile.precision(16);
216
     outfile.precision(16);
256
 
217
 
257
     if (whichDSF == 'd' || whichDSF == '1') {
218
     if (whichDSF == 'd' || whichDSF == '1') {
258
-      /*
259
-      outfile << 0 << "\t" << 1;  // full saturation at k = 0 !
260
-      for (int i = 1; i <= iK_UL; ++i)
261
-	outfile << endl << i << "\t" << Sum_omega_MEsq[i] * RefState.L * RefState.L
262
-	  * RefState.L * RefState.L/(4.0 * PI * PI * i * i * RefState.N);
263
-	  */
264
       for (int i = iKmin; i <= iKmax; ++i) {
219
       for (int i = iKmin; i <= iKmax; ++i) {
265
 	if (i > iKmin) outfile << endl;
220
 	if (i > iKmin) outfile << endl;
266
-	//outfile << i << "\t" << Sum_omega_MEsq[i - iKmin] * pow(RefState.L, 4.0)/(pow(2.0 * PI * ABACUS::max(abs(i), 1), 2.0) * RefState.N);
267
-	outfile << i << "\t" << Sum_omega_MEsq[i - iKmin] * pow(RefState.L, 4.0)/(pow(2.0 * PI * ABACUS::max(abs(i), 1), 2.0) * RefState.N)
221
+	outfile << i << "\t" << Sum_omega_MEsq[i - iKmin] * pow(RefState.L, 4.0)
222
+	  /(pow(2.0 * PI * ABACUS::max(abs(i), 1), 2.0) * RefState.N)
268
 	  // Include average of result at +iK and -iK in a third column: iK is at index index(iK) = iK - iKmin
223
 	  // Include average of result at +iK and -iK in a third column: iK is at index index(iK) = iK - iKmin
269
 	  // so -iK is at index index(-iK) = -iK - iKmin
224
 	  // so -iK is at index index(-iK) = -iK - iKmin
270
 	  // We can only use this index if it is >= 0 and < iKmax - iKmin + 1, otherwise third column is copy of second:
225
 	  // We can only use this index if it is >= 0 and < iKmax - iKmin + 1, otherwise third column is copy of second:
275
       }
230
       }
276
     }
231
     }
277
     else if (whichDSF == 'g' || whichDSF == 'o') {
232
     else if (whichDSF == 'g' || whichDSF == 'o') {
278
-      /*
279
-      for (int i = 0; i <= iK_UL; ++i)
280
-	outfile << endl << i << "\t" << Sum_omega_MEsq[i] * RefState.L
281
-	  /((4.0 * PI * PI * i * i)/(RefState.L * RefState.L) - Chem_Pot + 4.0 * RefState.c_int * RefState.N/RefState.L);
282
-      //cout << "Sum_MEsq = " << Sum_MEsq << "\tN/L = " << RefState.N/RefState.L << endl;
283
-      */
284
       for (int i = iKmin; i <= iKmax; ++i) {
233
       for (int i = iKmin; i <= iKmax; ++i) {
285
 	if (i > iKmin) outfile << endl;
234
 	if (i > iKmin) outfile << endl;
286
-	//outfile << i << "\t" << Sum_omega_MEsq[i - iKmin] * RefState.L
287
-	///((4.0 * PI * PI * i * i)/(RefState.L * RefState.L) - Chem_Pot + 4.0 * RefState.c_int * RefState.N/RefState.L);
288
 	outfile << i << "\t" << Sum_omega_MEsq[i - iKmin] * RefState.L
235
 	outfile << i << "\t" << Sum_omega_MEsq[i - iKmin] * RefState.L
289
 	  /((4.0 * PI * PI * i * i)/(RefState.L * RefState.L) - Chem_Pot + 4.0 * RefState.c_int * RefState.N/RefState.L)
236
 	  /((4.0 * PI * PI * i * i)/(RefState.L * RefState.L) - Chem_Pot + 4.0 * RefState.c_int * RefState.N/RefState.L)
290
 		<< "\t" << ((i + iKmin <= 0 && -i < iKmax + 1) ?
237
 		<< "\t" << ((i + iKmin <= 0 && -i < iKmax + 1) ?
291
-			    0.5 * (Sum_omega_MEsq[i - iKmin] + Sum_omega_MEsq[-i - iKmin]) : Sum_omega_MEsq[i - iKmin])
292
-			    * RefState.L/((4.0 * PI * PI * i * i)/(RefState.L * RefState.L) - Chem_Pot + 4.0 * RefState.c_int * RefState.N/RefState.L);
238
+			    0.5 * (Sum_omega_MEsq[i - iKmin] + Sum_omega_MEsq[-i - iKmin])
239
+			    : Sum_omega_MEsq[i - iKmin]) * RefState.L
240
+	  /((4.0 * PI * PI * i * i)/(RefState.L * RefState.L) - Chem_Pot + 4.0 * RefState.c_int * RefState.N/RefState.L);
293
       }
241
       }
294
     }
242
     }
295
 
243
 

+ 5
- 389
src/LIEBLIN/LiebLin_Tgt0.cc View File

20
 namespace ABACUS {
20
 namespace ABACUS {
21
 
21
 
22
 
22
 
23
-  /*
24
-  DP Entropy (LiebLin_Bethe_State& RefState, DP epsilon)
25
-  {
26
-    // This function calculates the entropy of a finite Lieb-Liniger state,
27
-    // using the quantum number space particle and hole densities.
28
-
29
-    // The densities are a sum of Gaussians with width epsilon.
30
-
31
-    // We calculate \rho (x) and \rho_h (x) for x_j on a fine lattice.
32
-
33
-    int Ix2max = RefState.Ix2.max();
34
-    int Ix2min = RefState.Ix2.min();
35
-
36
-    //cout << Ix2max << "\t" << Ix2min << endl;
37
-
38
-    // Give a bit of room for leftmost and rightmost particles Gaussians to attain asymptotic values:
39
-    Ix2max += int(10.0 * RefState.L * epsilon);
40
-    Ix2min -= int(10.0 * RefState.L * epsilon);
41
-
42
-    //cout << Ix2max << "\t" << Ix2min << endl;
43
-
44
-    DP xmax = Ix2max/(2.0* RefState.L);
45
-    DP xmin = Ix2min/(2.0* RefState.L);
46
-
47
-    //xmax += 10.0* epsilon;
48
-    //xmin -= 10.0* epsilon;
49
-
50
-    DP dx = 0.1/RefState.L;
51
-    int Nptsx = int((xmax - xmin)/dx);
52
-
53
-    Vect<bool> occupied (false, (Ix2max - Ix2min)/2 + 1); // whether there is a particle or not
54
-    for (int i = 0; i < RefState.N; ++i) occupied[(RefState.Ix2[i] - Ix2min)/2] = true;
55
-
56
-    Vect<double> rho(0.0, Nptsx);
57
-    Vect<double> rhoh(0.0, Nptsx);
58
-
59
-    //cout << xmin << "\t" << xmax << "\t" << dx << "\t" << Nptsx << endl;
60
-
61
-    DP x;
62
-    DP epsilonsq = epsilon * epsilon;
63
-    DP twoepsilonsq = 2.0 * epsilon * epsilon;
64
-
65
-    //Vect<DP> xparticle(RefState.N);
66
-    //for (int i = 0; i < RefState.N; ++i) xparticle[i] = RefState.Ix2[i]/(2.0* RefState.L);
67
-    Vect<DP> xarray((Ix2max - Ix2min)/2 + 1);
68
-    for (int i = 0; i < (Ix2max - Ix2min)/2 + 1; ++i) xarray[i] = (0.5*Ix2min + i)/RefState.L;
69
-
70
-    for (int ix = 0; ix < Nptsx; ++ix) {
71
-      x = xmin + dx * (ix + 0.5);
72
-      //for (int i = 0; i < RefState.N; ++i) rho[ix] += 1.0/((x - xparticle[i]) * (x - xparticle[i]) + epsilonsq);
73
-      //rho[ix] *= epsilon/(PI * RefState.L);
74
-      for (int i = 0; i < (Ix2max - Ix2min)/2 + 1; ++i) {
75
-	// Using Gaussians:
76
-	//if (occupied[i]) rho[ix] += exp(-(x - xarray[i]) * (x - xarray[i])/twoepsilonsq);
77
-	//else rhoh[ix] += exp(-(x - xarray[i]) * (x - xarray[i])/twoepsilonsq);
78
-	// Using Lorentzians:
79
-	if (occupied[i]) rho[ix] += 1.0/((x - xarray[i]) * (x - xarray[i]) + epsilonsq);
80
-	else rhoh[ix] += 1.0/((x - xarray[i]) * (x - xarray[i]) + epsilonsq);
81
-      }
82
-      //rho[ix] /= sqrt(twoPI) * epsilon * RefState.L;
83
-      //rhoh[ix] /= sqrt(twoPI) * epsilon * RefState.L;
84
-      rho[ix] *= epsilon/(PI * RefState.L);
85
-      rhoh[ix] *= epsilon/(PI * RefState.L);
86
-      //cout << ix << " x = " << x << "\trho = " << rho[ix] << "\trhoh = " << rhoh[ix] << "\trho + rhoh = " << rho[ix] + rhoh[ix] << endl;
87
-    }
88
-
89
-    // Now calculate the entropy:
90
-    complex<DP> entropy = 0.0;
91
-    DP Deltax = log(RefState.L)/RefState.L;
92
-    for (int ix = 0; ix < Nptsx; ++ix)
93
-      //entropy -= ln_Gamma (1.0 + rho[ix]) + ln_Gamma (2.0 - rho[ix]); // This is ln (\rho_tot choose \rho) with \rho_tot = 1.
94
-      entropy += ln_Gamma (RefState.L * (rho[ix] + rhoh[ix]) * Deltax + 1.0) - ln_Gamma(RefState.L * rho[ix] * Deltax + 1.0) - ln_Gamma (RefState.L * rhoh[ix] * Deltax + 1.0); // This is ln (\rho_tot choose \rho) with \rho_tot = 1.
95
-    entropy *= dx/Deltax;
96
-
97
-    //cout << "Entropy found " << entropy << "\t" << real(entropy) << endl;
98
-
99
-    return(real(entropy));
100
-  }
101
-  */
102
-
103
-  /*
104
-  DP Entropy_rho (LiebLin_Bethe_State& RefState, int Delta)
105
-  {
106
-    // This function calculates the discrete entropy of a finite Lieb-Liniger state,
107
-    // counting the possible permutations within windows of fixed width.
108
-
109
-    // We assume that the quantum numbers are ordered.
110
-
111
-    // Calculate a density \rho_\Delta (x) for x_j on the lattice:
112
-
113
-    int iK_UL = ABACUS::max(RefState.Ix2[0], RefState.Ix2[RefState.N - 1]);
114
-
115
-    Vect<double> rhoD(0.0, 2* iK_UL);
116
-
117
-    int fourDeltasq = 4 * Delta * Delta;
118
-    for (int ix = 0; ix < 2* iK_UL; ++ix) {
119
-      // x = (-iK_UL + 1/2 + ix)/L
120
-      for (int i = 0; i < RefState.N; ++i) rhoD[ix] += 1.0/((-2*iK_UL + 1 + 2*ix -RefState.Ix2[i]) * (-2*iK_UL + 1 + 2*ix -RefState.Ix2[i]) + fourDeltasq);
121
-      rhoD[ix] *= 4.0 * Delta/PI;
122
-      //cout << "x = " << (-iK_UL + 1/2 + ix)/RefState.L << "\trhoD = " << rhoD[ix] << endl;
123
-    }
124
-
125
-    // Now calculate the entropy:
126
-    DP entropy = 0.0;
127
-    for (int ix = 0; ix < 2* iK_UL; ++ix)
128
-      entropy -= rhoD[ix] * log(rhoD[ix]) + (1.0 - rhoD[ix]) * log(1.0 - rhoD[ix]);
129
-
130
-    return(entropy);
131
-  }
132
-  */
133
 
23
 
134
   DP Entropy_Fixed_Delta (LiebLin_Bethe_State& RefState, int Delta)
24
   DP Entropy_Fixed_Delta (LiebLin_Bethe_State& RefState, int Delta)
135
   {
25
   {
139
     // We assume that the quantum numbers are ordered.
29
     // We assume that the quantum numbers are ordered.
140
 
30
 
141
     // Fill in vector of occupancies:
31
     // Fill in vector of occupancies:
142
-    int nrIs = (RefState.Ix2[RefState.N-1] - RefState.Ix2[0])/2 + 1 + 2*Delta; // assume Ix2 are ordered, leave space of Delta on both sides
32
+    // assume Ix2 are ordered, leave space of Delta on both sides
33
+    int nrIs = (RefState.Ix2[RefState.N-1] - RefState.Ix2[0])/2 + 1 + 2*Delta;
143
     Vect<int> occupancy(0, nrIs);  // leave space of Delta on both sides
34
     Vect<int> occupancy(0, nrIs);  // leave space of Delta on both sides
144
     for (int i = 0; i < RefState.N; ++i) occupancy[Delta + (RefState.Ix2[i] -RefState.Ix2[0])/2] = 1;
35
     for (int i = 0; i < RefState.N; ++i) occupancy[Delta + (RefState.Ix2[i] -RefState.Ix2[0])/2] = 1;
145
     // Check:
36
     // Check:
146
     int ncheck = 0;
37
     int ncheck = 0;
147
     for (int i = 0; i < nrIs; ++i) if(occupancy[i] == 1) ncheck++;
38
     for (int i = 0; i < nrIs; ++i) if(occupancy[i] == 1) ncheck++;
148
-    //cout << "Check occupancy: " << endl << occupancy << endl;
149
     if (ncheck != RefState.N) {
39
     if (ncheck != RefState.N) {
150
       cout << ncheck << "\t" << RefState.N << endl;
40
       cout << ncheck << "\t" << RefState.N << endl;
151
       ABACUSerror("Counting q numbers incorrectly in Entropy.");
41
       ABACUSerror("Counting q numbers incorrectly in Entropy.");
154
     // Define some useful numbers:
44
     // Define some useful numbers:
155
     Vect_DP oneoverDeltalnchoose(Delta + 1);
45
     Vect_DP oneoverDeltalnchoose(Delta + 1);
156
     for (int i = 0; i <= Delta; ++i) oneoverDeltalnchoose[i] = ln_choose(Delta, i)/Delta;
46
     for (int i = 0; i <= Delta; ++i) oneoverDeltalnchoose[i] = ln_choose(Delta, i)/Delta;
157
-    //Vect_DP oneoverDeltalnchoosecheck(Delta + 1);
158
-    //for (int i = 0; i <= Delta; ++i) oneoverDeltalnchoosecheck[i] = log(DP(choose(Delta, i)))/Delta;
159
-    //cout << oneoverDeltalnchoose << endl;
160
-    //cout << oneoverDeltalnchoosecheck << endl;
161
 
47
 
162
     // Compute entropy:
48
     // Compute entropy:
163
     DP entropy = 0.0;
49
     DP entropy = 0.0;
185
     int Delta = int(log(RefState.L));
71
     int Delta = int(log(RefState.L));
186
     return(Entropy (RefState, Delta));
72
     return(Entropy (RefState, Delta));
187
   }
73
   }
188
-  /*
189
-  DP Canonical_Free_Energy (LiebLin_Bethe_State& RefState, DP kBT, int Delta)
190
-  {
191
-    return(RefState.E - kBT * Entropy (RefState, Delta));
192
-  }
193
 
74
 
194
-  DP Canonical_Free_Energy (LiebLin_Bethe_State& RefState, DP kBT, int Delta)
195
-  {
196
-    return(RefState.E - kBT * Entropy (RefState, Delta));
197
-  }
198
-  */
199
   DP Canonical_Free_Energy (LiebLin_Bethe_State& RefState, DP kBT)
75
   DP Canonical_Free_Energy (LiebLin_Bethe_State& RefState, DP kBT)
200
   {
76
   {
201
     return(RefState.E - kBT * Entropy (RefState));
77
     return(RefState.E - kBT * Entropy (RefState));
202
   }
78
   }
203
 
79
 
204
-  /*
205
-  //LiebLin_Bethe_State Canonical_Saddle_Point_State (DP c_int, DP L, int N, DP kBT, int Delta)
206
-  LiebLin_Bethe_State Canonical_Saddle_Point_State_pre20110618 (DP c_int, DP L, int N, DP kBT, DP epsilon)
207
-  {
208
-    // This function returns the discretized state minimizing the canonical free energy
209
-    // F = E - T S.
210
-
211
-    LiebLin_Bethe_State spstate(c_int, L, N);
212
-    spstate.Compute_All (true);
213
-
214
-    if (kBT < 1.0e-3) return(spstate); // interpret as zero T case
215
-
216
-    LiebLin_Bethe_State spstateup = spstate;
217
-    LiebLin_Bethe_State spstatedown = spstate;
218
-
219
-    bool converged = false;
220
-    bool convergedati = false;
221
-
222
-    DP canfreeenstay, canfreeenup, canfreeendown;
223
-    DP Estay, Eup, Edown;
224
-    DP Sstay, Sup, Sdown;
225
-
226
-    while (!converged) {
227
-
228
-      spstate.Compute_All (false);
229
-      converged = true;  // set to false if we change anything
230
-
231
-      // If we can minimize the free energy by changing the quantum number, we do:
232
-      // NOTE:  we keep the state symmetric w/r to parity.
233
-
234
-      for (int i = 0; i < N/2; ++i) {
235
-	// Try to increase or decrease this quantum number
236
-
237
-	convergedati = false;
238
-
239
-	while (!convergedati) {
240
-
241
-	  convergedati = true; // set to false if we change anything
242
-
243
-	  Estay = spstate.E;
244
-	  //Sstay = Entropy (spstate, Delta);
245
-	  Sstay = Entropy (spstate, epsilon);
246
-	  //canfreeenstay = Canonical_Free_Energy (spstate, kBT, Delta);
247
-	  canfreeenstay = Estay - kBT * Sstay;
248
-
249
-	  spstateup = spstate;
250
-	  if (i == 0 || spstateup.Ix2[i-1] < spstateup.Ix2[i] - 2) {
251
-	    spstateup.Ix2[i] -= 2;
252
-	    spstateup.Ix2[N-1-i] += 2;
253
-	    spstateup.Compute_All(false);
254
-	    Eup = spstateup.E;
255
-	    //Sup = Entropy(spstateup, Delta);
256
-	    Sup = Entropy(spstateup, epsilon);
257
-	    //canfreeenup = Canonical_Free_Energy (spstateup, kBT, Delta);
258
-	    canfreeenup = Eup - kBT * Sup;
259
-	  }
260
-	  else canfreeenup = canfreeenstay + 1.0e-6;
261
-
262
-	  spstatedown = spstate;
263
-	  if (spstatedown.Ix2[i+1] > spstatedown.Ix2[i] + 2) {
264
-	    spstatedown.Ix2[i] += 2;
265
-	    spstatedown.Ix2[N-1-i] -= 2;
266
-	    spstatedown.Compute_All(false);
267
-	    Edown = spstatedown.E;
268
-	    //Sdown = Entropy(spstatedown, Delta);
269
-	    Sdown = Entropy(spstatedown, epsilon);
270
-	    //canfreeendown = Canonical_Free_Energy (spstatedown, kBT, Delta);
271
-	    canfreeendown = Edown - kBT * Sdown;
272
-	  }
273
-	  else canfreeendown = canfreeenstay + 1.0e-6;
274
-
275
-	  //cout << "i = " << i << "\t" << spstate.Ix2[i] << "\t\t" << canfreeenstay << "\t" << canfreeenup << "\t" << canfreeendown
276
-	  // << "\t\t" << Estay << "\t" << Eup << "\t" << Edown << "\t\t" << Sstay << "\t" << Sup << "\t" << Sdown << endl;
277
-	  // Choose what to do:
278
-	  if (canfreeenup < canfreeenstay && canfreeendown < canfreeenstay)
279
-	    cout << canfreeenstay << "\t" << canfreeenup << "\t" << canfreeendown << "\tWarning:  unclear option for minimization." << endl;
280
-	  else if (canfreeenup < canfreeenstay) {
281
-	    spstate = spstateup;
282
-	    convergedati = false;
283
-	    converged = false;
284
-	  }
285
-	  else if (canfreeendown < canfreeenstay) {
286
-	    spstate = spstatedown;
287
-	    convergedati = false;
288
-	    converged = false;
289
-	  }
290
-	  // else do nothing.
291
-	} // while !convergedati
292
-
293
-      } // for i
294
-    } // while (!converged)
295
-
296
-    return(spstate);
297
-  }
298
-  */
299
-
300
-  /* REMOVED FROM ++G_3 ONWARDS
301
-  //LiebLin_Bethe_State Canonical_Saddle_Point_State (DP c_int, DP L, int N, DP kBT, int Delta)
302
-  //LiebLin_Bethe_State Canonical_Saddle_Point_State (DP c_int, DP L, int N, DP kBT, DP epsilon)
303
-  LiebLin_Bethe_State Canonical_Saddle_Point_State_pre8 (DP c_int, DP L, int N, DP kBT)
304
-  {
305
-    // This function returns the discretized state minimizing the canonical free energy
306
-    // F = E - T S.
307
-
308
-    // Improvement on version pre20110618: allow for pairwise `in' and `out' movements
309
-    // keeping the energy the same to order 1/L^2 but changing the entropy.
310
-
311
-    // The regulator Delta also has become an `internal' parameter.
312
-
313
-    LiebLin_Bethe_State spstate(c_int, L, N);
314
-    spstate.Compute_All (true);
315
-
316
-    if (kBT < 1.0e-3) return(spstate); // interpret as zero T case
317
-
318
-    LiebLin_Bethe_State spstateup = spstate;
319
-    LiebLin_Bethe_State spstatedown = spstate;
320
-    LiebLin_Bethe_State spstatein = spstate;
321
-    LiebLin_Bethe_State spstateout = spstate;
322
-
323
-    bool converged = false;
324
-    bool convergedati = false;
325
-
326
-    DP canfreeenstay, canfreeenup, canfreeendown, canfreeenin, canfreeenout;
327
-    DP Estay, Eup, Edown, Ein, Eout;
328
-    DP Sstay, Sup, Sdown, Sin, Sout;
329
-    Estay = 0.0; Eup = 0.0; Edown = 0.0; Ein = 0.0; Eout = 0.0;
330
-    Sstay = 0.0; Sup = 0.0; Sdown = 0.0; Sin = 0.0; Sout = 0.0;
331
-
332
-    while (!converged) {
333
-
334
-      spstate.Compute_All (false);
335
-      converged = true;  // set to false if we change anything
336
-
337
-      // If we can minimize the free energy by changing the quantum number, we do:
338
-      // NOTE:  we keep the state symmetric w/r to parity.
339
-
340
-      for (int i = 0; i < N/2 - 1; ++i) {
341
-
342
-	// Try to increase or decrease the quantum numbers at i ,
343
-	// or do an (approximately) energy-preserving move with i+1 (and parity pairs)
344
-	// giving 5 possible options: stay same, (\pm 1, 0), (+1, -1), (-1, +1)
345
-
346
-	convergedati = false;
347
-
348
-	while (!convergedati) {
349
-
350
-	  convergedati = true; // set to false if we change anything
351
-
352
-	  Estay = spstate.E;
353
-	  Sstay = Entropy (spstate);
354
-	  //Sstay = Entropy (spstate, Delta);
355
-	  //Sstay = Entropy (spstate, epsilon);
356
-	  //canfreeenstay = Canonical_Free_Energy (spstate, kBT, Delta);
357
-	  canfreeenstay = Estay - kBT * Sstay;
358
-
359
-	  spstateup = spstate;
360
-	  if (i == 0 || spstateup.Ix2[i-1] < spstateup.Ix2[i] - 2) {
361
-	    spstateup.Ix2[i] -= 2;
362
-	    spstateup.Ix2[N-1-i] += 2;
363
-	    spstateup.Compute_All(false);
364
-	    Eup = spstateup.E;
365
-	    Sup = Entropy(spstateup);
366
-	    //Sup = Entropy(spstateup, Delta);
367
-	    //Sup = Entropy(spstateup, epsilon);
368
-	    //canfreeenup = Canonical_Free_Energy (spstateup, kBT, Delta);
369
-	    canfreeenup = Eup - kBT * Sup;
370
-	  }
371
-	  else canfreeenup = canfreeenstay + 1.0e-6;
372
-
373
-	  spstatedown = spstate;
374
-	  if (spstatedown.Ix2[i+1] > spstatedown.Ix2[i] + 2) {
375
-	    spstatedown.Ix2[i] += 2;
376
-	    spstatedown.Ix2[N-1-i] -= 2;
377
-	    spstatedown.Compute_All(false);
378
-	    Edown = spstatedown.E;
379
-	    Sdown = Entropy(spstatedown);
380
-	    //Sdown = Entropy(spstatedown, Delta);
381
-	    //Sdown = Entropy(spstatedown, epsilon);
382
-	    //canfreeendown = Canonical_Free_Energy (spstatedown, kBT, Delta);
383
-	    canfreeendown = Edown - kBT * Sdown;
384
-	  }
385
-	  else canfreeendown = canfreeenstay + 1.0e-6;
386
-
387
-	  spstatein = spstate;
388
-	  if (spstatein.Ix2[i+1] > spstatein.Ix2[i] + 4) { // can move them closer
389
-	    spstatein.Ix2[i] += 2;
390
-	    spstatein.Ix2[i+1] -= 2;
391
-	    spstatein.Ix2[N-1-i] -= 2;
392
-	    spstatein.Ix2[N-1-i-1] += 2;
393
-	    spstatein.Compute_All(false);
394
-	    Ein = spstatein.E;
395
-	    Sin = Entropy(spstatein);
396
-	    //Sin = Entropy(spstatein, Delta);
397
-	    //Sin = Entropy(spstatein, epsilon);
398
-	    //canfreeenin = Canonical_Free_Energy (spstatein, kBT, Delta);
399
-	    canfreeenin = Ein - kBT * Sin;
400
-	  }
401
-	  else canfreeenin = canfreeenstay + 1.0e-6;
402
-
403
-	  spstateout = spstate;
404
-	  if (i == 0 && spstateout.Ix2[1] + 2 < spstateout.Ix2[2]
405
-	      || (i < N/2 - 1 && spstateout.Ix2[i] - 2 > spstateout.Ix2[i-1]
406
-		  && spstateout.Ix2[i+1] + 2 < spstateout.Ix2[i+2])) { // can move them further apart
407
-	    spstateout.Ix2[i] -= 2;
408
-	    spstateout.Ix2[i+1] += 2;
409
-	    spstateout.Ix2[N-1-i] += 2;
410
-	    spstateout.Ix2[N-1-i-1] -= 2;
411
-	    spstateout.Compute_All(false);
412
-	    Eout = spstateout.E;
413
-	    Sout = Entropy(spstateout);
414
-	    //Sout = Entropy(spstateout, Delta);
415
-	    //Sout = Entropy(spstateout, epsilon);
416
-	    //canfreeenout = Canonical_Free_Energy (spstateout, kBT, Delta);
417
-	    canfreeenout = Eout - kBT * Sout;
418
-	  }
419
-	  else canfreeenout = canfreeenstay + 1.0e-6;
420
-
421
-	  //cout << setprecision(8) << "i = " << i << "\t" << spstate.Ix2[i] << "\t" << spstate.Ix2[i+1] << "\t\t" << canfreeenstay << "\t" << canfreeenup << "\t" << canfreeendown << "\t" << canfreeenin << "\t" << canfreeenout << endl;
422
-	  //cout << "\t\tE: " << Estay << "\t" << Eup << "\t" << Edown << "\t" << Ein << "\t" << Eout << endl;
423
-	  //cout << "\t\tS: " << Sstay << "\t" << Sup << "\t" << Sdown << "\t" << Sin << "\t" << Sout << endl;
424
-
425
-	  // Choose what to do: find minimum,
426
-	  if (canfreeenstay < canfreeenup && canfreeenstay < canfreeendown && canfreeenstay < canfreeenin && canfreeenstay < canfreeenout) {
427
-	    // do nothing, convergetati is already true
428
-	  }
429
-	  else if (canfreeenup < canfreeenstay && canfreeenup < canfreeendown && canfreeenup < canfreeenin && canfreeenup < canfreeenout) {
430
-	    spstate = spstateup;
431
-	    convergedati = false;
432
-	    converged = false;
433
-	  }
434
-	  else if (canfreeendown < canfreeenstay && canfreeendown < canfreeenup && canfreeendown < canfreeenin && canfreeendown < canfreeenout) {
435
-	    spstate = spstatedown;
436
-	    convergedati = false;
437
-	    converged = false;
438
-	  }
439
-	  else if (canfreeenin < canfreeenstay && canfreeenin < canfreeenup && canfreeenin < canfreeendown && canfreeenin < canfreeenout) {
440
-	    spstate = spstatein;
441
-	    convergedati = false;
442
-	    converged = false;
443
-	  }
444
-	  else if (canfreeenout < canfreeenstay && canfreeenout < canfreeenup && canfreeenout < canfreeendown && canfreeenout < canfreeenin) {
445
-	    spstate = spstateout;
446
-	    convergedati = false;
447
-	    converged = false;
448
-	  }
449
-	  else cout << canfreeenstay << "\t" << canfreeenup << "\t" << canfreeendown << "\t" << canfreeenin << "\t" << canfreeenout << "\tWarning:  unclear option for minimization." << endl;
450
-
451
-	  // else do nothing.
452
-	} // while !convergedati
453
-
454
-      } // for i
455
-    } // while (!converged)
456
-
457
-    //cout << "Number of holes between I's: " << endl;
458
-    //for (int i = 0; i < N/2; ++i) cout << (spstate.Ix2[i+1] - spstate.Ix2[i])/2 - 1 << "\t";
459
-    //cout << endl;
460
-
461
-    return(spstate);
462
-  }
463
-  */
464
-
465
   DP rho_of_lambdaoc_1 (LiebLin_Bethe_State& RefState, DP lambdaoc, DP delta)
80
   DP rho_of_lambdaoc_1 (LiebLin_Bethe_State& RefState, DP lambdaoc, DP delta)
466
   {
81
   {
467
     DP answer = 0.0;
82
     DP answer = 0.0;
468
     for (int i = 0; i < RefState.N; ++i)
83
     for (int i = 0; i < RefState.N; ++i)
469
-      answer += atan((lambdaoc - RefState.lambdaoc[i])/delta + 0.5) - atan((lambdaoc - RefState.lambdaoc[i])/delta - 0.5);
84
+      answer += atan((lambdaoc - RefState.lambdaoc[i])/delta + 0.5)
85
+	- atan((lambdaoc - RefState.lambdaoc[i])/delta - 0.5);
470
     answer *= 1.0/(PI * delta * RefState.L);
86
     answer *= 1.0/(PI * delta * RefState.L);
471
 
87
 
472
     return(answer);
88
     return(answer);
477
     DP answer = 0.0;
93
     DP answer = 0.0;
478
     for (int i = 0; i < RefState.N; ++i)
94
     for (int i = 0; i < RefState.N; ++i)
479
       answer += 1.0/(pow(lambdaoc - RefState.lambdaoc[i], 2.0) + delta*delta);
95
       answer += 1.0/(pow(lambdaoc - RefState.lambdaoc[i], 2.0) + delta*delta);
480
-      answer *= delta/(PI * RefState.L);
96
+    answer *= delta/(PI * RefState.L);
481
 
97
 
482
     return(answer);
98
     return(answer);
483
   }
99
   }

+ 6
- 12
src/LIEBLIN/LiebLin_Twisted_ln_Overlap.cc View File

51
     return(1.0/Fn_V (j, -sign, lstate_lambdaoc, rstate));
51
     return(1.0/Fn_V (j, -sign, lstate_lambdaoc, rstate));
52
   }
52
   }
53
 
53
 
54
-  complex<DP> LiebLin_Twisted_ln_Overlap (DP expbeta, Vect<DP> lstate_lambdaoc, DP lstate_lnnorm, LiebLin_Bethe_State& rstate)
54
+  complex<DP> LiebLin_Twisted_ln_Overlap (DP expbeta, Vect<DP> lstate_lambdaoc,
55
+					  DP lstate_lnnorm, LiebLin_Bethe_State& rstate)
55
   {
56
   {
56
     Vect<complex<DP> > lstate_lambdaoc_CX(lstate_lambdaoc.size());
57
     Vect<complex<DP> > lstate_lambdaoc_CX(lstate_lambdaoc.size());
57
     for (int i = 0; i < lstate_lambdaoc.size(); ++i) lstate_lambdaoc_CX[i] = complex<DP>(lstate_lambdaoc[i]);
58
     for (int i = 0; i < lstate_lambdaoc.size(); ++i) lstate_lambdaoc_CX[i] = complex<DP>(lstate_lambdaoc[i]);
58
     return(LiebLin_Twisted_ln_Overlap (complex<DP>(expbeta), lstate_lambdaoc_CX, lstate_lnnorm, rstate));
59
     return(LiebLin_Twisted_ln_Overlap (complex<DP>(expbeta), lstate_lambdaoc_CX, lstate_lnnorm, rstate));
59
   }
60
   }
60
 
61
 
61
-  complex<DP> LiebLin_Twisted_ln_Overlap (complex<DP> expbeta, Vect<complex<DP> > lstate_lambdaoc, DP lstate_lnnorm, LiebLin_Bethe_State& rstate)
62
+  complex<DP> LiebLin_Twisted_ln_Overlap (complex<DP> expbeta, Vect<complex<DP> > lstate_lambdaoc,
63
+					  DP lstate_lnnorm, LiebLin_Bethe_State& rstate)
62
   {
64
   {
63
     // Computes the log of the overlap between the left state and the Bethe rstate
65
     // Computes the log of the overlap between the left state and the Bethe rstate
64
 
66
 
81
       Fn_Prod[a] = 1.0;
83
       Fn_Prod[a] = 1.0;
82
       for (int m = 0; m < rstate.N; ++m)
84
       for (int m = 0; m < rstate.N; ++m)
83
 	if (m != a) Fn_Prod[a] *= (lstate_lambdaoc[m] - rstate.lambdaoc[a])/(rstate.lambdaoc[m] - rstate.lambdaoc[a]);
85
 	if (m != a) Fn_Prod[a] *= (lstate_lambdaoc[m] - rstate.lambdaoc[a])/(rstate.lambdaoc[m] - rstate.lambdaoc[a]);
84
-      //rKern[a] = rstate.Kernel (a, p);
85
       rKern[a] = Kernel_Twisted (expbeta, rstate.lambdaoc[p] - rstate.lambdaoc[a]);
86
       rKern[a] = Kernel_Twisted (expbeta, rstate.lambdaoc[p] - rstate.lambdaoc[a]);
86
     }
87
     }
87
 
88
 
88
     for (int a = 0; a < rstate.N; ++a)
89
     for (int a = 0; a < rstate.N; ++a)
89
       for (int b = 0; b < rstate.N; ++b)
90
       for (int b = 0; b < rstate.N; ++b)
90
-	one_plus_U[a][b] = (a == b ? 1.0 : 0.0) + ((lstate_lambdaoc[a] - rstate.lambdaoc[a])/(1.0/Vplus_Nikita[a] - 1.0/Vminus_Nikita[a]))
91
+	one_plus_U[a][b] = (a == b ? 1.0 : 0.0)
92
+	  + ((lstate_lambdaoc[a] - rstate.lambdaoc[a])/(1.0/Vplus_Nikita[a] - 1.0/Vminus_Nikita[a]))
91
 	  * Fn_Prod[a] * (Kernel_Twisted(expbeta, rstate.lambdaoc[a] - rstate.lambdaoc[b]) - rKern[b]);
93
 	  * Fn_Prod[a] * (Kernel_Twisted(expbeta, rstate.lambdaoc[a] - rstate.lambdaoc[b]) - rKern[b]);
92
 
94
 
93
     complex<DP> ln_ddalpha_sigma = lndet_LU_CX_dstry(one_plus_U);
95
     complex<DP> ln_ddalpha_sigma = lndet_LU_CX_dstry(one_plus_U);
101
       for (int b = 0; b < rstate.N; ++b)
103
       for (int b = 0; b < rstate.N; ++b)
102
 	ln_prod_2 += log((lstate_lambdaoc[a] - rstate.lambdaoc[b] - II)/(rstate.lambdaoc[a] - lstate_lambdaoc[b]));
104
 	ln_prod_2 += log((lstate_lambdaoc[a] - rstate.lambdaoc[b] - II)/(rstate.lambdaoc[a] - lstate_lambdaoc[b]));
103
 
105
 
104
-    //cout << endl << ln_ddalpha_sigma << "\t" << ln_prod_V << "\t" << ln_prod_2 << "\t" << - log(2.0 * II * imag(Vplus[p])) << endl;
105
-    //cout << endl << ln_ddalpha_sigma << "\t" << ln_prod_V << "\t" << ln_prod_2 << "\t" << - log(Vplus[p] - Vminus[p]) << endl;
106
-
107
     ln_ddalpha_sigma += ln_prod_V + ln_prod_2 - log(Vplus_Nikita[p] - expbeta * Vminus_Nikita[p]);
106
     ln_ddalpha_sigma += ln_prod_V + ln_prod_2 - log(Vplus_Nikita[p] - expbeta * Vminus_Nikita[p]);
108
 
107
 
109
-    //cout << "shift = " << (complex<DP>(rstate.N) * (lstate_lambdaoc[0] - rstate.lambdaoc[0])/twoPI) << "\tKout = " << Kout << "\texp(-II*Kout) = " << exp(-II * Kout)
110
-    // << "\tlog(exp(-II * Kout) - 1.0) = " << log(exp(-II * Kout) - 1.0) << endl;
111
-    //cout << ln_ddalpha_sigma << "\t" << ln_prod_V << "\t" << ln_prod_2 << "\t" << lstate_lnnorm << endl << endl;
112
-
113
-    //return (log(1.0 - expbeta) + ln_ddalpha_sigma - 0.5 * (lstate_lnnorm + rstate.lnnorm));
114
     return (log(1.0 - exp(-II * Kout)) + ln_ddalpha_sigma - 0.5 * (lstate_lnnorm + rstate.lnnorm));
108
     return (log(1.0 - exp(-II * Kout)) + ln_ddalpha_sigma - 0.5 * (lstate_lnnorm + rstate.lnnorm));
115
   }
109
   }
116
 
110
 

+ 2
- 1
src/LIEBLIN/LiebLin_Twisted_lnnorm.cc View File

35
       for (int k = 0; k < N; ++k) {
35
       for (int k = 0; k < N; ++k) {
36
 	if (j == k) {
36
 	if (j == k) {
37
 	  sum_Kernel = 0.0;
37
 	  sum_Kernel = 0.0;
38
-	  for (int kp = 0; kp < N; ++kp) if (j != kp) sum_Kernel += 2.0/((lambdaoc[j] - lambdaoc[kp]) * (lambdaoc[j] - lambdaoc[kp]) + 1.0);
38
+	  for (int kp = 0; kp < N; ++kp)
39
+	    if (j != kp) sum_Kernel += 2.0/((lambdaoc[j] - lambdaoc[kp]) * (lambdaoc[j] - lambdaoc[kp]) + 1.0);
39
 	  Gaudin[j][k] = cxL + sum_Kernel;
40
 	  Gaudin[j][k] = cxL + sum_Kernel;
40
 	}
41
 	}
41
 	else Gaudin[j][k] = - 2.0/((lambdaoc[j] - lambdaoc[k]) * (lambdaoc[j] - lambdaoc[k]) + 1.0);
42
 	else Gaudin[j][k] = - 2.0/((lambdaoc[j] - lambdaoc[k]) * (lambdaoc[j] - lambdaoc[k]) + 1.0);

+ 2
- 4
src/LIEBLIN/LiebLin_Utils.cc View File

97
     lambda.Build_Reduced_Gaudin_Matrix (  Gaudin);
97
     lambda.Build_Reduced_Gaudin_Matrix (  Gaudin);
98
     lambda.Build_Reduced_BEC_Quench_Gaudin_Matrix (Gaudin_Quench);
98
     lambda.Build_Reduced_BEC_Quench_Gaudin_Matrix (Gaudin_Quench);
99
 
99
 
100
-    //DP ln_prefactor =  N/2.0  * log(2./fabs(c_int*L)   ) + 0.5 * (N*log(N) - N + 0.5*log(2. * PI * N));
101
-
102
     DP ln_prefactor =  N/2.0  * log(2./(c_int*L)   ) + 0.5 * real(ln_Gamma(complex<double>(N+1.0)));
100
     DP ln_prefactor =  N/2.0  * log(2./(c_int*L)   ) + 0.5 * real(ln_Gamma(complex<double>(N+1.0)));
103
 
101
 
104
-    for(int i =N/2; i<N; i ++) ln_prefactor -= log(fabs(lambda.lambdaoc[i ])) + 0.5*log( 1. + 4. * lambda.lambdaoc[i ]*lambda.lambdaoc[i ]) ;
102
+    for(int i =N/2; i<N; i ++)
103
+      ln_prefactor -= log(fabs(lambda.lambdaoc[i ])) + 0.5*log( 1. + 4. * lambda.lambdaoc[i ]*lambda.lambdaoc[i ]) ;
105
 
104
 
106
-    //cout << ln_prefactor << endl;
107
     return (ln_prefactor  + real(lndet_LU_dstry(Gaudin_Quench))  - 0.5 * real(lndet_LU_dstry(Gaudin)));
105
     return (ln_prefactor  + real(lndet_LU_dstry(Gaudin_Quench))  - 0.5 * real(lndet_LU_dstry(Gaudin)));
108
   }
106
   }
109
 
107
 

+ 2
- 97
src/LIEBLIN/LiebLin_ln_Overlap.cc View File

19
 using namespace ABACUS;
19
 using namespace ABACUS;
20
 
20
 
21
 namespace ABACUS {
21
 namespace ABACUS {
22
-  /*
23
-  complex<DP> Fn_V (int j, int sign, Vect<complex<DP> >& lstate_lambdaoc, LiebLin_Bethe_State& rstate)
24
-  {
25
-    complex<DP> result_num = 1.0;
26
-    complex<DP> result_den = 1.0;
27
-
28
-    complex<DP> signcx = complex<DP>(sign);
29
-
30
-    for (int m = 0; m < rstate.N; ++m) {
31
-      result_num *= (lstate_lambdaoc[m] - rstate.lambdaoc[j] + signcx * II);
32
-      result_den *= (rstate.lambdaoc[m] - rstate.lambdaoc[j] + signcx * II);
33
-    }
34
-
35
-    return(result_num/result_den);
36
-  }
37
-  */
38
 
22
 
39
   complex<DP> LiebLin_ln_Overlap (Vect<DP> lstate_lambdaoc, DP lstate_lnnorm, LiebLin_Bethe_State& rstate)
23
   complex<DP> LiebLin_ln_Overlap (Vect<DP> lstate_lambdaoc, DP lstate_lnnorm, LiebLin_Bethe_State& rstate)
40
   {
24
   {
77
 
61
 
78
     for (int j = 0; j < rstate.N; ++j)
62
     for (int j = 0; j < rstate.N; ++j)
79
       for (int k = 0; k < rstate.N; ++k)
63
       for (int k = 0; k < rstate.N; ++k)
80
-	//Omega[j][k] = exp(-II * rstate.cxL * lstate_lambdaoc[k] + ln_prod_plus[k] - ln_prod_ll_plus[k])
81
-	//* (II/((rstate.lambdaoc[j] - lstate_lambdaoc[k])*(rstate.lambdaoc[j] - lstate_lambdaoc[k] + II)))
82
-	//- (II/((rstate.lambdaoc[j] - lstate_lambdaoc[k])*(rstate.lambdaoc[j] - lstate_lambdaoc[k] - II)))
83
-	//* exp(ln_prod_minus[k] - ln_prod_ll_plus[k]);
84
 	Omega[j][k] = exp(-II * rstate.cxL * lstate_lambdaoc[k] - ln_prod_plus[k] + ln_prod_minus[k])
64
 	Omega[j][k] = exp(-II * rstate.cxL * lstate_lambdaoc[k] - ln_prod_plus[k] + ln_prod_minus[k])
85
 	  * (II/((rstate.lambdaoc[j] - lstate_lambdaoc[k])*(rstate.lambdaoc[j] - lstate_lambdaoc[k] - II)))
65
 	  * (II/((rstate.lambdaoc[j] - lstate_lambdaoc[k])*(rstate.lambdaoc[j] - lstate_lambdaoc[k] - II)))
86
 	  - (II/((rstate.lambdaoc[j] - lstate_lambdaoc[k])*(rstate.lambdaoc[j] - lstate_lambdaoc[k] + II)));
66
 	  - (II/((rstate.lambdaoc[j] - lstate_lambdaoc[k])*(rstate.lambdaoc[j] - lstate_lambdaoc[k] + II)));
87
 
67
 
88
-
89
-    //for (int j = 0; j < rstate.N; ++j) {
90
-    //for (int k = 0; k < rstate.N; ++k)
91
-    //cout << Omega[j][k] << "\t";
92
-    //cout << endl;
93
-    //}
94
-
95
-
96
     complex<DP> lndetOmega = lndet_LU_CX_dstry(Omega);
68
     complex<DP> lndetOmega = lndet_LU_CX_dstry(Omega);
97
 
69
 
98
-    //cout << "lndetOmega = " << lndetOmega << endl;
99
-
100
     // Prefactors:
70
     // Prefactors:
101
     complex<DP> ln_prod_d_mu = II * 0.5 * rstate.cxL * rstate.lambdaoc.sum();
71
     complex<DP> ln_prod_d_mu = II * 0.5 * rstate.cxL * rstate.lambdaoc.sum();
102
     complex<DP> ln_prod_d_lambdaoc = II * 0.5 * rstate.cxL * lstate_lambdaoc.sum();
72
     complex<DP> ln_prod_d_lambdaoc = II * 0.5 * rstate.cxL * lstate_lambdaoc.sum();
107
     for (int j = 0; j < rstate.N - 1; ++j)
77
     for (int j = 0; j < rstate.N - 1; ++j)
108
       for (int k = j+1; k < rstate.N; ++k) {
78
       for (int k = j+1; k < rstate.N; ++k) {
109
 	ln_prod_mu += log(rstate.lambdaoc[k] - rstate.lambdaoc[j]);
79
 	ln_prod_mu += log(rstate.lambdaoc[k] - rstate.lambdaoc[j]);
110
-	//ln_prod_lambdaoc += log((lstate_lambdaoc[j] - lstate_lambdaoc[k] + II) * (lstate_lambdaoc[j] - lstate_lambdaoc[k] - II)/(lstate_lambdaoc[k] - lstate_lambdaoc[j]));
111
 	ln_prod_lambdaoc += log(lstate_lambdaoc[k] - lstate_lambdaoc[j]);
80
 	ln_prod_lambdaoc += log(lstate_lambdaoc[k] - lstate_lambdaoc[j]);
112
       }
81
       }
113
 
82
 
115
       for (int k = 0; k < rstate.N; ++k)
84
       for (int k = 0; k < rstate.N; ++k)
116
 	ln_prod_plusminus += log((rstate.lambdaoc[j] - lstate_lambdaoc[k] + II));
85
 	ln_prod_plusminus += log((rstate.lambdaoc[j] - lstate_lambdaoc[k] + II));
117
 
86
 
118
-    //cout << "ln_prod_mu " << ln_prod_mu << "\tln_prod_lambdaoc " << ln_prod_lambdaoc << "\tln_prod_plusminus " << ln_prod_plusminus
119
-    // << "\texp1 " << exp(-ln_prod_mu - ln_prod_lambdaoc) << "\texp2 " << exp(ln_prod_plusminus) << endl;
120
-
121
-    //if (real(ln_prod_d_mu + ln_prod_d_lambdaoc - ln_prod_mu + ln_prod_lambdaoc + lndetOmega - 0.5 * (lstate_lnnorm + rstate.lnnorm)) > 10.0) {
122
-    //cout << ln_prod_d_mu << "\t" << ln_prod_d_lambdaoc << "\t" << -ln_prod_mu << "\t" << ln_prod_lambdaoc << "\t" << lndetOmega << "\t" << -0.5 * lstate_lnnorm << "\t" << -0.5 * rstate.lnnorm << endl;      cout << ln_prod_d_mu + ln_prod_d_lambdaoc - ln_prod_mu + ln_prod_lambdaoc + lndetOmega - 0.5 * (lstate_lnnorm + rstate.lnnorm) << endl;
123
-    //ABACUSerror("Overlap exceeds 1.");
124
-    //}
125
-
126
-    //return(ln_prod_d_mu + ln_prod_d_lambdaoc - ln_prod_mu + ln_prod_lambdaoc + lndetOmega - 0.5 * (lstate_lnnorm + rstate.lnnorm));
127
-    return(ln_prod_d_mu + ln_prod_d_lambdaoc - ln_prod_mu - ln_prod_lambdaoc + ln_prod_plusminus + lndetOmega - 0.5 * (lstate_lnnorm + rstate.lnnorm));
128
-  }
129
-
130
-  /*
131
-  // Incorrect version
132
-  complex<DP> LiebLin_ln_Overlap (Vect<complex<DP> > lstate_lambdaoc, DP lstate_lnnorm, LiebLin_Bethe_State& rstate)
133
-  {
134
-    // Computes the log of the overlap between the left state and the Bethe rstate
135
-
136
-    // If momentum difference is zero but states are different, then form factor is zero:
137
-
138
-    SQMat_CX one_plus_U (0.0, rstate.N);
139
-
140
-    Vect_CX Vplus (0.0, rstate.N);  // contains V^+_j
141
-    Vect_CX Vminus (0.0, rstate.N);  // contains V^-_j
142
-    Vect_CX Fn_Prod (0.0, rstate.N);  // product_{m\neq j} (\mu_m - \lambdaoc_j)/(\lambdaoc_m - \lambdaoc_j)
143
-    //Vect_DP rKern (0.0, rstate.N);   // K(lambdaoc_j - lambdaoc_p)
144
-
145
-    //int p = 0;
146
-
147
-    complex<DP> Kout = lstate_lambdaoc.sum() - rstate.K;
148
-
149
-    for (int a = 0; a < rstate.N; ++a) {
150
-      Vplus[a] = Fn_V (a, 1, lstate_lambdaoc, rstate);
151
-      Vminus[a] = Fn_V (a, -1, lstate_lambdaoc, rstate);
152
-      Fn_Prod[a] = 1.0;
153
-      for (int m = 0; m < rstate.N; ++m)
154
-	if (m != a) Fn_Prod[a] *= (lstate_lambdaoc[m] - rstate.lambdaoc[a])/(rstate.lambdaoc[m] - rstate.lambdaoc[a]);
155
-      //rKern[a] = rstate.Kernel (a, p);
156
-    }
157
-
158
-    for (int a = 0; a < rstate.N; ++a)
159
-      for (int b = 0; b < rstate.N; ++b)
160
-	one_plus_U[a][b] = (a == b ? 1.0 : 0.0) + II * ((lstate_lambdaoc[a] - rstate.lambdaoc[a])/(Vplus[a] - Vminus[a]))
161
-	  * Fn_Prod[a] * rstate.Kernel(a,b);
162
-
163
-    complex<DP> ln_ddalpha_sigma = lndet_LU_CX_dstry(one_plus_U);
164
-
165
-    complex<DP> ln_prod_V = 0.0;
166
-    for (int a = 0; a < rstate.N; ++a) ln_prod_V += log(Vplus[a] - Vminus[a]);
167
-
168
-    complex<DP> ln_prod_2 = 0.0;
169
-    for (int a = 0; a < rstate.N; ++a)
170
-      for (int b = 0; b < rstate.N; ++b)
171
-	ln_prod_2 += log((rstate.lambdaoc[a] - rstate.lambdaoc[b] + II)/(lstate_lambdaoc[a] - rstate.lambdaoc[b]));
172
-
173
-    //cout << endl << ln_ddalpha_sigma << "\t" << ln_prod_V << "\t" << ln_prod_2 << "\t" << - log(2.0 * II * imag(Vplus[p])) << endl;
174
-    cout << endl << ln_ddalpha_sigma << "\t" << ln_prod_V << "\t" << ln_prod_2 << "\t" << 0.5 * lstate_lnnorm << "\t" << 0.5 * rstate.lnnorm << endl;//- log(Vplus[p] - Vminus[p]) << endl;
175
-
176
-    ln_ddalpha_sigma += ln_prod_V + ln_prod_2;// - log(Vplus[p] - Vminus[p]);
177
-
178
-    //cout << "shift = " << (complex<DP>(rstate.N) * (lstate_lambdaoc[0] - rstate.lambdaoc[0])/twoPI) << "\tKout = " << Kout << "\texp(-II*Kout) = " << exp(-II * Kout)
179
-    // << "\tlog(exp(-II * Kout) - 1.0) = " << log(exp(-II * Kout) - 1.0) << endl;
180
-    //cout << ln_ddalpha_sigma << "\t" << ln_prod_V << "\t" << ln_prod_2 << "\t" << - log(Vplus[p] - Vminus[p]) << "\t" << lstate_lnnorm << endl << endl;
181
-
182
-    return (ln_ddalpha_sigma - 0.5 * (lstate_lnnorm + rstate.lnnorm));
87
+    return(ln_prod_d_mu + ln_prod_d_lambdaoc - ln_prod_mu - ln_prod_lambdaoc + ln_prod_plusminus
88
+	   + lndetOmega - 0.5 * (lstate_lnnorm + rstate.lnnorm));
183
   }
89
   }
184
-  */
185
 
90
 
186
 } // namespace ABACUS
91
 } // namespace ABACUS

+ 3
- 17
src/LIEBLIN/ln_Density_ME.cc View File

21
 
21
 
22
   complex<DP> Fn_V (int j, LiebLin_Bethe_State& lstate, LiebLin_Bethe_State& rstate)
22
   complex<DP> Fn_V (int j, LiebLin_Bethe_State& lstate, LiebLin_Bethe_State& rstate)
23
   {
23
   {
24
-    //complex<DP> result_num = 1.0;
25
-    //complex<DP> result_den = 1.0;
26
     complex<DP> result = 1.0;
24
     complex<DP> result = 1.0;
27
 
25
 
28
     for (int m = 0; m < lstate.N; ++m) {
26
     for (int m = 0; m < lstate.N; ++m) {
29
-      //result_num *= (lstate.lambdaoc[m] - rstate.lambdaoc[j] + II);
30
-      //result_den *= (rstate.lambdaoc[m] - rstate.lambdaoc[j] + II);
31
       result *= (lstate.lambdaoc[m] - rstate.lambdaoc[j] + II)/(rstate.lambdaoc[m] - rstate.lambdaoc[j] + II);
27
       result *= (lstate.lambdaoc[m] - rstate.lambdaoc[j] + II)/(rstate.lambdaoc[m] - rstate.lambdaoc[j] + II);
32
     }
28
     }
33
 
29
 
34
-    //return(result_num/result_den);
35
     return(result);
30
     return(result);
36
   }
31
   }
37
 
32
 
40
     // Computes the log of the density operator \rho(x = 0) matrix element between lstate and rstate.
35
     // Computes the log of the density operator \rho(x = 0) matrix element between lstate and rstate.
41
 
36
 
42
     // If we have lstate == rstate, density matrix element = N/L:
37
     // If we have lstate == rstate, density matrix element = N/L:
43
-
44
     if (lstate.Ix2 == rstate.Ix2) return(log(lstate.N/lstate.L));
38
     if (lstate.Ix2 == rstate.Ix2) return(log(lstate.N/lstate.L));
45
 
39
 
46
     // If momentum difference is zero but states are different, then matrix element is zero:
40
     // If momentum difference is zero but states are different, then matrix element is zero:
47
-
48
     else if (lstate.iK == rstate.iK) return(-200.0);  // so exp(.) is zero
41
     else if (lstate.iK == rstate.iK) return(-200.0);  // so exp(.) is zero
49
 
42
 
50
     SQMat_DP one_plus_U (0.0, lstate.N);
43
     SQMat_DP one_plus_U (0.0, lstate.N);
51
 
44
 
52
     Vect_CX Vplus (0.0, lstate.N);  // contains V^+_j;  V^-_j is the conjugate
45
     Vect_CX Vplus (0.0, lstate.N);  // contains V^+_j;  V^-_j is the conjugate
53
-    //Vect_DP Fn_Prod (0.0, lstate.N);  // product_{m\neq j} (\mu_m - \lambdaoc_j)/(\lambdaoc_m - \lambdaoc_j)
54
-    // From ABACUS++G_3 onwards: use logs to stabilize numerical values at small c, at the cost of execution speed.
55
     Vect_CX ln_Fn_Prod (0.0, lstate.N);  // product_{m\neq j} (\mu_m - \lambdaoc_j)/(\lambdaoc_m - \lambdaoc_j)
46
     Vect_CX ln_Fn_Prod (0.0, lstate.N);  // product_{m\neq j} (\mu_m - \lambdaoc_j)/(\lambdaoc_m - \lambdaoc_j)
56
     Vect_DP rKern (0.0, lstate.N);   // K(lambdaoc_j - lambdaoc_(p == arbitrary))
47
     Vect_DP rKern (0.0, lstate.N);   // K(lambdaoc_j - lambdaoc_(p == arbitrary))
57
 
48
 
62
 
53
 
63
     for (int a = 0; a < lstate.N; ++a) {
54
     for (int a = 0; a < lstate.N; ++a) {
64
       Vplus[a] = Fn_V (a, lstate, rstate);
55
       Vplus[a] = Fn_V (a, lstate, rstate);
65
-      //Fn_Prod[a] = 1.0;
66
       ln_Fn_Prod[a] = 0.0;;
56
       ln_Fn_Prod[a] = 0.0;;
67
       for (int m = 0; m < lstate.N; ++m)
57
       for (int m = 0; m < lstate.N; ++m)
68
-	//if (m != a) Fn_Prod[a] *= (lstate.lambdaoc[m] - rstate.lambdaoc[a])/(rstate.lambdaoc[m] - rstate.lambdaoc[a]);
69
-	if (m != a) ln_Fn_Prod[a] += log(complex<DP>(lstate.lambdaoc[m] - rstate.lambdaoc[a])/(rstate.lambdaoc[m] - rstate.lambdaoc[a]));
58
+	if (m != a) ln_Fn_Prod[a] += log(complex<DP>(lstate.lambdaoc[m] - rstate.lambdaoc[a])
59
+					 /(rstate.lambdaoc[m] - rstate.lambdaoc[a]));
70
       rKern[a] = rstate.Kernel (a, p);
60
       rKern[a] = rstate.Kernel (a, p);
71
     }
61
     }
72
 
62
 
73
     for (int a = 0; a < lstate.N; ++a)
63
     for (int a = 0; a < lstate.N; ++a)
74
       for (int b = 0; b < lstate.N; ++b)
64
       for (int b = 0; b < lstate.N; ++b)
75
 	one_plus_U[a][b] = (a == b ? 1.0 : 0.0) + 0.5 * ((lstate.lambdaoc[a] - rstate.lambdaoc[a])/imag(Vplus[a]))
65
 	one_plus_U[a][b] = (a == b ? 1.0 : 0.0) + 0.5 * ((lstate.lambdaoc[a] - rstate.lambdaoc[a])/imag(Vplus[a]))
76
-	  //* Fn_Prod[a] * (rstate.Kernel(a,b) - rKern[b]);
77
-	  * real(exp(ln_Fn_Prod[a])) * (rstate.Kernel(a,b) - rKern[b]);
66
+	  * real(exp(ln_Fn_Prod[a])) * (rstate.Kernel(a,b) - rKern[b]); // BUGRISK: why real here?
78
 
67
 
79
     complex<DP> ln_ddalpha_sigma = lndet_LU_dstry(one_plus_U);
68
     complex<DP> ln_ddalpha_sigma = lndet_LU_dstry(one_plus_U);
80
 
69
 
86
       for (int b = 0; b < lstate.N; ++b)
75
       for (int b = 0; b < lstate.N; ++b)
87
 	ln_prod_2 += log((rstate.lambdaoc[a] - rstate.lambdaoc[b] + II)/(lstate.lambdaoc[a] - rstate.lambdaoc[b]));
76
 	ln_prod_2 += log((rstate.lambdaoc[a] - rstate.lambdaoc[b] + II)/(lstate.lambdaoc[a] - rstate.lambdaoc[b]));
88
 
77
 
89
-    //cout << "ln_Fn_Prod = " << ln_Fn_Prod << endl;
90
-    //cout << endl << ln_ddalpha_sigma << "\t" << ln_prod_V << "\t" << ln_prod_2 << "\t" << - log(2.0 * II * imag(Vplus[p])) << "\t" << - 0.5 * (lstate.lnnorm + rstate.lnnorm) << "\t" << ln_ddalpha_sigma + ln_prod_V + ln_prod_2 - log(2.0 * II * imag(Vplus[p])) - 0.5 * (lstate.lnnorm + rstate.lnnorm) << endl;
91
-
92
     ln_ddalpha_sigma += ln_prod_V + ln_prod_2 - log(2.0 * II * imag(Vplus[p]));
78
     ln_ddalpha_sigma += ln_prod_V + ln_prod_2 - log(2.0 * II * imag(Vplus[p]));
93
 
79
 
94
     return (log(-II * Kout) + ln_ddalpha_sigma - 0.5 * (lstate.lnnorm + rstate.lnnorm));
80
     return (log(-II * Kout) + ln_ddalpha_sigma - 0.5 * (lstate.lnnorm + rstate.lnnorm));

+ 5
- 5
src/LIEBLIN/ln_Psi_ME.cc View File

66
     complex<DP> ln_prod_lambdaocsq_plus_one = 0.0;
66
     complex<DP> ln_prod_lambdaocsq_plus_one = 0.0;
67
     for (int a = 0; a < rstate.N - 1; ++a)
67
     for (int a = 0; a < rstate.N - 1; ++a)
68
       for (int b = a; b < rstate.N; ++b)
68
       for (int b = a; b < rstate.N; ++b)
69
-	ln_prod_lambdaocsq_plus_one += log(complex<DP>((rstate.lambdaoc[a] - rstate.lambdaoc[b]) * (rstate.lambdaoc[a] - rstate.lambdaoc[b])) + 1.0);
69
+	ln_prod_lambdaocsq_plus_one += log(complex<DP>((rstate.lambdaoc[a] - rstate.lambdaoc[b])
70
+						       * (rstate.lambdaoc[a] - rstate.lambdaoc[b])) + 1.0);
70
 
71
 
71
     complex<DP> ln_prod_lambdaoca_min_mub = 0.0;
72
     complex<DP> ln_prod_lambdaoca_min_mub = 0.0;
72
     for (int a = 0; a < rstate.N; ++a)
73
     for (int a = 0; a < rstate.N; ++a)
73
       for (int b = 0; b < lstate.N; ++b)
74
       for (int b = 0; b < lstate.N; ++b)
74
 	ln_prod_lambdaoca_min_mub += log(complex<DP>(rstate.lambdaoc[a] - lstate.lambdaoc[b]));
75
 	ln_prod_lambdaoca_min_mub += log(complex<DP>(rstate.lambdaoc[a] - lstate.lambdaoc[b]));
75
 
76
 
76
-    //cout << endl << "Factors are " << ln_det_U_Psi << "\t" << ln_prod_lambdaocsq_plus_one << "\t" << ln_prod_lambdaoca_min_mub << endl;
77
-
78
-    return (ln_det_U_Psi + 0.5 * log(lstate.c_int) + ln_prod_lambdaocsq_plus_one - ln_prod_lambdaoca_min_mub - 0.5 * (lstate.lnnorm + rstate.lnnorm));
77
+    return (ln_det_U_Psi + 0.5 * log(lstate.c_int) + ln_prod_lambdaocsq_plus_one - ln_prod_lambdaoca_min_mub
78
+	    - 0.5 * (lstate.lnnorm + rstate.lnnorm));
79
   }
79
   }
80
 
80
 
81
-}
81
+} // namespace ABACUS

+ 41
- 148
src/LIEBLIN/ln_g2_ME.cc View File

20
 using namespace ABACUS;
20
 using namespace ABACUS;
21
 
21
 
22
 namespace ABACUS {
22
 namespace ABACUS {
23
-/*
24
-  complex<DP> ln_g2_ME_old_jacopo (LiebLin_Bethe_State& mu, LiebLin_Bethe_State& lambda)
25
-  {
26
-
27
-    if (mu.Ix2 == lambda.Ix2) return(-200.);
28
-
29
-    DP c_int = mu.c_int;
30
-
31
-    SQMat_CX G(lambda.N);
32
-    SQMat_CX GpB(lambda.N);
33
-    SQMat_CX B(lambda.N);
34
-
35
-    complex<DP> log_themp;
36
-    complex<DP> lnprefactor = 0.  ;
37
-
38
-    lnprefactor += 2.*log(c_int) ;
39
-
40
-    for(int j=0; j < mu.N; ++j){
41
-      for(int k=0; k < j; ++k){
42
-	lnprefactor -= log((mu.lambdaoc[j] - mu.lambdaoc[k]));
43
-	lnprefactor -= log((lambda.lambdaoc[j] - lambda.lambdaoc[k]));
44
-      }
45
-    }
46
 
23
 
24
+  complex<DP> Fn_V_g2 (int j, LiebLin_Bethe_State& lstate, LiebLin_Bethe_State& rstate)
25
+  {
26
+    complex<DP> result = 1.0;
47
 
27
 
48
-    for(int j=0; j < mu.N; ++j){
49
-      for(int k=0; k <mu.N; ++k){
50
-	lnprefactor += log(mu.lambdaoc[j] - mu.lambdaoc[k] + II);
51
-      }
52
-    }
53
-
54
-    Vect_CX VVP (0.0, mu.N);
55
-    Vect_CX VVM (0.0, mu.N);
56
-
57
-    //compute the vectors
58
-    for(int j=0; j < mu.N; ++j) {
59
-      log_themp = 0.;
60
-      for(int k=0; k < mu.N; ++k) log_themp += log(mu.lambdaoc[j] - lambda.lambdaoc[k] + II) - log(mu.lambdaoc[j] - mu.lambdaoc[k] + II);
61
-      VVP[j] = exp(log_themp);
62
-    }
63
-
64
-    for(int j=0; j < mu.N; ++j) {
65
-      log_themp = 0.;
66
-      for(int k=0; k < mu.N; ++k) log_themp += log(mu.lambdaoc[j] - lambda.lambdaoc[k] - II) - log(mu.lambdaoc[j] - mu.lambdaoc[k] - II);
67
-      VVM[j] = exp(log_themp);
68
-    }
69
-
70
-    //compute the sum of determinants
71
-    complex<DP> sum_n =0.;
72
-    for(int n=0; n < mu.N; ++n) {
73
-        // compute the matrices
74
-      for (int a = 0; a < mu.N; ++a){
75
-	for (int b = 0; b < mu.N; ++b){
76
-	  if(b == n){
77
-	    G[a][b] = 2.*II* lambda.lambdaoc[a];
78
-	  }
79
-	  else{
80
-	    G[a][b] = II*1./(lambda.lambdaoc[a] - mu.lambdaoc[b])*( VVP[b]*1.0/(mu.lambdaoc[b] - lambda.lambdaoc[a] + II)  +
81
-								VVM[b]*1.0/(mu.lambdaoc[b] - lambda.lambdaoc[a] - II)  );
82
-	  }
83
-	}
84
-      }
85
-
86
-      for (int a = 0; a < mu.N; ++a){
87
-	for (int b = 0; b < mu.N; ++b){
88
-	  if(b == n){
89
-	    B[a][b] = 0.;
90
-	  }
91
-	  else{
92
-	    B[a][b] = II*1.0/(mu.lambdaoc[b] - mu.lambdaoc[n] - II) ;
93
-	  }
94
-	}
95
-      }
96
-
97
-      for (int a = 0; a < mu.N; ++a){
98
-	for (int b = 0; b < mu.N; ++b){
99
-	  GpB[a][b] = G[a][b] + B[a][b];
100
-	}
101
-      }
102
-      //finally add
103
-      sum_n +=   exp(	lndet_LU_CX(GpB) ) -  exp(lndet_LU_CX(G) ) ;
28
+    for (int m = 0; m < lstate.N; ++m) {
29
+      result *= (lstate.lambdaoc[m] - rstate.lambdaoc[j] + II)/(rstate.lambdaoc[m] - rstate.lambdaoc[j] + II);
104
     }
30
     }
105
 
31
 
106
-    return(log(sum_n ) + lnprefactor  - 0.5 * (mu.lnnorm + lambda.lnnorm));
32
+    return(result);
107
   }
33
   }
108
-*/
109
-    complex<DP> Fn_V_g2 (int j, LiebLin_Bethe_State& lstate, LiebLin_Bethe_State& rstate)
110
-    {
111
-        //complex<DP> result_num = 1.0;
112
-        //complex<DP> result_den = 1.0;
113
-        complex<DP> result = 1.0;
114
-
115
-        for (int m = 0; m < lstate.N; ++m) {
116
-            //result_num *= (lstate.lambdaoc[m] - rstate.lambdaoc[j] + II);
117
-            //result_den *= (rstate.lambdaoc[m] - rstate.lambdaoc[j] + II);
118
-            result *= (lstate.lambdaoc[m] - rstate.lambdaoc[j] + II)/(rstate.lambdaoc[m] - rstate.lambdaoc[j] + II);
119
-        }
120
-
121
-        //return(result_num/result_den);
122
-        return(result);
123
-    }
124
-
125
-
126
-    complex<DP> ln_g2_ME (LiebLin_Bethe_State& lstate, LiebLin_Bethe_State& rstate)
127
-    {
128
-        // Computes the log of the density operator \rho(x = 0) matrix element between lstate and rstate.
129
-
130
-        // If we have lstate == rstate, density matrix element = 0:
131
-
132
-
133
-        if (lstate.Ix2 == rstate.Ix2) return(-200.);
134
-
135
-
136
 
34
 
137
 
35
 
138
-        SQMat_DP one_plus_U (0.0, lstate.N);
139
-
140
-        Vect_CX Vplus (0.0, lstate.N);  // contains V^+_j;  V^-_j is the conjugate
141
-        //Vect_DP Fn_Prod (0.0, lstate.N);  // product_{m\neq j} (\mu_m - \lambdaoc_j)/(\lambdaoc_m - \lambdaoc_j)
142
-        // From ABACUS++G_3 onwards: use logs to stabilize numerical values at small c, at the cost of execution speed.
143
-        Vect_CX ln_Fn_Prod (0.0, lstate.N);  // product_{m\neq j} (\mu_m - \lambdaoc_j)/(\lambdaoc_m - \lambdaoc_j)
144
-        Vect_DP rKern (0.0, lstate.N);   // K(lambdaoc_j - lambdaoc_(p == arbitrary))
145
-
146
-        //int p = 0;
147
-        int p = rstate.N/2-1; // choice doesn't matter, see 1990_Slavnov_TMP_82 after (3.8). Choose rapidity around the middle.
148
-
149
-
150
-        DP c_int = rstate.c_int;
36
+  complex<DP> ln_g2_ME (LiebLin_Bethe_State& lstate, LiebLin_Bethe_State& rstate)
37
+  {
38
+    // Computes the log of the density operator \rho(x = 0) matrix element between lstate and rstate.
151
 
39
 
152
-        DP Eout = log(pow(lstate.E - rstate.E,2.)) - (2)*log(c_int)  - log(2*lstate.N);
40
+    // If we have lstate == rstate, density matrix element = 0:
41
+    if (lstate.Ix2 == rstate.Ix2) return(-200.);
153
 
42
 
154
-        for (int a = 0; a < lstate.N; ++a) {
155
-            Vplus[a] = Fn_V_g2 (a, lstate, rstate);
156
-            //Fn_Prod[a] = 1.0;
157
-            ln_Fn_Prod[a] = 0.0;;
158
-            for (int m = 0; m < lstate.N; ++m)
159
-                //if (m != a) Fn_Prod[a] *= (lstate.lambdaoc[m] - rstate.lambdaoc[a])/(rstate.lambdaoc[m] - rstate.lambdaoc[a]);
160
-                if (m != a) ln_Fn_Prod[a] += log(complex<DP>(lstate.lambdaoc[m] - rstate.lambdaoc[a])/(rstate.lambdaoc[m] - rstate.lambdaoc[a]));
161
-            rKern[a] = rstate.Kernel (a, p);
162
-        }
43
+    SQMat_DP one_plus_U (0.0, lstate.N);
163
 
44
 
164
-        for (int a = 0; a < lstate.N; ++a)
165
-            for (int b = 0; b < lstate.N; ++b)
166
-                one_plus_U[a][b] = (a == b ? 1.0 : 0.0) + 0.5 * 1./imag(Vplus[a])
167
-                //* Fn_Prod[a] * (rstate.Kernel(a,b) - rKern[b]);
168
-                * ((lstate.lambdaoc[a] - rstate.lambdaoc[a])*real(exp(ln_Fn_Prod[a])) * (rstate.Kernel(a,b) - rKern[b]) + rKern[b]);
45
+    Vect_CX Vplus (0.0, lstate.N);  // contains V^+_j;  V^-_j is the conjugate
46
+    Vect_CX ln_Fn_Prod (0.0, lstate.N);  // product_{m\neq j} (\mu_m - \lambdaoc_j)/(\lambdaoc_m - \lambdaoc_j)
47
+    Vect_DP rKern (0.0, lstate.N);   // K(lambdaoc_j - lambdaoc_(p == arbitrary))
169
 
48
 
170
-        complex<DP> ln_ddalpha_sigma = lndet_LU_dstry(one_plus_U);
49
+    int p = rstate.N/2-1; // choice doesn't matter, see 1990_Slavnov_TMP_82 after (3.8). Choose rapidity around the middle.
171
 
50
 
172
-        complex<DP> ln_prod_V = 0.0;
173
-        for (int a = 0; a < lstate.N; ++a) ln_prod_V += log(2.0 * II * imag(Vplus[a]));
51
+    DP c_int = rstate.c_int;
174
 
52
 
175
-        complex<DP> ln_prod_2 = 0.0;
176
-        for (int a = 0; a < lstate.N; ++a)
177
-            for (int b = 0; b < lstate.N; ++b)
178
-                ln_prod_2 += log((rstate.lambdaoc[a] - rstate.lambdaoc[b] + II)/(lstate.lambdaoc[a] - rstate.lambdaoc[b]));
53
+    DP Eout = log(pow(lstate.E - rstate.E,2.)) - (2)*log(c_int)  - log(2*lstate.N);
179
 
54
 
180
-        //cout << "ln_Fn_Prod = " << ln_Fn_Prod << endl;
181
-        //cout << endl << ln_ddalpha_sigma << "\t" << ln_prod_V << "\t" << ln_prod_2 << "\t" << - log(2.0 * II * imag(Vplus[p])) << "\t" << - 0.5 * (lstate.lnnorm + rstate.lnnorm) << "\t" << ln_ddalpha_sigma + ln_prod_V + ln_prod_2 - log(2.0 * II * imag(Vplus[p])) - 0.5 * (lstate.lnnorm + rstate.lnnorm) << endl;
55
+    for (int a = 0; a < lstate.N; ++a) {
56
+      Vplus[a] = Fn_V_g2 (a, lstate, rstate);
57
+      ln_Fn_Prod[a] = 0.0;;
58
+      for (int m = 0; m < lstate.N; ++m)
59
+	if (m != a) ln_Fn_Prod[a] += log(complex<DP>(lstate.lambdaoc[m] - rstate.lambdaoc[a])
60
+					 /(rstate.lambdaoc[m] - rstate.lambdaoc[a]));
61
+      rKern[a] = rstate.Kernel (a, p);
62
+    }
182
 
63
 
183
-        ln_ddalpha_sigma += ln_prod_V + ln_prod_2 - log(2.0 * II * imag(Vplus[p]));
64
+    for (int a = 0; a < lstate.N; ++a)
65
+      for (int b = 0; b < lstate.N; ++b)
66
+	one_plus_U[a][b] = (a == b ? 1.0 : 0.0) + 0.5 * 1./imag(Vplus[a])
67
+	  * ((lstate.lambdaoc[a] - rstate.lambdaoc[a])*real(exp(ln_Fn_Prod[a]))
68
+	     * (rstate.Kernel(a,b) - rKern[b]) + rKern[b]);
184
 
69
 
185
-        return (log(II) + Eout + ln_ddalpha_sigma - 0.5 * (lstate.lnnorm + rstate.lnnorm));
186
-    }
70
+    complex<DP> ln_ddalpha_sigma = lndet_LU_dstry(one_plus_U);
187
 
71
 
72
+    complex<DP> ln_prod_V = 0.0;
73
+    for (int a = 0; a < lstate.N; ++a) ln_prod_V += log(2.0 * II * imag(Vplus[a]));
188
 
74
 
75
+    complex<DP> ln_prod_2 = 0.0;
76
+    for (int a = 0; a < lstate.N; ++a)
77
+      for (int b = 0; b < lstate.N; ++b)
78
+	ln_prod_2 += log((rstate.lambdaoc[a] - rstate.lambdaoc[b] + II)/(lstate.lambdaoc[a] - rstate.lambdaoc[b]));
189
 
79
 
80
+    ln_ddalpha_sigma += ln_prod_V + ln_prod_2 - log(2.0 * II * imag(Vplus[p]));
190
 
81
 
82
+    return (log(II) + Eout + ln_ddalpha_sigma - 0.5 * (lstate.lnnorm + rstate.lnnorm));
83
+  }
191
 
84
 
192
 } // namespace ABACUS
85
 } // namespace ABACUS

+ 1
- 6
src/MATRIX/ludcmp_CX.cc View File

6
   const complex<DP> TINY = 1.0e-200;
6
   const complex<DP> TINY = 1.0e-200;
7
   int i, j, k;
7
   int i, j, k;
8
   int imax = 0;
8
   int imax = 0;
9
-  //  DP big, dum, sum, temp;
10
   complex<DP> big, dum, sum, temp;
9
   complex<DP> big, dum, sum, temp;
11
 
10
 
12
   int n = a.size();
11
   int n = a.size();
16
   for (i = 0; i < n; i++) {
15
   for (i = 0; i < n; i++) {
17
     big = 0.0;
16
     big = 0.0;
18
     for (j = 0; j < n; j++)
17
     for (j = 0; j < n; j++)
19
-      //      if ((temp = fabs(a[i][j])) > big) big = temp;
20
       if ((abs(temp = a[i][j])) > abs(big)) big = temp;
18
       if ((abs(temp = a[i][j])) > abs(big)) big = temp;
21
-      //if ((norm(temp = a[i][j])) > norm(big)) big = temp;
22
-    if (big == 0.0) throw Divide_by_zero(); //ABACUSerror("Singular matrix in routine ludcmp.");
19
+    if (big == 0.0) throw Divide_by_zero();
23
     vv[i] = 1.0/big;
20
     vv[i] = 1.0/big;
24
   }
21
   }
25
   for (j = 0; j < n; j++) {
22
   for (j = 0; j < n; j++) {
33
       sum = a[i][j];
30
       sum = a[i][j];
34
       for (k = 0; k < j; k++) sum -= a[i][k] * a[k][j];
31
       for (k = 0; k < j; k++) sum -= a[i][k] * a[k][j];
35
       a[i][j] = sum;
32
       a[i][j] = sum;
36
-      //      if ((dum = vv[i]*fabs(sum)) >= big) {
37
       if ((abs(dum = vv[i]*sum)) >= abs(big)) {
33
       if ((abs(dum = vv[i]*sum)) >= abs(big)) {
38
-      //if ((norm(dum = vv[i]*sum)) >= norm(big)) {
39
 	big = dum;
34
 	big = dum;
40
 	imax = i;
35
 	imax = i;
41
       }
36
       }

+ 0
- 1
src/MATRIX/tred2.cc View File

14
       for (k = 0; k < l + 1; k++) scale += fabs(a[i][k]);
14
       for (k = 0; k < l + 1; k++) scale += fabs(a[i][k]);
15
       if (scale == 0.0) e[i] = a[i][l];
15
       if (scale == 0.0) e[i] = a[i][l];
16
       else {
16
       else {
17
-	//  scale = 1.0;  // <- added this myself...
18
 	for (k = 0; k < l + 1; k++) {
17
 	for (k = 0; k < l + 1; k++) {
19
 	  a[i][k] /= scale;
18
 	  a[i][k] /= scale;
20
 	  h += a[i][k] * a[i][k];
19
 	  h += a[i][k] * a[i][k];

+ 47
- 30
src/NRG/NRG_DME_Matrix_Block_builder.cc View File

21
 
21
 
22
 namespace ABACUS {
22
 namespace ABACUS {
23
 
23
 
24
-  void Build_DME_Matrix_Block_for_NRG (DP c_int, DP L, int N, int iKmin, int iKmax, int Nstates_required, bool symmetric_states, int iKmod,
25
-				       int weighing_option, int nrglabel_left_begin, int nrglabel_left_end, int nrglabel_right_begin, int nrglabel_right_end,
24
+  void Build_DME_Matrix_Block_for_NRG (DP c_int, DP L, int N, int iKmin, int iKmax,
25
+				       int Nstates_required, bool symmetric_states, int iKmod,
26
+				       int weighing_option, int nrglabel_left_begin, int nrglabel_left_end,
27
+				       int nrglabel_right_begin, int nrglabel_right_end,
26
 				       int block_option, DP* DME_block_1, DP* DME_block_2, Vect_DP Kweight)
28
 				       int block_option, DP* DME_block_1, DP* DME_block_2, Vect_DP Kweight)
27
   {
29
   {
28
     // Given a list of states produced by Select_States_for_NRG, this function
30
     // Given a list of states produced by Select_States_for_NRG, this function
39
     // We assume the DME_blocks are already reserved in memory.
41
     // We assume the DME_blocks are already reserved in memory.
40
     // If !symmetric states, DME_block_2 doesn't need to be allocated.
42
     // If !symmetric states, DME_block_2 doesn't need to be allocated.
41
 
43
 
42
-    if (nrglabel_left_begin < 0 || nrglabel_right_begin < 0) ABACUSerror("beginning nrglabels negative in Build_DME_Matrix_Block_for_NRG");
43
-    if (nrglabel_left_end >= Nstates_required) ABACUSerror("nrglabel_left_end too large in Build_DME_Matric_Block_for_NRG");
44
-    if (nrglabel_right_end >= Nstates_required) ABACUSerror("nrglabel_right_end too large in Build_DME_Matric_Block_for_NRG");
44
+    if (nrglabel_left_begin < 0 || nrglabel_right_begin < 0)
45
+      ABACUSerror("beginning nrglabels negative in Build_DME_Matrix_Block_for_NRG");
46
+    if (nrglabel_left_end >= Nstates_required)
47
+      ABACUSerror("nrglabel_left_end too large in Build_DME_Matric_Block_for_NRG");
48
+    if (nrglabel_right_end >= Nstates_required)
49
+      ABACUSerror("nrglabel_right_end too large in Build_DME_Matric_Block_for_NRG");
50
+
51
+    if (nrglabel_left_begin > nrglabel_left_end)
52
+      ABACUSerror("nrglabels of left states improperly chosen in DME block builder.");
53
+    if (nrglabel_right_begin > nrglabel_right_end)
54
+      ABACUSerror("nrglabels of right states improperly chosen in DME block builder.");
45
 
55
 
46
-    if (nrglabel_left_begin > nrglabel_left_end) ABACUSerror("nrglabels of left states improperly chosen in DME block builder.");
47
-    if (nrglabel_right_begin > nrglabel_right_end) ABACUSerror("nrglabels of right states improperly chosen in DME block builder.");
48
     // DME_block is a pointer of size row_l * col_l, where
56
     // DME_block is a pointer of size row_l * col_l, where
49
     int block_row_length = nrglabel_right_end - nrglabel_right_begin + 1;
57
     int block_row_length = nrglabel_right_end - nrglabel_right_begin + 1;
50
     int block_col_length = nrglabel_left_end - nrglabel_left_begin + 1;
58
     int block_col_length = nrglabel_left_end - nrglabel_left_begin + 1;
77
     }
85
     }
78
 
86
 
79
     // Read the whole data file:
87
     // Read the whole data file:
80
-    //const int MAXDATA = 5000000;
81
     const int MAXDATA = ABACUS::max(nrglabel_left_end, nrglabel_right_end) + 10; // 10 for safety...
88
     const int MAXDATA = ABACUS::max(nrglabel_left_end, nrglabel_right_end) + 10; // 10 for safety...
82
 
89
 
83
     int* nrglabel = new int[MAXDATA];
90
     int* nrglabel = new int[MAXDATA];
123
 
130
 
124
       Kept_States_left[nrglabel_left - nrglabel_left_begin] = Scanstate;
131
       Kept_States_left[nrglabel_left - nrglabel_left_begin] = Scanstate;
125
 
132
 
126
-      if (!Scanstate.conv) cout << "State of label " << label[nrglabel_left] << " did not converge after " << Scanstate.iter_Newton
127
-				<< " Newton step; diffsq = " << Scanstate.diffsq << endl;
133
+      if (!Scanstate.conv)
134
+	cout << "State of label " << label[nrglabel_left] << " did not converge after " << Scanstate.iter_Newton
135
+	     << " Newton step; diffsq = " << Scanstate.diffsq << endl;
128
     } // for nrglabel_left
136
     } // for nrglabel_left
129
 
137
 
130
     for (int nrglabel_right = nrglabel_right_begin; nrglabel_right <= nrglabel_right_end; ++nrglabel_right) {
138
     for (int nrglabel_right = nrglabel_right_begin; nrglabel_right <= nrglabel_right_end; ++nrglabel_right) {
136
 
144
 
137
       Kept_States_right[nrglabel_right - nrglabel_right_begin] = Scanstate;
145
       Kept_States_right[nrglabel_right - nrglabel_right_begin] = Scanstate;
138
 
146
 
139
-      if (!Scanstate.conv) cout << "State of label " << label[nrglabel_right] << " did not converge after " << Scanstate.iter_Newton
140
-				<< " Newton step; diffsq = " << Scanstate.diffsq << endl;
147
+      if (!Scanstate.conv)
148
+	cout << "State of label " << label[nrglabel_right] << " did not converge after " << Scanstate.iter_Newton
149
+	     << " Newton step; diffsq = " << Scanstate.diffsq << endl;
141
     } // for nrglabel_left
150
     } // for nrglabel_left
142
 
151
 
143
 
152
 
147
       for (int lr = 0; lr < block_row_length; ++lr) {
156
       for (int lr = 0; lr < block_row_length; ++lr) {
148
 
157
 
149
 	if (Kept_States_left[ll].conv && Kept_States_right[lr].conv
158
 	if (Kept_States_left[ll].conv && Kept_States_right[lr].conv
150
-	    //&& abs(Kept_States[il].iK - Kept_States[ir].iK) % iKmod == 0)
151
 	    && abs(Kept_States_left[ll].iK) % iKmod == 0
159
 	    && abs(Kept_States_left[ll].iK) % iKmod == 0
152
 	    && abs(Kept_States_right[lr].iK) % iKmod == 0) {
160
 	    && abs(Kept_States_right[lr].iK) % iKmod == 0) {
153
 
161
 
176
 
184
 
177
 	      if (block_option == 1) {
185
 	      if (block_option == 1) {
178
 		DME_block_1[ll* block_row_length + lr] =
186
 		DME_block_1[ll* block_row_length + lr] =
179
-		  (Kweight[abs(Kept_States_left[ll].iK - Kept_States_right[lr].iK)] * real(exp(ln_Density_ME (Kept_States_left[ll], Kept_States_right[lr])))
180
-		   + Kweight[abs(Kept_States_left[ll].iK - PRstate.iK)] * real(exp(ln_Density_ME (Kept_States_left[ll], PRstate))));
187
+		  (Kweight[abs(Kept_States_left[ll].iK - Kept_States_right[lr].iK)]
188
+		   * real(exp(ln_Density_ME (Kept_States_left[ll], Kept_States_right[lr])))
189
+		   + Kweight[abs(Kept_States_left[ll].iK - PRstate.iK)]
190
+		   * real(exp(ln_Density_ME (Kept_States_left[ll], PRstate))));
181
 		// We don't do anything with block 2, we don't even assume it's been allocated.
191
 		// We don't do anything with block 2, we don't even assume it's been allocated.
182
 	      }
192
 	      }
183
 	      else if (block_option == 2) {
193
 	      else if (block_option == 2) {
184
 		DME_block_1[ll* block_row_length + lr] =
194
 		DME_block_1[ll* block_row_length + lr] =
185
-		  Kweight[abs(Kept_States_left[ll].iK - Kept_States_right[lr].iK)] * real(exp(ln_Density_ME (Kept_States_left[ll], Kept_States_right[lr])));
195
+		  Kweight[abs(Kept_States_left[ll].iK - Kept_States_right[lr].iK)]
196
+		  * real(exp(ln_Density_ME (Kept_States_left[ll], Kept_States_right[lr])));
186
 		DME_block_2[ll* block_row_length + lr] =
197
 		DME_block_2[ll* block_row_length + lr] =
187
-		  Kweight[abs(Kept_States_left[ll].iK - PRstate.iK)] * real(exp(ln_Density_ME (Kept_States_left[ll], PRstate)));
198
+		  Kweight[abs(Kept_States_left[ll].iK - PRstate.iK)]
199
+		  * real(exp(ln_Density_ME (Kept_States_left[ll], PRstate)));
188
 	      }
200
 	      }
189
 	    }
201
 	    }
190
 
202
 
194
 
206
 
195
 	      if (block_option == 1) {
207
 	      if (block_option == 1) {
196
 		DME_block_1[ll* block_row_length + lr] = sqrt(0.5) *
208
 		DME_block_1[ll* block_row_length + lr] = sqrt(0.5) *
197
-		  (Kweight[abs(Kept_States_left[ll].iK - Kept_States_right[lr].iK)] * real(exp(ln_Density_ME (Kept_States_left[ll], Kept_States_right[lr])))
198
-		   + Kweight[abs(Kept_States_left[ll].iK - PRstate.iK)] * real(exp(ln_Density_ME (Kept_States_left[ll], PRstate))));
209
+		  (Kweight[abs(Kept_States_left[ll].iK - Kept_States_right[lr].iK)]
210
+		   * real(exp(ln_Density_ME (Kept_States_left[ll], Kept_States_right[lr])))
211
+		   + Kweight[abs(Kept_States_left[ll].iK - PRstate.iK)]
212
+		   * real(exp(ln_Density_ME (Kept_States_left[ll], PRstate))));
199
 		// We don't do anything with block 2, we don't even assume it's been allocated.
213
 		// We don't do anything with block 2, we don't even assume it's been allocated.
200
 	      }
214
 	      }
201
 	      else if (block_option == 2) {
215
 	      else if (block_option == 2) {
202
 		DME_block_1[ll* block_row_length + lr] = sqrt(0.5) *
216
 		DME_block_1[ll* block_row_length + lr] = sqrt(0.5) *
203
-		  Kweight[abs(Kept_States_left[ll].iK - Kept_States_right[lr].iK)] * real(exp(ln_Density_ME (Kept_States_left[ll], Kept_States_right[lr])));
217
+		  Kweight[abs(Kept_States_left[ll].iK - Kept_States_right[lr].iK)]
218
+		  * real(exp(ln_Density_ME (Kept_States_left[ll], Kept_States_right[lr])));
204
 		DME_block_2[ll* block_row_length + lr] = sqrt(0.5) *
219
 		DME_block_2[ll* block_row_length + lr] = sqrt(0.5) *
205
-		  Kweight[abs(Kept_States_left[ll].iK - PRstate.iK)] * real(exp(ln_Density_ME (Kept_States_left[ll], PRstate)));
220
+		  Kweight[abs(Kept_States_left[ll].iK - PRstate.iK)]
221
+		  * real(exp(ln_Density_ME (Kept_States_left[ll], PRstate)));
206
 	      }
222
 	      }
207
 	    }
223
 	    }
208
 
224
 
212
 
228
 
213
 	      if (block_option == 1) {
229
 	      if (block_option == 1) {
214
 		DME_block_1[ll* block_row_length + lr] = sqrt(0.5) *
230
 		DME_block_1[ll* block_row_length + lr] = sqrt(0.5) *
215
-		  (Kweight[abs(Kept_States_left[ll].iK - Kept_States_right[lr].iK)] * real(exp(ln_Density_ME (Kept_States_left[ll], Kept_States_right[lr])))
216
-		   + Kweight[abs(PLstate.iK - Kept_States_right[lr].iK)] * real(exp(ln_Density_ME (PLstate, Kept_States_right[lr]))));
231
+		  (Kweight[abs(Kept_States_left[ll].iK - Kept_States_right[lr].iK)]
232
+		   * real(exp(ln_Density_ME (Kept_States_left[ll], Kept_States_right[lr])))
233
+		   + Kweight[abs(PLstate.iK - Kept_States_right[lr].iK)]
234
+		   * real(exp(ln_Density_ME (PLstate, Kept_States_right[lr]))));
217
 		// We don't do anything with block 2, we don't even assume it's been allocated.
235
 		// We don't do anything with block 2, we don't even assume it's been allocated.
218
 	      }
236
 	      }
219
 	      else if (block_option == 2) {
237
 	      else if (block_option == 2) {
220
 		DME_block_1[ll* block_row_length + lr] = sqrt(0.5) *
238
 		DME_block_1[ll* block_row_length + lr] = sqrt(0.5) *
221
-		  Kweight[abs(Kept_States_left[ll].iK - Kept_States_right[lr].iK)] * real(exp(ln_Density_ME (Kept_States_left[ll], Kept_States_right[lr])));
239
+		  Kweight[abs(Kept_States_left[ll].iK - Kept_States_right[lr].iK)]
240
+		  * real(exp(ln_Density_ME (Kept_States_left[ll], Kept_States_right[lr])));
222
 		DME_block_2[ll* block_row_length + lr] = sqrt(0.5) *
241
 		DME_block_2[ll* block_row_length + lr] = sqrt(0.5) *
223
-		  Kweight[abs(PLstate.iK - Kept_States_right[lr].iK)] * real(exp(ln_Density_ME (PLstate, Kept_States_right[lr])));
242
+		  Kweight[abs(PLstate.iK - Kept_States_right[lr].iK)]
243
+		  * real(exp(ln_Density_ME (PLstate, Kept_States_right[lr])));
224
 	      }
244
 	      }
225
 	    }
245
 	    }
226
 
246
 
229
 
249
 
230
 	else {
250
 	else {
231
 	  DME_block_1[ll* block_row_length + lr] = 0.0;
251
 	  DME_block_1[ll* block_row_length + lr] = 0.0;
232
-	  if (symmetric_states && block_option == 2) DME_block_2[ll* block_row_length + lr] = 0.0;  // condition, to prevent segfault if DME_block_2 not allocated.
252
+	  // condition, to prevent segfault if DME_block_2 not allocated.
253
+	  if (symmetric_states && block_option == 2) DME_block_2[ll* block_row_length + lr] = 0.0;
233
 	}
254
 	}
234
-
235
-	//cout << ll << "\t" << lr << "\t" << DME_block[ll* block_row_length + lr] << endl;
236
-
237
       } // for lr
255
       } // for lr
238
     } // for ll
256
     } // for ll
239
 
257
 
240
     return;
258
     return;
241
   }
259
   }
242
 
260
 
243
-
244
 } // namespace ABACUS
261
 } // namespace ABACUS

+ 0
- 2
src/NRG/NRG_K_Weight_integrand.cc View File

43
     return(value);
43
     return(value);
44
   }
44
   }
45
 
45
 
46
-
47
-
48
 } // namespace ABACUS
46
 } // namespace ABACUS

+ 4
- 121
src/NRG/NRG_State_Selector.cc View File

22
 
22
 
23
   DP Estimate_Contribution_of_Single_ph_Annihilation_Path_to_2nd_Order_PT (LiebLin_Bethe_State& TopState,
23
   DP Estimate_Contribution_of_Single_ph_Annihilation_Path_to_2nd_Order_PT (LiebLin_Bethe_State& TopState,
24
 									   LiebLin_Bethe_State& GroundState,
24
 									   LiebLin_Bethe_State& GroundState,
25
-									   //Vect_DP Weight_integral)
26
 									   Vect<complex <DP> >& FT_of_potential)
25
 									   Vect<complex <DP> >& FT_of_potential)
27
   {
26
   {
28
-    //cout << TopState.label << "\t" << GroundState.label << endl;
29
-    //cout << TopState.lambdaoc << endl;
30
-
31
     DP contrib_estimate = 0.0;
27
     DP contrib_estimate = 0.0;
32
 
28
 
33
     // Define OriginIx2 for labelling:
29
     // Define OriginIx2 for labelling:
49
     int nr_cont = 0;
45
     int nr_cont = 0;
50
 
46
 
51
     // Add first-order PT contribution, and 2nd order from ground state (V_{00} == 1)
47
     // Add first-order PT contribution, and 2nd order from ground state (V_{00} == 1)
52
-    //contrib_estimate += Weight_integral[Weight_integral.size()/2 + (TopState.iK - GroundState.iK)]
53
-    //* (densityME/(GroundState.E - TopState.E)) * (1.0 - (GroundState.N/GroundState.L)/(GroundState.E - TopState.E));
54
     contrib_estimate += abs(FT_of_potential[FT_of_potential.size()/2 + (TopState.iK - GroundState.iK)]
48
     contrib_estimate += abs(FT_of_potential[FT_of_potential.size()/2 + (TopState.iK - GroundState.iK)]
55
 			    * (densityME/(GroundState.E - TopState.E))
49
 			    * (densityME/(GroundState.E - TopState.E))
56
 			    * (1.0 - (GroundState.N/GroundState.L)/(GroundState.E - TopState.E)));
50
 			    * (1.0 - (GroundState.N/GroundState.L)/(GroundState.E - TopState.E)));
58
     nr_cont++;
52
     nr_cont++;
59
 
53
 
60
     // Add second order PT contribution coming from TopState:
54
     // Add second order PT contribution coming from TopState:
61
-    //contrib_estimate += Weight_integral[Weight_integral.size()/2 + 0]
62
-    //* Weight_integral[Weight_integral.size()/2 + (TopState.iK - GroundState.iK)]
63
-    //* 1.0 * densityME * (GroundState.N/GroundState.L) // 1.0 is V_{TopState, TopState}
64
-	///((GroundState.E - TopState.E) * (GroundState.E - TopState.E));
65
     contrib_estimate += abs(FT_of_potential[FT_of_potential.size()/2 + 0]
55
     contrib_estimate += abs(FT_of_potential[FT_of_potential.size()/2 + 0]
66
 			    * FT_of_potential[FT_of_potential.size()/2 + (TopState.iK - GroundState.iK)]
56
 			    * FT_of_potential[FT_of_potential.size()/2 + (TopState.iK - GroundState.iK)]
67
 			    * 1.0 * densityME * (GroundState.N/GroundState.L) // 1.0 is V_{TopState, TopState}
57
 			    * 1.0 * densityME * (GroundState.N/GroundState.L) // 1.0 is V_{TopState, TopState}
69
 
59
 
70
     nr_cont++;
60
     nr_cont++;
71
 
61
 
72
-    //cout << "Here b" << endl;
73
-
74
     // Now add 2nd order terms coming from single particle-hole annihilation paths:
62
     // Now add 2nd order terms coming from single particle-hole annihilation paths:
75
     // this is only to be included for states with at least 4 excitations (2 ph pairs)
63
     // this is only to be included for states with at least 4 excitations (2 ph pairs)
76
-
77
     if (nphpairs >= 2) {
64
     if (nphpairs >= 2) {
78
 
65
 
79
       for (int ipart = 0; ipart < nphpairs; ++ipart) {
66
       for (int ipart = 0; ipart < nphpairs; ++ipart) {
80
 	for (int ihole = 0; ihole < nphpairs; ++ihole) {
67
 	for (int ihole = 0; ihole < nphpairs; ++ihole) {
81
 
68
 
82
 	  LiebLin_Bethe_State DescendedState = TopState;
69
 	  LiebLin_Bethe_State DescendedState = TopState;
83
-	  //cout << "Here 2a" << "\tipart " << ipart << "\tihole " << ihole << " out of " << nphpairs << " nphpairs, label " << TopState.label << endl;
84
-	  //cout << "TopState.Ix2 " << TopState.Ix2 << endl;
85
-	  //cout << "DescendedIx2 " << DescendedState.Ix2 << endl;
86
 	  DescendedState.Annihilate_ph_pair(ipart, ihole, OriginIx2);
70
 	  DescendedState.Annihilate_ph_pair(ipart, ihole, OriginIx2);
87
 	  DescendedState.Compute_All(true);
71
 	  DescendedState.Compute_All(true);
88
-	  //cout << "DescendedIx2 " << DescendedState.Ix2 << endl;
89
 
72
 
90
 	  DP densityME_top_desc = real(exp(ln_Density_ME (TopState, DescendedState)));
73
 	  DP densityME_top_desc = real(exp(ln_Density_ME (TopState, DescendedState)));
91
 	  DP densityME_desc_ground = real(exp(ln_Density_ME (DescendedState, GroundState)));
74
 	  DP densityME_desc_ground = real(exp(ln_Density_ME (DescendedState, GroundState)));
92
 
75
 
93
-	  //contrib_estimate += Weight_integral[Weight_integral.size()/2 + (TopState.iK - DescendedState.iK)]
94
-	  //* Weight_integral[Weight_integral.size()/2 + (DescendedState.iK - GroundState.iK)]
95
-	  //* densityME_top_desc * densityME_desc_ground
96
-	  ///((GroundState.E - TopState.E) * (GroundState.E - DescendedState.E));
97
-
98
 	  // if intermediate state has momentum within allowable window, OK, otherwise discard contribution:
76
 	  // if intermediate state has momentum within allowable window, OK, otherwise discard contribution:
99
 	  if (abs(TopState.iK - DescendedState.iK) < FT_of_potential.size()/2 &&
77
 	  if (abs(TopState.iK - DescendedState.iK) < FT_of_potential.size()/2 &&
100
 	      abs(DescendedState.iK - GroundState.iK) < FT_of_potential.size()/2) {
78
 	      abs(DescendedState.iK - GroundState.iK) < FT_of_potential.size()/2) {
112
 	      for (int ihole2 = ihole; ihole2 < nphpairs - 1; ++ihole2) {
90
 	      for (int ihole2 = ihole; ihole2 < nphpairs - 1; ++ihole2) {
113
 
91
 
114
 		LiebLin_Bethe_State DescendedState2 = DescendedState;
92
 		LiebLin_Bethe_State DescendedState2 = DescendedState;
115
-		//cout << "Here 3a" << "\tipart2 " << ipart2 << "\tihole2 " << ihole2 << endl;
116
-		//cout << DescendedState2.Ix2 << endl;
117
 		DescendedState2.Annihilate_ph_pair(ipart2, ihole2, OriginIx2);
93
 		DescendedState2.Annihilate_ph_pair(ipart2, ihole2, OriginIx2);
118
 		DescendedState2.Compute_All(true);
94
 		DescendedState2.Compute_All(true);
119
-		//cout << DescendedState2.Ix2 << endl;
120
-		//cout << DescendedState2.lambdaoc << endl;
121
 
95
 
122
 		DP densityME_top_desc2 = real(exp(ln_Density_ME (TopState, DescendedState2)));
96
 		DP densityME_top_desc2 = real(exp(ln_Density_ME (TopState, DescendedState2)));
123
 		DP densityME_desc2_ground = real(exp(ln_Density_ME (DescendedState2, GroundState)));
97
 		DP densityME_desc2_ground = real(exp(ln_Density_ME (DescendedState2, GroundState)));
124
 
98
 
125
-		//contrib_estimate += Weight_integral[Weight_integral.size()/2 + (TopState.iK - DescendedState2.iK)]
126
-		//* Weight_integral[Weight_integral.size()/2 + (DescendedState2.iK - GroundState.iK)]
127
-		//* densityME_top_desc2 * densityME_desc2_ground
128
-		///((GroundState.E - TopState.E) * (GroundState.E - DescendedState2.E));
129
-
130
 		// if intermediate state has momentum within allowable window, OK, otherwise discard contribution:
99
 		// if intermediate state has momentum within allowable window, OK, otherwise discard contribution:
131
 		if (abs(TopState.iK - DescendedState2.iK) < FT_of_potential.size()/2 &&
100
 		if (abs(TopState.iK - DescendedState2.iK) < FT_of_potential.size()/2 &&
132
 		    abs(DescendedState2.iK - GroundState.iK) < FT_of_potential.size()/2) {
101
 		    abs(DescendedState2.iK - GroundState.iK) < FT_of_potential.size()/2) {
144
 		    for (int ihole3 = ihole2; ihole3 < nphpairs - 2; ++ihole3) {
113
 		    for (int ihole3 = ihole2; ihole3 < nphpairs - 2; ++ihole3) {
145
 
114
 
146
 		      LiebLin_Bethe_State DescendedState3 = DescendedState2;
115
 		      LiebLin_Bethe_State DescendedState3 = DescendedState2;
147
-		      //cout << "Here 4a" << "\tipart3 " << ipart3 << "\tihole3 " << ihole3 << endl;
148
 		      DescendedState3.Annihilate_ph_pair(ipart3, ihole3, OriginIx2);
116
 		      DescendedState3.Annihilate_ph_pair(ipart3, ihole3, OriginIx2);
149
-		      //cout << DescendedState3.Ix2 << endl;
150
 		      DescendedState3.Compute_All(true);
117
 		      DescendedState3.Compute_All(true);
151
-		      //cout << DescendedState3.Ix2 << endl;
152
 
118
 
153
 		      DP densityME_top_desc3 = real(exp(ln_Density_ME (TopState, DescendedState3)));
119
 		      DP densityME_top_desc3 = real(exp(ln_Density_ME (TopState, DescendedState3)));
154
 		      DP densityME_desc3_ground = real(exp(ln_Density_ME (DescendedState3, GroundState)));
120
 		      DP densityME_desc3_ground = real(exp(ln_Density_ME (DescendedState3, GroundState)));
155
 
121
 
156
-		      //contrib_estimate += Weight_integral[Weight_integral.size()/2 + (TopState.iK - DescendedState3.iK)]
157
-		      //* Weight_integral[Weight_integral.size()/2 + (DescendedState3.iK - GroundState.iK)]
158
-		      //* densityME_top_desc3 * densityME_desc3_ground
159
-		      ///((GroundState.E - TopState.E) * (GroundState.E - DescendedState3.E));
160
-
161
 		      // if intermediate state has momentum within allowable window, OK, otherwise discard contribution:
122
 		      // if intermediate state has momentum within allowable window, OK, otherwise discard contribution:
162
 		      if (abs(TopState.iK - DescendedState3.iK) < FT_of_potential.size()/2 &&
123
 		      if (abs(TopState.iK - DescendedState3.iK) < FT_of_potential.size()/2 &&
163
 			  abs(DescendedState3.iK - GroundState.iK) < FT_of_potential.size()/2) {
124
 			  abs(DescendedState3.iK - GroundState.iK) < FT_of_potential.size()/2) {
164
 
125
 
165
 			contrib_estimate += abs(FT_of_potential[FT_of_potential.size()/2 + (TopState.iK - DescendedState3.iK)]
126
 			contrib_estimate += abs(FT_of_potential[FT_of_potential.size()/2 + (TopState.iK - DescendedState3.iK)]
166
-						* FT_of_potential[FT_of_potential.size()/2 + (DescendedState3.iK - GroundState.iK)]
127
+						* FT_of_potential[FT_of_potential.size()/2
128
+								  + (DescendedState3.iK - GroundState.iK)]
167
 						* densityME_top_desc3 * densityME_desc3_ground
129
 						* densityME_top_desc3 * densityME_desc3_ground
168
 						/((GroundState.E - TopState.E) * (GroundState.E - DescendedState3.E)));
130
 						/((GroundState.E - TopState.E) * (GroundState.E - DescendedState3.E)));
169
 
131
 
181
       } // for ipart
143
       } // for ipart
182
     } // if nphpairs >= 2
144
     } // if nphpairs >= 2
183
 
145
 
184
-    //cout << "Here b" << endl;
185
-    //cout << "type_id " << TopState.type_id << "\tid " << TopState.id << "\tcontrib_est = " << contrib_estimate << "\tnr_cont = " << nr_cont << endl;
186
-
187
     return(contrib_estimate);
146
     return(contrib_estimate);
188
   }
147
   }
189
 
148
 
190
-  /*
191
-  DP Estimate_Contribution_of_Base_to_2nd_Order_PT (LiebLin_Bethe_State& ScanState, LiebLin_Bethe_State& GroundState,
192
-						    Vect_DP Weight_integral, LiebLin_States_and_Density_ME_of_Base& StatesBase)
193
-  {
194
-    // This function calculates the second-order perturbation theory contribution to
195
-    // state ScanState coming from states of base defined in StatesBase.
196
-
197
-    DP sum_contrib = 0.0;
198
-
199
-    for (int i = 0; i <= StatesBase.maxid; ++i)
200
-      sum_contrib += Weight_integral[Weight_integral.size()/2 + (ScanState.iK - StatesBase.State[i].iK)]
201
-	* Weight_integral[Weight_integral.size()/2 + (StatesBase.State[i].iK - GroundState.iK)]
202
-	* real(exp(ln_Density_ME (ScanState, StatesBase.State[i]))) * StatesBase.densityME[i]
203
-	/((GroundState.E - StatesBase.State[i].E) * (GroundState.E - ScanState.E));
204
-    // The strange vector size is so that iK == 0 corresponds to index size/2, as per convention
205
-    return(sum_contrib);
206
-  }
207
-  */
208
 
149
 
209
-  void Select_States_for_NRG (DP c_int, DP L, int N, int iKmin, int iKmax, int Nstates_required, bool symmetric_states, int iKmod,
210
-			      //int weighing_option, DP (*weight_integrand_fn) (Vect_DP), Vect_DP& args_to_weight_integrand)
211
-			      int weighing_option, Vect<complex <DP> >& FT_of_potential)
150
+  void Select_States_for_NRG (DP c_int, DP L, int N, int iKmin, int iKmax, int Nstates_required,
151
+			      bool symmetric_states, int iKmod, int weighing_option, Vect<complex <DP> >& FT_of_potential)
212
   {
152
   {
213
     // This function reads an existing partition function file and determines whether
153
     // This function reads an existing partition function file and determines whether
214
     // each state is to be included in NRG by applying an energy, momentum and form factor criterion.
154
     // each state is to be included in NRG by applying an energy, momentum and form factor criterion.
218
     // weighing_option == 1:  ordering according to perturbation theory in single p-h annihilation path
158
     // weighing_option == 1:  ordering according to perturbation theory in single p-h annihilation path
219
     // weighing_option == 2:  same as 1, but output of list is ordered in weight
159
     // weighing_option == 2:  same as 1, but output of list is ordered in weight
220
 
160
 
221
-
222
     stringstream filenameprefix;
161
     stringstream filenameprefix;
223
     Data_File_Name (filenameprefix, 'Z', c_int, L, N, iKmin, iKmax, 0.0, 0.0, "");
162
     Data_File_Name (filenameprefix, 'Z', c_int, L, N, iKmin, iKmax, 0.0, 0.0, "");
224
     string prefix = filenameprefix.str();
163
     string prefix = filenameprefix.str();
250
     NRG_outfile.open(NRG_Cstr);
189
     NRG_outfile.open(NRG_Cstr);
251
     if (NRG_outfile.fail()) ABACUSerror("Could not open NRG_outfile... ");
190
     if (NRG_outfile.fail()) ABACUSerror("Could not open NRG_outfile... ");
252
 
191
 
253
-    //NRG_outfile.setf(ios::scientific);
254
     NRG_outfile.precision(16);
192
     NRG_outfile.precision(16);
255
 
193
 
256
 
194
 
257
     // Read the whole data file:
195
     // Read the whole data file:
258
-    /*
259
-    // estimate its size:
260
-    struct stat statbuf;
261
-    stat (RAW_Cstr, &statbuf);
262
-    int filesize = statbuf.st_size;
263
-    // Determine the number of entries approximately
264
-    int entry_size = 1* sizeof(double) + 2*sizeof(int) + 3* sizeof(long long int);
265
-
266
-    int estimate_nr_entries = filesize/entry_size;
267
-    */
268
 
196
 
269
     // Count the number of entries in raw file:
197
     // Count the number of entries in raw file:
270
     int estimate_nr_entries = 0;
198
     int estimate_nr_entries = 0;
273
       getline(infile, line);
201
       getline(infile, line);
274
       estimate_nr_entries++;
202
       estimate_nr_entries++;
275
     }
203
     }
276
-
277
     const int MAXDATA = estimate_nr_entries;
204
     const int MAXDATA = estimate_nr_entries;
278
-    //cout << "estimate_nr_entries: " << estimate_nr_entries << endl;
279
 
205
 
280
     DP* E = new DP[MAXDATA];
206
     DP* E = new DP[MAXDATA];
281
     int* iK = new int[MAXDATA];
207
     int* iK = new int[MAXDATA];
282
-    //int* conv = new int[MAXDATA];
283
     string* label = new string[MAXDATA];
208
     string* label = new string[MAXDATA];
284
     bool* sym = new bool[MAXDATA];
209
     bool* sym = new bool[MAXDATA];
285
 
210
 
291
     while (((infile.peek()) != EOF) && (Ndata < MAXDATA)) {
216
     while (((infile.peek()) != EOF) && (Ndata < MAXDATA)) {
292
       infile >> E[Ndata];
217
       infile >> E[Ndata];
293
       infile >> iK[Ndata];
218
       infile >> iK[Ndata];
294
-      //infile >> conv[Ndata];
295
       infile >> label[Ndata];
219
       infile >> label[Ndata];
296
       Ndata++;
220
       Ndata++;
297
     }
221
     }
298
 
222
 
299
-    //cout << "input " << Ndata << " data lines." << endl;
300
     infile.close();
223
     infile.close();
301
 
224
 
302
     // Define the ground state:
225
     // Define the ground state:
313
     // To cover negative and positive momenta (in case potential is not symmetric),
236
     // To cover negative and positive momenta (in case potential is not symmetric),
314
     // we define the Weight_integral vector entry with index size/2 as corresponding to iK == 0.
237
     // we define the Weight_integral vector entry with index size/2 as corresponding to iK == 0.
315
 
238
 
316
-    /*
317
-    // DEPRECATED 25/1/2012: from now on (ABACUS++T_8 onwards), use FT of potential as argument to this function.
318
-    Vect_DP Weight_integral (0.0, 4* (iKmax - iKmin)); // we give a large window
319
-
320
-    //Vect_DP args(0.0, 2);
321
-    DP req_rel_prec = 1.0e-6;
322
-    DP req_abs_prec = 1.0e-6;
323
-    int max_nr_pts = 10000;
324
-
325
-    for (int iK = -Weight_integral.size()/2; iK < Weight_integral.size()/2; ++iK) {
326
-
327
-      args_to_weight_integrand[1] = DP(iK);
328
-
329
-      Integral_result answer = Integrate_optimal (weight_integrand_fn, args_to_weight_integrand,
330
-						  0, 0.0, 0.5, req_rel_prec, req_abs_prec, max_nr_pts);
331
-
332
-      Weight_integral[Weight_integral.size()/2 + iK] = answer.integ_est;
333
-
334
-    }
335
-    */
336
-
337
     // Calculate weight of states using selection criterion function
239
     // Calculate weight of states using selection criterion function
338
 
240
 
339
-    //DP absdensityME = 0.0;
340
     DP* weight = new DP[Ndata];
241
     DP* weight = new DP[Ndata];
341
 
242
 
342
     // For weighing using 2nd order PT, we only trace over 2 excitation states (1 p-h pair)
243
     // For weighing using 2nd order PT, we only trace over 2 excitation states (1 p-h pair)
344
 
245
 
345
     for (int i = 0; i < Ndata; ++i) {
246
     for (int i = 0; i < Ndata; ++i) {
346
 
247
 
347
-      //cout << i << " out of " << Ndata << "\tlabel = " << label[i] << endl;
348
-
349
       if (abs(iK[i]) % iKmod != 0) {     // if iK not a multiple of iKmod:  give stupidly high weight.
248
       if (abs(iK[i]) % iKmod != 0) {     // if iK not a multiple of iKmod:  give stupidly high weight.
350
 	weight[i] = 1.0e+100;
249
 	weight[i] = 1.0e+100;
351
 	sym[i] = false;  // doesn't matter
250
 	sym[i] = false;  // doesn't matter
359
 	if (weighing_option == 1 || weighing_option == 2) ScanState.Compute_All(true);
258
 	if (weighing_option == 1 || weighing_option == 2) ScanState.Compute_All(true);
360
 	sym[i] = ScanState.Check_Symmetry();
259
 	sym[i] = ScanState.Check_Symmetry();
361
 
260
 
362
-	//cout << "Setting state " << i << "\t to label " << label[i] << "\tsym: " << sym[i] << endl;
363
-
364
-	// WEIGHING THE STATES:  **********************************************
365
-
366
 	State_Label_Data currentdata = Read_State_Label (label[i], OriginIx2);
261
 	State_Label_Data currentdata = Read_State_Label (label[i], OriginIx2);
367
 	if (currentdata.nexc[0] == 0) weight[i] = 0.0;
262
 	if (currentdata.nexc[0] == 0) weight[i] = 0.0;
368
 
263
 
369
 	else if (symmetric_states && iK[i] < 0 || iK[i] < iKmin || iK[i] > iKmax) weight[i] = 1.0e+100;
264
 	else if (symmetric_states && iK[i] < 0 || iK[i] < iKmin || iK[i] > iKmax) weight[i] = 1.0e+100;
370
 
265
 
371
-	//else if (symmetric_states && iK[i] == 0 && !ScanState.Check_Symmetry()) {
372
 	else if (symmetric_states && iK[i] == 0 && !sym[i]) {
266
 	else if (symmetric_states && iK[i] == 0 && !sym[i]) {
373
 	  // This state is at zero momentum but not symmetric.  we keep it only if
267
 	  // This state is at zero momentum but not symmetric.  we keep it only if
374
 	  // the first non-symmetric pair of quantum numbers is right-weighted:
268
 	  // the first non-symmetric pair of quantum numbers is right-weighted:
378
 	    if (weighing_option == 0) weight[i] = E[i];
272
 	    if (weighing_option == 0) weight[i] = E[i];
379
 	    else if (weighing_option == 1 || weighing_option == 2)
273
 	    else if (weighing_option == 1 || weighing_option == 2)
380
 	      weight[i] = 1.0/(1.0e-100 + fabs(Estimate_Contribution_of_Single_ph_Annihilation_Path_to_2nd_Order_PT
274
 	      weight[i] = 1.0/(1.0e-100 + fabs(Estimate_Contribution_of_Single_ph_Annihilation_Path_to_2nd_Order_PT
381
-					       //(ScanState, GroundState, Weight_integral)));
382
 					       (ScanState, GroundState, FT_of_potential)));
275
 					       (ScanState, GroundState, FT_of_potential)));
383
 	  }
276
 	  }
384
 	  else weight[i] = 1.0e+100;
277
 	  else weight[i] = 1.0e+100;
388
 	  if (weighing_option == 0) weight[i] = E[i];
281
 	  if (weighing_option == 0) weight[i] = E[i];
389
 	  else if (weighing_option == 1 || weighing_option == 2)
282
 	  else if (weighing_option == 1 || weighing_option == 2)
390
 	    weight[i] = 1.0/(1.0e-100 + fabs(Estimate_Contribution_of_Single_ph_Annihilation_Path_to_2nd_Order_PT
283
 	    weight[i] = 1.0/(1.0e-100 + fabs(Estimate_Contribution_of_Single_ph_Annihilation_Path_to_2nd_Order_PT
391
-					     //(ScanState, GroundState, Weight_integral)));
392
 					     (ScanState, GroundState, FT_of_potential)));
284
 					     (ScanState, GroundState, FT_of_potential)));
393
 	}
285
 	}
394
-	//cout << i << " out of " << Ndata << "\tlabel = " << label[i] << "\tweight = " << weight[i] << endl;
395
       }
286
       }
396
     } // for i
287
     } // for i
397
 
288
 
402
 
293
 
403
     QuickSort(weight, index, 0, Ndata - 1);
294
     QuickSort(weight, index, 0, Ndata - 1);
404
 
295
 
405
-
406
     // Select states by increasing weight, with a max of Nstates_required entries
296
     // Select states by increasing weight, with a max of Nstates_required entries
407
 
297
 
408
     DP* E_kept = new DP[Nstates_required];
298
     DP* E_kept = new DP[Nstates_required];
409
     int* iK_kept = new int[Nstates_required];
299
     int* iK_kept = new int[Nstates_required];
410
-    //int* conv_kept = new int[Nstates_required];
411
     string* label_kept = new string[Nstates_required];
300
     string* label_kept = new string[Nstates_required];
412
     bool* sym_kept = new bool[Nstates_required];
301
     bool* sym_kept = new bool[Nstates_required];
413
     DP* weight_kept = new DP[Nstates_required];
302
     DP* weight_kept = new DP[Nstates_required];
414
 
303
 
415
     // Copy selected states into new vectors:
304
     // Copy selected states into new vectors:
416
-
417
     for (int i = 0; i < ABACUS::min(Ndata, Nstates_required); ++i) {
305
     for (int i = 0; i < ABACUS::min(Ndata, Nstates_required); ++i) {
418
       E_kept[i] = E[index[i] ];
306
       E_kept[i] = E[index[i] ];
419
       iK_kept[i] = iK[index[i] ];
307
       iK_kept[i] = iK[index[i] ];
425
 
313
 
426
 
314
 
427
     // If needed, order selected states by increasing energy:
315
     // If needed, order selected states by increasing energy:
428
-
429
     int* index_kept = new int[Nstates_required];
316
     int* index_kept = new int[Nstates_required];
430
     for (int i = 0; i < Nstates_required; ++i) index_kept[i] = i;
317
     for (int i = 0; i < Nstates_required; ++i) index_kept[i] = i;
431
 
318
 
436
     for (int i = 0; i < Nstates_required; ++i) {
323
     for (int i = 0; i < Nstates_required; ++i) {
437
       if (i > 0) NRG_outfile << endl;
324
       if (i > 0) NRG_outfile << endl;
438
       NRG_outfile << i << "\t" << E_kept[i] << "\t" << iK_kept[index_kept[i] ]
325
       NRG_outfile << i << "\t" << E_kept[i] << "\t" << iK_kept[index_kept[i] ]
439
-	//<< "\t" << conv_kept[index_kept[i] ]
440
 		  << "\t" << label_kept[index_kept[i] ]
326
 		  << "\t" << label_kept[index_kept[i] ]
441
 		  << "\t" << sym_kept[index_kept[i] ] << "\t" << weight_kept[index_kept[i] ];
327
 		  << "\t" << sym_kept[index_kept[i] ] << "\t" << weight_kept[index_kept[i] ];
442
     }
328
     }
443
 
329
 
444
     delete[] E;
330
     delete[] E;
445
     delete[] iK;
331
     delete[] iK;
446
-    //delete[] conv;
447
     delete[] label;
332
     delete[] label;
448
     delete[] sym;
333
     delete[] sym;
449
     delete[] E_kept;
334
     delete[] E_kept;
450
     delete[] iK_kept;
335
     delete[] iK_kept;
451
-    //delete[] conv_kept;
452
     delete[] label_kept;
336
     delete[] label_kept;
453
     delete[] sym_kept;
337
     delete[] sym_kept;
454
     delete[] weight;
338
     delete[] weight;
458
     return;
342
     return;
459
   }
343
   }
460
 
344
 
461
-
462
 } // namespace ABACUS
345
 } // namespace ABACUS

+ 145
- 332
src/ODSLF/ODSLF.cc
File diff suppressed because it is too large
View File


+ 0
- 119
src/ODSLF/ODSLF_Chem_Pot.cc View File

16
 
16
 
17
 namespace ABACUS {
17
 namespace ABACUS {
18
 
18
 
19
-  /*
20
-  DP Ezero (DP Delta, int N, int M)
21
-  {
22
-    // Returns the energy of the ground state with M down spins
23
-
24
-    if (M < 0 || M > N/2) ABACUSerror("M out of bounds in Ezero.");
25
-
26
-    DP E = -1.0; // sentinel value
27
-
28
-    if (M == 0) E = N * Delta/4.0;
29
-
30
-    else {
31
-
32
-      Heis_Chain BD1(1.0, Delta, 0.0, N);
33
-
34
-      Vect_INT Nrapidities_groundstate(0, BD1.Nstrings);
35
-
36
-      Nrapidities_groundstate[0] = M;
37
-
38
-      ODSLF_Base baseconfig_groundstate(BD1, Nrapidities_groundstate);
39
-
40
-      if ((Delta > 0.0) && (Delta < 1.0)) {
41
-	ODSLF_XXZ_Bethe_State groundstate(BD1, baseconfig_groundstate);
42
-	groundstate.Compute_All(true);
43
-	E = groundstate.E;
44
-      }
45
-
46
-      else if (Delta == 1.0) {
47
-	XXX_Bethe_State groundstate(BD1, baseconfig_groundstate);
48
-	groundstate.Compute_All(true);
49
-	E = groundstate.E;
50
-      }
51
-
52
-      else if (Delta > 1.0) {
53
-	XXZ_gpd_Bethe_State groundstate(BD1, baseconfig_groundstate);
54
-	groundstate.Compute_All(true);
55
-	E = groundstate.E;
56
-      }
57
-
58
-      else ABACUSerror("Anisotropy out of bounds in Ezero.");
59
-    }
60
-
61
-    return(E);
62
-  }
63
-
64
-  DP H_vs_M (DP Delta, int N, int M)
65
-  {
66
-    // Assumes dE/dM = 0 = dE_0/dM + h, with dE_0/dM = E_0(M) - E_0 (M - 1)
67
-
68
-    DP H = 0.0;
69
-
70
-    if (2*M == N) H = 0.0;
71
-
72
-    else if (Delta <= 1.0) H = Ezero (Delta, N, M - 1) - Ezero (Delta, N, M);
73
-
74
-    return(H);
75
-  }
76
-
77
-  DP HZmin (DP Delta, int N, int M, Vect_DP& Ezero_ref)
78
-  {
79
-    if (M < 0 || M > N/2 - 1) {
80
-      cout << "M = " << M << endl;
81
-      ABACUSerror("M out of bounds in HZmin.");
82
-    }
83
-
84
-    if (Ezero_ref[M] == -1.0) Ezero_ref[M] = Ezero(Delta, N, M);
85
-    if (Ezero_ref[M + 1] == -1.0) Ezero_ref[M + 1] = Ezero(Delta, N, M + 1);
86
-
87
-    return(Ezero_ref[M] - Ezero_ref[M + 1]);
88
-  }
89
-
90
-  int M_vs_H (DP Delta, int N, DP HZ)
91
-  {
92
-    // Returns the value of M for given field HZ
93
-
94
-    if (HZ < 0.0) ABACUSerror("Please use a positive field in M_vs_H.");
95
-
96
-    else if (HZ == 0.0) return(N/2);
97
-
98
-    // Here, -1.0 is a sentinel value.
99
-    Vect_DP Ezero(-1.0, N/2 + 1);  // contains the GSE[M].
100
-
101
-    // We look for M s.t. HZmin[M] < HZ <= HZmin[M + 1]
102
-
103
-    int M_actual = N/4; // start somewhere in middle
104
-    int M_step = N/8 - 1; // step
105
-    DP HZmin_actual = 0.0;
106
-    DP HZmax_actual = 0.0;
107
-    bool M_found = false;
108
-
109
-    if (HZ >= 1.0 + Delta) M_actual = 0;  // saturation
110
-
111
-    else {
112
-
113
-      HZmin_actual = HZmin (Delta, N, M_actual, Ezero);
114
-      HZmax_actual = HZmin (Delta, N, M_actual - 1, Ezero);
115
-
116
-      while (!M_found) {
117
-
118
-	if (HZmin_actual > HZ) M_actual += M_step;
119
-	else if (HZmax_actual <= HZ) M_actual -= M_step;
120
-
121
-	M_step = (M_step + 1)/2;
122
-
123
-	HZmin_actual = HZmin (Delta, N, M_actual, Ezero);
124
-	HZmax_actual = HZmin (Delta, N, M_actual - 1, Ezero);
125
-
126
-	M_found = (HZmin_actual < HZ && HZ <= HZmax_actual);
127
-
128
-	//cout << "M_actual = " << M_actual << "\tM_step = " << M_step
129
-	//   << "\tHZmin_actual = " << HZmin_actual << "\tHZmax_actual = " << HZmax_actual << "\tHZ = " << HZ << "\t" << M_found << endl;
130
-      }
131
-    }
132
-    //cout << "M found = " << M_actual << "\tHZmax = " << Ezero[M_actual] - Ezero[M_actual + 1] << "\tHZmin = " << Ezero[M_actual - 1] - Ezero[M_actual] << endl;
133
-
134
-    return(M_actual);
135
-  }
136
-  */
137
-
138
   DP Chemical_Potential (const ODSLF_Bethe_State& RefState)
19
   DP Chemical_Potential (const ODSLF_Bethe_State& RefState)
139
   {
20
   {
140
     return(-H_vs_M (RefState.chain.Delta, RefState.chain.Nsites, RefState.base.Mdown));  // - sign since E_{M+1} - E_M = -H
21
     return(-H_vs_M (RefState.chain.Delta, RefState.chain.Nsites, RefState.base.Mdown));  // - sign since E_{M+1} - E_M = -H

+ 0
- 7
src/ODSLF/ODSLF_Matrix_Element_Contrib.cc View File

19
 
19
 
20
 namespace ABACUS {
20
 namespace ABACUS {
21
 
21
 
22
-  //DP Compute_Matrix_Element_Contrib (char whichDSF, bool fixed_iK, ODSLF_XXZ_Bethe_State& LeftState,
23
-				     //ODSLF_XXZ_Bethe_State& RefState, DP Chem_Pot, fstream& DAT_outfile)
24
   DP Compute_Matrix_Element_Contrib (char whichDSF, int iKmin, int iKmax, ODSLF_XXZ_Bethe_State& LeftState,
22
   DP Compute_Matrix_Element_Contrib (char whichDSF, int iKmin, int iKmax, ODSLF_XXZ_Bethe_State& LeftState,
25
 				     ODSLF_XXZ_Bethe_State& RefState, DP Chem_Pot, fstream& DAT_outfile)
23
 				     ODSLF_XXZ_Bethe_State& RefState, DP Chem_Pot, fstream& DAT_outfile)
26
   {
24
   {
39
       ME = exp(real(ln_Smin_ME (RefState, LeftState)));
37
       ME = exp(real(ln_Smin_ME (RefState, LeftState)));
40
     else if (whichDSF == 'z') {
38
     else if (whichDSF == 'z') {
41
       if (LeftState.base_id == RefState.base_id && LeftState.type_id == RefState.type_id && LeftState.id == RefState.id)
39
       if (LeftState.base_id == RefState.base_id && LeftState.type_id == RefState.type_id && LeftState.id == RefState.id)
42
-	//MEsq = RefState.chain.Nsites * 0.25 * pow((1.0 - 2.0*RefState.base.Mdown/RefState.chain.Nsites), 2.0);
43
 	ME = sqrt(RefState.chain.Nsites * 0.25) * (1.0 - 2.0*RefState.base.Mdown/RefState.chain.Nsites);
40
 	ME = sqrt(RefState.chain.Nsites * 0.25) * (1.0 - 2.0*RefState.base.Mdown/RefState.chain.Nsites);
44
       else ME = exp(real(ln_Sz_ME (RefState, LeftState)));
41
       else ME = exp(real(ln_Sz_ME (RefState, LeftState)));
45
     }
42
     }
60
       if (whichDSF == 'Z') {
57
       if (whichDSF == 'Z') {
61
 	DAT_outfile << endl << LeftState.E - RefState.E - (LeftState.base.Mdown - RefState.base.Mdown) * Chem_Pot << "\t"
58
 	DAT_outfile << endl << LeftState.E - RefState.E - (LeftState.base.Mdown - RefState.base.Mdown) * Chem_Pot << "\t"
62
 		    << iKout << "\t"
59
 		    << iKout << "\t"
63
-	  //<< LeftState.conv << "\t"
64
 		    << LeftState.base_id << "\t" << LeftState.type_id << "\t" << LeftState.id;
60
 		    << LeftState.base_id << "\t" << LeftState.type_id << "\t" << LeftState.id;
65
       }
61
       }
66
       else {
62
       else {
67
 	DAT_outfile << endl << LeftState.E - RefState.E - (LeftState.base.Mdown - RefState.base.Mdown) * Chem_Pot << "\t"
63
 	DAT_outfile << endl << LeftState.E - RefState.E - (LeftState.base.Mdown - RefState.base.Mdown) * Chem_Pot << "\t"
68
 		    << iKout << "\t"
64
 		    << iKout << "\t"
69
 		    << ME << "\t"
65
 		    << ME << "\t"
70
-	  //<< LeftState.conv << "\t"
71
 		    << LeftState.base_id << "\t" << LeftState.type_id << "\t" << LeftState.id;
66
 		    << LeftState.base_id << "\t" << LeftState.type_id << "\t" << LeftState.id;
72
       }
67
       }
73
     } // if iKmin <= iKout <= iKmax
68
     } // if iKmin <= iKout <= iKmax
74
 
69
 
75
     // Calculate and return the data_value:
70
     // Calculate and return the data_value:
76
     DP data_value = ME * ME;
71
     DP data_value = ME * ME;
77
-    //DP data_value = (iKout == 0 ? 1.0 : 2.0) * MEsq;
78
     if (whichDSF == 'Z') // use 1/(1 + omega)
72
     if (whichDSF == 'Z') // use 1/(1 + omega)
79
       data_value = 1.0/(1.0 + LeftState.E - RefState.E - (LeftState.base.Mdown - RefState.base.Mdown) * Chem_Pot);
73
       data_value = 1.0/(1.0 + LeftState.E - RefState.E - (LeftState.base.Mdown - RefState.base.Mdown) * Chem_Pot);
80
     else if (fixed_iK) // data value is MEsq * omega:
74
     else if (fixed_iK) // data value is MEsq * omega:
83
     return(data_value);
77
     return(data_value);
84
   }
78
   }
85
 
79
 
86
-
87
 } // namespace ABACUS
80
 } // namespace ABACUS

+ 12
- 64
src/ODSLF/ODSLF_Sumrules.cc View File

59
 
59
 
60
       E0_Delta_eps = gstate2.E;
60
       E0_Delta_eps = gstate2.E;
61
     }
61
     }
62
-    /*
63
-    else if (Delta == 1.0) {
64
-      // Define the ground state
65
-      XXX_Bethe_State gstate(chain, gbase);
66
-
67
-      // Compute everything about the ground state
68
-      gstate.Compute_All(true);
69
-
70
-      E0_Delta = gstate.E;
71
-
72
-      // Define the ground state
73
-      XXZ_gpd_Bethe_State gstate2(chain2, gbase2);  // need XXZ_gpd here
74
-
75
-      // Compute everything about the ground state
76
-      gstate2.Compute_All(true);
77
-
78
-      E0_Delta_eps = gstate2.E;
79
-    }
80
-
81
-    else if (Delta > 1.0) {
82
-      // Define the ground state
83
-      XXZ_gpd_Bethe_State gstate(chain, gbase);
84
 
62
 
85
-      // Compute everything about the ground state
86
-      gstate.Compute_All(true);
87
-
88
-      E0_Delta = gstate.E;
89
-
90
-      // Define the ground state
91
-      XXZ_gpd_Bethe_State gstate2(chain2, gbase2);
92
-
93
-      // Compute everything about the ground state
94
-      gstate2.Compute_All(true);
95
-
96
-      E0_Delta_eps = gstate2.E;
97
-    }
98
-    */
99
     else ABACUSerror("Wrong anisotropy in ODSLF_S1_sumrule_factor.");
63
     else ABACUSerror("Wrong anisotropy in ODSLF_S1_sumrule_factor.");
100
 
64
 
101
     DP answer = 0.0;
65
     DP answer = 0.0;
117
 
81
 
118
     DP sumrule = 0.0;
82
     DP sumrule = 0.0;
119
 
83
 
120
-    if (mporz == 'm' || mporz == 'p') sumrule = - 2.0 * ((1.0 - Delta * cos((twoPI * iK)/N)) * X_x + (Delta - cos((twoPI * iK)/N)) * X_z)/N;
121
-    //if (mporz == 'm' || mporz == 'p') sumrule = - 1.0 * ((1.0 - Delta * cos((twoPI * iK)/N)) * 2.0 * X_x + (Delta - cos((twoPI * iK)/N)) * (X_x + X_z))/N;
84
+    if (mporz == 'm' || mporz == 'p')
85
+      sumrule = - 2.0 * ((1.0 - Delta * cos((twoPI * iK)/N)) * X_x + (Delta - cos((twoPI * iK)/N)) * X_z)/N;
122
 
86
 
123
     else if (mporz == 'z') sumrule = iK == 0 ? 1.0 : -2.0 * X_x * (1.0 - cos((twoPI * iK)/N))/N;
87
     else if (mporz == 'z') sumrule = iK == 0 ? 1.0 : -2.0 * X_x * (1.0 - cos((twoPI * iK)/N))/N;
124
 
88
 
127
 
91
 
128
     else ABACUSerror("option not implemented in ODSLF_S1_sumrule_factor.");
92
     else ABACUSerror("option not implemented in ODSLF_S1_sumrule_factor.");
129
 
93
 
130
-    //return(1.0/sumrule);
131
-    return(1.0/(sumrule + 1.0e-16)); // sumrule is 0 for iK == 0 or N
94
+    return(1.0/(sumrule + 1.0e-32)); // sumrule is 0 for iK == 0 or N
132
   }
95
   }
133
 
96
 
134
   DP ODSLF_S1_sumrule_factor (char mporz, DP Delta, int N, DP X_x, DP X_z, int iK)
97
   DP ODSLF_S1_sumrule_factor (char mporz, DP Delta, int N, DP X_x, DP X_z, int iK)
135
   {
98
   {
136
-
137
-    //DP X_x = X_avg ('x', Delta, N, M);
138
-    //DP X_z = X_avg ('z', Delta, N, M);
139
-
140
     DP sumrule = 0.0;
99
     DP sumrule = 0.0;
141
 
100
 
142
-    if (mporz == 'm' || mporz == 'p') sumrule = - 2.0 * ((1.0 - Delta * cos((twoPI * iK)/N)) * X_x + (Delta - cos((twoPI * iK)/N)) * X_z)/N;
143
-    //if (mporz == 'm' || mporz == 'p') sumrule = - 1.0 * ((1.0 - Delta * cos((twoPI * iK)/N)) * 2.0 * X_x + (Delta - cos((twoPI * iK)/N)) * (X_x + X_z))/N;
101
+    if (mporz == 'm' || mporz == 'p')
102
+      sumrule = - 2.0 * ((1.0 - Delta * cos((twoPI * iK)/N)) * X_x + (Delta - cos((twoPI * iK)/N)) * X_z)/N;
144
 
103
 
145
     else if (mporz == 'z') sumrule = -2.0 * X_x * (1.0 - cos((twoPI * iK)/N))/N;
104
     else if (mporz == 'z') sumrule = -2.0 * X_x * (1.0 - cos((twoPI * iK)/N))/N;
146
 
105
 
149
 
108
 
150
     else ABACUSerror("option not implemented in ODSLF_S1_sumrule_factor.");
109
     else ABACUSerror("option not implemented in ODSLF_S1_sumrule_factor.");
151
 
110
 
152
-    //return(1.0/sumrule);
153
-    return(1.0/(sumrule + 1.0e-16)); // sumrule is 0 for iK == 0 or N
111
+    return(1.0/(sumrule + 1.0e-32)); // sumrule is 0 for iK == 0 or N
154
   }
112
   }
155
 
113
 
156
-  //DP Sumrule_Factor (char whichDSF, Heis_Bethe_State& RefState, DP Chem_Pot, bool fixed_iK, int iKneeded)
157
   DP Sumrule_Factor (char whichDSF, ODSLF_Bethe_State& RefState, DP Chem_Pot, int iKmin, int iKmax)
114
   DP Sumrule_Factor (char whichDSF, ODSLF_Bethe_State& RefState, DP Chem_Pot, int iKmin, int iKmax)
158
   {
115
   {
159
     DP sumrule_factor = 1.0;
116
     DP sumrule_factor = 1.0;
160
-    //if (!fixed_iK) {
161
     if (iKmin != iKmax) {
117
     if (iKmin != iKmax) {
162
       if (whichDSF == 'Z') sumrule_factor = 1.0;
118
       if (whichDSF == 'Z') sumrule_factor = 1.0;
163
       else if (whichDSF == 'm')
119
       else if (whichDSF == 'm')
170
 
126
 
171
       else ABACUSerror("whichDSF option not consistent in Sumrule_Factor");
127
       else ABACUSerror("whichDSF option not consistent in Sumrule_Factor");
172
     }
128
     }
173
-    //else if (fixed_iK) {
174
     else if (iKmin == iKmax) {
129
     else if (iKmin == iKmax) {
175
       if (whichDSF == 'Z') sumrule_factor = 1.0;
130
       if (whichDSF == 'Z') sumrule_factor = 1.0;
176
       else if (whichDSF == 'm' || whichDSF == 'z' || whichDSF == 'p')
131
       else if (whichDSF == 'm' || whichDSF == 'z' || whichDSF == 'p')
177
-	//sumrule_factor = S1_sumrule_factor (whichDSF, RefState.chain.Delta, RefState.chain.Nsites, RefState.base.Mdown, iKneeded);
178
-	sumrule_factor = ODSLF_S1_sumrule_factor (whichDSF, RefState.chain.Delta, RefState.chain.Nsites, RefState.base.Mdown, iKmax);
132
+	sumrule_factor = ODSLF_S1_sumrule_factor (whichDSF, RefState.chain.Delta, RefState.chain.Nsites,
133
+						  RefState.base.Mdown, iKmax);
179
       else if (whichDSF == 'a') sumrule_factor = 1.0;
134
       else if (whichDSF == 'a') sumrule_factor = 1.0;
180
       else if (whichDSF == 'b') sumrule_factor = 1.0;
135
       else if (whichDSF == 'b') sumrule_factor = 1.0;
181
       else if (whichDSF == 'q') sumrule_factor = 1.0;
136
       else if (whichDSF == 'q') sumrule_factor = 1.0;
188
     return(sumrule_factor);
143
     return(sumrule_factor);
189
   }
144
   }
190
 
145
 
191
-  //void Evaluate_F_Sumrule (char whichDSF, const ODSLF_Bethe_State& RefState, DP Chem_Pot, int iKmin, int iKmax, const char* FFsq_Cstr, const char* FSR_Cstr)
192
-  void Evaluate_F_Sumrule (string prefix, char whichDSF, const ODSLF_Bethe_State& RefState, DP Chem_Pot, int iKmin, int iKmax)
146
+  void Evaluate_F_Sumrule (string prefix, char whichDSF, const ODSLF_Bethe_State& RefState,
147
+			   DP Chem_Pot, int iKmin, int iKmax)
193
   {
148
   {
194
 
149
 
195
     stringstream RAW_stringstream;    string RAW_string;
150
     stringstream RAW_stringstream;    string RAW_string;
205
     if(infile.fail()) ABACUSerror("Could not open input file in Evaluate_F_Sumrule(ODSLF...).");
160
     if(infile.fail()) ABACUSerror("Could not open input file in Evaluate_F_Sumrule(ODSLF...).");
206
 
161
 
207
     // We run through the data file to chech the f sumrule at each positive momenta:
162
     // We run through the data file to chech the f sumrule at each positive momenta:
208
-    //Vect<DP> Sum_omega_FFsq(0.0, RefState.chain.Nsites/2 + 1);  //
209
     Vect<DP> Sum_omega_FFsq(0.0, iKmax - iKmin + 1);  //
163
     Vect<DP> Sum_omega_FFsq(0.0, iKmax - iKmin + 1);  //
210
 
164
 
211
     DP omega, FF;
165
     DP omega, FF;
214
 
168
 
215
     while (infile.peek() != EOF) {
169
     while (infile.peek() != EOF) {
216
       infile >> omega >> iK >> FF >> conv >> base_id >> type_id >> id;
170
       infile >> omega >> iK >> FF >> conv >> base_id >> type_id >> id;
217
-      //if (iK > 0 && iK <= RefState.chain.Nsites/2) Sum_omega_FFsq[iK] += omega * FFsq;
218
       if (iK >= iKmin && iK <= iKmax) Sum_omega_FFsq[iK - iKmin] += omega * FF * FF;
171
       if (iK >= iKmin && iK <= iKmax) Sum_omega_FFsq[iK - iKmin] += omega * FF * FF;
219
     }
172
     }
220
 
173
 
227
     DP X_x = X_avg ('x', RefState.chain.Delta, RefState.chain.Nsites, RefState.base.Mdown);
180
     DP X_x = X_avg ('x', RefState.chain.Delta, RefState.chain.Nsites, RefState.base.Mdown);
228
     DP X_z = X_avg ('z', RefState.chain.Delta, RefState.chain.Nsites, RefState.base.Mdown);
181
     DP X_z = X_avg ('z', RefState.chain.Delta, RefState.chain.Nsites, RefState.base.Mdown);
229
 
182
 
230
-    /*
231
-    outfile << 0 << "\t" << Sum_omega_FFsq[0] * S1_sumrule_factor (whichDSF, RefState.chain.Delta, RefState.chain.Nsites, X_x, X_z, 0);
232
-    for (int i = 1; i <= RefState.chain.Nsites/2; ++i)
233
-      outfile << endl << i << "\t" << Sum_omega_FFsq[i] * S1_sumrule_factor (whichDSF, RefState.chain.Delta, RefState.chain.Nsites, X_x, X_z, i);
234
-    */
235
-
236
     for (int i = iKmin; i <= iKmax; ++i) {
183
     for (int i = iKmin; i <= iKmax; ++i) {
237
       if (i > iKmin) outfile << endl;
184
       if (i > iKmin) outfile << endl;
238
-      outfile << i << "\t" << Sum_omega_FFsq[i] * ODSLF_S1_sumrule_factor (whichDSF, RefState.chain.Delta, RefState.chain.Nsites, X_x, X_z, i);
185
+      outfile << i << "\t" << Sum_omega_FFsq[i] * ODSLF_S1_sumrule_factor (whichDSF, RefState.chain.Delta,
186
+									   RefState.chain.Nsites, X_x, X_z, i);
239
     }
187
     }
240
 
188
 
241
     outfile.close();
189
     outfile.close();

+ 92
- 84
src/ODSLF/ODSLF_XXZ_Bethe_State.cc View File

31
   // Function definitions:  class ODSLF_XXZ_Bethe_State
31
   // Function definitions:  class ODSLF_XXZ_Bethe_State
32
 
32
 
33
   ODSLF_XXZ_Bethe_State::ODSLF_XXZ_Bethe_State ()
33
   ODSLF_XXZ_Bethe_State::ODSLF_XXZ_Bethe_State ()
34
-    : ODSLF_Bethe_State(), sinhlambda(ODSLF_Lambda(chain, 1)), coshlambda(ODSLF_Lambda(chain, 1)), tanhlambda(ODSLF_Lambda(chain, 1))
34
+    : ODSLF_Bethe_State(), sinhlambda(ODSLF_Lambda(chain, 1)), coshlambda(ODSLF_Lambda(chain, 1)),
35
+      tanhlambda(ODSLF_Lambda(chain, 1))
35
   {};
36
   {};
36
 
37
 
37
   ODSLF_XXZ_Bethe_State::ODSLF_XXZ_Bethe_State (const ODSLF_XXZ_Bethe_State& RefState) // copy constructor
38
   ODSLF_XXZ_Bethe_State::ODSLF_XXZ_Bethe_State (const ODSLF_XXZ_Bethe_State& RefState) // copy constructor
38
-    : ODSLF_Bethe_State(RefState), sinhlambda(ODSLF_Lambda(RefState.chain, RefState.base)), coshlambda(ODSLF_Lambda(RefState.chain, RefState.base)),
39
+    : ODSLF_Bethe_State(RefState), sinhlambda(ODSLF_Lambda(RefState.chain, RefState.base)),
40
+      coshlambda(ODSLF_Lambda(RefState.chain, RefState.base)),
39
       tanhlambda(ODSLF_Lambda(RefState.chain, RefState.base))
41
       tanhlambda(ODSLF_Lambda(RefState.chain, RefState.base))
40
   {
42
   {
41
     // copy arrays into new ones
43
     // copy arrays into new ones
58
     //cout << "Here in XXZ BS constructor." << endl;
60
     //cout << "Here in XXZ BS constructor." << endl;
59
     //cout << (*this).lambda[0][0] << endl;
61
     //cout << (*this).lambda[0][0] << endl;
60
     //cout << "OK" << endl;
62
     //cout << "OK" << endl;
61
-    if ((RefChain.Delta <= -1.0) || (RefChain.Delta >= 1.0)) ABACUSerror("Delta out of range in ODSLF_XXZ_Bethe_State constructor");
63
+    if ((RefChain.Delta <= -1.0) || (RefChain.Delta >= 1.0))
64
+      ABACUSerror("Delta out of range in ODSLF_XXZ_Bethe_State constructor");
62
   }
65
   }
63
 
66
 
64
   ODSLF_XXZ_Bethe_State::ODSLF_XXZ_Bethe_State (const Heis_Chain& RefChain, const ODSLF_Base& RefBase)
67
   ODSLF_XXZ_Bethe_State::ODSLF_XXZ_Bethe_State (const Heis_Chain& RefChain, const ODSLF_Base& RefBase)
65
     : ODSLF_Bethe_State(RefChain, RefBase),
68
     : ODSLF_Bethe_State(RefChain, RefBase),
66
-      sinhlambda(ODSLF_Lambda(RefChain, RefBase)), coshlambda(ODSLF_Lambda(RefChain, RefBase)), tanhlambda(ODSLF_Lambda(RefChain, RefBase))
69
+      sinhlambda(ODSLF_Lambda(RefChain, RefBase)), coshlambda(ODSLF_Lambda(RefChain, RefBase)),
70
+      tanhlambda(ODSLF_Lambda(RefChain, RefBase))
67
   {
71
   {
68
-    if ((RefChain.Delta <= -1.0) || (RefChain.Delta >= 1.0)) ABACUSerror("Delta out of range in ODSLF_XXZ_Bethe_State constructor");
72
+    if ((RefChain.Delta <= -1.0) || (RefChain.Delta >= 1.0))
73
+      ABACUSerror("Delta out of range in ODSLF_XXZ_Bethe_State constructor");
69
   }
74
   }
70
 
75
 
71
-  ODSLF_XXZ_Bethe_State::ODSLF_XXZ_Bethe_State (const Heis_Chain& RefChain, long long int base_id_ref, long long int type_id_ref)
76
+  ODSLF_XXZ_Bethe_State::ODSLF_XXZ_Bethe_State (const Heis_Chain& RefChain,
77
+						long long int base_id_ref, long long int type_id_ref)
72
     : ODSLF_Bethe_State(RefChain, base_id_ref, type_id_ref),
78
     : ODSLF_Bethe_State(RefChain, base_id_ref, type_id_ref),
73
       sinhlambda(ODSLF_Lambda(chain, base)), coshlambda(ODSLF_Lambda(chain, base)), tanhlambda(ODSLF_Lambda(chain, base))
79
       sinhlambda(ODSLF_Lambda(chain, base)), coshlambda(ODSLF_Lambda(chain, base)), tanhlambda(ODSLF_Lambda(chain, base))
74
   {
80
   {
75
-    if ((RefChain.Delta <= -1.0) || (RefChain.Delta >= 1.0)) ABACUSerror("Delta out of range in ODSLF_XXZ_Bethe_State constructor");
81
+    if ((RefChain.Delta <= -1.0) || (RefChain.Delta >= 1.0))
82
+      ABACUSerror("Delta out of range in ODSLF_XXZ_Bethe_State constructor");
76
   }
83
   }
77
 
84
 
78
 
85
 
116
 
123
 
117
       for (int alpha = 0; alpha < base[i]; ++alpha) {
124
       for (int alpha = 0; alpha < base[i]; ++alpha) {
118
 
125
 
119
-	if(chain.par[i] == 1) lambda[i][alpha] = (tan(chain.Str_L[i] * 0.5 * chain.anis) * tan(PI * 0.5 * Ix2[i][alpha]/chain.Nsites));
120
-	else if (chain.par[i] == -1) lambda[i][alpha] = (-tan((PI * 0.5 * Ix2[i][alpha])/chain.Nsites)/tan(chain.Str_L[i] * 0.5 * chain.anis));
126
+	if(chain.par[i] == 1)
127
+	  lambda[i][alpha] = (tan(chain.Str_L[i] * 0.5 * chain.anis) * tan(PI * 0.5 * Ix2[i][alpha]/chain.Nsites));
128
+	else if (chain.par[i] == -1)
129
+	  lambda[i][alpha] = (-tan((PI * 0.5 * Ix2[i][alpha])/chain.Nsites)/tan(chain.Str_L[i] * 0.5 * chain.anis));
121
 
130
 
122
 	else ABACUSerror("Invalid parities in Set_Free_lambdas.");
131
 	else ABACUSerror("Invalid parities in Set_Free_lambdas.");
123
 
132
 
124
-	//	if (lambda[i][alpha] == 0.0) lambda[i][alpha] = 0.001 * (1.0 + i) * (1.0 + alpha) / chain.Nsites;  // some arbitrary starting point here...
125
-
126
       }
133
       }
127
     }
134
     }
128
 
135
 
168
     bool higher_string_on_zero = false;
175
     bool higher_string_on_zero = false;
169
     for (int j = 0; j < chain.Nstrings; ++j) {
176
     for (int j = 0; j < chain.Nstrings; ++j) {
170
       // The following line puts answer to true if there is at least one higher string with zero Ix2
177
       // The following line puts answer to true if there is at least one higher string with zero Ix2
171
-      for (int alpha = 0; alpha < base[j]; ++alpha) if ((Ix2[j][alpha] == 0) && (chain.Str_L[j] >= 2) /*&& !(chain.Str_L[j] % 2)*/)
172
-	higher_string_on_zero = true;
178
+      for (int alpha = 0; alpha < base[j]; ++alpha) if ((Ix2[j][alpha] == 0) && (chain.Str_L[j] >= 2))
179
+						      higher_string_on_zero = true;
173
       for (int alpha = 0; alpha < base[j]; ++alpha) if (Ix2[j][alpha] == 0) Zero_at_level[j] = true;
180
       for (int alpha = 0; alpha < base[j]; ++alpha) if (Ix2[j][alpha] == 0) Zero_at_level[j] = true;
174
       // NOTE:  if base[j] == 0, Zero_at_level[j] remains false.
181
       // NOTE:  if base[j] == 0, Zero_at_level[j] remains false.
175
     }
182
     }
181
     bool string_coincidence = false;
188
     bool string_coincidence = false;
182
     for (int j1 = 0; j1 < chain.Nstrings; ++j1) {
189
     for (int j1 = 0; j1 < chain.Nstrings; ++j1) {
183
       for (int j2 = j1 + 1; j2 < chain.Nstrings; ++j2)
190
       for (int j2 = j1 + 1; j2 < chain.Nstrings; ++j2)
184
-	if (Zero_at_level[j1] && Zero_at_level[j2] && (chain.par[j1] == chain.par[j2]) && (!((chain.Str_L[j1] + chain.Str_L[j2])%2)))
191
+	if (Zero_at_level[j1] && Zero_at_level[j2] && (chain.par[j1] == chain.par[j2])
192
+	    && (!((chain.Str_L[j1] + chain.Str_L[j2])%2)))
185
 	  string_coincidence = true;
193
 	  string_coincidence = true;
186
     }
194
     }
187
 
195
 
188
     bool M_odd_and_onep_on_zero = false;
196
     bool M_odd_and_onep_on_zero = false;
189
     if (option == 'z') { // for Sz, if M is odd, exclude symmetric states with a 1+ on zero
197
     if (option == 'z') { // for Sz, if M is odd, exclude symmetric states with a 1+ on zero
190
                          // (zero rapidities in left and right states, so FF det not defined).
198
                          // (zero rapidities in left and right states, so FF det not defined).
191
-      bool is_ground_state = base.Nrap[0] == base.Mdown && Ix2[0][0] == -(base.Mdown - 1) && Ix2[0][base.Mdown-1] == base.Mdown - 1;
199
+      bool is_ground_state = base.Nrap[0] == base.Mdown && Ix2[0][0] == -(base.Mdown - 1)
200
+	&& Ix2[0][base.Mdown-1] == base.Mdown - 1;
192
       if (Zero_at_level[0] && (base.Mdown % 2) && !is_ground_state) M_odd_and_onep_on_zero = true;
201
       if (Zero_at_level[0] && (base.Mdown % 2) && !is_ground_state) M_odd_and_onep_on_zero = true;
193
     }
202
     }
194
 
203
 
197
       if (Zero_at_level[0] && Zero_at_level[1]) onep_onem_on_zero = true;
206
       if (Zero_at_level[0] && Zero_at_level[1]) onep_onem_on_zero = true;
198
     }
207
     }
199
 
208
 
200
-    answer = !(symmetric_state && (higher_string_on_zero || string_coincidence || onep_onem_on_zero || M_odd_and_onep_on_zero));
209
+    answer = !(symmetric_state && (higher_string_on_zero || string_coincidence
210
+				   || onep_onem_on_zero || M_odd_and_onep_on_zero));
201
 
211
 
202
     // Now check that no Ix2 is equal to +N (since we take -N into account, and I + N == I by periodicity of exp)
212
     // Now check that no Ix2 is equal to +N (since we take -N into account, and I + N == I by periodicity of exp)
203
 
213
 
204
     for (int j = 0; j < chain.Nstrings; ++j)
214
     for (int j = 0; j < chain.Nstrings; ++j)
205
-      for (int alpha = 0; alpha < base[j]; ++alpha) if ((Ix2[j][alpha] < -chain.Nsites) || (Ix2[j][alpha] >= chain.Nsites)) answer = false;
215
+      for (int alpha = 0; alpha < base[j]; ++alpha)
216
+	if ((Ix2[j][alpha] < -chain.Nsites) || (Ix2[j][alpha] >= chain.Nsites)) answer = false;
206
 
217
 
207
     if (!answer) {
218
     if (!answer) {
208
       E = 0.0;
219
       E = 0.0;
226
       for (int beta = 0; beta < base[k]; ++beta) {
237
       for (int beta = 0; beta < base[k]; ++beta) {
227
 	if ((chain.Str_L[j] == 1) && (chain.Str_L[k] == 1))
238
 	if ((chain.Str_L[j] == 1) && (chain.Str_L[k] == 1))
228
 	  sumtheta += (chain.par[j] == chain.par[k])
239
 	  sumtheta += (chain.par[j] == chain.par[k])
229
-	    ? atan((tanhlambda[j][alpha] - tanhlambda[k][beta])/((1.0 - tanhlambda[j][alpha] * tanhlambda[k][beta]) * chain.ta_n_anis_over_2[2]))
230
-	    : - atan(((tanhlambda[j][alpha] - tanhlambda[k][beta])/(1.0 - tanhlambda[j][alpha] * tanhlambda[k][beta])) * chain.ta_n_anis_over_2[2]) ;
231
-	else sumtheta += 0.5 * ODSLF_Theta_XXZ((tanhlambda[j][alpha] - tanhlambda[k][beta])/(1.0 - tanhlambda[j][alpha] * tanhlambda[k][beta]),
232
-					 chain.Str_L[j], chain.Str_L[k], chain.par[j], chain.par[k], chain.ta_n_anis_over_2);
240
+	    ? atan((tanhlambda[j][alpha] - tanhlambda[k][beta])
241
+		   /((1.0 - tanhlambda[j][alpha] * tanhlambda[k][beta]) * chain.ta_n_anis_over_2[2]))
242
+	    : - atan(((tanhlambda[j][alpha] - tanhlambda[k][beta])
243
+		      /(1.0 - tanhlambda[j][alpha] * tanhlambda[k][beta])) * chain.ta_n_anis_over_2[2]) ;
244
+	else sumtheta += 0.5 * ODSLF_Theta_XXZ((tanhlambda[j][alpha] - tanhlambda[k][beta])
245
+					       /(1.0 - tanhlambda[j][alpha] * tanhlambda[k][beta]),
246
+					       chain.Str_L[j], chain.Str_L[k], chain.par[j], chain.par[k],
247
+					       chain.ta_n_anis_over_2);
233
       }
248
       }
234
     sumtheta *= 2.0;
249
     sumtheta *= 2.0;
235
 
250
 
236
-    BE[j][alpha] = ((chain.par[j] == 1) ? 2.0 * atan(tanhlambda[j][alpha]/chain.ta_n_anis_over_2[chain.Str_L[j]])
237
-		    : -2.0 * atan(tanhlambda[j][alpha] * chain.ta_n_anis_over_2[chain.Str_L[j]])) - (sumtheta + PI*Ix2[j][alpha])/chain.Nsites;
251
+    BE[j][alpha] =
252
+      ((chain.par[j] == 1) ? 2.0 * atan(tanhlambda[j][alpha]/chain.ta_n_anis_over_2[chain.Str_L[j]])
253
+       : -2.0 * atan(tanhlambda[j][alpha] * chain.ta_n_anis_over_2[chain.Str_L[j]]))
254
+      - (sumtheta + PI*Ix2[j][alpha])/chain.Nsites;
238
 
255
 
239
-   }
256
+  }
240
 
257
 
241
   void ODSLF_XXZ_Bethe_State::Compute_BE ()
258
   void ODSLF_XXZ_Bethe_State::Compute_BE ()
242
   {
259
   {
254
 	  for (int beta = 0; beta < base[k]; ++beta) {
271
 	  for (int beta = 0; beta < base[k]; ++beta) {
255
 	    if ((chain.Str_L[j] == 1) && (chain.Str_L[k] == 1))
272
 	    if ((chain.Str_L[j] == 1) && (chain.Str_L[k] == 1))
256
 	      sumtheta += (chain.par[j] == chain.par[k])
273
 	      sumtheta += (chain.par[j] == chain.par[k])
257
-		? atan((tanhlambda[j][alpha] - tanhlambda[k][beta])/((1.0 - tanhlambda[j][alpha] * tanhlambda[k][beta]) * chain.ta_n_anis_over_2[2]))
258
-		: - atan(((tanhlambda[j][alpha] - tanhlambda[k][beta])/(1.0 - tanhlambda[j][alpha] * tanhlambda[k][beta])) * chain.ta_n_anis_over_2[2]) ;
259
-	    else sumtheta += 0.5 * ODSLF_Theta_XXZ((tanhlambda[j][alpha] - tanhlambda[k][beta])/(1.0 - tanhlambda[j][alpha] * tanhlambda[k][beta]),
260
-					     chain.Str_L[j], chain.Str_L[k], chain.par[j], chain.par[k], chain.ta_n_anis_over_2);
274
+		? atan((tanhlambda[j][alpha] - tanhlambda[k][beta])
275
+		       /((1.0 - tanhlambda[j][alpha] * tanhlambda[k][beta]) * chain.ta_n_anis_over_2[2]))
276
+		: - atan(((tanhlambda[j][alpha] - tanhlambda[k][beta])
277
+			  /(1.0 - tanhlambda[j][alpha] * tanhlambda[k][beta])) * chain.ta_n_anis_over_2[2]) ;
278
+	    else sumtheta += 0.5 * ODSLF_Theta_XXZ((tanhlambda[j][alpha] - tanhlambda[k][beta])
279
+						   /(1.0 - tanhlambda[j][alpha] * tanhlambda[k][beta]),
280
+						   chain.Str_L[j], chain.Str_L[k], chain.par[j], chain.par[k],
281
+						   chain.ta_n_anis_over_2);
261
 	  }
282
 	  }
262
 	sumtheta *= 2.0;
283
 	sumtheta *= 2.0;
263
 
284
 
264
-	BE[j][alpha] = ((chain.par[j] == 1) ? 2.0 * atan(tanhlambda[j][alpha]/chain.ta_n_anis_over_2[chain.Str_L[j]])
265
-			: -2.0 * atan(tanhlambda[j][alpha] * chain.ta_n_anis_over_2[chain.Str_L[j]])) - (sumtheta + PI*Ix2[j][alpha])/chain.Nsites;
285
+	BE[j][alpha] =
286
+	  ((chain.par[j] == 1) ? 2.0 * atan(tanhlambda[j][alpha]/chain.ta_n_anis_over_2[chain.Str_L[j]])
287
+	   : -2.0 * atan(tanhlambda[j][alpha] * chain.ta_n_anis_over_2[chain.Str_L[j]]))
288
+	  - (sumtheta + PI*Ix2[j][alpha])/chain.Nsites;
266
 
289
 
267
-	//if (is_nan(BE[j][alpha])) cout << "BE nan: " << j << "\t" << alpha << "\t" << lambda[j][alpha] << "\t" << tanhlambda[j][alpha] << endl;
268
       }
290
       }
269
   }
291
   }
270
 
292
 
277
     DP arg = 0.0;
299
     DP arg = 0.0;
278
 
300
 
279
     if (chain.par[j] == 1) arg = chain.ta_n_anis_over_2[chain.Str_L[j]]
301
     if (chain.par[j] == 1) arg = chain.ta_n_anis_over_2[chain.Str_L[j]]
280
-      * tan(0.5 *
281
-	    //(PI * Ix2[j][alpha] + sumtheta)/chain.Nsites
282
-	    (2.0 * atan(tanhlambda[j][alpha]/chain.ta_n_anis_over_2[chain.Str_L[j]]) - BE[j][alpha])
283
-	    );
302
+			     * tan(0.5 *
303
+				   //(PI * Ix2[j][alpha] + sumtheta)/chain.Nsites
304
+				   (2.0 * atan(tanhlambda[j][alpha]/chain.ta_n_anis_over_2[chain.Str_L[j]]) - BE[j][alpha])
305
+				   );
284
 
306
 
285
-    else if (chain.par[j] == -1) arg = -tan(0.5 *
286
-					    //(PI * Ix2[j][alpha] + sumtheta)/chain.Nsites)
287
-					    (-2.0 * atan(tanhlambda[j][alpha] * chain.ta_n_anis_over_2[chain.Str_L[j]]) - BE[j][alpha]))
288
-      /chain.ta_n_anis_over_2[chain.Str_L[j]];
307
+    else if (chain.par[j] == -1)
308
+      arg = -tan(0.5 *
309
+		 (-2.0 * atan(tanhlambda[j][alpha] * chain.ta_n_anis_over_2[chain.Str_L[j]]) - BE[j][alpha]))
310
+	/chain.ta_n_anis_over_2[chain.Str_L[j]];
289
 
311
 
290
     if (fabs(arg) < 1.0) {
312
     if (fabs(arg) < 1.0) {
291
       new_lambda = atanh(arg);
313
       new_lambda = atanh(arg);
305
 	  for (int beta = 0; beta < base[k]; ++beta)
327
 	  for (int beta = 0; beta < base[k]; ++beta)
306
 	    if ((chain.Str_L[j] == 1) && (chain.Str_L[k] == 1))
328
 	    if ((chain.Str_L[j] == 1) && (chain.Str_L[k] == 1))
307
 	      sumtheta += (chain.par[j] == chain.par[k])
329
 	      sumtheta += (chain.par[j] == chain.par[k])
308
-		? atan((new_tanhlambda - tanhlambda[k][beta])/((1.0 - new_tanhlambda * tanhlambda[k][beta]) * chain.ta_n_anis_over_2[2]))
309
-		: - atan(((new_tanhlambda - tanhlambda[k][beta])/(1.0 - new_tanhlambda * tanhlambda[k][beta])) * chain.ta_n_anis_over_2[2]) ;
310
-	    else sumtheta += 0.5 * ODSLF_Theta_XXZ((new_tanhlambda - tanhlambda[k][beta])/(1.0 - new_tanhlambda * tanhlambda[k][beta]),
311
-					     chain.Str_L[j], chain.Str_L[k], chain.par[j], chain.par[k], chain.ta_n_anis_over_2);
330
+		? atan((new_tanhlambda - tanhlambda[k][beta])
331
+		       /((1.0 - new_tanhlambda * tanhlambda[k][beta]) * chain.ta_n_anis_over_2[2]))
332
+		: - atan(((new_tanhlambda - tanhlambda[k][beta])
333
+			  /(1.0 - new_tanhlambda * tanhlambda[k][beta])) * chain.ta_n_anis_over_2[2]) ;
334
+	    else sumtheta += 0.5 * ODSLF_Theta_XXZ((new_tanhlambda - tanhlambda[k][beta])
335
+						   /(1.0 - new_tanhlambda * tanhlambda[k][beta]),
336
+						   chain.Str_L[j], chain.Str_L[k], chain.par[j], chain.par[k],
337
+						   chain.ta_n_anis_over_2);
312
 	}
338
 	}
313
 	sumtheta *= 2.0;
339
 	sumtheta *= 2.0;
314
-	if (chain.par[j] == 1) arg = chain.ta_n_anis_over_2[chain.Str_L[j]] * tan(0.5 * (PI * Ix2[j][alpha] + sumtheta)/chain.Nsites);
340
+	if (chain.par[j] == 1)
341
+	  arg = chain.ta_n_anis_over_2[chain.Str_L[j]] * tan(0.5 * (PI * Ix2[j][alpha] + sumtheta)/chain.Nsites);
315
 
342
 
316
-	else if (chain.par[j] == -1) arg = -tan(0.5 * (PI * Ix2[j][alpha] + sumtheta)/chain.Nsites)/chain.ta_n_anis_over_2[chain.Str_L[j]];
343
+	else if (chain.par[j] == -1)
344
+	  arg = -tan(0.5 * (PI * Ix2[j][alpha] + sumtheta)/chain.Nsites)/chain.ta_n_anis_over_2[chain.Str_L[j]];
317
 
345
 
318
 	else ABACUSerror("Invalid parities in Iterate_BAE.");
346
 	else ABACUSerror("Invalid parities in Iterate_BAE.");
319
 
347
 
320
       }
348
       }
321
 
349
 
322
-      //cout << "Rapidity blows up !\t" << lambda[j][alpha] << "\t" << new_lambda << endl;
323
     }
350
     }
324
 
351
 
325
     return(new_lambda);
352
     return(new_lambda);
341
 
368
 
342
     for (int j = 0; j < chain.Nstrings; ++j) {
369
     for (int j = 0; j < chain.Nstrings; ++j) {
343
       for (int alpha = 0; alpha < base[j]; ++alpha) {
370
       for (int alpha = 0; alpha < base[j]; ++alpha) {
344
-	sum += sin(chain.Str_L[j] * chain.anis) / (chain.par[j] * cosh(2.0 * lambda[j][alpha]) - cos(chain.Str_L[j] * chain.anis));
371
+	sum += sin(chain.Str_L[j] * chain.anis)
372
+	  / (chain.par[j] * cosh(2.0 * lambda[j][alpha]) - cos(chain.Str_L[j] * chain.anis));
345
       }
373
       }
346
     }
374
     }
347
 
375
 
352
     return;
380
     return;
353
   }
381
   }
354
 
382
 
355
-  /*
356
-  void XXZ_Bethe_State::Compute_Momentum ()
357
-  {
358
-    int sum_Ix2 = 0;
359
-    DP sum_M = 0.0;
360
-
361
-    for (int j = 0; j < chain.Nstrings; ++j) {
362
-      sum_M += 0.5 * (1.0 + chain.par[j]) * base[j];
363
-      for (int alpha = 0; alpha < base[j]; ++alpha) {
364
-	sum_Ix2 += Ix2[j][alpha];
365
-      }
366
-    }
367
-
368
-    iK = (chain.Nsites/2) * int(sum_M + 0.1) - (sum_Ix2/2);  // + 0.1:  for safety...
369
-
370
-    while (iK >= chain.Nsites) iK -= chain.Nsites;
371
-    while (iK < 0) iK += chain.Nsites;
372
-
373
-    K = PI * sum_M - PI * sum_Ix2/chain.Nsites;
374
-
375
-    while (K >= 2.0*PI) K -= 2.0*PI;
376
-    while (K < 0.0) K += 2.0*PI;
377
-
378
-    return;
379
-  }
380
-  */
381
   void ODSLF_XXZ_Bethe_State::Build_Reduced_Gaudin_Matrix (SQMat<complex<DP> >& Gaudin_Red)
383
   void ODSLF_XXZ_Bethe_State::Build_Reduced_Gaudin_Matrix (SQMat<complex<DP> >& Gaudin_Red)
382
   {
384
   {
383
 
385
 
408
 		for (int betap = 0; betap < base[kp]; ++betap) {
410
 		for (int betap = 0; betap < base[kp]; ++betap) {
409
 		  if (!((j == kp) && (alpha == betap)))
411
 		  if (!((j == kp) && (alpha == betap)))
410
 		    sum_hbar_XXZ
412
 		    sum_hbar_XXZ
411
-		      += ODSLF_ddlambda_Theta_XXZ (lambda[j][alpha] - lambda[kp][betap], chain.Str_L[j], chain.Str_L[kp], chain.par[j], chain.par[kp],
412
-					     chain.si_n_anis_over_2);
413
+		      += ODSLF_ddlambda_Theta_XXZ (lambda[j][alpha] - lambda[kp][betap], chain.Str_L[j], chain.Str_L[kp],
414
+						   chain.par[j], chain.par[kp], chain.si_n_anis_over_2);
413
 		}
415
 		}
414
 	      }
416
 	      }
415
 
417
 
416
 	      Gaudin_Red[index_jalpha][index_kbeta]
418
 	      Gaudin_Red[index_jalpha][index_kbeta]
417
-		= complex<DP> ( chain.Nsites * ODSLF_hbar_XXZ (lambda[j][alpha], chain.Str_L[j], chain.par[j], chain.si_n_anis_over_2) - sum_hbar_XXZ);
419
+		= complex<DP> ( chain.Nsites * ODSLF_hbar_XXZ (lambda[j][alpha], chain.Str_L[j], chain.par[j],
420
+							       chain.si_n_anis_over_2) - sum_hbar_XXZ);
418
 	    }
421
 	    }
419
 
422
 
420
 	    else {
423
 	    else {
421
 	      if ((chain.Str_L[j] == 1) && (chain.Str_L[k] == 1))
424
 	      if ((chain.Str_L[j] == 1) && (chain.Str_L[k] == 1))
422
 		Gaudin_Red[index_jalpha][index_kbeta] =
425
 		Gaudin_Red[index_jalpha][index_kbeta] =
423
 		  complex<DP> ((chain.par[j] * chain.par[k] == 1)
426
 		  complex<DP> ((chain.par[j] * chain.par[k] == 1)
424
-			       ? chain.si_n_anis_over_2[4]/(pow(sinhlambda[j][alpha] * coshlambda[k][beta]
425
-								 - coshlambda[j][alpha] * sinhlambda[k][beta], 2.0) + sinzetasq)
426
-			       : chain.si_n_anis_over_2[4]/(-pow(coshlambda[j][alpha] * coshlambda[k][beta]
427
-								  - sinhlambda[j][alpha] * sinhlambda[k][beta], 2.0) + sinzetasq) );
427
+			       ? chain.si_n_anis_over_2[4]
428
+			       /(pow(sinhlambda[j][alpha] * coshlambda[k][beta]
429
+				     - coshlambda[j][alpha] * sinhlambda[k][beta], 2.0) + sinzetasq)
430
+			       : chain.si_n_anis_over_2[4]
431
+			       /(-pow(coshlambda[j][alpha] * coshlambda[k][beta]
432
+				      - sinhlambda[j][alpha] * sinhlambda[k][beta], 2.0) + sinzetasq) );
428
 	      else
433
 	      else
429
-		Gaudin_Red[index_jalpha][index_kbeta] = complex<DP> (ODSLF_ddlambda_Theta_XXZ (lambda[j][alpha] - lambda[k][beta], chain.Str_L[j], chain.Str_L[k],
430
-											  chain.par[j], chain.par[k], chain.si_n_anis_over_2));
434
+		Gaudin_Red[index_jalpha][index_kbeta] =
435
+		  complex<DP> (ODSLF_ddlambda_Theta_XXZ (lambda[j][alpha] - lambda[k][beta], chain.Str_L[j], chain.Str_L[k],
436
+							 chain.par[j], chain.par[k], chain.si_n_anis_over_2));
431
 	    }
437
 	    }
432
 	    index_kbeta++;
438
 	    index_kbeta++;
433
 	  }
439
 	  }
465
 
471
 
466
       result = (nj == nk) ? 0.0 : ODSLF_fbar_XXZ(tanhlambda, parj*park, tannzetaover2[fabs(nj - nk)]);
472
       result = (nj == nk) ? 0.0 : ODSLF_fbar_XXZ(tanhlambda, parj*park, tannzetaover2[fabs(nj - nk)]);
467
 
473
 
468
-      for (int a = 1; a < ABACUS::min(nj, nk); ++a) result += 2.0 * ODSLF_fbar_XXZ(tanhlambda, parj*park, tannzetaover2[fabs(nj - nk) + 2*a]);
474
+      for (int a = 1; a < ABACUS::min(nj, nk); ++a)
475
+	result += 2.0 * ODSLF_fbar_XXZ(tanhlambda, parj*park, tannzetaover2[fabs(nj - nk) + 2*a]);
469
 
476
 
470
       result += ODSLF_fbar_XXZ(tanhlambda, parj*park, tannzetaover2[nj + nk]);
477
       result += ODSLF_fbar_XXZ(tanhlambda, parj*park, tannzetaover2[nj + nk]);
471
     }
478
     }
490
   {
497
   {
491
     DP result = (nj == nk) ? 0.0 : ODSLF_hbar_XXZ(lambda, fabs(nj - nk), parj*park, si_n_anis_over_2);
498
     DP result = (nj == nk) ? 0.0 : ODSLF_hbar_XXZ(lambda, fabs(nj - nk), parj*park, si_n_anis_over_2);
492
 
499
 
493
-    for (int a = 1; a < ABACUS::min(nj, nk); ++a) result += 2.0 * ODSLF_hbar_XXZ(lambda, fabs(nj - nk) + 2*a, parj*park, si_n_anis_over_2);
500
+    for (int a = 1; a < ABACUS::min(nj, nk); ++a)
501
+      result += 2.0 * ODSLF_hbar_XXZ(lambda, fabs(nj - nk) + 2*a, parj*park, si_n_anis_over_2);
494
 
502
 
495
     result += ODSLF_hbar_XXZ(lambda, nj + nk, parj*park, si_n_anis_over_2);
503
     result += ODSLF_hbar_XXZ(lambda, nj + nk, parj*park, si_n_anis_over_2);
496
 
504
 

+ 260
- 266
src/ODSLF/ln_Smin_ME_ODSLF_XXZ.cc View File

18
 
18
 
19
 namespace ABACUS {
19
 namespace ABACUS {
20
 
20
 
21
-inline complex<DP> ln_Fn_F (ODSLF_XXZ_Bethe_State& B, int k, int beta, int b)
22
-{
23
-  complex<DP> ans = 0.0;
24
-  complex<DP> prod_temp = 1.0;
25
-  int counter = 0;
26
-  int arg = 0;
27
-  int absarg = 0;
28
-  int par_comb_1, par_comb_2;
21
+  inline complex<DP> ln_Fn_F (ODSLF_XXZ_Bethe_State& B, int k, int beta, int b)
22
+  {
23
+    complex<DP> ans = 0.0;
24
+    complex<DP> prod_temp = 1.0;
25
+    int counter = 0;
26
+    int arg = 0;
27
+    int absarg = 0;
28
+    int par_comb_1, par_comb_2;
29
+
30
+    for (int j = 0; j < B.chain.Nstrings; ++j) {
31
+
32
+      par_comb_1 = B.chain.par[j] == B.chain.par[k] ? 1 : 0;
33
+      par_comb_2 = B.chain.par[k] == B.chain.par[j] ? 0 : B.chain.par[k];
34
+
35
+      for (int alpha = 0; alpha < B.base.Nrap[j]; ++alpha) {
36
+	for (int a = 1; a <= B.chain.Str_L[j]; ++a) {
37
+
38
+	  if (!((j == k) && (alpha == beta) && (a == b))) {
39
+
40
+	    arg = B.chain.Str_L[j] - B.chain.Str_L[k] - 2 * (a - b);
41
+	    absarg = abs(arg);
42
+
43
+	    prod_temp *= ((B.sinhlambda[j][alpha] * B.coshlambda[k][beta]
44
+			   - B.coshlambda[j][alpha] * B.sinhlambda[k][beta])
45
+			  * (B.chain.co_n_anis_over_2[absarg] * par_comb_1
46
+			     - sgn_int(arg) * B.chain.si_n_anis_over_2[absarg] * par_comb_2)
47
+			  + II * (B.coshlambda[j][alpha] * B.coshlambda[k][beta]
48
+				  - B.sinhlambda[j][alpha] * B.sinhlambda[k][beta])
49
+			  * (sgn_int(arg) * B.chain.si_n_anis_over_2[absarg] * par_comb_1
50
+			     + B.chain.co_n_anis_over_2[absarg] * par_comb_2));
51
+	  }
52
+
53
+	  if (counter++ > 100) {  // we do at most 100 products before taking a log
54
+	    ans += log(prod_temp);
55
+	    prod_temp = 1.0;
56
+	    counter = 0;
57
+	  }
58
+
59
+	}}}
60
+
61
+    return(ans + log(prod_temp));
62
+  }
29
 
63
 
30
-  for (int j = 0; j < B.chain.Nstrings; ++j) {
64
+  inline complex<DP> ln_Fn_G (ODSLF_XXZ_Bethe_State& A, ODSLF_XXZ_Bethe_State& B, int k, int beta, int b)
65
+  {
66
+    complex<DP> ans = 0.0;
67
+    complex<DP> prod_temp = 1.0;
68
+    int counter = 0;
69
+    int arg = 0;
70
+    int absarg = 0;
71
+    int par_comb_1, par_comb_2;
31
 
72
 
32
-    par_comb_1 = B.chain.par[j] == B.chain.par[k] ? 1 : 0;
33
-    par_comb_2 = B.chain.par[k] == B.chain.par[j] ? 0 : B.chain.par[k];
73
+    for (int j = 0; j < A.chain.Nstrings; ++j) {
34
 
74
 
35
-    for (int alpha = 0; alpha < B.base.Nrap[j]; ++alpha) {
36
-      for (int a = 1; a <= B.chain.Str_L[j]; ++a) {
75
+      par_comb_1 = A.chain.par[j] == B.chain.par[k] ? 1 : 0;
76
+      par_comb_2 = B.chain.par[k] == A.chain.par[j] ? 0 : B.chain.par[k];
37
 
77
 
38
-	if (!((j == k) && (alpha == beta) && (a == b))) {
78
+      for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha) {
79
+	for (int a = 1; a <= A.chain.Str_L[j]; ++a) {
39
 
80
 
40
-	  arg = B.chain.Str_L[j] - B.chain.Str_L[k] - 2 * (a - b);
81
+	  arg = A.chain.Str_L[j] - B.chain.Str_L[k] - 2 * (a - b);
41
 	  absarg = abs(arg);
82
 	  absarg = abs(arg);
42
-	  /*
43
-	  prod_temp *= 0.5 * //done later...
44
-	    ((B.sinhlambda[j][alpha] * B.coshlambda[k][beta] - B.coshlambda[j][alpha] * B.sinhlambda[k][beta])
45
-	     * (B.chain.co_n_anis_over_2[absarg] * (1.0 + B.chain.par[j] * B.chain.par[k])
46
-		- sgn_int(arg) * B.chain.si_n_anis_over_2[absarg] * (B.chain.par[k] - B.chain.par[j]))
47
-			+ II * (B.coshlambda[j][alpha] * B.coshlambda[k][beta] - B.sinhlambda[j][alpha] * B.sinhlambda[k][beta])
48
-			* (sgn_int(arg) * B.chain.si_n_anis_over_2[absarg] * (1.0 + B.chain.par[j] * B.chain.par[k])
49
-			   + B.chain.co_n_anis_over_2[absarg] * (B.chain.par[k] - B.chain.par[j])) );
50
-	  */
51
-
52
-	  prod_temp *= ((B.sinhlambda[j][alpha] * B.coshlambda[k][beta] - B.coshlambda[j][alpha] * B.sinhlambda[k][beta])
53
-			* (B.chain.co_n_anis_over_2[absarg] * par_comb_1 - sgn_int(arg) * B.chain.si_n_anis_over_2[absarg] * par_comb_2)
54
-			+ II * (B.coshlambda[j][alpha] * B.coshlambda[k][beta] - B.sinhlambda[j][alpha] * B.sinhlambda[k][beta])
55
-			* (sgn_int(arg) * B.chain.si_n_anis_over_2[absarg] * par_comb_1 + B.chain.co_n_anis_over_2[absarg] * par_comb_2));
56
-	}
83
+	  prod_temp *= ((A.sinhlambda[j][alpha] * B.coshlambda[k][beta]
84
+			 - A.coshlambda[j][alpha] * B.sinhlambda[k][beta])
85
+			* (A.chain.co_n_anis_over_2[absarg] * par_comb_1
86
+			   - sgn_int(arg) * A.chain.si_n_anis_over_2[absarg] * par_comb_2)
87
+			+ II * (A.coshlambda[j][alpha] * B.coshlambda[k][beta]
88
+				- A.sinhlambda[j][alpha] * B.sinhlambda[k][beta])
89
+			* (sgn_int(arg) * A.chain.si_n_anis_over_2[absarg] * par_comb_1
90
+			   + A.chain.co_n_anis_over_2[absarg] * par_comb_2));
91
+
92
+	  if (counter++ > 100) {  // we do at most 100 products before taking a log
93
+	    ans += log(prod_temp);
94
+	    prod_temp = 1.0;
95
+	    counter = 0;
96
+	  }
97
+	}}}
98
+
99
+    return(ans + log(prod_temp));
100
+  }
57
 
101
 
58
-	if (counter++ > 100) {  // we do at most 100 products before taking a log
59
-	  ans += log(prod_temp);
60
-	  prod_temp = 1.0;
61
-	  counter = 0;
62
-	}
102
+  inline complex<DP> Fn_K (ODSLF_XXZ_Bethe_State& A, int j, int alpha, int a,
103
+			   ODSLF_XXZ_Bethe_State& B, int k, int beta, int b)
104
+  {
105
+    int arg1 = A.chain.Str_L[j] - B.chain.Str_L[k] - 2 * (a - b);
106
+    int absarg1 = abs(arg1);
107
+    int arg2 = arg1 + 2;
108
+    int absarg2 = abs(arg2);
109
+
110
+    return(4.0/(
111
+		((A.sinhlambda[j][alpha] * B.coshlambda[k][beta] - A.coshlambda[j][alpha] * B.sinhlambda[k][beta])
112
+		 * (A.chain.co_n_anis_over_2[absarg1] * (1.0 + A.chain.par[j] * B.chain.par[k])
113
+		    - sgn_int(arg1) * A.chain.si_n_anis_over_2[absarg1] * (B.chain.par[k] - A.chain.par[j]))
114
+		 + II * (A.coshlambda[j][alpha] * B.coshlambda[k][beta] - A.sinhlambda[j][alpha] * B.sinhlambda[k][beta])
115
+		 * (sgn_int(arg1) * A.chain.si_n_anis_over_2[absarg1] * (1.0 + A.chain.par[j] * B.chain.par[k])
116
+		    + A.chain.co_n_anis_over_2[absarg1] * (B.chain.par[k] - A.chain.par[j])) )
117
+		*
118
+		((A.sinhlambda[j][alpha] * B.coshlambda[k][beta] - A.coshlambda[j][alpha] * B.sinhlambda[k][beta])
119
+		 * (A.chain.co_n_anis_over_2[absarg2] * (1.0 + A.chain.par[j] * B.chain.par[k])
120
+		    - sgn_int(arg2) * A.chain.si_n_anis_over_2[absarg2] * (B.chain.par[k] - A.chain.par[j]))
121
+		 + II * (A.coshlambda[j][alpha] * B.coshlambda[k][beta] - A.sinhlambda[j][alpha] * B.sinhlambda[k][beta])
122
+		 * (sgn_int(arg2) * A.chain.si_n_anis_over_2[absarg2] * (1.0 + A.chain.par[j] * B.chain.par[k])
123
+		    + A.chain.co_n_anis_over_2[absarg2] * (B.chain.par[k] - A.chain.par[j])) )
124
+		));
63
 
125
 
64
-      }}}
65
-
66
-  return(ans + log(prod_temp));
67
-}
68
-
69
-inline complex<DP> ln_Fn_G (ODSLF_XXZ_Bethe_State& A, ODSLF_XXZ_Bethe_State& B, int k, int beta, int b)
70
-{
71
-  complex<DP> ans = 0.0;
72
-  complex<DP> prod_temp = 1.0;
73
-  int counter = 0;
74
-  int arg = 0;
75
-  int absarg = 0;
76
-  int par_comb_1, par_comb_2;
77
-
78
-  for (int j = 0; j < A.chain.Nstrings; ++j) {
79
-
80
-    par_comb_1 = A.chain.par[j] == B.chain.par[k] ? 1 : 0;
81
-    par_comb_2 = B.chain.par[k] == A.chain.par[j] ? 0 : B.chain.par[k];
82
-
83
-    for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha) {
84
-      for (int a = 1; a <= A.chain.Str_L[j]; ++a) {
85
-
86
-	arg = A.chain.Str_L[j] - B.chain.Str_L[k] - 2 * (a - b);
87
-	absarg = abs(arg);
88
-	/*
89
-	prod_temp *= 0.5 * //done later...
90
-	  ((A.sinhlambda[j][alpha] * B.coshlambda[k][beta] - A.coshlambda[j][alpha] * B.sinhlambda[k][beta])
91
-		      * (A.chain.co_n_anis_over_2[absarg] * (1.0 + A.chain.par[j] * B.chain.par[k])
92
-			 - sgn_int(arg) * A.chain.si_n_anis_over_2[absarg] * (B.chain.par[k] - A.chain.par[j]))
93
-		      + II * (A.coshlambda[j][alpha] * B.coshlambda[k][beta] - A.sinhlambda[j][alpha] * B.sinhlambda[k][beta])
94
-		      * (sgn_int(arg) * A.chain.si_n_anis_over_2[absarg] * (1.0 + A.chain.par[j] * B.chain.par[k])
95
-			 + A.chain.co_n_anis_over_2[absarg] * (B.chain.par[k] - A.chain.par[j])) );
96
-	*/
97
-	prod_temp *= ((A.sinhlambda[j][alpha] * B.coshlambda[k][beta] - A.coshlambda[j][alpha] * B.sinhlambda[k][beta])
98
-		      * (A.chain.co_n_anis_over_2[absarg] * par_comb_1 - sgn_int(arg) * A.chain.si_n_anis_over_2[absarg] * par_comb_2)
99
-		      + II * (A.coshlambda[j][alpha] * B.coshlambda[k][beta] - A.sinhlambda[j][alpha] * B.sinhlambda[k][beta])
100
-		      * (sgn_int(arg) * A.chain.si_n_anis_over_2[absarg] * par_comb_1 + A.chain.co_n_anis_over_2[absarg] * par_comb_2));
101
-
102
-	if (counter++ > 100) {  // we do at most 100 products before taking a log
103
-	  ans += log(prod_temp);
104
-	  prod_temp = 1.0;
105
-	  counter = 0;
106
-	}
107
-      }}}
108
-
109
-  return(ans + log(prod_temp));
110
-}
111
-
112
-inline complex<DP> Fn_K (ODSLF_XXZ_Bethe_State& A, int j, int alpha, int a, ODSLF_XXZ_Bethe_State& B, int k, int beta, int b)
113
-{
114
-  int arg1 = A.chain.Str_L[j] - B.chain.Str_L[k] - 2 * (a - b);
115
-  int absarg1 = abs(arg1);
116
-  int arg2 = arg1 + 2;
117
-  int absarg2 = abs(arg2);
118
-
119
-  return(4.0/(
120
-	      ((A.sinhlambda[j][alpha] * B.coshlambda[k][beta] - A.coshlambda[j][alpha] * B.sinhlambda[k][beta])
121
-		      * (A.chain.co_n_anis_over_2[absarg1] * (1.0 + A.chain.par[j] * B.chain.par[k])
122
-			 - sgn_int(arg1) * A.chain.si_n_anis_over_2[absarg1] * (B.chain.par[k] - A.chain.par[j]))
123
-		      + II * (A.coshlambda[j][alpha] * B.coshlambda[k][beta] - A.sinhlambda[j][alpha] * B.sinhlambda[k][beta])
124
-		      * (sgn_int(arg1) * A.chain.si_n_anis_over_2[absarg1] * (1.0 + A.chain.par[j] * B.chain.par[k])
125
-			 + A.chain.co_n_anis_over_2[absarg1] * (B.chain.par[k] - A.chain.par[j])) )
126
-	 *
127
-	 ((A.sinhlambda[j][alpha] * B.coshlambda[k][beta] - A.coshlambda[j][alpha] * B.sinhlambda[k][beta])
128
-		      * (A.chain.co_n_anis_over_2[absarg2] * (1.0 + A.chain.par[j] * B.chain.par[k])
129
-			 - sgn_int(arg2) * A.chain.si_n_anis_over_2[absarg2] * (B.chain.par[k] - A.chain.par[j]))
130
-		      + II * (A.coshlambda[j][alpha] * B.coshlambda[k][beta] - A.sinhlambda[j][alpha] * B.sinhlambda[k][beta])
131
-		      * (sgn_int(arg2) * A.chain.si_n_anis_over_2[absarg2] * (1.0 + A.chain.par[j] * B.chain.par[k])
132
-			 + A.chain.co_n_anis_over_2[absarg2] * (B.chain.par[k] - A.chain.par[j])) )
133
-	      ));
134
-
135
-}
136
-
137
-inline complex<DP> Fn_L (ODSLF_XXZ_Bethe_State& A, int j, int alpha, int a, ODSLF_XXZ_Bethe_State& B, int k, int beta, int b)
138
-{
139
-  return (sinh(2.0 * (A.lambda[j][alpha] - B.lambda[k][beta]
140
-		      + 0.5 * II * B.chain.anis * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b - 0.5))
141
-		      + 0.25 * II * PI * complex<DP>(-A.chain.par[j] + B.chain.par[k])))
142
-	  * pow(Fn_K (A, j, alpha, a, B, k, beta, b), 2.0));
143
-}
144
-
145
-complex<DP> ln_Smin_ME (ODSLF_XXZ_Bethe_State& A, ODSLF_XXZ_Bethe_State& B)
146
-{
147
-  // This function returns the natural log of the S^- operator matrix element.
148
-  // The A and B states can contain strings.
149
-
150
-  // Check that the two states are compatible
151
-
152
-  if (A.chain != B.chain) ABACUSerror("Incompatible ODSLF_XXZ_Chains in Smin matrix element.");
153
-
154
-  // Check that A and B are Mdown-compatible:
155
-
156
-  if (A.base.Mdown != B.base.Mdown + 1) ABACUSerror("Incompatible Mdown between the two states in Smin matrix element!");
157
-
158
-  // Compute the sinh and cosh of rapidities
159
-
160
-  A.Compute_sinhlambda();
161
-  A.Compute_coshlambda();
162
-  B.Compute_sinhlambda();
163
-  B.Compute_coshlambda();
164
-
165
-  // Some convenient arrays
166
-
167
-  ODSLF_Lambda re_ln_Fn_F_B_0(B.chain, B.base);
168
-  ODSLF_Lambda im_ln_Fn_F_B_0(B.chain, B.base);
169
-  ODSLF_Lambda re_ln_Fn_G_0(B.chain, B.base);
170
-  ODSLF_Lambda im_ln_Fn_G_0(B.chain, B.base);
171
-  ODSLF_Lambda re_ln_Fn_G_2(B.chain, B.base);
172
-  ODSLF_Lambda im_ln_Fn_G_2(B.chain, B.base);
173
-
174
-  complex<DP> ln_prod1 = 0.0;
175
-  complex<DP> ln_prod2 = 0.0;
176
-  complex<DP> ln_prod3 = 0.0;
177
-  complex<DP> ln_prod4 = 0.0;
178
-
179
-  for (int i = 0; i < A.chain.Nstrings; ++i)
180
-    for (int alpha = 0; alpha < A.base.Nrap[i]; ++alpha)
181
-      for (int a = 1; a <= A.chain.Str_L[i]; ++a)
182
-	ln_prod1 += log(norm(sinh(A.lambda[i][alpha] + 0.5 * II * A.chain.anis * (A.chain.Str_L[i] + 1.0 - 2.0 * a - 1.0)
183
-				  + 0.25 * II * PI * (1.0 - A.chain.par[i]))));
184
-
185
-  for (int i = 0; i < B.chain.Nstrings; ++i)
186
-    for (int alpha = 0; alpha < B.base.Nrap[i]; ++alpha)
187
-      for (int a = 1; a <= B.chain.Str_L[i]; ++a)
188
-	if (norm(sinh(B.lambda[i][alpha] + 0.5 * II * B.chain.anis * (B.chain.Str_L[i] + 1.0 - 2.0 * a - 1.0)
189
-		      + 0.25 * II * PI * (1.0 - B.chain.par[i]))) > 100.0 * MACHINE_EPS_SQ)
190
-	  ln_prod2 += log(norm(sinh(B.lambda[i][alpha] + 0.5 * II * B.chain.anis * (B.chain.Str_L[i] + 1.0 - 2.0 * a - 1.0)
191
-				    + 0.25 * II * PI * (1.0 - B.chain.par[i]))));
192
-
193
-  // Define the F ones earlier...
194
-
195
-  for (int j = 0; j < B.chain.Nstrings; ++j) {
196
-    for (int alpha = 0; alpha < B.base.Nrap[j]; ++alpha) {
197
-      re_ln_Fn_F_B_0[j][alpha] = real(ln_Fn_F(B, j, alpha, 0));
198
-      im_ln_Fn_F_B_0[j][alpha] = imag(ln_Fn_F(B, j, alpha, 0));
199
-      re_ln_Fn_G_0[j][alpha] = real(ln_Fn_G(A, B, j, alpha, 0));
200
-      im_ln_Fn_G_0[j][alpha] = imag(ln_Fn_G(A, B, j, alpha, 0));
201
-      re_ln_Fn_G_2[j][alpha] = real(ln_Fn_G(A, B, j, alpha, 2));
202
-      im_ln_Fn_G_2[j][alpha] = imag(ln_Fn_G(A, B, j, alpha, 2));
203
-    }
204
   }
126
   }
205
 
127
 
206
-  DP logabssinzeta = log(abs(sin(A.chain.anis)));
128
+  inline complex<DP> Fn_L (ODSLF_XXZ_Bethe_State& A, int j, int alpha, int a,
129
+			   ODSLF_XXZ_Bethe_State& B, int k, int beta, int b)
130
+  {
131
+    return (sinh(2.0 * (A.lambda[j][alpha] - B.lambda[k][beta]
132
+			+ 0.5 * II * B.chain.anis * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b - 0.5))
133
+			+ 0.25 * II * PI * complex<DP>(-A.chain.par[j] + B.chain.par[k])))
134
+	    * pow(Fn_K (A, j, alpha, a, B, k, beta, b), 2.0));
135
+  }
207
 
136
 
208
-  // Define regularized products in prefactors
137
+  complex<DP> ln_Smin_ME (ODSLF_XXZ_Bethe_State& A, ODSLF_XXZ_Bethe_State& B)
138
+  {
139
+    // This function returns the natural log of the S^- operator matrix element.
140
+    // The A and B states can contain strings.
141
+
142
+    // Check that the two states are compatible
143
+
144
+    if (A.chain != B.chain)
145
+      ABACUSerror("Incompatible ODSLF_XXZ_Chains in Smin matrix element.");
146
+
147
+    // Check that A and B are Mdown-compatible:
148
+
149
+    if (A.base.Mdown != B.base.Mdown + 1)
150
+      ABACUSerror("Incompatible Mdown between the two states in Smin matrix element!");
151
+
152
+    // Compute the sinh and cosh of rapidities
153
+
154
+    A.Compute_sinhlambda();
155
+    A.Compute_coshlambda();
156
+    B.Compute_sinhlambda();
157
+    B.Compute_coshlambda();
158
+
159
+    // Some convenient arrays
160
+
161
+    ODSLF_Lambda re_ln_Fn_F_B_0(B.chain, B.base);
162
+    ODSLF_Lambda im_ln_Fn_F_B_0(B.chain, B.base);
163
+    ODSLF_Lambda re_ln_Fn_G_0(B.chain, B.base);
164
+    ODSLF_Lambda im_ln_Fn_G_0(B.chain, B.base);
165
+    ODSLF_Lambda re_ln_Fn_G_2(B.chain, B.base);
166
+    ODSLF_Lambda im_ln_Fn_G_2(B.chain, B.base);
167
+
168
+    complex<DP> ln_prod1 = 0.0;
169
+    complex<DP> ln_prod2 = 0.0;
170
+    complex<DP> ln_prod3 = 0.0;
171
+    complex<DP> ln_prod4 = 0.0;
172
+
173
+    for (int i = 0; i < A.chain.Nstrings; ++i)
174
+      for (int alpha = 0; alpha < A.base.Nrap[i]; ++alpha)
175
+	for (int a = 1; a <= A.chain.Str_L[i]; ++a)
176
+	  ln_prod1 += log(norm(sinh(A.lambda[i][alpha] + 0.5 * II * A.chain.anis * (A.chain.Str_L[i] + 1.0 - 2.0 * a - 1.0)
177
+				    + 0.25 * II * PI * (1.0 - A.chain.par[i]))));
178
+
179
+    for (int i = 0; i < B.chain.Nstrings; ++i)
180
+      for (int alpha = 0; alpha < B.base.Nrap[i]; ++alpha)
181
+	for (int a = 1; a <= B.chain.Str_L[i]; ++a)
182
+	  if (norm(sinh(B.lambda[i][alpha] + 0.5 * II * B.chain.anis * (B.chain.Str_L[i] + 1.0 - 2.0 * a - 1.0)
183
+			+ 0.25 * II * PI * (1.0 - B.chain.par[i]))) > 100.0 * MACHINE_EPS_SQ)
184
+	    ln_prod2 += log(norm(sinh(B.lambda[i][alpha] + 0.5 * II * B.chain.anis * (B.chain.Str_L[i] + 1.0 - 2.0 * a - 1.0)
185
+				      + 0.25 * II * PI * (1.0 - B.chain.par[i]))));
186
+
187
+    // Define the F ones earlier...
188
+
189
+    for (int j = 0; j < B.chain.Nstrings; ++j) {
190
+      for (int alpha = 0; alpha < B.base.Nrap[j]; ++alpha) {
191
+	re_ln_Fn_F_B_0[j][alpha] = real(ln_Fn_F(B, j, alpha, 0));
192
+	im_ln_Fn_F_B_0[j][alpha] = imag(ln_Fn_F(B, j, alpha, 0));
193
+	re_ln_Fn_G_0[j][alpha] = real(ln_Fn_G(A, B, j, alpha, 0));
194
+	im_ln_Fn_G_0[j][alpha] = imag(ln_Fn_G(A, B, j, alpha, 0));
195
+	re_ln_Fn_G_2[j][alpha] = real(ln_Fn_G(A, B, j, alpha, 2));
196
+	im_ln_Fn_G_2[j][alpha] = imag(ln_Fn_G(A, B, j, alpha, 2));
197
+      }
198
+    }
209
 
199
 
210
-  for (int j = 0; j < A.chain.Nstrings; ++j)
211
-    for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha)
212
-      for (int a = 1; a <= A.chain.Str_L[j]; ++a)
213
-	ln_prod3 += ln_Fn_F(A, j, alpha, a - 1);  // assume only one-strings here
200
+    DP logabssinzeta = log(abs(sin(A.chain.anis)));
214
 
201
 
215
-  ln_prod3 -= A.base.Mdown * log(abs(sin(A.chain.anis)));
202
+    // Define regularized products in prefactors
216
 
203
 
217
-  for (int k = 0; k < B.chain.Nstrings; ++k)
218
-    for (int beta = 0; beta < B.base.Nrap[k]; ++beta)
219
-      for (int b = 1; b <= B.chain.Str_L[k]; ++b) {
220
-	if (b == 1) ln_prod4 += re_ln_Fn_F_B_0[k][beta];
221
-	else if (b > 1) ln_prod4 += ln_Fn_F(B, k, beta, b - 1);
222
-    }
204
+    for (int j = 0; j < A.chain.Nstrings; ++j)
205
+      for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha)
206
+	for (int a = 1; a <= A.chain.Str_L[j]; ++a)
207
+	  ln_prod3 += ln_Fn_F(A, j, alpha, a - 1);  // assume only one-strings here
223
 
208
 
224
-  ln_prod4 -= B.base.Mdown * log(abs(sin(B.chain.anis)));
209
+    ln_prod3 -= A.base.Mdown * log(abs(sin(A.chain.anis)));
225
 
210
 
226
-  // Now proceed to build the Hm matrix
211
+    for (int k = 0; k < B.chain.Nstrings; ++k)
212
+      for (int beta = 0; beta < B.base.Nrap[k]; ++beta)
213
+	for (int b = 1; b <= B.chain.Str_L[k]; ++b) {
214
+	  if (b == 1) ln_prod4 += re_ln_Fn_F_B_0[k][beta];
215
+	  else if (b > 1) ln_prod4 += ln_Fn_F(B, k, beta, b - 1);
216
+	}
227
 
217
 
228
-  SQMat_CX Hm(0.0, A.base.Mdown);
218
+    ln_prod4 -= B.base.Mdown * log(abs(sin(B.chain.anis)));
229
 
219
 
230
-  int index_a = 0;
231
-  int index_b = 0;
220
+    // Now proceed to build the Hm matrix
232
 
221
 
233
-  complex<DP> sum1 = 0.0;
234
-  complex<DP> sum2 = 0.0;
235
-  complex<DP> prod_num = 0.0;
236
-  complex<DP> Fn_K_0_G_0 = 0.0;
237
-  complex<DP> Prod_powerN = 0.0;
238
-  complex<DP> Fn_K_1_G_2 = 0.0;
239
-  complex<DP> one_over_A_sinhlambda_sq_plus_sinzetaover2sq;
222
+    SQMat_CX Hm(0.0, A.base.Mdown);
240
 
223
 
224
+    int index_a = 0;
225
+    int index_b = 0;
241
 
226
 
242
-  for (int j = 0; j < A.chain.Nstrings; ++j) {
243
-    for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha) {
244
-      for (int a = 1; a <= A.chain.Str_L[j]; ++a) {
227
+    complex<DP> sum1 = 0.0;
228
+    complex<DP> sum2 = 0.0;
229
+    complex<DP> prod_num = 0.0;
230
+    complex<DP> Fn_K_0_G_0 = 0.0;
231
+    complex<DP> Prod_powerN = 0.0;
232
+    complex<DP> Fn_K_1_G_2 = 0.0;
233
+    complex<DP> one_over_A_sinhlambda_sq_plus_sinzetaover2sq;
245
 
234
 
246
-	index_b = 0;
247
 
235
 
248
-	one_over_A_sinhlambda_sq_plus_sinzetaover2sq = 1.0/((sinh(A.lambda[j][alpha] + 0.5 * II * A.chain.anis * (A.chain.Str_L[j] + 1.0 - 2.0 * a)
249
-								  + 0.25 * II * PI * (1.0 - A.chain.par[j])))
250
-							    * (sinh(A.lambda[j][alpha] + 0.5 * II * A.chain.anis * (A.chain.Str_L[j] + 1.0 - 2.0 * a)
251
-								  + 0.25 * II * PI * (1.0 - A.chain.par[j])))
252
-							    + pow(sin(0.5*A.chain.anis), 2.0));
236
+    for (int j = 0; j < A.chain.Nstrings; ++j) {
237
+      for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha) {
238
+	for (int a = 1; a <= A.chain.Str_L[j]; ++a) {
253
 
239
 
254
-	for (int k = 0; k < B.chain.Nstrings; ++k) {
255
-	  for (int beta = 0; beta < B.base.Nrap[k]; ++beta) {
256
-	    for (int b = 1; b <= B.chain.Str_L[k]; ++b) {
240
+	  index_b = 0;
257
 
241
 
258
-	      if (B.chain.Str_L[k] == 1) {
242
+	  one_over_A_sinhlambda_sq_plus_sinzetaover2sq =
243
+	    1.0/((sinh(A.lambda[j][alpha] + 0.5 * II * A.chain.anis * (A.chain.Str_L[j] + 1.0 - 2.0 * a)
244
+		       + 0.25 * II * PI * (1.0 - A.chain.par[j])))
245
+		 * (sinh(A.lambda[j][alpha] + 0.5 * II * A.chain.anis * (A.chain.Str_L[j] + 1.0 - 2.0 * a)
246
+			 + 0.25 * II * PI * (1.0 - A.chain.par[j])))
247
+		 + pow(sin(0.5*A.chain.anis), 2.0));
259
 
248
 
260
-		// use simplified code for one-string here:  original form of Hm matrix
249
+	  for (int k = 0; k < B.chain.Nstrings; ++k) {
250
+	    for (int beta = 0; beta < B.base.Nrap[k]; ++beta) {
251
+	      for (int b = 1; b <= B.chain.Str_L[k]; ++b) {
261
 
252
 
262
-		Fn_K_0_G_0 = Fn_K (A, j, alpha, a, B, k, beta, 0) *
263
-		  exp(re_ln_Fn_G_0[k][beta] + II * im_ln_Fn_G_0[k][beta] - re_ln_Fn_F_B_0[k][beta] + logabssinzeta);
264
-		Fn_K_1_G_2 = Fn_K (A, j, alpha, a, B, k, beta, 1) *
265
-		  exp(re_ln_Fn_G_2[k][beta] + II * im_ln_Fn_G_2[k][beta] - re_ln_Fn_F_B_0[k][beta] + logabssinzeta);
253
+		if (B.chain.Str_L[k] == 1) {
266
 
254
 
267
-		Prod_powerN = pow( B.chain.par[k] == 1 ?
268
-				   (B.sinhlambda[k][beta] * B.chain.co_n_anis_over_2[1] + II * B.coshlambda[k][beta] * B.chain.si_n_anis_over_2[1])
269
-				   /(B.sinhlambda[k][beta] * B.chain.co_n_anis_over_2[1] - II * B.coshlambda[k][beta] * B.chain.si_n_anis_over_2[1])
270
-				   :
271
-				   (B.coshlambda[k][beta] * B.chain.co_n_anis_over_2[1] + II * B.sinhlambda[k][beta] * B.chain.si_n_anis_over_2[1])
272
-				   /(B.coshlambda[k][beta] * B.chain.co_n_anis_over_2[1] - II * B.sinhlambda[k][beta] * B.chain.si_n_anis_over_2[1])
273
-				   , complex<DP> (B.chain.Nsites));
255
+		  // use simplified code for one-string here:  original form of Hm matrix
274
 
256
 
275
-		Hm[index_a][index_b] = Fn_K_0_G_0 - (1.0 - 2.0 * (B.base.Mdown % 2)) * // MODIF from XXZ
276
-		  Prod_powerN * Fn_K_1_G_2;
257
+		  Fn_K_0_G_0 = Fn_K (A, j, alpha, a, B, k, beta, 0) *
258
+		    exp(re_ln_Fn_G_0[k][beta] + II * im_ln_Fn_G_0[k][beta] - re_ln_Fn_F_B_0[k][beta] + logabssinzeta);
259
+		  Fn_K_1_G_2 = Fn_K (A, j, alpha, a, B, k, beta, 1) *
260
+		    exp(re_ln_Fn_G_2[k][beta] + II * im_ln_Fn_G_2[k][beta] - re_ln_Fn_F_B_0[k][beta] + logabssinzeta);
277
 
261
 
278
-	      } // if (B.chain.Str_L == 1)
262
+		  Prod_powerN = pow( B.chain.par[k] == 1 ?
263
+				     (B.sinhlambda[k][beta] * B.chain.co_n_anis_over_2[1]
264
+				      + II * B.coshlambda[k][beta] * B.chain.si_n_anis_over_2[1])
265
+				     /(B.sinhlambda[k][beta] * B.chain.co_n_anis_over_2[1]
266
+				       - II * B.coshlambda[k][beta] * B.chain.si_n_anis_over_2[1])
267
+				     :
268
+				     (B.coshlambda[k][beta] * B.chain.co_n_anis_over_2[1]
269
+				      + II * B.sinhlambda[k][beta] * B.chain.si_n_anis_over_2[1])
270
+				     /(B.coshlambda[k][beta] * B.chain.co_n_anis_over_2[1]
271
+				       - II * B.sinhlambda[k][beta] * B.chain.si_n_anis_over_2[1])
272
+				     , complex<DP> (B.chain.Nsites));
279
 
273
 
280
-	      else {
274
+		  Hm[index_a][index_b] = Fn_K_0_G_0 - (1.0 - 2.0 * (B.base.Mdown % 2)) * // MODIF from XXZ
275
+		    Prod_powerN * Fn_K_1_G_2;
281
 
276
 
282
-		if (b <= B.chain.Str_L[k] - 1) Hm[index_a][index_b] = Fn_K(A, j, alpha, a, B, k, beta, b);
283
-		else if (b == B.chain.Str_L[k]) {
277
+		} // if (B.chain.Str_L == 1)
284
 
278
 
285
-		  Vect_CX ln_FunctionF(B.chain.Str_L[k] + 2);
286
-		  for (int i = 0; i < B.chain.Str_L[k] + 2; ++i) ln_FunctionF[i] = ln_Fn_F (B, k, beta, i);
279
+		else {
287
 
280
 
288
-		  Vect_CX ln_FunctionG(B.chain.Str_L[k] + 2);
289
-		  for (int i = 0; i < B.chain.Str_L[k] + 2; ++i) ln_FunctionG[i] = ln_Fn_G (A, B, k, beta, i);
281
+		  if (b <= B.chain.Str_L[k] - 1) Hm[index_a][index_b] = Fn_K(A, j, alpha, a, B, k, beta, b);
282
+		  else if (b == B.chain.Str_L[k]) {
290
 
283
 
291
-		  sum1 = 0.0;
284
+		    Vect_CX ln_FunctionF(B.chain.Str_L[k] + 2);
285
+		    for (int i = 0; i < B.chain.Str_L[k] + 2; ++i) ln_FunctionF[i] = ln_Fn_F (B, k, beta, i);
292
 
286
 
293
-		  sum1 += Fn_K (A, j, alpha, a, B, k, beta, 0) * exp(ln_FunctionG[0] + ln_FunctionG[1] - ln_FunctionF[0] - ln_FunctionF[1]);
287
+		    Vect_CX ln_FunctionG(B.chain.Str_L[k] + 2);
288
+		    for (int i = 0; i < B.chain.Str_L[k] + 2; ++i) ln_FunctionG[i] = ln_Fn_G (A, B, k, beta, i);
294
 
289
 
295
-		  sum1 += (1.0 - 2.0 * (B.base.Mdown % 2)) * // MODIF from XXZ
296
-		    Fn_K (A, j, alpha, a, B, k, beta, B.chain.Str_L[k])
297
-		    * exp(ln_FunctionG[B.chain.Str_L[k]] + ln_FunctionG[B.chain.Str_L[k] + 1]
298
-			  - ln_FunctionF[B.chain.Str_L[k]] - ln_FunctionF[B.chain.Str_L[k] + 1]);
290
+		    sum1 = 0.0;
299
 
291
 
300
-		  for (int jsum = 1; jsum < B.chain.Str_L[k]; ++jsum)
292
+		    sum1 += Fn_K (A, j, alpha, a, B, k, beta, 0)
293
+		      * exp(ln_FunctionG[0] + ln_FunctionG[1] - ln_FunctionF[0] - ln_FunctionF[1]);
301
 
294
 
302
-		    sum1 -= Fn_L (A, j, alpha, a, B, k, beta, jsum) *
303
-		      exp(ln_FunctionG[jsum] + ln_FunctionG[jsum + 1] - ln_FunctionF[jsum] - ln_FunctionF[jsum + 1]);
295
+		    sum1 += (1.0 - 2.0 * (B.base.Mdown % 2)) * // MODIF from XXZ
296
+		      Fn_K (A, j, alpha, a, B, k, beta, B.chain.Str_L[k])
297
+		      * exp(ln_FunctionG[B.chain.Str_L[k]] + ln_FunctionG[B.chain.Str_L[k] + 1]
298
+			    - ln_FunctionF[B.chain.Str_L[k]] - ln_FunctionF[B.chain.Str_L[k] + 1]);
304
 
299
 
305
-		  /*
306
-		  sum2 = 0.0;
300
+		    for (int jsum = 1; jsum < B.chain.Str_L[k]; ++jsum)
307
 
301
 
308
-		  for (int jsum = 1; jsum <= B.chain.Str_L[k]; ++jsum)  sum2 += exp(ln_FunctionG[jsum] - ln_FunctionF[jsum]);
302
+		      sum1 -= Fn_L (A, j, alpha, a, B, k, beta, jsum) *
303
+			exp(ln_FunctionG[jsum] + ln_FunctionG[jsum + 1] - ln_FunctionF[jsum] - ln_FunctionF[jsum + 1]);
309
 
304
 
310
-		  */
311
-		  prod_num = exp(II * im_ln_Fn_F_B_0[k][beta] + ln_FunctionF[1] - ln_FunctionG[B.chain.Str_L[k]] + logabssinzeta);
305
+		    prod_num = exp(II * im_ln_Fn_F_B_0[k][beta] + ln_FunctionF[1]
306
+				   - ln_FunctionG[B.chain.Str_L[k]] + logabssinzeta);
312
 
307
 
313
-		  for (int jsum = 2; jsum <= B.chain.Str_L[k]; ++jsum)
314
-		    prod_num *= exp(ln_FunctionG[jsum] - real(ln_Fn_F(B, k, beta, jsum - 1)) + logabssinzeta);
315
-		  // include all string contributions F_B_0 in this term
308
+		    for (int jsum = 2; jsum <= B.chain.Str_L[k]; ++jsum)
309
+		      prod_num *= exp(ln_FunctionG[jsum] - real(ln_Fn_F(B, k, beta, jsum - 1)) + logabssinzeta);
310
+		    // include all string contributions F_B_0 in this term
316
 
311
 
317
-		  Hm[index_a][index_b] = prod_num * sum1;
312
+		    Hm[index_a][index_b] = prod_num * sum1;
318
 
313
 
319
-		} // else if (b == B.chain.Str_L[k])
320
-	      } // else
314
+		  } // else if (b == B.chain.Str_L[k])
315
+		} // else
321
 
316
 
322
-	      index_b++;
323
-	    }}} // sums over k, beta, b
317
+		index_b++;
318
+	      }}} // sums over k, beta, b
324
 
319
 
325
-	// now define the elements Hm[a][M]
320
+	  // now define the elements Hm[a][M]
326
 
321
 
327
-	Hm[index_a][B.base.Mdown] = one_over_A_sinhlambda_sq_plus_sinzetaover2sq;
322
+	  Hm[index_a][B.base.Mdown] = one_over_A_sinhlambda_sq_plus_sinzetaover2sq;
328
 
323
 
329
-	index_a++;
330
-      }}} // sums over j, alpha, a
324
+	  index_a++;
325
+	}}} // sums over j, alpha, a
331
 
326
 
332
-  complex<DP> ln_ME_sq = log(1.0 * A.chain.Nsites) + real(ln_prod1 - ln_prod2) - real(ln_prod3) + real(ln_prod4)
333
-    + 2.0 * real(lndet_LU_CX_dstry(Hm)) + logabssinzeta - A.lnnorm - B.lnnorm;
327
+    complex<DP> ln_ME_sq = log(1.0 * A.chain.Nsites) + real(ln_prod1 - ln_prod2) - real(ln_prod3) + real(ln_prod4)
328
+      + 2.0 * real(lndet_LU_CX_dstry(Hm)) + logabssinzeta - A.lnnorm - B.lnnorm;
334
 
329
 
335
-  //return(ln_ME_sq);
336
-  return(0.5 * ln_ME_sq); // Return ME, not MEsq
330
+    return(0.5 * ln_ME_sq); // Return ME, not MEsq
337
 
331
 
338
-}
332
+  }
339
 
333
 
340
 } // namespace ABACUS
334
 } // namespace ABACUS

+ 266
- 269
src/ODSLF/ln_Sz_ME_ODSLF_XXZ.cc View File

18
 
18
 
19
 namespace ABACUS {
19
 namespace ABACUS {
20
 
20
 
21
-inline complex<DP> ln_Fn_F (ODSLF_XXZ_Bethe_State& B, int k, int beta, int b)
22
-{
23
-  complex<DP> ans = 0.0;
24
-  complex<DP> prod_temp = 1.0;
25
-  int counter = 0;
26
-  int arg = 0;
27
-  int absarg = 0;
28
-  int par_comb_1, par_comb_2;
21
+  inline complex<DP> ln_Fn_F (ODSLF_XXZ_Bethe_State& B, int k, int beta, int b)
22
+  {
23
+    complex<DP> ans = 0.0;
24
+    complex<DP> prod_temp = 1.0;
25
+    int counter = 0;
26
+    int arg = 0;
27
+    int absarg = 0;
28
+    int par_comb_1, par_comb_2;
29
 
29
 
30
-  for (int j = 0; j < B.chain.Nstrings; ++j) {
30
+    for (int j = 0; j < B.chain.Nstrings; ++j) {
31
 
31
 
32
-    par_comb_1 = B.chain.par[j] == B.chain.par[k] ? 1 : 0;
33
-    par_comb_2 = B.chain.par[k] == B.chain.par[j] ? 0 : B.chain.par[k];
32
+      par_comb_1 = B.chain.par[j] == B.chain.par[k] ? 1 : 0;
33
+      par_comb_2 = B.chain.par[k] == B.chain.par[j] ? 0 : B.chain.par[k];
34
 
34
 
35
-    for (int alpha = 0; alpha < B.base.Nrap[j]; ++alpha) {
35
+      for (int alpha = 0; alpha < B.base.Nrap[j]; ++alpha) {
36
 
36
 
37
-      for (int a = 1; a <= B.chain.Str_L[j]; ++a) {
37
+	for (int a = 1; a <= B.chain.Str_L[j]; ++a) {
38
 
38
 
39
-	if (!((j == k) && (alpha == beta) && (a == b))) {
39
+	  if (!((j == k) && (alpha == beta) && (a == b))) {
40
 
40
 
41
-	  arg = B.chain.Str_L[j] - B.chain.Str_L[k] - 2 * (a - b);
42
-	  absarg = abs(arg);
43
-	  /*
44
-	  prod_temp *= 0.5 *
45
-	    ((B.sinhlambda[j][alpha] * B.coshlambda[k][beta] - B.coshlambda[j][alpha] * B.sinhlambda[k][beta])
46
-			* (B.chain.co_n_anis_over_2[absarg] * (1.0 + B.chain.par[j] * B.chain.par[k])
47
-			   - sgn_int(arg) * B.chain.si_n_anis_over_2[absarg] * (B.chain.par[k] - B.chain.par[j]))
48
-			+ II * (B.coshlambda[j][alpha] * B.coshlambda[k][beta] - B.sinhlambda[j][alpha] * B.sinhlambda[k][beta])
49
-			* (sgn_int(arg)
50
-			   * B.chain.si_n_anis_over_2[absarg] * (1.0 + B.chain.par[j] * B.chain.par[k])
51
-			   + B.chain.co_n_anis_over_2[absarg] * (B.chain.par[k] - B.chain.par[j])) );
52
-	  */
53
-	  prod_temp *= ((B.sinhlambda[j][alpha] * B.coshlambda[k][beta] - B.coshlambda[j][alpha] * B.sinhlambda[k][beta])
54
-			* (B.chain.co_n_anis_over_2[absarg] * par_comb_1 - sgn_int(arg) * B.chain.si_n_anis_over_2[absarg] * par_comb_2)
55
-			+ II * (B.coshlambda[j][alpha] * B.coshlambda[k][beta] - B.sinhlambda[j][alpha] * B.sinhlambda[k][beta])
56
-			* (sgn_int(arg) * B.chain.si_n_anis_over_2[absarg] * par_comb_1 + B.chain.co_n_anis_over_2[absarg] * par_comb_2));
41
+	    arg = B.chain.Str_L[j] - B.chain.Str_L[k] - 2 * (a - b);
42
+	    absarg = abs(arg);
43
+	    prod_temp *= ((B.sinhlambda[j][alpha] * B.coshlambda[k][beta]
44
+			   - B.coshlambda[j][alpha] * B.sinhlambda[k][beta])
45
+			  * (B.chain.co_n_anis_over_2[absarg] * par_comb_1
46
+			     - sgn_int(arg) * B.chain.si_n_anis_over_2[absarg] * par_comb_2)
47
+			  + II * (B.coshlambda[j][alpha] * B.coshlambda[k][beta]
48
+				  - B.sinhlambda[j][alpha] * B.sinhlambda[k][beta])
49
+			  * (sgn_int(arg) * B.chain.si_n_anis_over_2[absarg] * par_comb_1
50
+			     + B.chain.co_n_anis_over_2[absarg] * par_comb_2));
57
 
51
 
58
-	}
52
+	  }
59
 
53
 
60
-	if (counter++ > 100) {  // we do at most 100 products before taking a log
61
-	  ans += log(prod_temp);
62
-	  prod_temp = 1.0;
63
-	  counter = 0;
64
-	}
54
+	  if (counter++ > 100) {  // we do at most 100 products before taking a log
55
+	    ans += log(prod_temp);
56
+	    prod_temp = 1.0;
57
+	    counter = 0;
58
+	  }
65
 
59
 
66
-      }}}
67
-
68
-  return(ans + log(prod_temp));
69
-}
70
-
71
-inline complex<DP> ln_Fn_G (ODSLF_XXZ_Bethe_State& A, ODSLF_XXZ_Bethe_State& B, int k, int beta, int b)
72
-{
73
-  complex<DP> ans = 0.0;
74
-  complex<DP> prod_temp = 1.0;
75
-  int counter = 0;
76
-  int arg = 0;
77
-  int absarg = 0;
78
-  int par_comb_1, par_comb_2;
79
-
80
-  for (int j = 0; j < A.chain.Nstrings; ++j) {
81
-
82
-    par_comb_1 = A.chain.par[j] == B.chain.par[k] ? 1 : 0;
83
-    par_comb_2 = B.chain.par[k] == A.chain.par[j] ? 0 : B.chain.par[k];
84
-
85
-    for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha) {
86
-
87
-      for (int a = 1; a <= A.chain.Str_L[j]; ++a) {
88
-
89
-	arg = A.chain.Str_L[j] - B.chain.Str_L[k] - 2 * (a - b);
90
-	absarg = abs(arg);
91
-
92
-	/*
93
-	prod_temp *= 0.5 *
94
-	  ((A.sinhlambda[j][alpha] * B.coshlambda[k][beta] - A.coshlambda[j][alpha] * B.sinhlambda[k][beta])
95
-		      * (A.chain.co_n_anis_over_2[absarg] * (1.0 + A.chain.par[j] * B.chain.par[k])
96
-			 - sgn_int(arg) * A.chain.si_n_anis_over_2[absarg] * (B.chain.par[k] - A.chain.par[j]))
97
-		      + II * (A.coshlambda[j][alpha] * B.coshlambda[k][beta] - A.sinhlambda[j][alpha] * B.sinhlambda[k][beta])
98
-		      * (sgn_int(arg) * A.chain.si_n_anis_over_2[absarg] * (1.0 + A.chain.par[j] * B.chain.par[k])
99
-			 + A.chain.co_n_anis_over_2[absarg] * (B.chain.par[k] - A.chain.par[j])) );
100
-	*/
101
-	prod_temp *= ((A.sinhlambda[j][alpha] * B.coshlambda[k][beta] - A.coshlambda[j][alpha] * B.sinhlambda[k][beta])
102
-		      * (A.chain.co_n_anis_over_2[absarg] * par_comb_1 - sgn_int(arg) * A.chain.si_n_anis_over_2[absarg] * par_comb_2)
103
-		      + II * (A.coshlambda[j][alpha] * B.coshlambda[k][beta] - A.sinhlambda[j][alpha] * B.sinhlambda[k][beta])
104
-		      * (sgn_int(arg) * A.chain.si_n_anis_over_2[absarg] * par_comb_1 + A.chain.co_n_anis_over_2[absarg] * par_comb_2));
105
-
106
-	if (counter++ > 100) {  // we do at most 100 products before taking a log
107
-	  ans += log(prod_temp);
108
-	  prod_temp = 1.0;
109
-	  counter = 0;
110
-	}
111
-      }}}
112
-
113
-  return(ans + log(prod_temp));
114
-}
115
-
116
-inline complex<DP> Fn_K (ODSLF_XXZ_Bethe_State& A, int j, int alpha, int a, ODSLF_XXZ_Bethe_State& B, int k, int beta, int b)
117
-{
118
-  int arg1 = A.chain.Str_L[j] - B.chain.Str_L[k] - 2 * (a - b);
119
-  int absarg1 = abs(arg1);
120
-  int arg2 = arg1 + 2;
121
-  int absarg2 = abs(arg2);
122
-
123
-  return(4.0/(
124
-	      ((A.sinhlambda[j][alpha] * B.coshlambda[k][beta] - A.coshlambda[j][alpha] * B.sinhlambda[k][beta])
125
-	       * (A.chain.co_n_anis_over_2[absarg1] * (1.0 + A.chain.par[j] * B.chain.par[k])
126
-		  - sgn_int(arg1) * A.chain.si_n_anis_over_2[absarg1] * (B.chain.par[k] - A.chain.par[j]))
127
-	       + II * (A.coshlambda[j][alpha] * B.coshlambda[k][beta] - A.sinhlambda[j][alpha] * B.sinhlambda[k][beta])
128
-	       * (sgn_int(arg1) * A.chain.si_n_anis_over_2[absarg1] * (1.0 + A.chain.par[j] * B.chain.par[k])
129
-		  + A.chain.co_n_anis_over_2[absarg1] * (B.chain.par[k] - A.chain.par[j])) )
130
-	      *
131
-	      ((A.sinhlambda[j][alpha] * B.coshlambda[k][beta] - A.coshlambda[j][alpha] * B.sinhlambda[k][beta])
132
-	       * (A.chain.co_n_anis_over_2[absarg2] * (1.0 + A.chain.par[j] * B.chain.par[k])
133
-		  - sgn_int(arg2) * A.chain.si_n_anis_over_2[absarg2] * (B.chain.par[k] - A.chain.par[j]))
134
-	       + II * (A.coshlambda[j][alpha] * B.coshlambda[k][beta] - A.sinhlambda[j][alpha] * B.sinhlambda[k][beta])
135
-	       * (sgn_int(arg2) * A.chain.si_n_anis_over_2[absarg2] * (1.0 + A.chain.par[j] * B.chain.par[k])
136
-		  + A.chain.co_n_anis_over_2[absarg2] * (B.chain.par[k] - A.chain.par[j])) )
137
-	      ));
138
-
139
-}
140
-
141
-inline complex<DP> Fn_L (ODSLF_XXZ_Bethe_State& A, int j, int alpha, int a, ODSLF_XXZ_Bethe_State& B, int k, int beta, int b)
142
-{
143
-  return (sinh(2.0 * (A.lambda[j][alpha] - B.lambda[k][beta]
144
-		      + 0.5 * II * B.chain.anis * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b - 0.5))
145
-		      + 0.25 * II * PI * complex<DP>(-A.chain.par[j] + B.chain.par[k])))
146
-	  * pow(Fn_K (A, j, alpha, a, B, k, beta, b), 2.0));
147
-}
148
-
149
-complex<DP> ln_Sz_ME (ODSLF_XXZ_Bethe_State& A, ODSLF_XXZ_Bethe_State& B)
150
-{
151
-  // This function returns the natural log of the S^z operator matrix element.
152
-  // The A and B states can contain strings.
153
-
154
-  // Check that the two states refer to the same XXZ_Chain
155
-
156
-  if (A.chain != B.chain) ABACUSerror("Incompatible ODSLF_XXZ_Chains in Sz matrix element.");
157
-
158
-  // Check that A and B are compatible:  same Mdown
159
-
160
-  if (A.base.Mdown != B.base.Mdown) ABACUSerror("Incompatible Mdown between the two states in Sz matrix element!");
161
-
162
-  // Compute the sinh and cosh of rapidities
163
-
164
-  A.Compute_sinhlambda();
165
-  A.Compute_coshlambda();
166
-  B.Compute_sinhlambda();
167
-  B.Compute_coshlambda();
168
-
169
-  // Some convenient arrays
170
-
171
-  ODSLF_Lambda re_ln_Fn_F_B_0(B.chain, B.base);
172
-  ODSLF_Lambda im_ln_Fn_F_B_0(B.chain, B.base);
173
-  ODSLF_Lambda re_ln_Fn_G_0(B.chain, B.base);
174
-  ODSLF_Lambda im_ln_Fn_G_0(B.chain, B.base);
175
-  ODSLF_Lambda re_ln_Fn_G_2(B.chain, B.base);
176
-  ODSLF_Lambda im_ln_Fn_G_2(B.chain, B.base);
177
-
178
-  complex<DP> ln_prod1 = 0.0;
179
-  complex<DP> ln_prod2 = 0.0;
180
-  complex<DP> ln_prod3 = 0.0;
181
-  complex<DP> ln_prod4 = 0.0;
182
-
183
-  for (int i = 0; i < A.chain.Nstrings; ++i)
184
-    for (int alpha = 0; alpha < A.base.Nrap[i]; ++alpha)
185
-      for (int a = 1; a <= A.chain.Str_L[i]; ++a)
186
-	ln_prod1 += log(norm(sinh(A.lambda[i][alpha] + 0.5 * II * A.chain.anis * (A.chain.Str_L[i] + 1.0 - 2.0 * a - 1.0)
187
-				  + 0.25 * II * PI * (1.0 - A.chain.par[i]))));
188
-
189
-  for (int i = 0; i < B.chain.Nstrings; ++i)
190
-    for (int alpha = 0; alpha < B.base.Nrap[i]; ++alpha)
191
-      for (int a = 1; a <= B.chain.Str_L[i]; ++a)
192
-	if (norm(sinh(B.lambda[i][alpha] + 0.5 * II * B.chain.anis * (B.chain.Str_L[i] + 1.0 - 2.0 * a - 1.0)
193
-		      + 0.25 * II * PI * (1.0 - B.chain.par[i]))) > 100.0 * MACHINE_EPS_SQ)
194
-	  ln_prod2 += log(norm(sinh(B.lambda[i][alpha] + 0.5 * II * B.chain.anis * (B.chain.Str_L[i] + 1.0 - 2.0 * a - 1.0)
195
-				    + 0.25 * II * PI * (1.0 - B.chain.par[i]))));
196
-
197
-  // Define the F ones earlier...
198
-
199
-  for (int j = 0; j < B.chain.Nstrings; ++j) {
200
-    for (int alpha = 0; alpha < B.base.Nrap[j]; ++alpha) {
201
-      re_ln_Fn_F_B_0[j][alpha] = real(ln_Fn_F(B, j, alpha, 0));
202
-      im_ln_Fn_F_B_0[j][alpha] = imag(ln_Fn_F(B, j, alpha, 0));
203
-      re_ln_Fn_G_0[j][alpha] = real(ln_Fn_G(A, B, j, alpha, 0));
204
-      im_ln_Fn_G_0[j][alpha] = imag(ln_Fn_G(A, B, j, alpha, 0));
205
-      re_ln_Fn_G_2[j][alpha] = real(ln_Fn_G(A, B, j, alpha, 2));
206
-      im_ln_Fn_G_2[j][alpha] = imag(ln_Fn_G(A, B, j, alpha, 2));
207
-    }
60
+	}}}
61
+
62
+    return(ans + log(prod_temp));
208
   }
63
   }
209
 
64
 
210
-  DP logabssinzeta = log(abs(sin(A.chain.anis)));
65
+  inline complex<DP> ln_Fn_G (ODSLF_XXZ_Bethe_State& A, ODSLF_XXZ_Bethe_State& B, int k, int beta, int b)
66
+  {
67
+    complex<DP> ans = 0.0;
68
+    complex<DP> prod_temp = 1.0;
69
+    int counter = 0;
70
+    int arg = 0;
71
+    int absarg = 0;
72
+    int par_comb_1, par_comb_2;
211
 
73
 
212
-  // Define regularized products in prefactors
74
+    for (int j = 0; j < A.chain.Nstrings; ++j) {
213
 
75
 
214
-  for (int j = 0; j < A.chain.Nstrings; ++j)
215
-    for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha)
216
-      for (int a = 1; a <= A.chain.Str_L[j]; ++a) {
217
-	ln_prod3 += ln_Fn_F (A, j, alpha, a - 1);
218
-      }
76
+      par_comb_1 = A.chain.par[j] == B.chain.par[k] ? 1 : 0;
77
+      par_comb_2 = B.chain.par[k] == A.chain.par[j] ? 0 : B.chain.par[k];
219
 
78
 
220
-  ln_prod3 -= A.base.Mdown * log(abs(sin(A.chain.anis)));
79
+      for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha) {
221
 
80
 
222
-  for (int k = 0; k < B.chain.Nstrings; ++k)
223
-    for (int beta = 0; beta < B.base.Nrap[k]; ++beta)
224
-      for (int b = 1; b <= B.chain.Str_L[k]; ++b) {
225
-	if (b == 1) ln_prod4 += re_ln_Fn_F_B_0[k][beta];
226
-	else if (b > 1) ln_prod4 += ln_Fn_F(B, k, beta, b - 1);
81
+	for (int a = 1; a <= A.chain.Str_L[j]; ++a) {
82
+
83
+	  arg = A.chain.Str_L[j] - B.chain.Str_L[k] - 2 * (a - b);
84
+	  absarg = abs(arg);
85
+
86
+	  prod_temp *= ((A.sinhlambda[j][alpha] * B.coshlambda[k][beta]
87
+			 - A.coshlambda[j][alpha] * B.sinhlambda[k][beta])
88
+			* (A.chain.co_n_anis_over_2[absarg] * par_comb_1
89
+			   - sgn_int(arg) * A.chain.si_n_anis_over_2[absarg] * par_comb_2)
90
+			+ II * (A.coshlambda[j][alpha] * B.coshlambda[k][beta]
91
+				- A.sinhlambda[j][alpha] * B.sinhlambda[k][beta])
92
+			* (sgn_int(arg) * A.chain.si_n_anis_over_2[absarg] * par_comb_1
93
+			   + A.chain.co_n_anis_over_2[absarg] * par_comb_2));
94
+
95
+	  if (counter++ > 100) {  // we do at most 100 products before taking a log
96
+	    ans += log(prod_temp);
97
+	    prod_temp = 1.0;
98
+	    counter = 0;
99
+	  }
100
+	}}}
101
+
102
+    return(ans + log(prod_temp));
103
+  }
104
+
105
+  inline complex<DP> Fn_K (ODSLF_XXZ_Bethe_State& A, int j, int alpha, int a,
106
+			   ODSLF_XXZ_Bethe_State& B, int k, int beta, int b)
107
+  {
108
+    int arg1 = A.chain.Str_L[j] - B.chain.Str_L[k] - 2 * (a - b);
109
+    int absarg1 = abs(arg1);
110
+    int arg2 = arg1 + 2;
111
+    int absarg2 = abs(arg2);
112
+
113
+    return(4.0/(
114
+		((A.sinhlambda[j][alpha] * B.coshlambda[k][beta] - A.coshlambda[j][alpha] * B.sinhlambda[k][beta])
115
+		 * (A.chain.co_n_anis_over_2[absarg1] * (1.0 + A.chain.par[j] * B.chain.par[k])
116
+		    - sgn_int(arg1) * A.chain.si_n_anis_over_2[absarg1] * (B.chain.par[k] - A.chain.par[j]))
117
+		 + II * (A.coshlambda[j][alpha] * B.coshlambda[k][beta] - A.sinhlambda[j][alpha] * B.sinhlambda[k][beta])
118
+		 * (sgn_int(arg1) * A.chain.si_n_anis_over_2[absarg1] * (1.0 + A.chain.par[j] * B.chain.par[k])
119
+		    + A.chain.co_n_anis_over_2[absarg1] * (B.chain.par[k] - A.chain.par[j])) )
120
+		*
121
+		((A.sinhlambda[j][alpha] * B.coshlambda[k][beta] - A.coshlambda[j][alpha] * B.sinhlambda[k][beta])
122
+		 * (A.chain.co_n_anis_over_2[absarg2] * (1.0 + A.chain.par[j] * B.chain.par[k])
123
+		    - sgn_int(arg2) * A.chain.si_n_anis_over_2[absarg2] * (B.chain.par[k] - A.chain.par[j]))
124
+		 + II * (A.coshlambda[j][alpha] * B.coshlambda[k][beta] - A.sinhlambda[j][alpha] * B.sinhlambda[k][beta])
125
+		 * (sgn_int(arg2) * A.chain.si_n_anis_over_2[absarg2] * (1.0 + A.chain.par[j] * B.chain.par[k])
126
+		    + A.chain.co_n_anis_over_2[absarg2] * (B.chain.par[k] - A.chain.par[j])) )
127
+		));
128
+
129
+  }
130
+
131
+  inline complex<DP> Fn_L (ODSLF_XXZ_Bethe_State& A, int j, int alpha, int a,
132
+			   ODSLF_XXZ_Bethe_State& B, int k, int beta, int b)
133
+  {
134
+    return (sinh(2.0 * (A.lambda[j][alpha] - B.lambda[k][beta]
135
+			+ 0.5 * II * B.chain.anis * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b - 0.5))
136
+			+ 0.25 * II * PI * complex<DP>(-A.chain.par[j] + B.chain.par[k])))
137
+	    * pow(Fn_K (A, j, alpha, a, B, k, beta, b), 2.0));
138
+  }
139
+
140
+  complex<DP> ln_Sz_ME (ODSLF_XXZ_Bethe_State& A, ODSLF_XXZ_Bethe_State& B)
141
+  {
142
+    // This function returns the natural log of the S^z operator matrix element.
143
+    // The A and B states can contain strings.
144
+
145
+    // Check that the two states refer to the same XXZ_Chain
146
+
147
+    if (A.chain != B.chain)
148
+      ABACUSerror("Incompatible ODSLF_XXZ_Chains in Sz matrix element.");
149
+
150
+    // Check that A and B are compatible:  same Mdown
151
+
152
+    if (A.base.Mdown != B.base.Mdown)
153
+      ABACUSerror("Incompatible Mdown between the two states in Sz matrix element!");
154
+
155
+    // Compute the sinh and cosh of rapidities
156
+
157
+    A.Compute_sinhlambda();
158
+    A.Compute_coshlambda();
159
+    B.Compute_sinhlambda();
160
+    B.Compute_coshlambda();
161
+
162
+    // Some convenient arrays
163
+
164
+    ODSLF_Lambda re_ln_Fn_F_B_0(B.chain, B.base);
165
+    ODSLF_Lambda im_ln_Fn_F_B_0(B.chain, B.base);
166
+    ODSLF_Lambda re_ln_Fn_G_0(B.chain, B.base);
167
+    ODSLF_Lambda im_ln_Fn_G_0(B.chain, B.base);
168
+    ODSLF_Lambda re_ln_Fn_G_2(B.chain, B.base);
169
+    ODSLF_Lambda im_ln_Fn_G_2(B.chain, B.base);
170
+
171
+    complex<DP> ln_prod1 = 0.0;
172
+    complex<DP> ln_prod2 = 0.0;
173
+    complex<DP> ln_prod3 = 0.0;
174
+    complex<DP> ln_prod4 = 0.0;
175
+
176
+    for (int i = 0; i < A.chain.Nstrings; ++i)
177
+      for (int alpha = 0; alpha < A.base.Nrap[i]; ++alpha)
178
+	for (int a = 1; a <= A.chain.Str_L[i]; ++a)
179
+	  ln_prod1 += log(norm(sinh(A.lambda[i][alpha] + 0.5 * II * A.chain.anis * (A.chain.Str_L[i] + 1.0 - 2.0 * a - 1.0)
180
+				    + 0.25 * II * PI * (1.0 - A.chain.par[i]))));
181
+
182
+    for (int i = 0; i < B.chain.Nstrings; ++i)
183
+      for (int alpha = 0; alpha < B.base.Nrap[i]; ++alpha)
184
+	for (int a = 1; a <= B.chain.Str_L[i]; ++a)
185
+	  if (norm(sinh(B.lambda[i][alpha] + 0.5 * II * B.chain.anis * (B.chain.Str_L[i] + 1.0 - 2.0 * a - 1.0)
186
+			+ 0.25 * II * PI * (1.0 - B.chain.par[i]))) > 100.0 * MACHINE_EPS_SQ)
187
+	    ln_prod2 += log(norm(sinh(B.lambda[i][alpha] + 0.5 * II * B.chain.anis * (B.chain.Str_L[i] + 1.0 - 2.0 * a - 1.0)
188
+				      + 0.25 * II * PI * (1.0 - B.chain.par[i]))));
189
+
190
+    // Define the F ones earlier...
191
+
192
+    for (int j = 0; j < B.chain.Nstrings; ++j) {
193
+      for (int alpha = 0; alpha < B.base.Nrap[j]; ++alpha) {
194
+	re_ln_Fn_F_B_0[j][alpha] = real(ln_Fn_F(B, j, alpha, 0));
195
+	im_ln_Fn_F_B_0[j][alpha] = imag(ln_Fn_F(B, j, alpha, 0));
196
+	re_ln_Fn_G_0[j][alpha] = real(ln_Fn_G(A, B, j, alpha, 0));
197
+	im_ln_Fn_G_0[j][alpha] = imag(ln_Fn_G(A, B, j, alpha, 0));
198
+	re_ln_Fn_G_2[j][alpha] = real(ln_Fn_G(A, B, j, alpha, 2));
199
+	im_ln_Fn_G_2[j][alpha] = imag(ln_Fn_G(A, B, j, alpha, 2));
227
       }
200
       }
201
+    }
228
 
202
 
229
-  ln_prod4 -= B.base.Mdown * log(abs(sin(B.chain.anis)));
203
+    DP logabssinzeta = log(abs(sin(A.chain.anis)));
230
 
204
 
231
-  // Now proceed to build the Hm2P matrix
205
+    // Define regularized products in prefactors
232
 
206
 
233
-  SQMat_CX Hm2P(0.0, A.base.Mdown);
207
+    for (int j = 0; j < A.chain.Nstrings; ++j)
208
+      for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha)
209
+	for (int a = 1; a <= A.chain.Str_L[j]; ++a) {
210
+	  ln_prod3 += ln_Fn_F (A, j, alpha, a - 1);
211
+	}
234
 
212
 
235
-  int index_a = 0;
236
-  int index_b = 0;
213
+    ln_prod3 -= A.base.Mdown * log(abs(sin(A.chain.anis)));
237
 
214
 
238
-  complex<DP> sum1 = 0.0;
239
-  complex<DP> sum2 = 0.0;
240
-  complex<DP> prod_num = 0.0;
241
-  complex<DP> Fn_K_0_G_0 = 0.0;
242
-  complex<DP> Prod_powerN = 0.0;
243
-  complex<DP> Fn_K_1_G_2 = 0.0;
244
-  complex<DP> two_over_A_sinhlambda_sq_plus_sinzetaover2sq;
215
+    for (int k = 0; k < B.chain.Nstrings; ++k)
216
+      for (int beta = 0; beta < B.base.Nrap[k]; ++beta)
217
+	for (int b = 1; b <= B.chain.Str_L[k]; ++b) {
218
+	  if (b == 1) ln_prod4 += re_ln_Fn_F_B_0[k][beta];
219
+	  else if (b > 1) ln_prod4 += ln_Fn_F(B, k, beta, b - 1);
220
+	}
245
 
221
 
222
+    ln_prod4 -= B.base.Mdown * log(abs(sin(B.chain.anis)));
246
 
223
 
247
-  for (int j = 0; j < A.chain.Nstrings; ++j) {
248
-    for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha) {
249
-      for (int a = 1; a <= A.chain.Str_L[j]; ++a) {
224
+    // Now proceed to build the Hm2P matrix
250
 
225
 
251
-	index_b = 0;
226
+    SQMat_CX Hm2P(0.0, A.base.Mdown);
252
 
227
 
253
-	two_over_A_sinhlambda_sq_plus_sinzetaover2sq = 2.0/((sinh(A.lambda[j][alpha] + 0.5 * II * A.chain.anis * (A.chain.Str_L[j] + 1.0 - 2.0 * a)
254
-								  + 0.25 * II * PI * (1.0 - A.chain.par[j])))
255
-							    * (sinh(A.lambda[j][alpha] + 0.5 * II * A.chain.anis * (A.chain.Str_L[j] + 1.0 - 2.0 * a)
256
-								  + 0.25 * II * PI * (1.0 - A.chain.par[j])))
257
-							     + pow(sin(0.5*A.chain.anis), 2.0));
228
+    int index_a = 0;
229
+    int index_b = 0;
258
 
230
 
259
-	for (int k = 0; k < B.chain.Nstrings; ++k) {
260
-	  for (int beta = 0; beta < B.base.Nrap[k]; ++beta) {
261
-	    for (int b = 1; b <= B.chain.Str_L[k]; ++b) {
231
+    complex<DP> sum1 = 0.0;
232
+    complex<DP> sum2 = 0.0;
233
+    complex<DP> prod_num = 0.0;
234
+    complex<DP> Fn_K_0_G_0 = 0.0;
235
+    complex<DP> Prod_powerN = 0.0;
236
+    complex<DP> Fn_K_1_G_2 = 0.0;
237
+    complex<DP> two_over_A_sinhlambda_sq_plus_sinzetaover2sq;
262
 
238
 
263
-	      if (B.chain.Str_L[k] == 1) {
264
 
239
 
265
-		// use simplified code for one-string here:  original form of Hm2P matrix
240
+    for (int j = 0; j < A.chain.Nstrings; ++j) {
241
+      for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha) {
242
+	for (int a = 1; a <= A.chain.Str_L[j]; ++a) {
266
 
243
 
267
-		Fn_K_0_G_0 = Fn_K (A, j, alpha, a, B, k, beta, 0) *
268
-		  exp(re_ln_Fn_G_0[k][beta] + II * im_ln_Fn_G_0[k][beta] - re_ln_Fn_F_B_0[k][beta] + logabssinzeta);
269
-		Fn_K_1_G_2 = Fn_K (A, j, alpha, a, B, k, beta, 1) *
270
-		  exp(re_ln_Fn_G_2[k][beta] + II * im_ln_Fn_G_2[k][beta] - re_ln_Fn_F_B_0[k][beta] + logabssinzeta);
244
+	  index_b = 0;
271
 
245
 
272
-		Prod_powerN = pow( B.chain.par[k] == 1 ?
273
-				   (B.sinhlambda[k][beta] * B.chain.co_n_anis_over_2[1] + II * B.coshlambda[k][beta] * B.chain.si_n_anis_over_2[1])
274
-				   /(B.sinhlambda[k][beta] * B.chain.co_n_anis_over_2[1] - II * B.coshlambda[k][beta] * B.chain.si_n_anis_over_2[1])
275
-				   :
276
-				   (B.coshlambda[k][beta] * B.chain.co_n_anis_over_2[1] + II * B.sinhlambda[k][beta] * B.chain.si_n_anis_over_2[1])
277
-				   /(B.coshlambda[k][beta] * B.chain.co_n_anis_over_2[1] - II * B.sinhlambda[k][beta] * B.chain.si_n_anis_over_2[1])
278
-				   , complex<DP> (B.chain.Nsites));
246
+	  two_over_A_sinhlambda_sq_plus_sinzetaover2sq =
247
+	    2.0/((sinh(A.lambda[j][alpha] + 0.5 * II * A.chain.anis * (A.chain.Str_L[j] + 1.0 - 2.0 * a)
248
+		       + 0.25 * II * PI * (1.0 - A.chain.par[j])))
249
+		 * (sinh(A.lambda[j][alpha] + 0.5 * II * A.chain.anis * (A.chain.Str_L[j] + 1.0 - 2.0 * a)
250
+			 + 0.25 * II * PI * (1.0 - A.chain.par[j])))
251
+		 + pow(sin(0.5*A.chain.anis), 2.0));
279
 
252
 
280
-		Hm2P[index_a][index_b] = Fn_K_0_G_0 - (-1.0 + 2.0 * (B.base.Mdown % 2)) * // MODIF from XXZ
281
-		  Prod_powerN * Fn_K_1_G_2 - two_over_A_sinhlambda_sq_plus_sinzetaover2sq
282
-		    * exp(II*im_ln_Fn_F_B_0[k][beta] + logabssinzeta);
253
+	  for (int k = 0; k < B.chain.Nstrings; ++k) {
254
+	    for (int beta = 0; beta < B.base.Nrap[k]; ++beta) {
255
+	      for (int b = 1; b <= B.chain.Str_L[k]; ++b) {
283
 
256
 
284
-	      }
257
+		if (B.chain.Str_L[k] == 1) {
285
 
258
 
286
-	      else {
259
+		  // use simplified code for one-string here:  original form of Hm2P matrix
287
 
260
 
288
-		if (b <= B.chain.Str_L[k] - 1) Hm2P[index_a][index_b] = Fn_K(A, j, alpha, a, B, k, beta, b);
289
-		else if (b == B.chain.Str_L[k]) {
261
+		  Fn_K_0_G_0 = Fn_K (A, j, alpha, a, B, k, beta, 0) *
262
+		    exp(re_ln_Fn_G_0[k][beta] + II * im_ln_Fn_G_0[k][beta] - re_ln_Fn_F_B_0[k][beta] + logabssinzeta);
263
+		  Fn_K_1_G_2 = Fn_K (A, j, alpha, a, B, k, beta, 1) *
264
+		    exp(re_ln_Fn_G_2[k][beta] + II * im_ln_Fn_G_2[k][beta] - re_ln_Fn_F_B_0[k][beta] + logabssinzeta);
290
 
265
 
291
-		  Vect_CX ln_FunctionF(B.chain.Str_L[k] + 2);
292
-		  for (int i = 0; i < B.chain.Str_L[k] + 2; ++i) ln_FunctionF[i] = ln_Fn_F (B, k, beta, i);
266
+		  Prod_powerN = pow( B.chain.par[k] == 1 ?
267
+				     (B.sinhlambda[k][beta] * B.chain.co_n_anis_over_2[1]
268
+				      + II * B.coshlambda[k][beta] * B.chain.si_n_anis_over_2[1])
269
+				     /(B.sinhlambda[k][beta] * B.chain.co_n_anis_over_2[1]
270
+				       - II * B.coshlambda[k][beta] * B.chain.si_n_anis_over_2[1])
271
+				     :
272
+				     (B.coshlambda[k][beta] * B.chain.co_n_anis_over_2[1]
273
+				      + II * B.sinhlambda[k][beta] * B.chain.si_n_anis_over_2[1])
274
+				     /(B.coshlambda[k][beta] * B.chain.co_n_anis_over_2[1]
275
+				       - II * B.sinhlambda[k][beta] * B.chain.si_n_anis_over_2[1])
276
+				     , complex<DP> (B.chain.Nsites));
293
 
277
 
294
-		  Vect_CX ln_FunctionG(B.chain.Str_L[k] + 2);
295
-		  for (int i = 0; i < B.chain.Str_L[k] + 2; ++i) ln_FunctionG[i] = ln_Fn_G (A, B, k, beta, i);
278
+		  Hm2P[index_a][index_b] = Fn_K_0_G_0 - (-1.0 + 2.0 * (B.base.Mdown % 2)) * // MODIF from XXZ
279
+		    Prod_powerN * Fn_K_1_G_2 - two_over_A_sinhlambda_sq_plus_sinzetaover2sq
280
+		    * exp(II*im_ln_Fn_F_B_0[k][beta] + logabssinzeta);
281
+
282
+		}
283
+
284
+		else {
296
 
285
 
297
-		  sum1 = 0.0;
286
+		  if (b <= B.chain.Str_L[k] - 1) Hm2P[index_a][index_b] = Fn_K(A, j, alpha, a, B, k, beta, b);
287
+		  else if (b == B.chain.Str_L[k]) {
298
 
288
 
299
-		  sum1 += Fn_K (A, j, alpha, a, B, k, beta, 0) * exp(ln_FunctionG[0] + ln_FunctionG[1] - ln_FunctionF[0] - ln_FunctionF[1]);
289
+		    Vect_CX ln_FunctionF(B.chain.Str_L[k] + 2);
290
+		    for (int i = 0; i < B.chain.Str_L[k] + 2; ++i) ln_FunctionF[i] = ln_Fn_F (B, k, beta, i);
300
 
291
 
301
-		  sum1 += (-1.0 + 2.0 * (B.base.Mdown % 2)) * // MODIF from XXZ
302
-		    Fn_K (A, j, alpha, a, B, k, beta, B.chain.Str_L[k])
303
-		    * exp(ln_FunctionG[B.chain.Str_L[k]] + ln_FunctionG[B.chain.Str_L[k] + 1]
304
-			  - ln_FunctionF[B.chain.Str_L[k]] - ln_FunctionF[B.chain.Str_L[k] + 1]);
292
+		    Vect_CX ln_FunctionG(B.chain.Str_L[k] + 2);
293
+		    for (int i = 0; i < B.chain.Str_L[k] + 2; ++i) ln_FunctionG[i] = ln_Fn_G (A, B, k, beta, i);
305
 
294
 
306
-		  for (int jsum = 1; jsum < B.chain.Str_L[k]; ++jsum)
295
+		    sum1 = 0.0;
307
 
296
 
308
-		    sum1 -= Fn_L (A, j, alpha, a, B, k, beta, jsum) *
309
-		      exp(ln_FunctionG[jsum] + ln_FunctionG[jsum + 1] - ln_FunctionF[jsum] - ln_FunctionF[jsum + 1]);
297
+		    sum1 += Fn_K (A, j, alpha, a, B, k, beta, 0)
298
+		      * exp(ln_FunctionG[0] + ln_FunctionG[1] - ln_FunctionF[0] - ln_FunctionF[1]);
310
 
299
 
311
-		  sum2 = 0.0;
300
+		    sum1 += (-1.0 + 2.0 * (B.base.Mdown % 2)) * // MODIF from XXZ
301
+		      Fn_K (A, j, alpha, a, B, k, beta, B.chain.Str_L[k])
302
+		      * exp(ln_FunctionG[B.chain.Str_L[k]] + ln_FunctionG[B.chain.Str_L[k] + 1]
303
+			    - ln_FunctionF[B.chain.Str_L[k]] - ln_FunctionF[B.chain.Str_L[k] + 1]);
312
 
304
 
313
-		  for (int jsum = 1; jsum <= B.chain.Str_L[k]; ++jsum)  sum2 += exp(ln_FunctionG[jsum] - ln_FunctionF[jsum]);
305
+		    for (int jsum = 1; jsum < B.chain.Str_L[k]; ++jsum)
314
 
306
 
315
-		  prod_num = exp(II * im_ln_Fn_F_B_0[k][beta] + ln_FunctionF[1] - ln_FunctionG[B.chain.Str_L[k]] + logabssinzeta);
307
+		      sum1 -= Fn_L (A, j, alpha, a, B, k, beta, jsum) *
308
+			exp(ln_FunctionG[jsum] + ln_FunctionG[jsum + 1] - ln_FunctionF[jsum] - ln_FunctionF[jsum + 1]);
316
 
309
 
317
-		  for (int jsum = 2; jsum <= B.chain.Str_L[k]; ++jsum)
318
-		    prod_num *= exp(ln_FunctionG[jsum] - real(ln_FunctionF[jsum - 1]) + logabssinzeta);
319
-		  // include all string contributions F_B_0 in this term
310
+		    sum2 = 0.0;
320
 
311
 
321
-		  Hm2P[index_a][index_b] = prod_num * (sum1 - sum2 * two_over_A_sinhlambda_sq_plus_sinzetaover2sq);
312
+		    for (int jsum = 1; jsum <= B.chain.Str_L[k]; ++jsum)
313
+		      sum2 += exp(ln_FunctionG[jsum] - ln_FunctionF[jsum]);
322
 
314
 
323
-		} // else if (b == B.chain.Str_L[k])
324
-	      } // else
315
+		    prod_num = exp(II * im_ln_Fn_F_B_0[k][beta] + ln_FunctionF[1]
316
+				   - ln_FunctionG[B.chain.Str_L[k]] + logabssinzeta);
325
 
317
 
326
-	      index_b++;
327
-	    }}} // sums over k, beta, b
328
-	index_a++;
329
-      }}} // sums over j, alpha, a
318
+		    for (int jsum = 2; jsum <= B.chain.Str_L[k]; ++jsum)
319
+		      prod_num *= exp(ln_FunctionG[jsum] - real(ln_FunctionF[jsum - 1]) + logabssinzeta);
320
+		    // include all string contributions F_B_0 in this term
330
 
321
 
331
-  DP re_ln_det = real(lndet_LU_CX_dstry(Hm2P));
322
+		    Hm2P[index_a][index_b] = prod_num * (sum1 - sum2 * two_over_A_sinhlambda_sq_plus_sinzetaover2sq);
332
 
323
 
333
-  complex<DP> ln_ME_sq = log(0.25 * A.chain.Nsites) + real(ln_prod1 - ln_prod2) - real(ln_prod3) + real(ln_prod4)
334
-    + 2.0 * /*real(lndet_LU_CX_dstry(Hm2P))*/ re_ln_det - A.lnnorm - B.lnnorm;
324
+		  } // else if (b == B.chain.Str_L[k])
325
+		} // else
335
 
326
 
336
-  //cout << endl << ln_prod1 << "\t" << ln_prod2 << "\t" << ln_prod3 << "\t" << ln_prod4 << "\t" << A.lnnorm << "\t" << B.lnnorm
337
-  //  << "\t" << re_ln_det << "\t" << ln_ME_sq << endl;
327
+		index_b++;
328
+	      }}} // sums over k, beta, b
329
+	  index_a++;
330
+	}}} // sums over j, alpha, a
338
 
331
 
339
-  //return(ln_ME_sq);
340
-  return(0.5 * ln_ME_sq); // Return ME, not MEsq
332
+    DP re_ln_det = real(lndet_LU_CX_dstry(Hm2P));
341
 
333
 
342
-}
334
+    complex<DP> ln_ME_sq = log(0.25 * A.chain.Nsites) + real(ln_prod1 - ln_prod2) - real(ln_prod3) + real(ln_prod4)
335
+      + 2.0 * re_ln_det - A.lnnorm - B.lnnorm;
336
+
337
+    return(0.5 * ln_ME_sq); // Return ME, not MEsq
338
+
339
+  }
343
 
340
 
344
 } // namespace ABACUS
341
 } // namespace ABACUS

+ 6
- 26
src/RICHARDSON/Richardson.cc View File

31
     //DP bquad = -1.0/g_int - sumoneovereps[j];
31
     //DP bquad = -1.0/g_int - sumoneovereps[j];
32
     //DP cquad = sumSovereps[j];
32
     //DP cquad = sumSovereps[j];
33
     /*
33
     /*
34
-    DP discr = 0.0;
35
-    bool retval = false;
36
-    //if ((discr = bquad * bquad - 4.0 * cquad) >= 0.0) {
37
-    if ((discr = (1.0/g_int + sumoneovereps[j]) * (1.0/g_int + sumoneovereps[j]) - 4.0 * sumSovereps[j]) >= 0.0) {
34
+      DP discr = 0.0;
35
+      bool retval = false;
36
+      //if ((discr = bquad * bquad - 4.0 * cquad) >= 0.0) {
37
+      if ((discr = (1.0/g_int + sumoneovereps[j]) * (1.0/g_int + sumoneovereps[j]) - 4.0 * sumSovereps[j]) >= 0.0) {
38
       discr = sqrt(discr);
38
       discr = sqrt(discr);
39
       Sjleft = 0.5 * (-(1.0/g_int + sumoneovereps[j]) - discr);
39
       Sjleft = 0.5 * (-(1.0/g_int + sumoneovereps[j]) - discr);
40
       Sjright = 0.5 * (-(1.0/g_int + sumoneovereps[j]) + discr);
40
       Sjright = 0.5 * (-(1.0/g_int + sumoneovereps[j]) + discr);
41
       retval = true;
41
       retval = true;
42
-    }
42
+      }
43
 
43
 
44
-    return(retval);
44
+      return(retval);
45
     */
45
     */
46
 
46
 
47
     complex<DP> discr = sqrt((1.0/g_int + sumoneovereps[j]) * (1.0/g_int + sumoneovereps[j]) - 4.0 * sumSovereps[j]);
47
     complex<DP> discr = sqrt((1.0/g_int + sumoneovereps[j]) * (1.0/g_int + sumoneovereps[j]) - 4.0 * sumSovereps[j]);
48
-    //complex<DP> discr = sqrt(ABACUS::max(0.0, real((1.0/g_int + sumoneovereps[j]) * (1.0/g_int + sumoneovereps[j]) - 4.0 * sumSovereps[j])));
49
     Sjleft = 0.5 * (1.0/g_int + sumoneovereps[j] - discr);
48
     Sjleft = 0.5 * (1.0/g_int + sumoneovereps[j] - discr);
50
     Sjright = 0.5 * (1.0/g_int + sumoneovereps[j] + discr);
49
     Sjright = 0.5 * (1.0/g_int + sumoneovereps[j] + discr);
51
     return(true);
50
     return(true);
93
 
92
 
94
       // Re-solve for jmax:
93
       // Re-solve for jmax:
95
       if (Solve_Richardson_Quad_S (g_int, epsilon, sumoneovereps, S, sumSovereps, jmax, Sleft, Sright)) {
94
       if (Solve_Richardson_Quad_S (g_int, epsilon, sumoneovereps, S, sumSovereps, jmax, Sleft, Sright)) {
96
-	//if (leftroot[jmax] == true) S[jmax] = damping * Sleft + (1.0 - damping) * S[jmax];
97
-	//else S[jmax] = damping * Sright + (1.0 - damping) * S[jmax];
98
 	if (abs(S[jmax] - Sleft) < abs(S[jmax] - Sright)) S[jmax] = damping * Sleft + (1.0 - damping) * S[jmax];
95
 	if (abs(S[jmax] - Sleft) < abs(S[jmax] - Sright)) S[jmax] = damping * Sleft + (1.0 - damping) * S[jmax];
99
 	else S[jmax] = damping * Sright + (1.0 - damping) * S[jmax];
96
 	else S[jmax] = damping * Sright + (1.0 - damping) * S[jmax];
100
       }
97
       }
104
       cout << " to " << S[jmax] << endl;
101
       cout << " to " << S[jmax] << endl;
105
 
102
 
106
       // Re-solve also for a random j, given by
103
       // Re-solve also for a random j, given by
107
-      //int jrand = int(maxabsLHSRE * 1.0e+6) % Nlevels;
108
       int jrand = rand() % Nlevels;
104
       int jrand = rand() % Nlevels;
109
       cout << "identified jrand = " << jrand << endl;
105
       cout << "identified jrand = " << jrand << endl;
110
       cout << "S[jrand]: from " << S[jrand];
106
       cout << "S[jrand]: from " << S[jrand];
111
 
107
 
112
       if (Solve_Richardson_Quad_S (g_int, epsilon, sumoneovereps, S, sumSovereps, jrand, Sleft, Sright)) {
108
       if (Solve_Richardson_Quad_S (g_int, epsilon, sumoneovereps, S, sumSovereps, jrand, Sleft, Sright)) {
113
-	//if (leftroot[jrand] == true) S[jrand] = damping * Sleft + (1.0 - damping) * S[jrand];
114
-	//else S[jrand] = damping * Sright + (1.0 - damping) * S[jrand];
115
 	if (abs(S[jrand] - Sleft) < abs(S[jrand] - Sright)) S[jrand] = damping * Sleft + (1.0 - damping) * S[jrand];
109
 	if (abs(S[jrand] - Sleft) < abs(S[jrand] - Sright)) S[jrand] = damping * Sleft + (1.0 - damping) * S[jrand];
116
 	else S[jrand] = damping * Sright + (1.0 - damping) * S[jrand];
110
 	else S[jrand] = damping * Sright + (1.0 - damping) * S[jrand];
117
       }
111
       }
120
       }
114
       }
121
       cout << " to " << S[jrand] << endl;
115
       cout << " to " << S[jrand] << endl;
122
 
116
 
123
-      /*
124
-      for (int j = 0; j < Nlevels; ++j) {
125
-	if (Solve_Richardson_Quad_S (g_int, epsilon, sumoneovereps, S, sumSovereps, j, Sleft, Sright)) {
126
-	  if (leftroot[j] == true) S[j] = damping * Sleft + (1.0 - damping) * S[j];
127
-	  else S[j] = damping * Sright + (1.0 - damping) * S[j];
128
-	}
129
-	else {
130
-	  ABACUSerror("Complex root.");
131
-	}
132
-      }
133
-      */
134
-
135
       // Recalculate all sums:
117
       // Recalculate all sums:
136
       for (int j = 0; j < Nlevels; ++j) {
118
       for (int j = 0; j < Nlevels; ++j) {
137
 	sumSovereps[j] = 0.0;
119
 	sumSovereps[j] = 0.0;
144
   }
126
   }
145
 
127
 
146
 
128
 
147
-
148
-
149
 } // namespace ABACUS
129
 } // namespace ABACUS
150
 
130
 
151
 
131
 

Loading…
Cancel
Save