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.

ln_Overlap_XXX.cc 8.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258
  1. /**********************************************************
  2. This software is part of J.-S. Caux's ABACUS library.
  3. Copyright (c) J.-S. Caux.
  4. -----------------------------------------------------------
  5. File: ln_Overlap_XXX.cc
  6. Purpose: compute the overlap between an on-shell and an off-shell states
  7. ***********************************************************/
  8. #include "ABACUS.h"
  9. using namespace std;
  10. using namespace ABACUS;
  11. namespace ABACUS {
  12. inline complex<DP> ln_Fn_F (XXX_Bethe_State& B, int k, int beta, int b)
  13. {
  14. complex<DP> ans = 0.0;
  15. for (int j = 0; j < B.chain.Nstrings; ++j) {
  16. for (int alpha = 0; alpha < B.base.Nrap[j]; ++alpha) {
  17. for (int a = 1; a <= B.chain.Str_L[j]; ++a) {
  18. if (!((j == k) && (alpha == beta) && (a == b)))
  19. ans += log(B.lambda[j][alpha] - B.lambda[k][beta]
  20. + 0.5 * II * (B.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b)));
  21. }
  22. }
  23. }
  24. return(ans);
  25. }
  26. inline complex<DP> ln_Fn_G (XXX_Bethe_State& A, XXX_Bethe_State& B, int k, int beta, int b)
  27. {
  28. complex<DP> ans = 0.0;
  29. for (int j = 0; j < A.chain.Nstrings; ++j) {
  30. for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha) {
  31. for (int a = 1; a <= A.chain.Str_L[j]; ++a) {
  32. ans += log(A.lambda[j][alpha] - B.lambda[k][beta]
  33. + 0.5 * II * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b)));
  34. }
  35. }
  36. }
  37. return(ans);
  38. }
  39. inline complex<DP> Fn_K (XXX_Bethe_State& A, int j, int alpha, int a, XXX_Bethe_State& B, int k, int beta, int b)
  40. {
  41. return(1.0/((A.lambda[j][alpha] - B.lambda[k][beta]
  42. + 0.5 * II * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b)))
  43. * (A.lambda[j][alpha] - B.lambda[k][beta]
  44. + 0.5 * II * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b - 1.0)) )));
  45. }
  46. inline complex<DP> Fn_L (XXX_Bethe_State& A, int j, int alpha, int a, XXX_Bethe_State& B, int k, int beta, int b)
  47. {
  48. return ((2.0 * (A.lambda[j][alpha] - B.lambda[k][beta]
  49. + 0.5 * II * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b - 0.5))
  50. ))
  51. * pow(Fn_K (A, j, alpha, a, B, k, beta, b), 2.0));
  52. }
  53. complex<DP> ln_Overlap (XXX_Bethe_State& A, XXX_Bethe_State& B)
  54. {
  55. // This function returns the overlap of states A and B.
  56. // The A and B states can contain strings.
  57. // IMPORTANT ASSUMPTIONS:
  58. // - State B is an eigenstate of the model on which the overlap measure is defined
  59. // Check that A and B are compatible: same Mdown
  60. if (A.base.Mdown != B.base.Mdown) return(complex<DP>(-300.0)); // overlap vanishes
  61. // Some convenient arrays
  62. Lambda re_ln_Fn_F_B_0(B.chain, B.base);
  63. Lambda im_ln_Fn_F_B_0(B.chain, B.base);
  64. Lambda re_ln_Fn_G_0(B.chain, B.base);
  65. Lambda im_ln_Fn_G_0(B.chain, B.base);
  66. Lambda re_ln_Fn_G_2(B.chain, B.base);
  67. Lambda im_ln_Fn_G_2(B.chain, B.base);
  68. //complex<DP> ln_prod1 = 0.0;
  69. //complex<DP> ln_prod2 = 0.0;
  70. complex<DP> ln_prod3 = 0.0;
  71. complex<DP> ln_prod4 = 0.0;
  72. /*
  73. for (int i = 0; i < A.chain.Nstrings; ++i)
  74. for (int alpha = 0; alpha < A.base.Nrap[i]; ++alpha)
  75. for (int a = 1; a <= A.chain.Str_L[i]; ++a)
  76. ln_prod1 += log(norm((A.lambda[i][alpha] + 0.5 * II * (A.chain.Str_L[i] + 1.0 - 2.0 * a - 1.0))));
  77. for (int i = 0; i < B.chain.Nstrings; ++i)
  78. for (int alpha = 0; alpha < B.base.Nrap[i]; ++alpha)
  79. for (int a = 1; a <= B.chain.Str_L[i]; ++a)
  80. if (norm((B.lambda[i][alpha] + 0.5 * II * (B.chain.Str_L[i] + 1.0 - 2.0 * a - 1.0))) > 100.0 * MACHINE_EPS_SQ)
  81. ln_prod2 += log(norm((B.lambda[i][alpha] + 0.5 * II * (B.chain.Str_L[i] + 1.0 - 2.0 * a - 1.0))));
  82. */
  83. // Define the F ones earlier...
  84. for (int j = 0; j < B.chain.Nstrings; ++j) {
  85. for (int alpha = 0; alpha < B.base.Nrap[j]; ++alpha) {
  86. re_ln_Fn_F_B_0[j][alpha] = real(ln_Fn_F(B, j, alpha, 0));
  87. im_ln_Fn_F_B_0[j][alpha] = imag(ln_Fn_F(B, j, alpha, 0));
  88. re_ln_Fn_G_0[j][alpha] = real(ln_Fn_G(A, B, j, alpha, 0));
  89. im_ln_Fn_G_0[j][alpha] = imag(ln_Fn_G(A, B, j, alpha, 0));
  90. re_ln_Fn_G_2[j][alpha] = real(ln_Fn_G(A, B, j, alpha, 2));
  91. im_ln_Fn_G_2[j][alpha] = imag(ln_Fn_G(A, B, j, alpha, 2));
  92. }
  93. }
  94. // Define regularized products in prefactors
  95. for (int j = 0; j < A.chain.Nstrings; ++j)
  96. for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha)
  97. for (int a = 1; a <= A.chain.Str_L[j]; ++a)
  98. ln_prod3 += ln_Fn_F (A, j, alpha, a - 1);
  99. // ln_prod3 -= A.base.Mdown * log(abs(sin(A.chain.zeta)));
  100. for (int k = 0; k < B.chain.Nstrings; ++k)
  101. for (int beta = 0; beta < B.base.Nrap[k]; ++beta)
  102. for (int b = 1; b <= B.chain.Str_L[k]; ++b) {
  103. if (b == 1) ln_prod4 += re_ln_Fn_F_B_0[k][beta];
  104. else if (b > 1) ln_prod4 += ln_Fn_F(B, k, beta, b - 1);
  105. }
  106. // ln_prod4 -= B.base.Mdown * log(abs(sin(B.chain.zeta)));
  107. // Now proceed to build the Hm2P matrix
  108. SQMat_CX Hm2P(0.0, A.base.Mdown);
  109. int index_a = 0;
  110. int index_b = 0;
  111. complex<DP> sum1 = 0.0;
  112. //complex<DP> sum2 = 0.0;
  113. complex<DP> prod_num = 0.0;
  114. complex<DP> Fn_K_0_G_0 = 0.0;
  115. complex<DP> Prod_powerN = 0.0;
  116. complex<DP> Fn_K_1_G_2 = 0.0;
  117. //complex<DP> two_over_A_lambda_sq_plus_1over2sq;
  118. for (int j = 0; j < A.chain.Nstrings; ++j) {
  119. for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha) {
  120. for (int a = 1; a <= A.chain.Str_L[j]; ++a) {
  121. index_b = 0;
  122. //two_over_A_lambda_sq_plus_1over2sq = 2.0/((A.lambda[j][alpha] + 0.5 * II * (A.chain.Str_L[j] + 1.0 - 2.0 * a)) *
  123. // (A.lambda[j][alpha] + 0.5 * II * (A.chain.Str_L[j] + 1.0 - 2.0 * a)) + 0.25);
  124. for (int k = 0; k < B.chain.Nstrings; ++k) {
  125. for (int beta = 0; beta < B.base.Nrap[k]; ++beta) {
  126. for (int b = 1; b <= B.chain.Str_L[k]; ++b) {
  127. if (B.chain.Str_L[k] == 1) {
  128. // use simplified code for one-string here: original form of Hm2P matrix
  129. Fn_K_0_G_0 = Fn_K (A, j, alpha, a, B, k, beta, 0) *
  130. exp(re_ln_Fn_G_0[k][beta] + II * im_ln_Fn_G_0[k][beta] - re_ln_Fn_F_B_0[k][beta]);
  131. Fn_K_1_G_2 = Fn_K (A, j, alpha, a, B, k, beta, 1) *
  132. exp(re_ln_Fn_G_2[k][beta] + II * im_ln_Fn_G_2[k][beta] - re_ln_Fn_F_B_0[k][beta]);
  133. //Prod_powerN = pow((B.lambda[k][beta] + 0.5 * II)/(B.lambda[k][beta] - 0.5 * II), complex<DP> (B.chain.Nsites));
  134. Prod_powerN = pow((B.lambda[k][beta] + 0.5 * II)/(B.lambda[k][beta] - 0.5 * II), complex<DP> (A.chain.Nsites)); // careful !
  135. Hm2P[index_a][index_b] = Fn_K_0_G_0 - Prod_powerN * Fn_K_1_G_2
  136. //- two_over_A_lambda_sq_plus_1over2sq * exp(II*im_ln_Fn_F_B_0[k][beta]);
  137. ;
  138. }
  139. else {
  140. if (b <= B.chain.Str_L[k] - 1) Hm2P[index_a][index_b] = Fn_K(A, j, alpha, a, B, k, beta, b);
  141. else if (b == B.chain.Str_L[k]) {
  142. Vect_CX ln_FunctionF(B.chain.Str_L[k] + 2);
  143. for (int i = 0; i < B.chain.Str_L[k] + 2; ++i) ln_FunctionF[i] = ln_Fn_F (B, k, beta, i);
  144. Vect_CX ln_FunctionG(B.chain.Str_L[k] + 2);
  145. for (int i = 0; i < B.chain.Str_L[k] + 2; ++i) ln_FunctionG[i] = ln_Fn_G (A, B, k, beta, i);
  146. sum1 = 0.0;
  147. sum1 += Fn_K (A, j, alpha, a, B, k, beta, 0) * exp(ln_FunctionG[0] + ln_FunctionG[1] - ln_FunctionF[0] - ln_FunctionF[1]);
  148. sum1 += Fn_K (A, j, alpha, a, B, k, beta, B.chain.Str_L[k])
  149. * exp(ln_FunctionG[B.chain.Str_L[k]] + ln_FunctionG[B.chain.Str_L[k] + 1]
  150. - ln_FunctionF[B.chain.Str_L[k]] - ln_FunctionF[B.chain.Str_L[k] + 1]);
  151. for (int jsum = 1; jsum < B.chain.Str_L[k]; ++jsum)
  152. sum1 -= Fn_L (A, j, alpha, a, B, k, beta, jsum) *
  153. exp(ln_FunctionG[jsum] + ln_FunctionG[jsum + 1] - ln_FunctionF[jsum] - ln_FunctionF[jsum + 1]);
  154. //sum2 = 0.0;
  155. //for (int jsum = 1; jsum <= B.chain.Str_L[k]; ++jsum) sum2 += exp(ln_FunctionG[jsum] - ln_FunctionF[jsum]);
  156. prod_num = exp(II * im_ln_Fn_F_B_0[k][beta] + ln_FunctionF[1] - ln_FunctionG[B.chain.Str_L[k]]);
  157. for (int jsum = 2; jsum <= B.chain.Str_L[k]; ++jsum)
  158. prod_num *= exp(ln_FunctionG[jsum] - real(ln_Fn_F(B, k, beta, jsum - 1))); // include all string contributions F_B_0 in this term
  159. //Hm2P[index_a][index_b] = prod_num * (sum1 - sum2 * two_over_A_lambda_sq_plus_1over2sq);
  160. Hm2P[index_a][index_b] = prod_num * sum1;
  161. } // else if (b == B.chain.Str_L[k])
  162. } // else
  163. index_b++;
  164. }}} // sums over k, beta, b
  165. index_a++;
  166. }}} // sums over j, alpha, a
  167. //cout << "Matrix: " << endl;
  168. //Hm2P.Print();
  169. complex<DP> det = lndet_LU_CX_dstry(Hm2P);
  170. /*
  171. complex<DP> ln_form_factor_sq = log(0.25 * A.chain.Nsites) + real(ln_prod1 - ln_prod2) - real(ln_prod3) + real(ln_prod4)
  172. // + 2.0 * real(lndet_LU_CX_dstry(Hm2P))
  173. + 2.0 * det
  174. - A.lnnorm - B.lnnorm;
  175. //cout << "ln_SZ: " << endl << ln_prod1 << "\t" << -ln_prod2 << "\t" << -ln_prod3 << "\t" << ln_prod4 << "\t" << 2.0 * det
  176. // << "\t" << -A.lnnorm << "\t" << -B.lnnorm << endl;
  177. return(ln_form_factor_sq);
  178. */
  179. complex<DP> ln_overlap = 0.5 * (-ln_prod3 + ln_prod4) + det - 0.5 * (A.lnnorm + B.lnnorm);
  180. cout << "ln_overlap: " << endl << -ln_prod3 << "\t" << ln_prod4 << "\t" << 2.0 * det
  181. << "\t" << -A.lnnorm << "\t" << -B.lnnorm << endl;
  182. return(ln_overlap);
  183. }
  184. } // namespace ABACUS