You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

Heis_Matrix_Element_Contrib.cc 17KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378
  1. /**********************************************************
  2. This software is part of J.-S. Caux's ABACUS library.
  3. Copyright (c) J.-S. Caux.
  4. -----------------------------------------------------------
  5. File: src/HEIS/Heis_Matrix_Element_Contrib.cc
  6. Purpose: handles the generic call for a matrix element.
  7. ***********************************************************/
  8. #include "ABACUS.h"
  9. using namespace std;
  10. using namespace ABACUS;
  11. namespace ABACUS {
  12. //DP Compute_Matrix_Element_Contrib (char whichDSF, bool fixed_iK, XXZ_Bethe_State& LeftState,
  13. //XXZ_Bethe_State& RightState, DP Chem_Pot, fstream& DAT_outfile)
  14. //DP Compute_Matrix_Element_Contrib (char whichDSF, int iKmin, int iKmax, XXZ_Bethe_State& LeftState,
  15. // XXZ_Bethe_State& RightState, DP Chem_Pot, fstream& DAT_outfile)
  16. DP Compute_Matrix_Element_Contrib (char whichDSF, int iKmin, int iKmax, XXZ_Bethe_State& LeftState,
  17. XXZ_Bethe_State& RightState, DP Chem_Pot, stringstream& DAT_outfile)
  18. {
  19. // This function prints the matrix information to the fstream,
  20. // and returns a weighed `data_value' to be multiplied by sumrule_factor,
  21. // to determine if scanning along this thread should be continued.
  22. // Identify which matrix element is needed from the number of particles in Left and Right states:
  23. bool fixed_iK = (iKmin == iKmax);
  24. DP ME = 0.0;
  25. if (!(LeftState.conv && RightState.conv)) ME = 0.0;
  26. else if (whichDSF == 'Z')
  27. ME = LeftState.E - RightState.E;
  28. else if (whichDSF == 'm')
  29. ME = exp(real(ln_Smin_ME (RightState, LeftState)));
  30. else if (whichDSF == 'z') {
  31. if (LeftState.label == RightState.label)
  32. //MEsq = RightState.chain.Nsites * 0.25 * pow((1.0 - 2.0*RightState.base.Mdown/RightState.chain.Nsites), 2.0);
  33. ME = sqrt(RightState.chain.Nsites * 0.25) * (1.0 - 2.0*RightState.base.Mdown/RightState.chain.Nsites);
  34. else ME = exp(real(ln_Sz_ME (RightState, LeftState)));
  35. }
  36. else if (whichDSF == 'p')
  37. ME = exp(real(ln_Smin_ME (LeftState, RightState)));
  38. else ABACUSerror("Wrong whichDSF in Compute_Matrix_Element_Contrib.");
  39. if (is_nan(ME)) ME = 0.0;
  40. //if (LeftState.dev > 1.0e-16 || RightState.dev > 1.0e-16) ME = 0.0; // kill deviated contributions
  41. // Do the momentum business:
  42. int iKout = LeftState.iK - RightState.iK;
  43. while(iKout < 0) iKout += RightState.chain.Nsites;
  44. while(iKout >= RightState.chain.Nsites) iKout -= RightState.chain.Nsites;
  45. DAT_outfile << setprecision(16);
  46. // Print information to fstream:
  47. if (iKout >= iKmin && iKout <= iKmax) {
  48. if (whichDSF == 'Z') {
  49. DAT_outfile << endl << setprecision(16) << LeftState.E - RightState.E - (LeftState.base.Mdown - RightState.base.Mdown) * Chem_Pot << "\t"
  50. << iKout << "\t"
  51. //<< LeftState.conv << "\t"
  52. << setprecision(3) << LeftState.dev << "\t"
  53. << LeftState.label;
  54. }
  55. else {
  56. DAT_outfile << endl << setprecision(16) << LeftState.E - RightState.E - (LeftState.base.Mdown - RightState.base.Mdown) * Chem_Pot << "\t"
  57. << iKout << "\t"
  58. << ME << "\t"
  59. //<< LeftState.conv << "\t"
  60. << setprecision(3) << LeftState.dev << "\t"
  61. << LeftState.label;
  62. }
  63. } // if iKmin <= iKout <= iKmax
  64. // Calculate and return the data_value:
  65. DP data_value = ME * ME;
  66. //DP data_value = (iKout == 0 ? 1.0 : 2.0) * MEsq;
  67. if (whichDSF == 'Z') // use 1/(1 + omega)
  68. data_value = 1.0/(1.0 + LeftState.E - RightState.E - (LeftState.base.Mdown - RightState.base.Mdown) * Chem_Pot);
  69. else if (fixed_iK) // data value is MEsq * omega:
  70. data_value = ME * ME * (LeftState.E - RightState.E - (LeftState.base.Mdown - RightState.base.Mdown) * Chem_Pot);
  71. return(data_value);
  72. }
  73. //DP Compute_Matrix_Element_Contrib (char whichDSF, bool fixed_iK, XXX_Bethe_State& LeftState,
  74. //XXX_Bethe_State& RightState, DP Chem_Pot, fstream& DAT_outfile)
  75. //DP Compute_Matrix_Element_Contrib (char whichDSF, int iKmin, int iKmax, XXX_Bethe_State& LeftState,
  76. //XXX_Bethe_State& RightState, DP Chem_Pot, fstream& DAT_outfile)
  77. DP Compute_Matrix_Element_Contrib (char whichDSF, int iKmin, int iKmax, XXX_Bethe_State& LeftState,
  78. XXX_Bethe_State& RightState, DP Chem_Pot, stringstream& DAT_outfile)
  79. {
  80. // This function prints the matrix element information to the fstream,
  81. // and returns a weighed `data_value' to be multiplied by sumrule_factor,
  82. // to determine if scanning along this thread should be continued.
  83. // Identify which matrix element is needed from the number of particles in Left and Right states:
  84. bool fixed_iK = (iKmin == iKmax);
  85. DP ME = 0.0;
  86. complex<DP> ME_CX = 0.0;
  87. int nrinfrap = 0; // for energy shift from chemical potential
  88. if (!(LeftState.conv && RightState.conv)) { ME = 0.0; ME_CX = 0.0;}
  89. else if (whichDSF == 'Z')
  90. ME = LeftState.E - RightState.E;
  91. else if (whichDSF == 'm')
  92. ME = exp(real(ln_Smin_ME (RightState, LeftState)));
  93. else if (whichDSF == 'z') {
  94. // Recognize the presence of an infinite rapidity:
  95. if (LeftState.base.Mdown == RightState.base.Mdown - 1) { // infinite rapidity present, use rescaled S^- matrix element instead of S^z one:
  96. nrinfrap = 1;
  97. // Correction factor for MEsq: Smffsq to Szffsq = 1/(N - 2M + 2)
  98. ME = sqrt(1.0/(RightState.chain.Nsites - 2*RightState.base.Mdown + 2)) * exp(real(ln_Smin_ME (RightState, LeftState)));
  99. }
  100. else { // no infinite rapidity, use S^z matrix element:
  101. if (LeftState.label == RightState.label)
  102. //MEsq = RightState.chain.Nsites * 0.25 * pow((1.0 - 2.0*RightState.base.Mdown/RightState.chain.Nsites), 2.0);
  103. ME = sqrt(RightState.chain.Nsites * 0.25) * (1.0 - 2.0*RightState.base.Mdown/RightState.chain.Nsites);
  104. else ME = exp(real(ln_Sz_ME (RightState, LeftState)));
  105. }
  106. }
  107. else if (whichDSF == 'p') {
  108. // Recognize the presence of two infinite rapidities:
  109. if (LeftState.base.Mdown == RightState.base.Mdown - 1) { // two infinite rapidities, use rescaled S^- matrix element instead of S^+
  110. nrinfrap = 2;
  111. // Correction factor for MEsq: Smffsq to Spffsq = 2/((N - 2M + 2) (N - 2M + 1))
  112. ME = sqrt(2.0/((RightState.chain.Nsites - 2*RightState.base.Mdown + 2.0) * (RightState.chain.Nsites - 2*RightState.base.Mdown + 1.0)))
  113. * exp(real(ln_Smin_ME (RightState, LeftState)));
  114. }
  115. else if (LeftState.base.Mdown == RightState.base.Mdown) { // one infinite rapidity, use rescaled S^z matrix element instead of S^+
  116. nrinfrap = 1;
  117. // Correction factor for MEsq: Szffsq to Spffsq = 4/(N - 2M)
  118. ME = sqrt(4.0/(RightState.chain.Nsites - 2* RightState.base.Mdown)) * exp(real(ln_Sz_ME (RightState, LeftState)));
  119. }
  120. else ME = exp(real(ln_Smin_ME (LeftState, RightState)));
  121. }
  122. else if (whichDSF == 'a') // S^z_j S^z_{j+1} operator
  123. ME = exp(real(ln_Szz_ME (LeftState, RightState)));
  124. else if (whichDSF == 'b') // S^z_j S^-_{j+1} + h.c. operator
  125. ME = exp(real(ln_Szm_p_Smz_ME (RightState, LeftState)));
  126. else if (whichDSF == 'c') // S^-_j S^-{j+1} operator
  127. ME = exp(real(ln_Smm_ME (RightState, LeftState)));
  128. else if (whichDSF == 'q') // Geometric quench
  129. //ME_CX = ln_Overlap (LeftState, RightState);
  130. ME_CX = ln_Overlap (RightState, LeftState);
  131. else ABACUSerror("Wrong whichDSF in Compute_Matrix_Element_Contrib.");
  132. if (is_nan(ME)) ME = 0.0;
  133. if (is_nan(norm(ME_CX))) ME_CX = -100.0;
  134. //if (LeftState.dev > 1.0e-16 || RightState.dev > 1.0e-16) {
  135. //ME = 0.0; ME_CX = (0.0,0.0); // kill deviated contributions
  136. //}
  137. // Do the momentum business:
  138. int iKout = LeftState.iK - RightState.iK;
  139. while(iKout < 0) iKout += RightState.chain.Nsites;
  140. while(iKout >= RightState.chain.Nsites) iKout -= RightState.chain.Nsites;
  141. DAT_outfile << setprecision(16);
  142. // Print information to fstream:
  143. if (iKout >= iKmin && iKout <= iKmax) {
  144. if (whichDSF == 'Z') {
  145. DAT_outfile << endl << setprecision(16) << LeftState.E - RightState.E - (LeftState.base.Mdown + nrinfrap - RightState.base.Mdown) * Chem_Pot << "\t"
  146. << iKout << "\t"
  147. //<< LeftState.conv << "\t"
  148. << setprecision(3) << LeftState.dev << "\t"
  149. << LeftState.label;
  150. }
  151. else if (whichDSF == 'q') {
  152. DAT_outfile << endl << setprecision(16) << LeftState.E - RightState.E - (LeftState.base.Mdown + nrinfrap - RightState.base.Mdown) * Chem_Pot << "\t"
  153. << iKout << "\t"
  154. << real(ME_CX) << "\t" << imag(ME_CX) - twoPI * int(imag(ME_CX)/twoPI + 1.0e-10) << "\t"
  155. //<< LeftState.conv << "\t"
  156. << setprecision(3) << LeftState.dev << "\t"
  157. << LeftState.label;
  158. }
  159. else {
  160. DAT_outfile << endl << setprecision(16) << LeftState.E - RightState.E - (LeftState.base.Mdown + nrinfrap - RightState.base.Mdown) * Chem_Pot << "\t"
  161. << iKout << "\t"
  162. << ME << "\t"
  163. //<< LeftState.conv << "\t"
  164. << setprecision(3) << LeftState.dev << "\t"
  165. << LeftState.label;
  166. }
  167. } // if iKmin <= iKout <= iKmax
  168. // Calculate and return the data_value:
  169. DP data_value = ME * ME;
  170. //DP data_value = (iKout == 0 ? 1.0 : 2.0) * MEsq;
  171. if (whichDSF == 'Z') // use 1/(1 + omega)
  172. data_value = 1.0/(1.0 + LeftState.E - RightState.E - (LeftState.base.Mdown - RightState.base.Mdown) * Chem_Pot);
  173. else if (whichDSF == 'q')
  174. data_value = exp(2.0 * real(ME_CX));
  175. else if (fixed_iK) // data value is MEsq * omega:
  176. data_value = ME * ME * (LeftState.E - RightState.E - (LeftState.base.Mdown - RightState.base.Mdown) * Chem_Pot);
  177. return(data_value);
  178. }
  179. //DP Compute_Matrix_Element_Contrib (char whichDSF, bool fixed_iK, XXZ_gpd_Bethe_State& LeftState,
  180. //XXZ_gpd_Bethe_State& RightState, DP Chem_Pot, fstream& DAT_outfile)
  181. //DP Compute_Matrix_Element_Contrib (char whichDSF, int iKmin, int iKmax, XXZ_gpd_Bethe_State& LeftState,
  182. // XXZ_gpd_Bethe_State& RightState, DP Chem_Pot, fstream& DAT_outfile)
  183. DP Compute_Matrix_Element_Contrib (char whichDSF, int iKmin, int iKmax, XXZ_gpd_Bethe_State& LeftState,
  184. XXZ_gpd_Bethe_State& RightState, DP Chem_Pot, stringstream& DAT_outfile)
  185. {
  186. // This function prints the matrix element information to the fstream,
  187. // and returns a weighed `data_value' to be multiplied by sumrule_factor,
  188. // to determine if scanning along this thread should be continued.
  189. /*
  190. cout << "\t" << LeftState.label << endl << "\t" << LeftState.Ix2 << endl;
  191. cout << "\t0: ";
  192. for (int i = 0; i < LeftState.base.Nrap[0]; ++i) cout << LeftState.lambda[0][i]*2.0/PI << "\t";
  193. cout << endl;
  194. cout << "\t1: ";
  195. for (int i = 0; i < LeftState.base.Nrap[1]; ++i) cout << LeftState.lambda[1][i]*2.0/PI << "\t";
  196. cout << endl;
  197. */
  198. bool fixed_iK = (iKmin == iKmax);
  199. // If any of the rapidities outside of fundamental interval -pi/2 < lambda <= pi/2, set matrix element to zero.
  200. bool rap_in_fundamental = true;
  201. int sum1 = 0;
  202. for (int j = 0; j < LeftState.chain.Nstrings; ++j) {
  203. //for (int alpha = 0; alpha < LeftState.base.Nrap[j]; ++alpha) {
  204. //if (LeftState.lambda[j][alpha] <= -0.5*PI || LeftState.lambda[j][alpha] > 0.5*PI)
  205. //if (LeftState.lambda[j][alpha] <= -0.5*PI || LeftState.lambda[j][alpha] > 0.5*PI)
  206. //rap_in_fundamental = false;
  207. //}
  208. /*
  209. // TEST 2014 06 26: comment this out, replace by -\pi/2 \leq \lambda \leq \pi/2, see below
  210. if (LeftState.base.Nrap[j] > 0 && LeftState.lambda[j][LeftState.base.Nrap[j] - 1] - LeftState.lambda[j][0] >= PI)
  211. rap_in_fundamental = false;
  212. sum1 = 0;
  213. for (int k = 0; k < LeftState.chain.Nstrings; ++k)
  214. sum1 += LeftState.base.Nrap[k] * (2 * ABACUS::min(LeftState.chain.Str_L[j], LeftState.chain.Str_L[k]) - ((j == k) ? 1 : 0));
  215. // This almost does it: only missing are the states with one on -PI/2 and one on PI/2
  216. if (LeftState.base.Nrap[j] >= 1
  217. && (LeftState.Ix2[j][0] <= -(LeftState.chain.Nsites - sum1)
  218. || (LeftState.Ix2[j][LeftState.base.Nrap[j] - 1] - LeftState.Ix2[j][0])
  219. > 2*(LeftState.chain.Nsites - sum1)))
  220. rap_in_fundamental = false;
  221. */
  222. // attempt 2014 06 26
  223. //for (int alpha = 0; alpha < LeftState.base.Nrap[j]; ++alpha) {
  224. //if (LeftState.lambda[j][alpha] < -0.5*PI || LeftState.lambda[j][alpha] > 0.5*PI)
  225. // rap_in_fundamental = false;
  226. //}
  227. /*
  228. if (LeftState.base.Nrap[j] > 0 &&
  229. ((LeftState.lambda[j][LeftState.base.Nrap[j] - 1] - LeftState.lambda[j][0] >= PI)
  230. || LeftState.lambda[j][0] < -0.5*PI + 1.0e-10
  231. || LeftState.lambda[j][LeftState.base.Nrap[j] - 1] > 0.5*PI
  232. //|| LeftState.lambda[j][0] > 0.5*PI
  233. //((LeftState.lambda[j][LeftState.base.Nrap[j] - 1] - LeftState.lambda[j][0] >= PI - 1.0e-10)
  234. //|| LeftState.lambda[j][0] < -0.5*PI + 1.0e-10
  235. //|| LeftState.lambda[j][LeftState.base.Nrap[j] - 1] > 0.5*PI + 1.0e-10
  236. )) // include safety in limits
  237. rap_in_fundamental = false;
  238. */
  239. /*
  240. if (LeftState.base.Nrap[j] > 0 &&
  241. ((LeftState.lambda[j][LeftState.base.Nrap[j] - 1] - LeftState.lambda[j][0] >= PI)
  242. //|| (LeftState.base.Nrap[j] == 1 && fabs(LeftState.lambda[j][0]) > 0.5*PI)
  243. ))
  244. rap_in_fundamental = false;
  245. */
  246. // Logic: allow rapidities -PI/2 <= lambda <= PI/2 (including boundaries)
  247. if (LeftState.base.Nrap[j] > 0 &&
  248. (LeftState.lambda[j][0] < -PI/2 || LeftState.lambda[j][LeftState.base.Nrap[j] - 1] > PI/2))
  249. rap_in_fundamental = false;
  250. if (RightState.base.Nrap[j] > 0 &&
  251. (RightState.lambda[j][0] < -PI/2 || RightState.lambda[j][RightState.base.Nrap[j] - 1] > PI/2))
  252. rap_in_fundamental = false;
  253. // rapidities should also be ordered as the quantum numbers:
  254. for (int alpha = 1; alpha < LeftState.base.Nrap[j]; ++alpha)
  255. if (LeftState.lambda[j][alpha - 1] >= LeftState.lambda[j][alpha])
  256. rap_in_fundamental = false;
  257. for (int alpha = 1; alpha < RightState.base.Nrap[j]; ++alpha)
  258. if (RightState.lambda[j][alpha - 1] >= RightState.lambda[j][alpha])
  259. rap_in_fundamental = false;
  260. } // for int j
  261. // Identify which matrix element is needed from the number of particles in Left and Right states:
  262. DP ME = 0.0;
  263. //if (!(LeftState.conv && RightState.conv)) ME = 0.0;
  264. if (!(LeftState.conv && RightState.conv && rap_in_fundamental)) ME = 0.0;
  265. else if (whichDSF == 'Z')
  266. ME = LeftState.E - RightState.E;
  267. else if (whichDSF == 'm')
  268. ME = exp(real(ln_Smin_ME (RightState, LeftState)));
  269. else if (whichDSF == 'z') {
  270. if (LeftState.label == RightState.label)
  271. //MEsq = RightState.chain.Nsites * 0.25 * pow((1.0 - 2.0*RightState.base.Mdown/RightState.chain.Nsites), 2.0);
  272. ME = sqrt(RightState.chain.Nsites * 0.25) * (1.0 - 2.0*RightState.base.Mdown/RightState.chain.Nsites);
  273. else ME = exp(real(ln_Sz_ME (RightState, LeftState)));
  274. }
  275. else if (whichDSF == 'p')
  276. ME = exp(real(ln_Smin_ME (LeftState, RightState)));
  277. else ABACUSerror("Wrong whichDSF in Compute_Matrix_Element_Contrib.");
  278. if (is_nan(ME)) ME = 0.0;
  279. //if (LeftState.dev > 1.0e+2 || RightState.dev > 1.0e+2) ME = 0.0; // kill deviated contributions
  280. if (fabs(ME) > 1.0) ME = 0.0;
  281. // Do the momentum business:
  282. int iKout = LeftState.iK - RightState.iK;
  283. while(iKout < 0) iKout += RightState.chain.Nsites;
  284. while(iKout >= RightState.chain.Nsites) iKout -= RightState.chain.Nsites;
  285. DAT_outfile << setprecision(16);
  286. // Print information to fstream:
  287. if (iKout >= iKmin && iKout <= iKmax) {
  288. if (whichDSF == 'Z') {
  289. DAT_outfile << endl << setprecision(16) << LeftState.E - RightState.E - (LeftState.base.Mdown - RightState.base.Mdown) * Chem_Pot << "\t"
  290. << iKout << "\t"
  291. //<< LeftState.conv << "\t"
  292. << setprecision(3) << LeftState.dev << "\t"
  293. << LeftState.label;
  294. }
  295. else {
  296. DAT_outfile << endl << setprecision(16) << LeftState.E - RightState.E - (LeftState.base.Mdown - RightState.base.Mdown) * Chem_Pot << "\t"
  297. << iKout << "\t"
  298. << ME << "\t"
  299. //<< LeftState.conv << "\t"
  300. << setprecision(3) << LeftState.dev << "\t"
  301. << LeftState.label;
  302. /*
  303. cout << setprecision(16) << LeftState.E - RightState.E - (LeftState.base.Mdown - RightState.base.Mdown) * Chem_Pot << "\t" << iKout << "\t" << ME << "\t" << setprecision(3) << LeftState.dev << "\t" << LeftState.label << "\t" << setprecision(16) << LeftState.lambda[0][0]/PI << "\t" << LeftState.Ix2[0][0] << "\t" << LeftState.lambda[0][LeftState.base.Nrap[0] - 1]/PI << "\t" << LeftState.Ix2[0][LeftState.base.Nrap[0] - 1];
  304. if (LeftState.base.Nrap[1] > 0) cout << "\t" << LeftState.lambda[1][0]/PI << "\t" << LeftState.Ix2[1][0];
  305. if (LeftState.lambda[0][0] < -0.5*PI + 1.0e-10 || LeftState.lambda[0][LeftState.base.Nrap[0] - 1] > 0.5*PI - 1.0e-10 || (LeftState.base.Nrap[1] > 0 && (LeftState.lambda[1][0] < -0.5*PI || LeftState.lambda[1][0] > 0.5*PI))) cout << "\t" << "*****";
  306. cout << endl;
  307. */
  308. }
  309. } // if iKmin <= iKout <= iKmax
  310. // Calculate and return the data_value:
  311. DP data_value = ME * ME;
  312. //DP data_value = (iKout == 0 ? 1.0 : 2.0) * MEsq;
  313. if (whichDSF == 'Z') // use 1/(1 + omega)
  314. data_value = 1.0/(1.0 + LeftState.E - RightState.E - (LeftState.base.Mdown - RightState.base.Mdown) * Chem_Pot);
  315. else if (fixed_iK) // data value is MEsq * omega:
  316. data_value = ME * ME * (LeftState.E - RightState.E - (LeftState.base.Mdown - RightState.base.Mdown) * Chem_Pot);
  317. return(data_value);
  318. }
  319. } // namespace ABACUS