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.

Offsets.cc 12KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276
  1. /**********************************************************
  2. This software is part of J.-S. Caux's ABACUS library.
  3. Copyright (c) J.-S. Caux.
  4. -----------------------------------------------------------
  5. File: src/BETHE/Offsets.cc
  6. Purpose: defines functions in Offsets class.
  7. IN DEVELOPMENT
  8. ***********************************************************/
  9. #include "ABACUS.h"
  10. using namespace std;
  11. namespace ABACUS {
  12. // Function definitions: class Offsets
  13. Offsets::Offsets () : base(), Tableau(Vect<Young_Tableau>()), type_id(0LL), id(0LL), maxid(0LL) {};
  14. Offsets::Offsets (const Offsets& RefOffset) // copy constructor
  15. : base(RefOffset.base), Tableau(Vect<Young_Tableau> (2 * base.Nrap.size() + 2)), type_id(RefOffset.type_id), id(RefOffset.id), maxid(RefOffset.maxid)
  16. {
  17. for (int i = 0; i < 2 * base.Nrap.size() + 2; ++i) Tableau[i] = RefOffset.Tableau[i];
  18. }
  19. Offsets::Offsets (const Heis_Base& RefBase, long long int req_type_id)
  20. // sets all tableaux to empty ones, with nparticles(req_type_id) at each level
  21. {
  22. // Build nparticles vector from req_type_id
  23. Vect<int> nparticles(0, 2* RefBase.Nrap.size() + 2);
  24. long long int factor = pow_ulli (10LL, nparticles.size() - 1);
  25. long long int id_eff = req_type_id;
  26. for (int i = 0; i < nparticles.size(); ++i) {
  27. nparticles[nparticles.size() - 1 - i] = id_eff/factor;
  28. id_eff -= factor * nparticles[nparticles.size() - 1 - i];
  29. factor /= 10LL;
  30. }
  31. // Check if we've got the right vector...
  32. long long int idcheck = Offsets_type_id (nparticles);
  33. if (idcheck != req_type_id) ABACUSerror("idcheck != req_type_id in Offsets constructor.");
  34. (*this) = Offsets(RefBase, nparticles);
  35. }
  36. Offsets::Offsets (const Heis_Base& RefBase, Vect<int> nparticles) // sets all tableaux to empty ones, with nparticles at each level
  37. : base(RefBase), Tableau(Vect<Young_Tableau> (2 * base.Nrap.size() + 2)), type_id(Offsets_type_id (nparticles)), id(0LL), maxid(0LL)
  38. {
  39. // Checks on nparticles vector:
  40. if (nparticles.size() != 2 * base.Nrap.size() + 2) ABACUSerror("Wrong nparticles.size in Offsets constructor.");
  41. //if (base.Nrap[0] != (nparticles[3] + nparticles[2] + base.Mdown - nparticles[0] - nparticles[1])) ABACUSerror("Wrong Nrap[0] in Offsets constructor.");
  42. if (nparticles[3] + nparticles[2] != nparticles[0] + nparticles[1]) {
  43. cout << nparticles[0] << "\t" << nparticles[1] << "\t" << nparticles[2] << "\t" << nparticles[3] << endl;
  44. ABACUSerror("Wrong Npar[0-3] in Offsets constructor.");
  45. }
  46. for (int base_level = 1; base_level < base.Nrap.size(); ++ base_level)
  47. if (base.Nrap[base_level] != nparticles[2*base_level + 2] + nparticles[2*base_level + 3]) {
  48. cout << base_level << "\t" << base.Nrap[base_level] << "\t" << nparticles[2*base_level + 2] << "\t" << nparticles[2*base_level + 3] << endl;
  49. ABACUSerror("Wrong Nrap[] in Offsets constructor.");
  50. }
  51. // nparticles[0,1]: number of holes on R and L side in GS interval
  52. if (nparticles[0] > (base.Nrap[0] + 1)/2) ABACUSerror("nparticles[0] too large in Offsets constructor.");
  53. if (nparticles[1] > base.Nrap[0]/2) ABACUSerror("nparticles[1] too large in Offsets constructor.");
  54. // nparticles[2,3]: number of particles of type 0 on R and L side out of GS interval
  55. if (nparticles[2] > (base.Ix2_max[0] - base.Nrap[0] + 1)/2) ABACUSerror("nparticles[2] too large in Offsets constructor.");
  56. if (nparticles[3] > (base.Ix2_max[0] - base.Nrap[0] + 1)/2) ABACUSerror("nparticles[3] too large in Offsets constructor.");
  57. for (int base_level = 1; base_level < base.Nrap.size(); ++ base_level)
  58. if ((nparticles[2*base_level + 2] > 0 && nparticles[2*base_level + 2] > (base.Ix2_max[base_level] - ((base.Nrap[base_level] + 1) % 2) + 2)/2)
  59. //|| (nparticles[2*base_level + 3] > 0 && nparticles[2*base_level + 3] > (base.Ix2_max[base_level] - (base.Nrap[base_level] % 2) - 1)/2)) {
  60. || (nparticles[2*base_level + 3] > 0
  61. && nparticles[2*base_level + 3] > base.Ix2_max[base_level] + 1 - (base.Ix2_max[base_level] - ((base.Nrap[base_level] + 1) % 2) + 2)/2)) {
  62. cout << base_level << "\t" << nparticles[2*base_level + 2] << "\t" << (base.Ix2_max[base_level] - ((base.Nrap[base_level] + 1) % 2) + 2)/2
  63. << "\t" << nparticles[2*base_level + 3] << "\t" << (base.Ix2_max[base_level] - (base.Nrap[base_level] % 2) - 1)/2
  64. << "\t" << (nparticles[2*base_level + 2] > 0) << "\t" << (nparticles[2*base_level + 2] > (base.Ix2_max[base_level] - ((base.Nrap[base_level] + 1) % 2) + 2)/2)
  65. //<< "\t" << (nparticles[2*base_level + 3] > 0) << "\t" << (nparticles[2*base_level + 3] > (base.Ix2_max[base_level] - (base.Nrap[base_level] % 2) - 1)/2)
  66. << "\t" << (nparticles[2*base_level + 3] > 0) << "\t"
  67. << (nparticles[2*base_level + 3] > base.Ix2_max[base_level] + 1 - (base.Ix2_max[base_level] - ((base.Nrap[base_level] + 1) % 2) + 2)/2)
  68. << endl;
  69. ABACUSerror("nparticles too large in Offsets constructor.");
  70. }
  71. // Check sum of rapidities
  72. // Holes in GS interval
  73. Tableau[0] = Young_Tableau(nparticles[0], (base.Nrap[0] + 1)/2 - nparticles[0]);
  74. Tableau[1] = Young_Tableau(nparticles[1], base.Nrap[0]/2 - nparticles[1], Tableau[0]);
  75. // Particles of type 0 out of GS interval
  76. Tableau[2] = Young_Tableau(nparticles[2], (base.Ix2_max[0] - base.Nrap[0] + 1)/2 - nparticles[2], Tableau[0]);
  77. Tableau[3] = Young_Tableau(nparticles[3], (base.Ix2_max[0] - base.Nrap[0] + 1)/2 - nparticles[3], Tableau[2]);
  78. // Tableaux of index i = 2,...: data about string type i/2-1.
  79. for (int base_level = 1; base_level < base.Nrap.size(); ++base_level) {
  80. Tableau[2*base_level + 2] = Young_Tableau(nparticles[2*base_level + 2],
  81. //(base.Ix2_max[base_level] - ((base.Nrap[base_level]) % 2) + 2)/2 - nparticles[2*base_level + 2], Tableau[2]);
  82. //(base.Ix2_max[base_level] - base.Nrap[base_level] % 2 + 2)/2 - nparticles[2*base_level + 2], Tableau[2]);
  83. (base.Ix2_max[base_level] - ((base.Nrap[base_level] + 1) % 2))/2 + 1 - nparticles[2*base_level + 2], Tableau[2]);
  84. Tableau[2*base_level + 3] = Young_Tableau(nparticles[2*base_level + 3],
  85. //(base.Ix2_max[base_level] - base.Nrap[base_level] % 2)/2 - nparticles[2*base_level + 3], Tableau[3]);
  86. (base.Ix2_max[base_level] - (base.Nrap[base_level] % 2) - 1)/2 + 1 - nparticles[2*base_level + 3], Tableau[3]);
  87. }
  88. maxid = 1LL;
  89. //id = Tableau[0].id;
  90. for (int i = 0; i < nparticles.size(); ++i) {
  91. maxid *= Tableau[i].maxid + 1LL;
  92. //id += maxid + Tableau[i].id;
  93. }
  94. maxid -= 1LL;
  95. }
  96. Offsets& Offsets::operator= (const Offsets& RefOffset)
  97. {
  98. if (this != &RefOffset) {
  99. base = RefOffset.base;
  100. Tableau = RefOffset.Tableau;
  101. type_id = RefOffset.type_id;
  102. id = RefOffset.id;
  103. maxid = RefOffset.maxid;
  104. }
  105. return(*this);
  106. }
  107. bool Offsets::operator<= (const Offsets& RefOffsets)
  108. {
  109. // Check whether all nonzero tableau row lengths in RefOffsets
  110. // are <= than those in *this
  111. bool answer = true;
  112. for (int level = 0; level < 4; ++level) { // check fundamental level only
  113. //for (int level = 0; level < 2 * base.Nrap.size() + 2; ++level) {
  114. // First check whether all rows which exist in both tableaux satisfy rule:
  115. for (int tableau_level = 0; tableau_level < ABACUS::min(Tableau[level].Nrows, RefOffsets.Tableau[level].Nrows); ++tableau_level)
  116. if (Tableau[level].Row_L[tableau_level] > RefOffsets.Tableau[level].Row_L[tableau_level])
  117. answer = false;
  118. // Now check whether there exist extra rows violating rule:
  119. for (int tableau_level = ABACUS::min(Tableau[level].Nrows, RefOffsets.Tableau[level].Nrows); tableau_level < Tableau[level].Nrows; ++tableau_level)
  120. if (Tableau[level].Row_L[tableau_level] > 0) answer = false;
  121. }
  122. return(answer);
  123. }
  124. bool Offsets::operator>= (const Offsets& RefOffsets)
  125. {
  126. // Check whether all nonzero tableau row lengths in RefOffsets
  127. // are >= than those in *this
  128. bool answer = true;
  129. for (int level = 0; level < 4; ++level) { // check fundamental level only
  130. //for (int level = 0; level < 2 * base.Nrap.size() + 2; ++level) {
  131. // First check whether all rows which exist in both tableaux satisfy rule:
  132. for (int tableau_level = 0; tableau_level < ABACUS::min(Tableau[level].Nrows, RefOffsets.Tableau[level].Nrows); ++tableau_level)
  133. if (Tableau[level].Row_L[tableau_level] < RefOffsets.Tableau[level].Row_L[tableau_level])
  134. answer = false;
  135. // Now check whether there exist extra rows violating rule:
  136. for (int tableau_level = ABACUS::min(Tableau[level].Nrows, RefOffsets.Tableau[level].Nrows); tableau_level < RefOffsets.Tableau[level].Nrows; ++tableau_level)
  137. if (RefOffsets.Tableau[level].Row_L[tableau_level] > 0) answer = false;
  138. }
  139. return(answer);
  140. }
  141. void Offsets::Compute_type_id ()
  142. {
  143. type_id = 0LL;
  144. for (int i = 0; i < 2*base.Nrap.size() + 2; ++i) {
  145. Tableau[i].Compute_id();
  146. type_id += Tableau[i].Nrows * pow_ulli(10LL, i);
  147. }
  148. }
  149. void Offsets::Set_to_id (long long int idnr)
  150. {
  151. // The idnr of the Offset is given by
  152. // sub_id[0] + (total number of tableaux of type 0) * (sub_id[1] + (total number of tableaux of type 1) * (sub_id[2] + ...
  153. // + total number of tableaux of type (2*base.Nrap.size()) * sub_id[2*base.Nrap.size() + 1]
  154. if (idnr > maxid) {
  155. cout << idnr << "\t" << maxid << endl;
  156. ABACUSerror("idnr too large in offsets.Set_to_id.");
  157. }
  158. id = idnr;
  159. Vect<long long int> sub_id(0LL, 2*base.Nrap.size() + 2);
  160. long long int idnr_eff = idnr;
  161. long long int temp_prod = 1LL;
  162. Vect<long long int> result_choose(2*base.Nrap.size() + 2);
  163. for (int i = 0; i <= 2*base.Nrap.size(); ++i) {
  164. //result_choose[i] = choose_lli(Tableau[i].Nrows + Tableau[i].Ncols, Tableau[i].Nrows);
  165. result_choose[i] = Tableau[i].maxid + 1LL;
  166. temp_prod *= result_choose[i];
  167. }
  168. for (int i = 2*base.Nrap.size() + 1; i > 0; --i) {
  169. sub_id[i] = idnr_eff/temp_prod;
  170. idnr_eff -= sub_id[i] * temp_prod;
  171. temp_prod /= result_choose[i-1];
  172. }
  173. sub_id[0] = idnr_eff; // what's left goes to the bottom...
  174. for (int i = 0; i <= 2*base.Nrap.size() + 1; ++i) {
  175. //cout << "level = " << i << " Tableau.id = " << sub_id[i] << endl;
  176. if ((Tableau[i].Nrows * Tableau[i].Ncols == 0) && (sub_id[i] != 0)) ABACUSerror("index too large in offset.Set_to_id.");
  177. if (Tableau[i].id != sub_id[i]) Tableau[i].Set_to_id(sub_id[i]);
  178. }
  179. Compute_type_id ();
  180. return;
  181. }
  182. void Offsets::Compute_id ()
  183. {
  184. long long int prod_maxid = 1LL;
  185. id = 0LL;
  186. for (int i = 0; i < 2*base.Nrap.size() + 2; ++i) {
  187. Tableau[i].Compute_id();
  188. id += Tableau[i].id * prod_maxid;
  189. prod_maxid *= Tableau[i].maxid + 1LL;
  190. }
  191. }
  192. Vect<long long int> Offsets::Descendents (bool fixed_iK)
  193. {
  194. // From a given vector of Young tableaux specifying a particular eigenstate,
  195. // this function provides the full set of descendents (either at the same momentum if
  196. // fixed_iK == true, or not) by returning a vector of all descendent id's (leaving the
  197. // base and type invariant), which can then be used for further calculations.
  198. // This set of descendents is meant to be used when calculating either partition functions
  199. // or zero-temperature correlation functions.
  200. // IMPORTANT ASSUMPTIONS:
  201. // - all even sectors consistently increase/decrease momentum for increasing tableau row length
  202. // - all odd sectors consistently decrease/increase momentum for increasing tableau row length
  203. // FOR FIXED MOMENTUM:
  204. // all tableau levels `above' the lowest occupied one are descended as for fixed_iK == false,
  205. // and the lowest sector's highest tableau level's row length is modified (increased or decreased by one
  206. // unit if possible) such that the iK of Tableau_desc == iK of Tableau_ref.
  207. // The logic behind this is that for a state with nexc excitations, we let run nexc - 1 of the
  208. // excitations, and the lowest one is fixed in place by the momentum constraint, if possible.
  209. Vect<Young_Tableau> Tableau_ref = (*this).Tableau;
  210. Vect<Young_Tableau> Tableau_desc = Tableau_ref;
  211. }
  212. } // namespace ABACUS