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.

LiebLin_Rho_vs_Psidag_Psi.cc 5.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. /**********************************************************
  2. This software is part of J.-S. Caux's ABACUS library.
  3. Copyright (c) J.-S. Caux.
  4. -----------------------------------------------------------
  5. File: ln_Density_ME.cc
  6. Purpose: Computes the density operator \rho(x = 0) matrix element
  7. ***********************************************************/
  8. #include "ABACUS.h"
  9. using namespace std;
  10. using namespace ABACUS;
  11. /**
  12. The matrix elements of \f$\hat{\rho}(x=0)\f$ and \f$\Psi^\dagger (x=0) \Psi(x=0)\f$
  13. are compared between two random bra and ket states. The density matrix element is
  14. directly computed from the determinant representation. The field operator product is
  15. computed by introducing a resolution of the identity. The function outputs the degree
  16. of accuracy achieved.
  17. */
  18. int main()
  19. {
  20. DP c_int = 4.344;
  21. DP L = 8.0;
  22. int N = 8;
  23. DP kBT = 8.0;
  24. int DiKmax = 10*N;
  25. // Use a thermal state to get some nontrivial distribution
  26. //LiebLin_Bethe_State spstate = Canonical_Saddle_Point_State (c_int, L, N, kBT);
  27. LiebLin_Bethe_State spstate (c_int, L, N);
  28. // spstate.Ix2[0] -= 8;
  29. // spstate.Ix2[1] -= 4;
  30. // spstate.Ix2[2] -= 2;
  31. // spstate.Ix2[N-3] += 2;
  32. // spstate.Ix2[N-2] += 4;
  33. // spstate.Ix2[N-1] += 6; // keep asymmetry
  34. spstate.Compute_All(true);
  35. //cout << setprecision(16) << spstate << endl;
  36. // Now define the anchor for scanning
  37. LiebLin_Bethe_State SeedScanState = Remove_Particle_at_Center (spstate);
  38. SeedScanState.Compute_All(true);
  39. //cout << setprecision(16) << SeedScanState << endl;
  40. // Map out the available unoccupied quantum nrs
  41. // We scan from Ix2min - DiKmax to Ix2max + DiKmax, and there are N-1 occupied, so there are
  42. int nr_par_positions = DiKmax + (SeedScanState.Ix2[N-2] - SeedScanState.Ix2[0])/2 + 1 - N + 1;
  43. Vect<int> Ix2_available (nr_par_positions);
  44. int nfound = 0;
  45. for (int i = SeedScanState.Ix2[0] - DiKmax; i <= SeedScanState.Ix2[N-2] + DiKmax; i += 2) {
  46. bool available = true;
  47. for (int j = 0; j < N-1; ++j)
  48. if (i == SeedScanState.Ix2[j]) {
  49. available = false;
  50. break;
  51. }
  52. if (available)
  53. Ix2_available[nfound++] = i;
  54. }
  55. if (nfound != nr_par_positions) {
  56. cout << "nround = " << nfound << "\tnr_par_positions = " << nr_par_positions << endl;
  57. ABACUSerror("Wrong number of particle positions found.");
  58. }
  59. // Define bra and ket states
  60. LiebLin_Bethe_State lstate = spstate;
  61. lstate.Ix2[0] -= 4;
  62. lstate.Ix2[1] -= 2;
  63. lstate.Compute_All(false);
  64. cout << setprecision(16) << lstate << endl;
  65. LiebLin_Bethe_State rstate = spstate;
  66. rstate.Ix2[N-1] += 8;
  67. rstate.Ix2[N-2] += 2;
  68. rstate.Compute_All(false);
  69. cout << setprecision(16) << rstate << endl;
  70. //lstate = rstate;
  71. // Matrix element to reproduce
  72. complex<DP> ln_rho_ME = ln_Density_ME(lstate, rstate);
  73. cout << "ln_Density_ME = " << ln_rho_ME << endl;
  74. // We now do hard-coded scanning of up to fixed nr of particle-hole pairs
  75. complex<DP> Psidag_Psi = 0.0;
  76. LiebLin_Bethe_State scanstate = SeedScanState;
  77. // Zero particle-hole:
  78. scanstate = SeedScanState;
  79. Psidag_Psi += exp(conj(ln_Psi_ME(scanstate, lstate)) + ln_Psi_ME(scanstate, rstate));
  80. cout << "Ratio Rho/PsidagPsi After scanning 0 p-h: "
  81. << setprecision(16) << real(Psidag_Psi/exp(ln_rho_ME))
  82. << "\t" << imag(Psidag_Psi/exp(ln_rho_ME)) << endl;
  83. // One particle-hole:
  84. char a;
  85. for (int ih1 = 0; ih1 < N-1; ++ih1)
  86. for (int ipar1 = 0; ipar1 < nr_par_positions - 1; ++ipar1) {
  87. scanstate = SeedScanState;
  88. scanstate.Ix2[ih1] = Ix2_available[ipar1];
  89. scanstate.Ix2.QuickSort();
  90. scanstate.Compute_All(true);
  91. Psidag_Psi += exp(conj(ln_Psi_ME(scanstate, lstate)) + ln_Psi_ME(scanstate, rstate));
  92. // cout << "ih1 = " << ih1 << "\tipar1 = " << ipar1
  93. // << "\tPsidag_Psi = " << setprecision(16) << Psidag_Psi << endl;
  94. //cout << scanstate << endl;
  95. //cin >> a;
  96. }
  97. cout << "Ratio Rho/PsidagPsi After scanning 1 p-h: "
  98. << setprecision(16) << real(Psidag_Psi/exp(ln_rho_ME))
  99. << "\t" << imag(Psidag_Psi/exp(ln_rho_ME)) << endl;
  100. // Two particle-hole:
  101. for (int ih1 = 0; ih1 < N-2; ++ih1)
  102. for (int ih2 = ih1+1; ih2 < N-1; ++ih2)
  103. for (int ipar1 = 0; ipar1 < nr_par_positions - 2; ++ipar1) {
  104. for (int ipar2 = ipar1+1; ipar2 < nr_par_positions - 1; ++ipar2) {
  105. scanstate = SeedScanState;
  106. scanstate.Ix2[ih1] = Ix2_available[ipar1];
  107. scanstate.Ix2[ih2] = Ix2_available[ipar2];
  108. scanstate.Ix2.QuickSort();
  109. scanstate.Compute_All(true);
  110. Psidag_Psi += exp(conj(ln_Psi_ME(scanstate, lstate)) + ln_Psi_ME(scanstate, rstate));
  111. }
  112. }
  113. cout << "Ratio Rho/PsidagPsi After scanning 2 p-h: "
  114. << setprecision(16) << real(Psidag_Psi/exp(ln_rho_ME))
  115. << "\t" << imag(Psidag_Psi/exp(ln_rho_ME)) << endl;
  116. // Three particle-hole:
  117. for (int ih1 = 0; ih1 < N-3; ++ih1)
  118. for (int ih2 = ih1+1; ih2 < N-2; ++ih2)
  119. for (int ih3 = ih2+1; ih3 < N-1; ++ih3)
  120. for (int ipar1 = 0; ipar1 < nr_par_positions - 3; ++ipar1) {
  121. for (int ipar2 = ipar1+1; ipar2 < nr_par_positions - 2; ++ipar2) {
  122. for (int ipar3 = ipar2+1; ipar3 < nr_par_positions - 1; ++ipar3) {
  123. scanstate = SeedScanState;
  124. scanstate.Ix2[ih1] = Ix2_available[ipar1];
  125. scanstate.Ix2[ih2] = Ix2_available[ipar2];
  126. scanstate.Ix2[ih3] = Ix2_available[ipar3];
  127. scanstate.Ix2.QuickSort();
  128. scanstate.Compute_All(true);
  129. Psidag_Psi += exp(conj(ln_Psi_ME(scanstate, lstate)) + ln_Psi_ME(scanstate, rstate));
  130. }
  131. }
  132. // cout << "Ratio Rho/PsidagPsi while scanning 3 p-h: "
  133. // << setprecision(16) << real(Psidag_Psi/exp(ln_rho_ME))
  134. // << "\t" << imag(Psidag_Psi/exp(ln_rho_ME)) << endl;
  135. }
  136. cout << "Ratio Rho/PsidagPsi After scanning 3 p-h: "
  137. << setprecision(16) << real(Psidag_Psi/exp(ln_rho_ME))
  138. << "\t" << imag(Psidag_Psi/exp(ln_rho_ME)) << endl;
  139. return(0);
  140. }