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.

ODSLF.cc 47KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428
  1. /**********************************************************
  2. This software is part of J.-S. Caux's ABACUS library.
  3. Copyright (c) J.-S. Caux.
  4. -----------------------------------------------------------
  5. File: src/1DSLF/1DSLF.cc
  6. Purpose: defines functions for 1d spinless fermion classes.
  7. ***********************************************************/
  8. #include "ABACUS.h"
  9. using namespace std;
  10. namespace ABACUS {
  11. //***************************************************************************************************
  12. // Function definitions: class ODSLF_Base
  13. ODSLF_Base::ODSLF_Base () : Mdown(0), Nrap(Vect<int>()), Nraptot(0), Ix2_infty(Vect<DP>()), Ix2_max(Vect<int>()) {}
  14. ODSLF_Base::ODSLF_Base (const ODSLF_Base& RefBase) // copy constructor
  15. : Mdown(RefBase.Mdown), Nrap(Vect<int>(RefBase.Nrap.size())), Nraptot(RefBase.Nraptot),
  16. Ix2_infty(Vect<DP>(RefBase.Nrap.size())), Ix2_max(Vect<int>(RefBase.Nrap.size())),
  17. id(RefBase.id)
  18. {
  19. for (int i = 0; i < Nrap.size(); ++i) {
  20. Nrap[i] = RefBase.Nrap[i];
  21. Ix2_infty[i] = RefBase.Ix2_infty[i];
  22. Ix2_max[i] = RefBase.Ix2_max[i];
  23. }
  24. }
  25. ODSLF_Base::ODSLF_Base (const Heis_Chain& RefChain, int M)
  26. : Mdown(M), Nrap(Vect<int>(RefChain.Nstrings)), Nraptot(0), Ix2_infty(Vect<DP>(RefChain.Nstrings)),
  27. Ix2_max(Vect<int>(RefChain.Nstrings))
  28. {
  29. for (int i = 0; i < RefChain.Nstrings; ++i) Nrap[i] = 0;
  30. Nrap[0] = M;
  31. Nraptot = 0;
  32. for (int i = 0; i < RefChain.Nstrings; ++i) Nraptot += Nrap[i];
  33. // The id of this is zero by definition
  34. id = 0LL;
  35. // Now compute the Ix2_infty numbers
  36. (*this).Compute_Ix2_limits(RefChain);
  37. }
  38. ODSLF_Base::ODSLF_Base (const Heis_Chain& RefChain, const Vect<int>& Nrapidities)
  39. : Mdown(0), Nrap(Nrapidities), Nraptot(0), Ix2_infty(Vect<DP>(RefChain.Nstrings)),
  40. Ix2_max(Vect<int>(RefChain.Nstrings)), id (0LL)
  41. {
  42. // Check consistency of Nrapidities vector with RefChain
  43. if (RefChain.Nstrings != Nrapidities.size())
  44. ABACUSerror("Incompatible Nrapidities vector used in ODSLF_Base constructor.");
  45. int Mcheck = 0;
  46. for (int i = 0; i < RefChain.Nstrings; ++i) Mcheck += RefChain.Str_L[i] * Nrap[i];
  47. Mdown = Mcheck;
  48. Nraptot = 0;
  49. for (int i = 0; i < RefChain.Nstrings; ++i) Nraptot += Nrap[i];
  50. // Compute id
  51. id += Nrapidities[0];
  52. long long int factor = 100000LL;
  53. for (int i = 1; i < RefChain.Nstrings; ++i) {
  54. id += factor * Nrapidities[i];
  55. factor *= 100LL;
  56. }
  57. // Now compute the Ix2_infty numbers
  58. (*this).Compute_Ix2_limits(RefChain);
  59. }
  60. ODSLF_Base::ODSLF_Base (const Heis_Chain& RefChain, long long int id_ref)
  61. : Mdown(0), Nrap(Vect<int>(RefChain.Nstrings)), Nraptot(0), Ix2_infty(Vect<DP>(RefChain.Nstrings)),
  62. Ix2_max(Vect<int>(RefChain.Nstrings)), id (id_ref)
  63. {
  64. // Build Nrapidities vector from id_ref
  65. long long int factor = pow_ulli (10LL, 2* RefChain.Nstrings + 1);
  66. long long int id_eff = id_ref;
  67. for (int i = 0; i < RefChain.Nstrings - 1; ++i) {
  68. Nrap[RefChain.Nstrings - 1 - i] = id_eff/factor;
  69. id_eff -= factor * Nrap[RefChain.Nstrings - 1 - i];
  70. factor /= 100LL;
  71. }
  72. Nrap[0] = id_eff;
  73. int Mcheck = 0;
  74. for (int i = 0; i < RefChain.Nstrings; ++i) Mcheck += RefChain.Str_L[i] * Nrap[i];
  75. Mdown = Mcheck;
  76. Nraptot = 0;
  77. for (int i = 0; i < RefChain.Nstrings; ++i) Nraptot += Nrap[i];
  78. // Now compute the Ix2_infty numbers
  79. (*this).Compute_Ix2_limits(RefChain);
  80. }
  81. ODSLF_Base& ODSLF_Base::operator= (const ODSLF_Base& RefBase)
  82. {
  83. if (this != & RefBase) {
  84. Mdown = RefBase.Mdown;
  85. Nrap = RefBase.Nrap;
  86. Nraptot = RefBase.Nraptot;
  87. Ix2_infty = RefBase.Ix2_infty;
  88. Ix2_max = RefBase.Ix2_max;
  89. id = RefBase.id;
  90. }
  91. return(*this);
  92. }
  93. bool ODSLF_Base::operator== (const ODSLF_Base& RefBase)
  94. {
  95. bool answer = (Nrap == RefBase.Nrap);
  96. return (answer);
  97. }
  98. bool ODSLF_Base::operator!= (const ODSLF_Base& RefBase)
  99. {
  100. bool answer = (Nrap != RefBase.Nrap);
  101. return (answer);
  102. }
  103. void ODSLF_Base::Compute_Ix2_limits (const Heis_Chain& RefChain)
  104. {
  105. if ((RefChain.Delta > 0.0) && (RefChain.Delta < 1.0)) {
  106. // Compute the Ix2_infty numbers
  107. DP sum1 = 0.0;
  108. DP sum2 = 0.0;
  109. for (int j = 0; j < RefChain.Nstrings; ++j) {
  110. sum1 = 0.0;
  111. for (int k = 0; k < RefChain.Nstrings; ++k) {
  112. sum2 = 0.0;
  113. sum2 += (RefChain.Str_L[j] == RefChain.Str_L[k]) ? 0.0 :
  114. 2.0 * atan(tan(0.25 * PI * (1.0 + RefChain.par[j] * RefChain.par[k])
  115. - 0.5 * fabs(RefChain.Str_L[j] - RefChain.Str_L[k]) * RefChain.anis));
  116. sum2 += 2.0 * atan(tan(0.25 * PI * (1.0 + RefChain.par[j] * RefChain.par[k])
  117. - 0.5 * (RefChain.Str_L[j] + RefChain.Str_L[k]) * RefChain.anis));
  118. for (int a = 1; a < ABACUS::min(RefChain.Str_L[j], RefChain.Str_L[k]); ++a)
  119. sum2 += 2.0 * 2.0 * atan(tan(0.25 * PI * (1.0 + RefChain.par[j] * RefChain.par[k])
  120. - 0.5 * (fabs(RefChain.Str_L[j] - RefChain.Str_L[k]) + 2.0*a) * RefChain.anis));
  121. sum1 += (Nrap[k] - ((j == k) ? 1 : 0)) * sum2;
  122. }
  123. Ix2_infty[j] = (1.0/PI) * fabs(RefChain.Nsites * 2.0
  124. * atan(tan(0.25 * PI * (1.0 + RefChain.par[j])
  125. - 0.5 * RefChain.Str_L[j] * RefChain.anis)) - sum1);
  126. } // The Ix2_infty are now set.
  127. // Now compute the Ix2_max limits
  128. for (int j = 0; j < RefChain.Nstrings; ++j) {
  129. Ix2_max[j] = int(floor(Ix2_infty[j])); // sets basic integer
  130. // Reject formally infinite rapidities (i.e. if Delta is root of unity)
  131. // For ODSLF: parity of quantum numbers is complicated:
  132. // if (N-1 + M_j + (M + 1) n_j + (1 - nu_j) N/2) is even, q# are integers,
  133. // so Ix2_max must be even (conversely, if odd, then odd).
  134. if ((Ix2_max[j] + RefChain.Nsites - 1 + Nrap[j] + (Nraptot + 1) * RefChain.Str_L[j]
  135. + (RefChain.par[j] == 1 ? 0 : RefChain.Nsites)) % 2) Ix2_max[j] -= 1;
  136. while (Ix2_max[j] > RefChain.Nsites) {
  137. Ix2_max[j] -= 2;
  138. }
  139. }
  140. } // if XXZ gapless
  141. else if (RefChain.Delta == 1.0) {
  142. // Compute the Ix2_infty numbers
  143. int sum1 = 0;
  144. for (int j = 0; j < RefChain.Nstrings; ++j) {
  145. sum1 = 0;
  146. for (int k = 0; k < RefChain.Nstrings; ++k) {
  147. sum1 += Nrap[k] * (2 * ABACUS::min(RefChain.Str_L[j], RefChain.Str_L[k]) - ((j == k) ? 1 : 0));
  148. }
  149. Ix2_infty[j] = (RefChain.Nsites + 1.0 - sum1); // to get counting right...
  150. } // The Ix2_infty are now set.
  151. // Now compute the Ix2_max limits
  152. for (int j = 0; j < RefChain.Nstrings; ++j) {
  153. Ix2_max[j] = int(floor(Ix2_infty[j])); // sets basic integer
  154. // Give the correct parity to Ix2_max
  155. // If Nrap is even, Ix2_max must be odd. If odd, then even.
  156. //if (!((Nrap[j] + Ix2_max[j]) % 2)) Ix2_max[j] -= 1; DEACTIVATED FOR ODSLF !
  157. // If Ix2_max equals Ix2_infty, we reduce it by 2:
  158. if (Ix2_max[j] == int(Ix2_infty[j])) Ix2_max[j] -= 2;
  159. while (Ix2_max[j] > RefChain.Nsites) {
  160. Ix2_max[j] -= 2;
  161. }
  162. }
  163. } // if XXX AFM
  164. else if (RefChain.Delta > 1.0) {
  165. // Compute the Ix2_infty numbers
  166. int sum1 = 0;
  167. for (int j = 0; j < RefChain.Nstrings; ++j) {
  168. sum1 = 0;
  169. for (int k = 0; k < RefChain.Nstrings; ++k) {
  170. sum1 += Nrap[k] * (2 * ABACUS::min(RefChain.Str_L[j], RefChain.Str_L[k]) - ((j == k) ? 1 : 0));
  171. }
  172. Ix2_infty[j] = (RefChain.Nsites - 1 + 2 * RefChain.Str_L[j] - sum1);
  173. } // The Ix2_infty are now set.
  174. // Now compute the Ix2_max limits
  175. for (int j = 0; j < RefChain.Nstrings; ++j) {
  176. Ix2_max[j] = int(floor(Ix2_infty[j])); // sets basic integer
  177. // Give the correct parity to Ix2_max
  178. // If Nrap is even, Ix2_max must be odd. If odd, then even.
  179. //if (!((Nrap[j] + Ix2_max[j]) % 2)) Ix2_max[j] -= 1; DEACTIVATED FOR ODSLF !
  180. // If Ix2_max equals Ix2_infty, we reduce it by 2:
  181. //if (Ix2_max[j] == Ix2_infty[j]) Ix2_max[j] -= 2;
  182. while (Ix2_max[j] > RefChain.Nsites) {
  183. Ix2_max[j] -= 2;
  184. }
  185. }
  186. } // if XXZ_gpd
  187. }
  188. void ODSLF_Base::Scan_for_Possible_Types (Vect<long long int>& possible_type_id, int& nfound,
  189. int base_level, Vect<int>& Nexcitations)
  190. {
  191. if (base_level == 0) {
  192. // We set all sectors 0, 1, 2, 3
  193. int Nexc_max_0 = (Nrap[0] + 1)/2; // holes on R
  194. int Nexc_max_1 = Nrap[0]/2;
  195. int Nexc_max_2 = (Ix2_max[0] - Nrap[0] + 1)/2;
  196. int Nexc_max_3 = Nexc_max_2;
  197. // Count the number of excitations in higher levels:
  198. int Nexc_above = 0;
  199. for (int i = 4; i < Nexcitations.size(); ++i) Nexc_above += Nexcitations[i];
  200. for (int nphpairs = 0; nphpairs <= NEXC_MAX_HEIS/2 - Nexc_above; ++nphpairs)
  201. for (int nexc0 = 0; nexc0 <= ABACUS::min(Nexc_max_0, nphpairs); ++nexc0) {
  202. int nexc1 = nphpairs - nexc0;
  203. for (int nexc2 = 0; nexc2 <= ABACUS::min(Nexc_max_2, nphpairs); ++nexc2) {
  204. int nexc3 = nphpairs - nexc2;
  205. if (nexc1 >= 0 && nexc1 <= Nexc_max_1 && nexc3 >= 0 && nexc3 <= Nexc_max_3) {
  206. // acceptable type found
  207. Nexcitations[0] = nexc0; Nexcitations[1] = nexc1; Nexcitations[2] = nexc2; Nexcitations[3] = nexc3;
  208. possible_type_id[nfound] = Ix2_Offsets_type_id (Nexcitations);
  209. nfound++;
  210. }
  211. }
  212. }
  213. }
  214. else { // base_level > 0
  215. // We scan over the possible distributions of the excitations on the L and R sides:
  216. // Count the number of slots available on R:
  217. int Nexc_R_max = (Ix2_max[base_level] + 2)/2;
  218. int Nexc_L_max = (Ix2_max[base_level] + 1)/2;
  219. for (int Nexcleft = 0; Nexcleft <= Nrap[base_level]; ++Nexcleft)
  220. if (Nexcleft <= Nexc_L_max && Nrap[base_level] - Nexcleft <= Nexc_R_max) {
  221. Nexcitations[2*base_level + 2] = Nrap[base_level] - Nexcleft;
  222. Nexcitations[2*base_level + 3] = Nexcleft;
  223. Scan_for_Possible_Types (possible_type_id, nfound, base_level - 1, Nexcitations);
  224. }
  225. }
  226. }
  227. Vect<long long int> ODSLF_Base::Possible_Types ()
  228. {
  229. // Given a base, this returns a vector of possible types
  230. Vect<long long int> possible_type_id (0LL, 1000);
  231. int nfound = 0;
  232. Vect<int> Nexcitations (0, 2*Nrap.size() + 2);
  233. Scan_for_Possible_Types (possible_type_id, nfound, Nrap.size() - 1, Nexcitations);
  234. // Copy results into new vector:
  235. Vect<long long int> possible_type_id_found (nfound);
  236. for (int i = 0; i < nfound; ++i)
  237. possible_type_id_found[i] = possible_type_id[i];
  238. return(possible_type_id_found);
  239. }
  240. //***************************************************************************************************
  241. // Function definitions: class Ix2_Config
  242. ODSLF_Ix2_Config::ODSLF_Ix2_Config () {}
  243. ODSLF_Ix2_Config::ODSLF_Ix2_Config (const Heis_Chain& RefChain, int M)
  244. : Nstrings(1), Nrap(Vect<int>(M,1)), Nraptot(M), Ix2(new int*[1]) // single type of string here
  245. {
  246. Ix2[0] = new int[M];
  247. for (int j = 0; j < M; ++j) {
  248. Ix2[0][j] = -(M - 1) + 2*j;
  249. // Use simplification: Nrap[0] = M = Nraptot, Str_L[0] = 1, par = 1, so
  250. if ((Ix2[0][j] + RefChain.Nsites) % 2) Ix2[0][j] -= 1;
  251. }
  252. }
  253. ODSLF_Ix2_Config::ODSLF_Ix2_Config (const Heis_Chain& RefChain, const ODSLF_Base& base)
  254. : Nstrings(RefChain.Nstrings), Nrap(base.Nrap), Nraptot(base.Nraptot), Ix2(new int*[RefChain.Nstrings])
  255. {
  256. Ix2[0] = new int[base.Nraptot];
  257. for (int i = 1; i < RefChain.Nstrings; ++i) Ix2[i] = Ix2[i-1] + base[i-1];
  258. // And now for the other string types...
  259. for (int i = 0; i < RefChain.Nstrings; ++i) {
  260. for (int j = 0; j < base[i]; ++j) Ix2[i][j] = -(base[i] - 1) + 2*j + 1 - (base[i] % 2);
  261. }
  262. // ODSLF: put back correct parity of quantum nr:
  263. for (int i = 0; i < RefChain.Nstrings; ++i)
  264. for (int j = 0; j < base[i]; ++j)
  265. if ((Ix2[i][j] + RefChain.Nsites - 1 + base.Nrap[i] + (base.Nraptot + 1) * RefChain.Str_L[i] + (RefChain.par[i] == 1 ? 0 : RefChain.Nsites)) % 2)
  266. Ix2[i][j] -= 1;
  267. }
  268. ODSLF_Ix2_Config& ODSLF_Ix2_Config::operator= (const ODSLF_Ix2_Config& RefConfig)
  269. {
  270. if (this != &RefConfig) {
  271. Nstrings = RefConfig.Nstrings;
  272. Nrap = RefConfig.Nrap;
  273. Nraptot = RefConfig.Nraptot;
  274. if (Ix2 != 0) {
  275. delete[] (Ix2[0]);
  276. delete[] (Ix2);
  277. }
  278. Ix2 = new int*[Nstrings];
  279. Ix2[0] = new int[Nraptot];
  280. for (int i = 1; i < Nstrings; ++i) Ix2[i] = Ix2[i-1] + Nrap[i-1];
  281. for (int i = 0; i < Nstrings; ++i)
  282. for (int j = 0; j < Nrap[i]; ++j) Ix2[i][j] = RefConfig.Ix2[i][j];
  283. }
  284. return(*this);
  285. }
  286. ODSLF_Ix2_Config::~ODSLF_Ix2_Config()
  287. {
  288. if (Ix2 != 0) {
  289. delete[] (Ix2[0]);
  290. delete[] Ix2;
  291. }
  292. }
  293. std::ostream& operator<< (std::ostream& s, const ODSLF_Ix2_Config& RefConfig)
  294. {
  295. s << &RefConfig << "\t" << RefConfig.Nstrings << "\t" << RefConfig.Nraptot << endl;
  296. for (int i = 0; i < RefConfig.Nstrings; ++i) s << RefConfig.Nrap[i] << "\t";
  297. s << endl;
  298. for (int i = 0; i < RefConfig.Nstrings; ++i) {
  299. s << "i " << i << "\t";
  300. for (int j = 0; j < RefConfig.Nrap[i]; ++j) s << RefConfig.Ix2[i][j] << "\t";
  301. s << endl;
  302. }
  303. return(s);
  304. }
  305. //***************************************************************************************************
  306. // Function definitions: class Lambda
  307. ODSLF_Lambda::ODSLF_Lambda () {}
  308. ODSLF_Lambda::ODSLF_Lambda (const Heis_Chain& RefChain, int M)
  309. : Nstrings(1), Nrap(Vect<int>(M,1)), Nraptot(M), lambda(new DP*[1]) // single type of string here
  310. {
  311. lambda[0] = new DP[M];
  312. for (int j = 0; j < M; ++j) lambda[0][j] = 0.0;
  313. }
  314. ODSLF_Lambda::ODSLF_Lambda (const Heis_Chain& RefChain, const ODSLF_Base& base)
  315. : Nstrings(RefChain.Nstrings), Nrap(base.Nrap), Nraptot(base.Nraptot), lambda(new DP*[RefChain.Nstrings])
  316. {
  317. lambda[0] = new DP[base.Nraptot];
  318. for (int i = 1; i < RefChain.Nstrings; ++i) lambda[i] = lambda[i-1] + base[i-1];
  319. for (int i = 0; i < RefChain.Nstrings; ++i) {
  320. for (int j = 0; j < base[i]; ++j) lambda[i][j] = 0.0;
  321. }
  322. }
  323. ODSLF_Lambda& ODSLF_Lambda::operator= (const ODSLF_Lambda& RefLambda)
  324. {
  325. if (this != &RefLambda) {
  326. Nstrings = RefLambda.Nstrings;
  327. Nrap = RefLambda.Nrap;
  328. Nraptot = RefLambda.Nraptot;
  329. if (lambda != 0) {
  330. delete[] (lambda[0]);
  331. delete[] (lambda);
  332. }
  333. lambda = new DP*[Nstrings];
  334. lambda[0] = new DP[Nraptot];
  335. for (int i = 1; i < Nstrings; ++i) lambda[i] = lambda[i-1] + Nrap[i-1];
  336. for (int i = 0; i < Nstrings; ++i)
  337. for (int j = 0; j < Nrap[i]; ++j) lambda[i][j] = RefLambda.lambda[i][j];
  338. }
  339. return(*this);
  340. }
  341. ODSLF_Lambda::~ODSLF_Lambda()
  342. {
  343. if (lambda != 0) {
  344. delete[] (lambda[0]);
  345. delete[] lambda;
  346. }
  347. }
  348. //***************************************************************************************************
  349. // Function definitions: class ODSLF_Ix2_Offsets
  350. ODSLF_Ix2_Offsets::ODSLF_Ix2_Offsets () : base(), Tableau(Vect<Young_Tableau>()), type_id(0LL), id(0LL), maxid(0LL) {};
  351. ODSLF_Ix2_Offsets::ODSLF_Ix2_Offsets (const ODSLF_Ix2_Offsets& RefOffset) // copy constructor
  352. : base(RefOffset.base), Tableau(Vect<Young_Tableau> (2 * base.Nrap.size() + 2)), type_id(RefOffset.type_id), id(RefOffset.id), maxid(RefOffset.maxid)
  353. {
  354. for (int i = 0; i < 2 * base.Nrap.size() + 2; ++i) Tableau[i] = RefOffset.Tableau[i];
  355. }
  356. ODSLF_Ix2_Offsets::ODSLF_Ix2_Offsets (const ODSLF_Base& RefBase, long long int req_type_id)
  357. // sets all tableaux to empty ones, with nparticles(req_type_id) at each level
  358. {
  359. // Build nparticles vector from req_type_id
  360. Vect<int> nparticles(0, 2* RefBase.Nrap.size() + 2);
  361. long long int factor = pow_ulli (10LL, nparticles.size() - 1);
  362. long long int id_eff = req_type_id;
  363. for (int i = 0; i < nparticles.size(); ++i) {
  364. nparticles[nparticles.size() - 1 - i] = id_eff/factor;
  365. id_eff -= factor * nparticles[nparticles.size() - 1 - i];
  366. factor /= 10LL;
  367. }
  368. // Check if we've got the right vector...
  369. long long int idcheck = Ix2_Offsets_type_id (nparticles);
  370. if (idcheck != req_type_id) ABACUSerror("idcheck != req_type_id in Ix2_Offsets constructor.");
  371. (*this) = ODSLF_Ix2_Offsets(RefBase, nparticles);
  372. }
  373. ODSLF_Ix2_Offsets::ODSLF_Ix2_Offsets (const ODSLF_Base& RefBase, Vect<int> nparticles)
  374. // sets all tableaux to empty ones, with nparticles at each level
  375. : base(RefBase), Tableau(Vect<Young_Tableau> (2 * base.Nrap.size() + 2)),
  376. type_id(Ix2_Offsets_type_id (nparticles)), id(0LL), maxid(0LL)
  377. {
  378. // Checks on nparticles vector:
  379. if (nparticles.size() != 2 * base.Nrap.size() + 2)
  380. ABACUSerror("Wrong nparticles.size in Ix2_Offsets constructor.");
  381. if (nparticles[3] + nparticles[2] != nparticles[0] + nparticles[1]) {
  382. cout << nparticles[0] << "\t" << nparticles[1] << "\t" << nparticles[2] << "\t" << nparticles[3] << endl;
  383. ABACUSerror("Wrong Npar[0-3] in Ix2_Offsets constructor.");
  384. }
  385. for (int base_level = 1; base_level < base.Nrap.size(); ++ base_level)
  386. if (base.Nrap[base_level] != nparticles[2*base_level + 2] + nparticles[2*base_level + 3]) {
  387. cout << base_level << "\t" << base.Nrap[base_level] << "\t" << nparticles[2*base_level + 2]
  388. << "\t" << nparticles[2*base_level + 3] << endl;
  389. ABACUSerror("Wrong Nrap[] in Ix2_Offsets constructor.");
  390. }
  391. // nparticles[0,1]: number of holes on R and L side in GS interval
  392. if (nparticles[0] > (base.Nrap[0] + 1)/2)
  393. ABACUSerror("nparticles[0] too large in Ix2_Offsets constructor.");
  394. if (nparticles[1] > base.Nrap[0]/2)
  395. ABACUSerror("nparticles[1] too large in Ix2_Offsets constructor.");
  396. // nparticles[2,3]: number of particles of type 0 on R and L side out of GS interval
  397. if (nparticles[2] > (base.Ix2_max[0] - base.Nrap[0] + 1)/2)
  398. ABACUSerror("nparticles[2] too large in Ix2_Offsets constructor.");
  399. if (nparticles[3] > (base.Ix2_max[0] - base.Nrap[0] + 1)/2)
  400. ABACUSerror("nparticles[3] too large in Ix2_Offsets constructor.");
  401. for (int base_level = 1; base_level < base.Nrap.size(); ++ base_level)
  402. if ((nparticles[2*base_level + 2] > 0 && nparticles[2*base_level + 2]
  403. > (base.Ix2_max[base_level] + 2)/2) // ODSLF modif
  404. || (nparticles[2*base_level + 3] > 0
  405. && nparticles[2*base_level + 3] > (base.Ix2_max[base_level] + 1)/2)) // ODSLF modif
  406. {
  407. cout << base_level << "\t" << base.Ix2_max[base_level] << "\t" << base.Ix2_infty[base_level]
  408. << "\t" << nparticles[2*base_level + 2] << "\t"
  409. << (base.Ix2_max[base_level] - ((base.Nrap[base_level] + 1) % 2) + 2)/2
  410. << "\t" << nparticles[2*base_level + 3] << "\t"
  411. << (base.Ix2_max[base_level] - (base.Nrap[base_level] % 2) - 1)/2
  412. << "\t" << (nparticles[2*base_level + 2] > 0) << "\t"
  413. << (nparticles[2*base_level + 2] > (base.Ix2_max[base_level] - ((base.Nrap[base_level] + 1) % 2) + 2)/2)
  414. << "\t" << (nparticles[2*base_level + 3] > 0) << "\t"
  415. << (nparticles[2*base_level + 3] > base.Ix2_max[base_level] + 1
  416. - (base.Ix2_max[base_level] - ((base.Nrap[base_level] + 1) % 2) + 2)/2)
  417. << endl;
  418. ABACUSerror("nparticles too large in Ix2_Offsets constructor.");
  419. }
  420. // Check sum of rapidities
  421. // Holes in GS interval
  422. Tableau[0] = Young_Tableau(nparticles[0], (base.Nrap[0] + 1)/2 - nparticles[0]);
  423. Tableau[1] = Young_Tableau(nparticles[1], base.Nrap[0]/2 - nparticles[1], Tableau[0]);
  424. // Particles of type 0 out of GS interval
  425. Tableau[2] = Young_Tableau(nparticles[2], (base.Ix2_max[0] - base.Nrap[0] + 1)/2 - nparticles[2], Tableau[0]);
  426. Tableau[3] = Young_Tableau(nparticles[3], (base.Ix2_max[0] - base.Nrap[0] + 1)/2 - nparticles[3], Tableau[2]);
  427. // Tableaux of index i = 2,...: data about string type i/2-1.
  428. for (int base_level = 1; base_level < base.Nrap.size(); ++base_level) {
  429. Tableau[2*base_level + 2] =
  430. Young_Tableau(nparticles[2*base_level + 2],
  431. (base.Ix2_max[base_level] - ((base.Nrap[base_level] + 1) % 2))/2 + 1
  432. - nparticles[2*base_level + 2], Tableau[2]);
  433. Tableau[2*base_level + 3] =
  434. Young_Tableau(nparticles[2*base_level + 3],
  435. (base.Ix2_max[base_level] - (base.Nrap[base_level] % 2) - 1)/2 + 1
  436. - nparticles[2*base_level + 3], Tableau[3]);
  437. }
  438. maxid = 1LL;
  439. for (int i = 0; i < nparticles.size(); ++i) {
  440. maxid *= Tableau[i].maxid + 1LL;
  441. }
  442. maxid -= 1LL;
  443. }
  444. ODSLF_Ix2_Offsets& ODSLF_Ix2_Offsets::operator= (const ODSLF_Ix2_Offsets& RefOffset)
  445. {
  446. if (this != &RefOffset) {
  447. base = RefOffset.base;
  448. Tableau = RefOffset.Tableau;
  449. type_id = RefOffset.type_id;
  450. id = RefOffset.id;
  451. maxid = RefOffset.maxid;
  452. }
  453. return(*this);
  454. }
  455. bool ODSLF_Ix2_Offsets::operator<= (const ODSLF_Ix2_Offsets& RefOffsets)
  456. {
  457. // Check whether all nonzero tableau row lengths in RefOffsets
  458. // are <= than those in *this
  459. bool answer = true;
  460. for (int level = 0; level < 4; ++level) { // check fundamental level only
  461. // First check whether all rows which exist in both tableaux satisfy rule:
  462. for (int tableau_level = 0; tableau_level
  463. < ABACUS::min(Tableau[level].Nrows, RefOffsets.Tableau[level].Nrows); ++tableau_level)
  464. if (Tableau[level].Row_L[tableau_level] > RefOffsets.Tableau[level].Row_L[tableau_level])
  465. answer = false;
  466. // Now check whether there exist extra rows violating rule:
  467. for (int tableau_level = ABACUS::min(Tableau[level].Nrows, RefOffsets.Tableau[level].Nrows);
  468. tableau_level < Tableau[level].Nrows; ++tableau_level)
  469. if (Tableau[level].Row_L[tableau_level] > 0) answer = false;
  470. }
  471. return(answer);
  472. }
  473. bool ODSLF_Ix2_Offsets::operator>= (const ODSLF_Ix2_Offsets& RefOffsets)
  474. {
  475. // Check whether all nonzero tableau row lengths in RefOffsets
  476. // are >= than those in *this
  477. bool answer = true;
  478. for (int level = 0; level < 4; ++level) { // check fundamental level only
  479. // First check whether all rows which exist in both tableaux satisfy rule:
  480. for (int tableau_level = 0; tableau_level
  481. < ABACUS::min(Tableau[level].Nrows, RefOffsets.Tableau[level].Nrows); ++tableau_level)
  482. if (Tableau[level].Row_L[tableau_level] < RefOffsets.Tableau[level].Row_L[tableau_level])
  483. answer = false;
  484. // Now check whether there exist extra rows violating rule:
  485. for (int tableau_level = ABACUS::min(Tableau[level].Nrows, RefOffsets.Tableau[level].Nrows);
  486. tableau_level < RefOffsets.Tableau[level].Nrows; ++tableau_level)
  487. if (RefOffsets.Tableau[level].Row_L[tableau_level] > 0) answer = false;
  488. }
  489. return(answer);
  490. }
  491. void ODSLF_Ix2_Offsets::Set_to_id (long long int idnr)
  492. {
  493. // The idnr of the Offset is given by
  494. // sub_id[0] + (total number of tableaux of type 0) * (sub_id[1] + (total number of tableaux of type 1) * (sub_id[2] + ...
  495. // + total number of tableaux of type (2*base.Nrap.size()) * sub_id[2*base.Nrap.size() + 1]
  496. if (idnr > maxid) {
  497. cout << idnr << "\t" << maxid << endl;
  498. ABACUSerror("idnr too large in offsets.Set_to_id.");
  499. }
  500. id = idnr;
  501. Vect<long long int> sub_id(0LL, 2*base.Nrap.size() + 2);
  502. long long int idnr_eff = idnr;
  503. long long int temp_prod = 1LL;
  504. Vect<long long int> result_choose(2*base.Nrap.size() + 2);
  505. for (int i = 0; i <= 2*base.Nrap.size(); ++i) {
  506. result_choose[i] = Tableau[i].maxid + 1LL;
  507. temp_prod *= result_choose[i];
  508. }
  509. for (int i = 2*base.Nrap.size() + 1; i > 0; --i) {
  510. sub_id[i] = idnr_eff/temp_prod;
  511. idnr_eff -= sub_id[i] * temp_prod;
  512. temp_prod /= result_choose[i-1];
  513. }
  514. sub_id[0] = idnr_eff; // what's left goes to the bottom...
  515. for (int i = 0; i <= 2*base.Nrap.size() + 1; ++i) {
  516. if ((Tableau[i].Nrows * Tableau[i].Ncols == 0) && (sub_id[i] != 0))
  517. ABACUSerror("index too large in offset.Set_to_id.");
  518. if (Tableau[i].id != sub_id[i]) Tableau[i].Set_to_id(sub_id[i]);
  519. }
  520. Compute_type_id ();
  521. return;
  522. }
  523. void ODSLF_Ix2_Offsets::Compute_type_id ()
  524. {
  525. type_id = 0LL;
  526. for (int i = 0; i < 2*base.Nrap.size() + 2; ++i) {
  527. Tableau[i].Compute_id();
  528. type_id += Tableau[i].Nrows * pow_ulli(10LL, i);
  529. }
  530. }
  531. void ODSLF_Ix2_Offsets::Compute_id ()
  532. {
  533. long long int prod_maxid = 1LL;
  534. id = 0LL;
  535. for (int i = 0; i < 2*base.Nrap.size() + 2; ++i) {
  536. Tableau[i].Compute_id();
  537. id += Tableau[i].id * prod_maxid;
  538. prod_maxid *= Tableau[i].maxid + 1LL;
  539. }
  540. }
  541. bool ODSLF_Ix2_Offsets::Add_Boxes_From_Lowest (int Nboxes, bool odd_sectors)
  542. {
  543. // Tries to add Nboxes to Young tableau in given sector parity.
  544. // If Nboxes is too large to be accommodated, `false' is returned.
  545. ODSLF_Ix2_Offsets offsets_init(*this); // keep a copy in case it fails
  546. if (Nboxes < 0) ABACUSerror("Can't use Nboxes < 0 in Add_Boxes_From_Lowest");
  547. else if (Nboxes == 0) return(true); // nothing to do
  548. int Nboxes_put = 0;
  549. int working_sector = odd_sectors;
  550. // We start from the bottom up.
  551. while (Nboxes_put < Nboxes && working_sector < 2*base.Nrap.size() + 2) {
  552. Nboxes_put += Tableau[working_sector].Add_Boxes_From_Lowest(Nboxes - Nboxes_put);
  553. working_sector += 2;
  554. }
  555. Compute_id();
  556. if (Nboxes_put < Nboxes) (*this) = offsets_init; // reset !
  557. else if (Nboxes_put > Nboxes) {
  558. cout << Nboxes_put << "\t" << Nboxes << endl;
  559. ABACUSerror("Putting too many boxes in Ix2_Offsets::Add_Boxes_From_Lowest.");
  560. }
  561. return(Nboxes_put == Nboxes);
  562. }
  563. //***************************************************************************************************
  564. // Function definitions: class ODSLF_Ix2_Offsets_List
  565. ODSLF_Ix2_Offsets_List::ODSLF_Ix2_Offsets_List() : ndef(0), Offsets(Vect<ODSLF_Ix2_Offsets>(NBASESMAX)) {};
  566. ODSLF_Ix2_Offsets& ODSLF_Ix2_Offsets_List::Return_Offsets (ODSLF_Base& RefBase, Vect<int> nparticles)
  567. {
  568. long long int Ix2_Offsets_type_id_ref = Ix2_Offsets_type_id (nparticles);
  569. int n = 0;
  570. while (n < ndef && !(Ix2_Offsets_type_id_ref == Offsets[n].type_id && RefBase == Offsets[n].base)) n++;
  571. if (n == ndef) {
  572. Offsets[n] = ODSLF_Ix2_Offsets (RefBase, nparticles);
  573. ndef++;
  574. }
  575. if (ndef >= NBASESMAX) ABACUSerror("Ix2_Offsets_List: need bigger Offsets vector.");
  576. return(Offsets[n]);
  577. }
  578. ODSLF_Ix2_Offsets& ODSLF_Ix2_Offsets_List::Return_Offsets (ODSLF_Base& RefBase, long long int req_type_id)
  579. {
  580. int n = 0;
  581. while (n < ndef && !(req_type_id == Offsets[n].type_id && RefBase == Offsets[n].base)) n++;
  582. if (n == ndef) {
  583. Offsets[n] = ODSLF_Ix2_Offsets (RefBase, req_type_id);
  584. ndef++;
  585. }
  586. if (ndef >= NBASESMAX) ABACUSerror("Ix2_Offsets_List: need bigger Offsets vector.");
  587. return(Offsets[n]);
  588. }
  589. //***************************************************************************************************
  590. // Function definitions: class ODSLF_Bethe_State
  591. ODSLF_Bethe_State::ODSLF_Bethe_State ()
  592. : chain(Heis_Chain()), base(ODSLF_Base()), offsets(ODSLF_Ix2_Offsets()), Ix2(ODSLF_Ix2_Config(chain, 1)),
  593. lambda(ODSLF_Lambda(chain, 1)), BE(ODSLF_Lambda(chain, 1)), diffsq(0.0), conv(0), iter(0), iter_Newton(0),
  594. E(0.0), iK(0), K(0.0), lnnorm(-100.0), base_id(0LL), type_id(0LL), id(0LL), maxid(0LL), nparticles(0)
  595. {
  596. };
  597. ODSLF_Bethe_State::ODSLF_Bethe_State (const ODSLF_Bethe_State& RefState) // copy constructor
  598. : chain(RefState.chain), base(RefState.base), offsets(RefState.offsets),
  599. Ix2(ODSLF_Ix2_Config(RefState.chain, RefState.base)),
  600. lambda(ODSLF_Lambda(RefState.chain, RefState.base)), BE(ODSLF_Lambda(RefState.chain, RefState.base)),
  601. diffsq(RefState.diffsq), conv(RefState.conv), iter(RefState.iter), iter_Newton(RefState.iter_Newton),
  602. E(RefState.E), iK(RefState.iK), K(RefState.K), lnnorm(RefState.lnnorm),
  603. base_id(RefState.base_id), type_id(RefState.type_id), id(RefState.id), maxid(RefState.maxid),
  604. nparticles(RefState.nparticles)
  605. {
  606. // copy arrays into new ones
  607. for (int j = 0; j < RefState.chain.Nstrings; ++j) {
  608. for (int alpha = 0; alpha < RefState.base[j]; ++j) {
  609. Ix2[j][alpha] = RefState.Ix2[j][alpha];
  610. lambda[j][alpha] = RefState.lambda[j][alpha];
  611. }
  612. }
  613. }
  614. ODSLF_Bethe_State::ODSLF_Bethe_State (const ODSLF_Bethe_State& RefState, long long int type_id_ref)
  615. : chain(RefState.chain), base(RefState.base), offsets(ODSLF_Ix2_Offsets(RefState.base, type_id_ref)),
  616. Ix2(ODSLF_Ix2_Config(RefState.chain, RefState.base)), lambda(ODSLF_Lambda(RefState.chain, RefState.base)),
  617. BE(ODSLF_Lambda(RefState.chain, RefState.base)), diffsq(1.0), conv(0), iter(0), iter_Newton(0),
  618. E(0.0), iK(0), K(0.0), lnnorm(-100.0),
  619. base_id(RefState.base_id), type_id(0LL), id(0LL), maxid(offsets.maxid), nparticles(0)
  620. {
  621. (*this).Set_Ix2_Offsets (offsets);
  622. }
  623. ODSLF_Bethe_State::ODSLF_Bethe_State (const Heis_Chain& RefChain, int M)
  624. : chain(RefChain), base(RefChain, M), offsets(base, 0LL), Ix2(ODSLF_Ix2_Config(RefChain, M)),
  625. lambda(ODSLF_Lambda(RefChain, M)),
  626. BE(ODSLF_Lambda(RefChain, M)), diffsq(1.0), conv(0), iter(0), iter_Newton(0),
  627. E(0.0), iK(0), K(0.0), lnnorm(-100.0),
  628. base_id(0LL), type_id(0LL), id(0LL), maxid(offsets.maxid), nparticles(0)
  629. {
  630. }
  631. ODSLF_Bethe_State::ODSLF_Bethe_State (const Heis_Chain& RefChain, const ODSLF_Base& RefBase)
  632. : chain(RefChain), base(RefBase), offsets(RefBase, 0LL),
  633. Ix2(ODSLF_Ix2_Config(RefChain, RefBase)), lambda(ODSLF_Lambda(RefChain, RefBase)),
  634. BE(ODSLF_Lambda(RefChain, RefBase)), diffsq(1.0), conv(0), iter(0), iter_Newton(0),
  635. E(0.0), iK(0), K(0.0), lnnorm(-100.0),
  636. base_id(RefBase.id), type_id(0LL), id(0LL), maxid(offsets.maxid), nparticles(0)
  637. {
  638. // Check that the number of rapidities is consistent with Mdown
  639. int Mcheck = 0;
  640. for (int i = 0; i < RefChain.Nstrings; ++i) Mcheck += base[i] * RefChain.Str_L[i];
  641. if (RefBase.Mdown != Mcheck)
  642. ABACUSerror("Wrong M from Nrapidities input vector, in ODSLF_Bethe_State constructor.");
  643. }
  644. ODSLF_Bethe_State::ODSLF_Bethe_State (const Heis_Chain& RefChain,
  645. long long int base_id_ref, long long int type_id_ref)
  646. : chain(RefChain), base(ODSLF_Base(RefChain, base_id_ref)), offsets(base, type_id_ref),
  647. Ix2(ODSLF_Ix2_Config(RefChain, base)), lambda(ODSLF_Lambda(RefChain, base)),
  648. BE(ODSLF_Lambda(RefChain, base)), diffsq(1.0), conv(0), iter(0), iter_Newton(0),
  649. E(0.0), iK(0), K(0.0), lnnorm(-100.0),
  650. base_id(base_id_ref), type_id(type_id_ref), id(0LL), maxid(offsets.maxid), nparticles(0)
  651. {
  652. }
  653. void ODSLF_Bethe_State::Set_Ix2_Offsets (const ODSLF_Ix2_Offsets& RefOffset) // sets the Ix2 to given offsets
  654. {
  655. if (base != RefOffset.base)
  656. ABACUSerror("Offset with incompatible base used in ODSLF_Bethe_State::Set_Ix2_Offsets.");
  657. // For each base_level, we make sure that the Ix2 are ordered: Ix2[0][j] < Ix2[0][k] if j < k.
  658. // Level 2: particles in R part outside GS interval
  659. for (int j = 0; j < RefOffset.Tableau[2].Nrows; ++j) {
  660. Ix2[0][base.Nrap[0] - 1 - j]
  661. = base.Nrap[0] - 1 + 2* RefOffset.Tableau[2].Nrows - 2*j + 2*RefOffset.Tableau[2].Row_L[j];
  662. }
  663. nparticles = RefOffset.Tableau[2].Nrows;
  664. // Level 0: holes in R part of GS interval
  665. for (int j = 0; j < RefOffset.Tableau[0].Ncols; ++j) {
  666. Ix2[0][base.Nrap[0] - 1 - RefOffset.Tableau[2].Nrows - j] = (base.Nrap[0] + 1) % 2
  667. + 2*RefOffset.Tableau[0].Ncols - 2 - 2*j + 2*RefOffset.Tableau[0].Col_L[j];
  668. }
  669. nparticles += RefOffset.Tableau[0].Ncols;
  670. // Level 1: holes in L part of GS interval
  671. for (int j = 0; j < RefOffset.Tableau[1].Ncols; ++j) {
  672. Ix2[0][base.Nrap[0] - 1 - RefOffset.Tableau[0].Ncols - RefOffset.Tableau[2].Nrows - j]
  673. = -1 - (base.Nrap[0] % 2) - 2* j - 2*RefOffset.Tableau[1].Col_L[RefOffset.Tableau[1].Ncols - 1 - j];
  674. }
  675. nparticles += RefOffset.Tableau[1].Ncols;
  676. // Level 3: particles in L part outside GS interval
  677. for (int j = 0; j < RefOffset.Tableau[3].Nrows; ++j) {
  678. Ix2[0][base.Nrap[0] - 1 - RefOffset.Tableau[0].Ncols - RefOffset.Tableau[1].Ncols - RefOffset.Tableau[2].Nrows - j]
  679. = -(base.Nrap[0] + 1 + 2*j + 2*RefOffset.Tableau[3].Row_L[RefOffset.Tableau[3].Nrows - 1 - j]);
  680. }
  681. nparticles += RefOffset.Tableau[3].Nrows;
  682. // Subsequent levels: particles on R and L
  683. for (int base_level = 1; base_level < base.Nrap.size(); ++base_level) {
  684. for (int j = 0; j < RefOffset.Tableau[2*base_level + 2].Nrows; ++j)
  685. Ix2[base_level][base.Nrap[base_level] - 1 - j]
  686. = ((base.Nrap[base_level] + 1) % 2) + 2*(RefOffset.Tableau[2*base_level + 2].Nrows - 1) -2*j
  687. + 2*RefOffset.Tableau[2*base_level + 2].Row_L[j];
  688. nparticles += RefOffset.Tableau[2*base_level + 2].Nrows;
  689. for (int j = 0; j < RefOffset.Tableau[2*base_level + 3].Nrows; ++j)
  690. Ix2[base_level][base.Nrap[base_level] - 1 - RefOffset.Tableau[2*base_level + 2].Nrows - j]
  691. = -1 - ((base.Nrap[base_level]) % 2) -2*j
  692. - 2*RefOffset.Tableau[2*base_level + 3].Row_L[RefOffset.Tableau[2*base_level + 3].Nrows - 1 - j];
  693. nparticles += RefOffset.Tableau[2*base_level + 3].Nrows;
  694. }
  695. // ODSLF: put back correct parity of quantum nr:
  696. for (int j = 0; j < base.Nrap.size(); ++j)
  697. for (int alpha = 0; alpha < base[j]; ++alpha)
  698. if ((Ix2[j][alpha] + chain.Nsites - 1 + base.Nrap[j] + (base.Nraptot + 1) * chain.Str_L[j]
  699. + (chain.par[j] == 1 ? 0 : chain.Nsites)) % 2)
  700. Ix2[j][alpha] -= 1;
  701. type_id = RefOffset.type_id;
  702. id = RefOffset.id;
  703. maxid = RefOffset.maxid;
  704. return;
  705. }
  706. void ODSLF_Bethe_State::Set_to_id (long long int id_ref)
  707. {
  708. offsets.Set_to_id (id_ref);
  709. (*this).Set_Ix2_Offsets (offsets);
  710. }
  711. void ODSLF_Bethe_State::Set_to_id (long long int id_ref, ODSLF_Bethe_State& RefState)
  712. {
  713. offsets.Set_to_id (id_ref);
  714. (*this).Set_Ix2_Offsets (offsets);
  715. }
  716. bool ODSLF_Bethe_State::Check_Symmetry ()
  717. {
  718. // Checks whether the I's are symmetrically distributed.
  719. bool symmetric_state = true;
  720. int arg, test1, test3;
  721. for (int j = 0; j < chain.Nstrings; ++j) {
  722. test1 = 0;
  723. test3 = 0;
  724. for (int alpha = 0; alpha < base[j]; ++alpha) {
  725. // since Ix2 = N is same as Ix2 = -N by periodicity, this is symmetric.
  726. arg = (Ix2[j][alpha] != chain.Nsites) ? Ix2[j][alpha] : 0;
  727. test1 += arg;
  728. test3 += arg * arg * arg; // to make sure that all I's are symmetrical...
  729. }
  730. if (!(symmetric_state && (test1 == 0) && (test3 == 0))) symmetric_state = false;
  731. }
  732. return symmetric_state;
  733. }
  734. void ODSLF_Bethe_State::Compute_diffsq ()
  735. {
  736. DP maxterm = 0.0;
  737. int jmax, alphamax;
  738. diffsq = 0.0;
  739. for (int j = 0; j < chain.Nstrings; ++j)
  740. for (int alpha = 0; alpha < base[j]; ++alpha) {
  741. diffsq += pow(BE[j][alpha], 2.0);
  742. if (pow(BE[j][alpha], 2.0)/chain.Nsites > maxterm) {
  743. jmax = j;
  744. alphamax = alpha;
  745. maxterm = pow(BE[j][alpha], 2.0)/chain.Nsites;
  746. }
  747. }
  748. diffsq /= DP(chain.Nsites);
  749. }
  750. void ODSLF_Bethe_State::Iterate_BAE ()
  751. {
  752. for (int j = 0; j < chain.Nstrings; ++j) {
  753. for (int alpha = 0; alpha < base[j]; ++alpha)
  754. {
  755. lambda[j][alpha] = Iterate_BAE (j, alpha);
  756. }
  757. }
  758. iter++;
  759. (*this).Compute_BE();
  760. (*this).Compute_diffsq();
  761. }
  762. void ODSLF_Bethe_State::BAE_smackdown (DP max_allowed)
  763. {
  764. // Re-solves for all rapidities lambda[j][alpha] such that BE[j][alpha]^2/N > max_allowed.
  765. // Assumes that BE[][] is up-to-date.
  766. for (int j = 0; j < chain.Nstrings; ++j)
  767. for (int alpha = 0; alpha < base[j]; ++alpha)
  768. if (pow(BE[j][alpha], 2.0)/chain.Nsites > max_allowed) (*this).Solve_BAE (j, alpha, max_allowed, 100);
  769. }
  770. void ODSLF_Bethe_State::Solve_BAE_smackdown (DP max_allowed, int maxruns)
  771. {
  772. int runs_done = 0;
  773. (*this).Compute_BE();
  774. (*this).Compute_diffsq();
  775. while (diffsq > chain.prec && diffsq > max_allowed && runs_done < maxruns) {
  776. (*this).BAE_smackdown (max_allowed);
  777. (*this).Compute_BE();
  778. (*this).Compute_diffsq();
  779. runs_done++;
  780. }
  781. }
  782. void ODSLF_Bethe_State::Iterate_BAE_Newton ()
  783. {
  784. // does one step of a Newton method on the rapidities...
  785. // Assumes that BE[j][alpha] have been computed
  786. Vect_CX dlambda (0.0, base.Nraptot); // contains delta lambda computed from Newton's method
  787. SQMat_CX Gaudin (0.0, base.Nraptot);
  788. Vect_INT indx (base.Nraptot);
  789. ODSLF_Lambda lambda_ref(chain, base);
  790. for (int j = 0; j < chain.Nstrings; ++j)
  791. for (int alpha = 0; alpha < base[j]; ++alpha) lambda_ref[j][alpha] = lambda[j][alpha];
  792. (*this).Build_Reduced_Gaudin_Matrix (Gaudin);
  793. int index = 0;
  794. for (int j = 0; j < chain.Nstrings; ++j)
  795. for (int alpha = 0; alpha < base[j]; ++alpha) {
  796. dlambda[index] = - BE[j][alpha] * chain.Nsites;
  797. index++;
  798. }
  799. DP d;
  800. try {
  801. ludcmp_CX (Gaudin, indx, d);
  802. lubksb_CX (Gaudin, indx, dlambda);
  803. }
  804. catch (Divide_by_zero) {
  805. diffsq = log(-1.0); // reset to nan to stop Newton method
  806. return;
  807. }
  808. // Regularize dlambda: max step is +-1.0 to prevent rapidity flying off into outer space.
  809. for (int i = 0; i < base.Nraptot; ++i) if (fabs(real(dlambda[i])) > 1.0) dlambda[i] = 0.0;
  810. index = 0;
  811. for (int j = 0; j < chain.Nstrings; ++j)
  812. for (int alpha = 0; alpha < base[j]; ++alpha) {
  813. lambda[j][alpha] = lambda_ref[j][alpha] + real(dlambda[index]);
  814. index++;
  815. }
  816. (*this).Compute_BE();
  817. (*this).Iterate_BAE();
  818. (*this).Compute_diffsq();
  819. // if we've converged, calculate the norm here, since the work has been done...
  820. if (diffsq < chain.prec) {
  821. lnnorm = 0.0;
  822. for (int j = 0; j < base.Nraptot; j++) lnnorm += log(abs(Gaudin[j][j]));
  823. }
  824. iter_Newton++;
  825. return;
  826. }
  827. void ODSLF_Bethe_State::Solve_BAE (int j, int alpha, DP req_prec, int itermax)
  828. {
  829. // Finds the root lambda[j][alpha] to precision req_prec
  830. DP prec_obtained = 1.0;
  831. int niter_here = 0;
  832. while (prec_obtained > req_prec && niter_here < itermax) {
  833. lambda[j][alpha] = (*this).Iterate_BAE (j, alpha);
  834. (*this).Compute_BE (j, alpha);
  835. prec_obtained = pow(BE[j][alpha], 2.0)/chain.Nsites;
  836. niter_here++;
  837. }
  838. }
  839. void ODSLF_Bethe_State::Find_Rapidities (bool reset_rapidities)
  840. {
  841. // This function finds the rapidities of the eigenstate
  842. lnnorm = -100.0; // sentinel value, recalculated if Newton method used in the last step of iteration.
  843. ODSLF_Lambda lambda_ref(chain, base);
  844. diffsq = 1.0;
  845. if (reset_rapidities)
  846. (*this).Set_Free_lambdas();
  847. (*this).Compute_BE();
  848. iter = 0;
  849. iter_Newton = 0;
  850. // Start with conventional iterations
  851. DP iter_prec = 1.0e-2/DP(chain.Nsites);
  852. clock_t interp_start;
  853. clock_t interp_stop;
  854. clock_t Newton_start;
  855. clock_t Newton_stop;
  856. int iter_interp_start, iter_interp_stop, iter_Newton_start, iter_Newton_stop;
  857. DP diffsq_interp_start, diffsq_interp_stop, diffsq_Newton_start, diffsq_Newton_stop;
  858. while (diffsq > chain.prec && iter < 300 && iter_Newton < 20) {
  859. do {
  860. interp_start = clock();
  861. iter_interp_start = iter;
  862. diffsq_interp_start = diffsq;
  863. if (diffsq > iter_prec) (*this).Solve_BAE_interp (iter_prec, 10);
  864. interp_stop = clock();
  865. iter_interp_stop = iter;
  866. diffsq_interp_stop = diffsq;
  867. iter_prec = diffsq * 0.001;
  868. } while (diffsq > chain.prec && !is_nan(diffsq) && diffsq_interp_stop/diffsq_interp_start < 0.001);
  869. // If we haven't even reached iter_prec, try normal iterations without extrapolations
  870. if (diffsq > iter_prec) {
  871. (*this).Solve_BAE_smackdown (0.1 * diffsq, 1);
  872. }
  873. // Now try Newton
  874. Newton_start = clock();
  875. iter_Newton_start = iter_Newton;
  876. diffsq_Newton_start = diffsq;
  877. if (diffsq > iter_prec) (*this).Solve_BAE_Newton (chain.prec, 5);
  878. Newton_stop = clock();
  879. iter_Newton_stop = iter_Newton;
  880. diffsq_Newton_stop = diffsq;
  881. if (diffsq > iter_prec) (*this).Solve_BAE_smackdown (0.1 * diffsq, 1);
  882. if (diffsq > iter_prec) (*this).Solve_BAE_straight_iter (0.1 * diffsq, 50);
  883. // If we haven't converged here, retry with more precision in interp method...
  884. if (is_nan(diffsq)) {
  885. (*this).Set_Free_lambdas(); // good start if we've messed up with Newton
  886. diffsq = 1.0;
  887. }
  888. iter_prec *= 1.0e-4;
  889. iter_prec = ABACUS::max(iter_prec, chain.prec);
  890. }
  891. // Check convergence:
  892. conv = (diffsq < chain.prec && (*this).Check_Rapidities()) ? 1 : 0;
  893. return;
  894. }
  895. void ODSLF_Bethe_State::Solve_BAE_Newton (DP Newton_prec, int max_iter_Newton)
  896. {
  897. // This function attempts to get convergence diffsq <= Newton_prec in at most max_iter_Newton steps.
  898. // The results are accepted if diffsq has decreased, otherwise the lambda's are reset to original values, defined as...
  899. ODSLF_Lambda lambda_ref(chain, base);
  900. DP diffsq_ref = 1.0;
  901. for (int j = 0; j < chain.Nstrings; ++j)
  902. for (int alpha = 0; alpha < base[j]; ++alpha) lambda_ref[j][alpha] = lambda[j][alpha];
  903. diffsq_ref = diffsq;
  904. // Now begin solving...
  905. int iter_done_here = 0;
  906. while ((diffsq > Newton_prec) && (diffsq < 10.0) && (!is_nan(diffsq)) && (iter_done_here < max_iter_Newton)) {
  907. (*this).Iterate_BAE_Newton();
  908. iter_done_here++;
  909. (*this).Iterate_BAE();
  910. }
  911. if ((diffsq > diffsq_ref) || (is_nan(diffsq))) {
  912. // This procedure has failed. We reset everything to begin values.
  913. for (int j = 0; j < chain.Nstrings; ++j)
  914. for (int alpha = 0; alpha < base[j]; ++alpha) lambda[j][alpha] = lambda_ref[j][alpha];
  915. diffsq = diffsq_ref;
  916. }
  917. return;
  918. }
  919. void ODSLF_Bethe_State::Solve_BAE_straight_iter (DP interp_prec, int max_iter_interp)
  920. {
  921. // This function attempts to get convergence diffsq <= interp_prec in at most max_iter_interp steps.
  922. // If this fails, the lambda's are reset to original values, defined as...
  923. ODSLF_Lambda lambda_ref(chain, base);
  924. DP diffsq_ref = 1.0;
  925. for (int j = 0; j < chain.Nstrings; ++j)
  926. for (int alpha = 0; alpha < base[j]; ++alpha) lambda_ref[j][alpha] = lambda[j][alpha];
  927. diffsq_ref = diffsq;
  928. // Now begin solving...
  929. diffsq = 1.0;
  930. int iter_done_here = 0;
  931. while ((diffsq > interp_prec) && (max_iter_interp > iter_done_here)) {
  932. (*this).Iterate_BAE();
  933. iter_done_here++;
  934. }
  935. if ((diffsq > diffsq_ref)) {
  936. // This procedure has failed. We reset everything to begin values.
  937. for (int j = 0; j < chain.Nstrings; ++j)
  938. for (int alpha = 0; alpha < base[j]; ++alpha) lambda[j][alpha] = lambda_ref[j][alpha];
  939. diffsq = diffsq_ref;
  940. }
  941. }
  942. void ODSLF_Bethe_State::Solve_BAE_interp (DP interp_prec, int max_iter_interp)
  943. {
  944. // This function attempts to get convergence diffsq <= interp_prec in at most max_iter_interp steps.
  945. // If this fails, the lambda's are reset to original values, defined as...
  946. ODSLF_Lambda lambda_ref(chain, base);
  947. DP diffsq_ref = 1.0;
  948. for (int j = 0; j < chain.Nstrings; ++j)
  949. for (int alpha = 0; alpha < base[j]; ++alpha) lambda_ref[j][alpha] = lambda[j][alpha];
  950. diffsq_ref = diffsq;
  951. // Now begin solving...
  952. diffsq = 1.0;
  953. int iter_done_here = 0;
  954. ODSLF_Lambda lambda1(chain, base);
  955. ODSLF_Lambda lambda2(chain, base);
  956. ODSLF_Lambda lambda3(chain, base);
  957. ODSLF_Lambda lambda4(chain, base);
  958. ODSLF_Lambda lambda5(chain, base);
  959. while ((diffsq > interp_prec) && (max_iter_interp > iter_done_here)) {
  960. (*this).Iterate_BAE();
  961. for (int j = 0; j < chain.Nstrings; ++j)
  962. for (int alpha = 0; alpha < base[j]; ++alpha) lambda1[j][alpha] = lambda[j][alpha];
  963. (*this).Iterate_BAE();
  964. for (int j = 0; j < chain.Nstrings; ++j)
  965. for (int alpha = 0; alpha < base[j]; ++alpha) lambda2[j][alpha] = lambda[j][alpha];
  966. (*this).Iterate_BAE();
  967. for (int j = 0; j < chain.Nstrings; ++j)
  968. for (int alpha = 0; alpha < base[j]; ++alpha) lambda3[j][alpha] = lambda[j][alpha];
  969. (*this).Iterate_BAE();
  970. for (int j = 0; j < chain.Nstrings; ++j)
  971. for (int alpha = 0; alpha < base[j]; ++alpha) lambda4[j][alpha] = lambda[j][alpha];
  972. iter_done_here += 4;
  973. // now extrapolate the result to infinite number of iterations...
  974. Vect_DP rap(0.0, 4);
  975. Vect_DP oneoverP(0.0, 4);
  976. DP deltalambda = 0.0;
  977. for (int i = 0; i < 4; ++i) oneoverP[i] = 1.0/(1.0 + i*i);
  978. for (int j = 0; j < chain.Nstrings; ++j) for (int alpha = 0; alpha < base[j]; ++alpha) {
  979. rap[0] = lambda1[j][alpha];
  980. rap[1] = lambda2[j][alpha];
  981. rap[2] = lambda3[j][alpha];
  982. rap[3] = lambda4[j][alpha];
  983. polint (oneoverP, rap, 0.0, lambda[j][alpha], deltalambda);
  984. }
  985. (*this).Iterate_BAE();
  986. }
  987. if ((diffsq >= diffsq_ref)) {
  988. // This procedure has failed. We reset everything to begin values.
  989. for (int j = 0; j < chain.Nstrings; ++j)
  990. for (int alpha = 0; alpha < base[j]; ++alpha) lambda[j][alpha] = lambda_ref[j][alpha];
  991. diffsq = diffsq_ref;
  992. }
  993. return;
  994. }
  995. void ODSLF_Bethe_State::Compute_lnnorm ()
  996. {
  997. if (true || lnnorm == -100.0) { // else norm already calculated by Newton method
  998. // Actually, compute anyway to increase accuracy !
  999. SQMat_CX Gaudin_Red(base.Nraptot);
  1000. (*this).Build_Reduced_Gaudin_Matrix(Gaudin_Red);
  1001. complex<DP> lnnorm_check = lndet_LU_CX_dstry(Gaudin_Red);
  1002. lnnorm = real(lnnorm_check);
  1003. }
  1004. return;
  1005. }
  1006. void ODSLF_Bethe_State::Compute_Momentum ()
  1007. {
  1008. int sum_Ix2 = 0;
  1009. DP sum_M = 0.0;
  1010. for (int j = 0; j < chain.Nstrings; ++j) {
  1011. sum_M += 0.5 * (1.0 + chain.par[j]) * base[j];
  1012. for (int alpha = 0; alpha < base[j]; ++alpha) {
  1013. sum_Ix2 += Ix2[j][alpha];
  1014. }
  1015. }
  1016. iK = (chain.Nsites/2) * int(sum_M + 0.1) - (sum_Ix2/2); // + 0.1: for safety...
  1017. while (iK >= chain.Nsites) iK -= chain.Nsites;
  1018. while (iK < 0) iK += chain.Nsites;
  1019. K = PI * sum_M - PI * sum_Ix2/chain.Nsites;
  1020. while (K >= 2.0*PI) K -= 2.0*PI;
  1021. while (K < 0.0) K += 2.0*PI;
  1022. return;
  1023. }
  1024. void ODSLF_Bethe_State::Compute_All (bool reset_rapidities) // solves BAE, computes E, K and lnnorm
  1025. {
  1026. (*this).Find_Rapidities (reset_rapidities);
  1027. if (conv == 1) {
  1028. (*this).Compute_Energy ();
  1029. (*this).Compute_Momentum ();
  1030. (*this).Compute_lnnorm ();
  1031. }
  1032. return;
  1033. }
  1034. bool ODSLF_Bethe_State::Boost_Momentum (int iKboost)
  1035. {
  1036. if (iKboost == 0) return(true); // done
  1037. ODSLF_Ix2_Offsets offsets_here = offsets;
  1038. bool success = false;
  1039. if (iKboost < 0)
  1040. success = offsets_here.Add_Boxes_From_Lowest(-iKboost, 0); // add boxes in even sectors to decrease iK
  1041. else if (iKboost > 0)
  1042. success = offsets_here.Add_Boxes_From_Lowest(iKboost, 1); // add boxes in odd sectors to increase iK
  1043. if (success) (*this).Set_Ix2_Offsets(offsets_here);
  1044. return(success);
  1045. }
  1046. std::ostream& operator<< (std::ostream& s, const ODSLF_Bethe_State& state)
  1047. {
  1048. // sends all the state data to output stream
  1049. s << endl << "******** Chain with Nsites = " << state.chain.Nsites
  1050. << " Mdown (nr fermions) = " << state.base.Mdown
  1051. << ": eigenstate with base_id " << state.base_id << ", type_id " << state.type_id
  1052. << " id " << state.id << " maxid " << state.offsets.maxid << endl
  1053. << "E = " << state.E << " K = " << state.K << " iK = " << state.iK
  1054. << " lnnorm = " << state.lnnorm << endl
  1055. << "conv = " << state.conv << " iter = " << state.iter
  1056. << " iter_Newton = " << state.iter_Newton << "\tdiffsq " << state.diffsq << endl;
  1057. for (int j = 0; j < state.chain.Nstrings; ++j) {
  1058. if (state.base.Nrap[j] > 0) {
  1059. s << "Type " << j << " Str_L = " << state.chain.Str_L[j]
  1060. << " par = " << state.chain.par[j] << " M_j = " << state.base.Nrap[j]
  1061. << " Ix2_infty = " << state.base.Ix2_infty[j] << " Ix2_max = " << state.base.Ix2_max[j] << endl;
  1062. Vect_INT qnumbers(state.base.Nrap[j]);
  1063. Vect_DP rapidities(state.base.Nrap[j]);
  1064. for (int alpha = 0; alpha < state.base.Nrap[j]; ++alpha) {
  1065. qnumbers[alpha] = state.Ix2[j][alpha];
  1066. rapidities[alpha] = state.lambda[j][alpha];
  1067. }
  1068. qnumbers.QuickSort();
  1069. rapidities.QuickSort();
  1070. s << "Ix2 quantum numbers: " << endl;
  1071. for (int alpha = 0; alpha < state.base.Nrap[j]; ++alpha) s << qnumbers[alpha] << " ";
  1072. s << endl;
  1073. s << "Rapidities: " << endl;
  1074. for (int alpha = 0; alpha < state.base.Nrap[j]; ++alpha) s << rapidities[alpha] << " ";
  1075. s << endl;
  1076. }
  1077. }
  1078. s << endl;
  1079. return s;
  1080. }
  1081. } // namespace ABACUS