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.

ABACUS_Scan.h 36KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828
  1. /**********************************************************
  2. This software is part of J.-S. Caux's ABACUS library.
  3. Copyright (c) J.-S. Caux.
  4. -----------------------------------------------------------
  5. File: ABACUS_Scan.h
  6. Purpose: Declares all classes and functions used in the
  7. ABACUS logic of scanning with threads.
  8. ***********************************************************/
  9. #ifndef ABACUS_SCAN_H
  10. #define ABACUS_SCAN_H
  11. #include "ABACUS.h"
  12. namespace ABACUS {
  13. const int MAX_STATE_LIST_SIZE = 10000;
  14. // Functions in src/UTILS/Data_File_Name.cc:
  15. void Data_File_Name (std::stringstream& name, char whichDSF, DP c_int, DP L, int N,
  16. int iKmin, int iKmax, DP kBT, DP L2, std::string defaultname);
  17. void Data_File_Name (std::stringstream& name, char whichDSF, int iKmin, int iKmax, DP kBT,
  18. LiebLin_Bethe_State& State, LiebLin_Bethe_State& RefScanState, std::string defaultname);
  19. void Data_File_Name (std::stringstream& name, char whichDSF, DP Delta, int N, int M, int iKmin, int iKmax,
  20. DP kBT, int N2, std::string defaultname);
  21. void Data_File_Name (std::stringstream& name, char whichDSF, int iKmin, int iKmax, DP kBT,
  22. Heis_Bethe_State& State, Heis_Bethe_State& RefScanState, std::string defaultname);
  23. void ODSLF_Data_File_Name (std::stringstream& name, char whichDSF, DP Delta, int N, int M,
  24. int iKmin, int iKmax, DP kBT, int N2, std::string defaultname);
  25. void Data_File_Name (std::stringstream& name, char whichDSF, int iKmin, int iKmax, DP kBT,
  26. ODSLF_Bethe_State& State, ODSLF_Bethe_State& RefScanState, std::string defaultname);
  27. // Coding to convert ints to strings: for application in reduced labels
  28. //const int ABACUScodingsize = 64; // use a multiple of 2 to accelerate divisions in labeling.
  29. //const char ABACUScoding[] = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '!', '?'};
  30. // From ABACUS++T_8 onwards: forbid special characters as |, :, !, ? and all capital letters in labels.
  31. // This is due to the dumb capitalization-preserving but capitalization-insensitive HFS+ filesystem on Mac OS X.
  32. const int ABACUScodingsize = 32;
  33. const char ABACUScoding[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v'};
  34. const char LABELSEP = '_'; // was _
  35. const char TYPESEP = 'x'; // was |
  36. const char EXCSEP = 'y'; // was :
  37. const char INEXCSEP = 'z'; // was @
  38. struct State_Label_Data {
  39. Vect<int> type; // integer type labels of the types present
  40. Vect<int> M; // how many particles of each type
  41. Vect<int> nexc; // how many excitations as compared to the reference state used
  42. Vect<Vect<int> > Ix2old; // which Ix2 will be excited
  43. Vect<Vect<int> > Ix2exc; // which Ix2 the excitation has shifted to
  44. State_Label_Data (const Vect<int>& type_ref, const Vect<int>& M_ref,
  45. const Vect<int>& nexc_ref, const Vect<Vect<int> >& Ix2old_ref, const Vect<Vect<int> >& Ix2exc_ref)
  46. {
  47. type = type_ref; M = M_ref; nexc = nexc_ref; Ix2old = Ix2old_ref; Ix2exc = Ix2exc_ref;
  48. }
  49. };
  50. std::string Extract_Base_Label (std::string label); // works for labels and complabels
  51. std::string Extract_nexc_Label (std::string label);
  52. // For compressed labels: conversions between integers and char/strings.
  53. std::string Convert_POSINT_to_STR (int int_to_convert);
  54. int Convert_CHAR_to_POSINT (char char_to_convert);
  55. int Convert_STR_to_POSINT (std::string str_to_convert);
  56. State_Label_Data Read_Base_Label (std::string label);
  57. State_Label_Data Read_State_Label (std::string label, const Vect<Vect<int> >& OriginIx2);
  58. State_Label_Data Read_State_Label (std::string label, const Vect<int>& OriginIx2); // if there is only one type
  59. std::string Return_State_Label (State_Label_Data data, const Vect<Vect<int> >& OriginIx2);
  60. std::string Return_State_Label (State_Label_Data data, const Vect<int>& OriginIx2); // if there is only one type
  61. std::string Return_State_Label (const Vect<Vect<int> >& ScanIx2, const Vect<Vect<int> >& OriginIx2);
  62. std::string Return_State_Label (const Vect<int>& ScanIx2, const Vect<int>& OriginIx2); // if there is only one type
  63. Vect<Vect<int> > Return_Ix2_from_Label (std::string label_ref, const Vect<Vect<int> >& OriginIx2);
  64. Vect<int> Return_Ix2_from_Label (std::string label_ref, const Vect<int>& OriginIx2); // specialization to Lieb-Liniger
  65. // Functions for descending states: in SCAN/Descendents.cc
  66. Vect<std::string> Descendent_States_with_iK_Stepped_Up (std::string ScanIx2_label, const LiebLin_Bethe_State& OriginState, bool disperse_only_current_exc, bool preserve_nexc);
  67. Vect<std::string> Descendent_States_with_iK_Stepped_Down (std::string ScanIx2_label, const LiebLin_Bethe_State& OriginState, bool disperse_only_current_exc, bool preserve_nexc);
  68. Vect<std::string> Descendent_States_with_iK_Preserved (std::string ScanIx2_label, const LiebLin_Bethe_State& OriginState, bool disperse_only_current_exc_up, bool preserve_nexc_up, bool disperse_only_current_exc_down, bool preserve_nexc_down);
  69. Vect<std::string> Descendent_States_with_iK_Stepped_Up (std::string ScanIx2_label, const Heis_Bethe_State& OriginState, bool disperse_only_current_exc, bool preserve_nexc);
  70. Vect<std::string> Descendent_States_with_iK_Stepped_Down (std::string ScanIx2_label, const Heis_Bethe_State& OriginState, bool disperse_only_current_exc, bool preserve_nexc);
  71. Vect<std::string> Descendent_States_with_iK_Preserved (std::string ScanIx2_label, const Heis_Bethe_State& OriginState, bool disperse_only_current_exc_up, bool preserve_nexc_up, bool disperse_only_current_exc_down, bool preserve_nexc_down);
  72. // For symmetric state scanning:
  73. Vect<std::string> Descendent_States_with_iK_Stepped_Up_rightIx2only
  74. (std::string ScanIx2_label, const LiebLin_Bethe_State& OriginState, bool disperse_only_current_exc, bool preserve_nexc);
  75. Vect<std::string> Descendent_States_with_iK_Stepped_Down_rightIx2only
  76. (std::string ScanIx2_label, const LiebLin_Bethe_State& OriginState, bool disperse_only_current_exc, bool preserve_nexc);
  77. Vect<std::string> Descendent_States_with_iK_Stepped_Up_rightIx2only
  78. (std::string ScanIx2_label, const Heis_Bethe_State& OriginState, bool disperse_only_current_exc, bool preserve_nexc);
  79. Vect<std::string> Descendent_States_with_iK_Stepped_Down_rightIx2only
  80. (std::string ScanIx2_label, const Heis_Bethe_State& OriginState, bool disperse_only_current_exc, bool preserve_nexc);
  81. // Functions in src/SCAN/General_Scan.cc:
  82. void Scan_LiebLin (char whichDSF, DP c_int, DP L, int N, int iKmin, int iKmax, DP kBT,
  83. int Max_Secs, DP target_sumrule, bool refine, int paralevel, Vect<int> rank, Vect<int> nr_processors);
  84. void Scan_LiebLin (char whichDSF, DP c_int, DP L, int N, int iKmin, int iKmax, DP kBT,
  85. int Max_Secs, DP target_sumrule, bool refine);
  86. void Scan_LiebLin (char whichDSF, LiebLin_Bethe_State AveragingState, std::string defaultScanStatename, int iKmin, int iKmax,
  87. int Max_Secs, DP target_sumrule, bool refine, int paralevel, Vect<int> rank, Vect<int> nr_processors);
  88. void Scan_LiebLin (char whichDSF, LiebLin_Bethe_State AveragingState, std::string defaultname, int iKmin, int iKmax,
  89. int Max_Secs, DP target_sumrule, bool refine);
  90. void Scan_LiebLin_Geometric_Quench (DP c_int, DP L_1, int type_id_1, long long int id_1, DP L_2, int N,
  91. int iK_UL, int Max_Secs, DP target_sumrule, bool refine);
  92. void Scan_Heis (char whichDSF, DP Delta, int N, int M, int iKmin, int iKmax,
  93. int Max_Secs, DP target_sumrule, bool refine, int paralevel, Vect<int> rank, Vect<int> nr_processors);
  94. void Scan_Heis (char whichDSF, DP Delta, int N, int M, int iKmin, int iKmax,
  95. int Max_Secs, DP target_sumrule, bool refine);
  96. void Scan_Heis (char whichDSF, XXZ_Bethe_State& AveragingState, std::string defaultScanStatename, int iKmin, int iKmax,
  97. int Max_Secs, DP target_sumrule, bool refine, int paralevel, Vect<int> rank, Vect<int> nr_processors);
  98. void Scan_Heis (char whichDSF, XXX_Bethe_State& AveragingState, std::string defaultScanStatename, int iKmin, int iKmax,
  99. int Max_Secs, DP target_sumrule, bool refine, int paralevel, Vect<int> rank, Vect<int> nr_processors);
  100. void Scan_Heis (char whichDSF, XXZ_gpd_Bethe_State& AveragingState, std::string defaultScanStatename, int iKmin, int iKmax,
  101. int Max_Secs, DP target_sumrule, bool refine, int paralevel, Vect<int> rank, Vect<int> nr_processors);
  102. void Scan_ODSLF (char whichDSF, DP Delta, int N, int M, int iKmin, int iKmax,
  103. int Max_Secs, DP target_sumrule, bool refine, int rank, int nr_processors);
  104. void Scan_ODSLF (char whichDSF, DP Delta, int N, int M, int iKmin, int iKmax, int Max_Secs, bool refine);
  105. void Scan_ODSLF (char whichDSF, DP Delta, int N, int M, int iKneeded, int Max_Secs, bool refine);
  106. void Scan_ODSLF (char whichDSF, DP Delta, int N, int M, int Max_Secs, bool refine);
  107. // Functions to prepare and wrapup parallel scans:
  108. void Prepare_Parallel_Scan_LiebLin (char whichDSF, DP c_int, DP L, int N, int iKmin, int iKmax, DP kBT,
  109. std::string defaultname, int paralevel, Vect<int> rank_lower_paralevels,
  110. Vect<int> nr_processors_lower_paralevels, int nr_processors_at_newlevel);
  111. void Wrapup_Parallel_Scan_LiebLin (char whichDSF, DP c_int, DP L, int N, int iKmin, int iKmax, DP kBT,
  112. std::string defaultname, int paralevel, Vect<int> rank_lower_paralevels,
  113. Vect<int> nr_processors_lower_paralevels, int nr_processors_at_newlevel);
  114. void Prepare_Parallel_Scan_Heis (char whichDSF, DP Delta, int N, int M, int iKmin, int iKmax,
  115. int paralevel, Vect<int> rank_lower_paralevels,
  116. Vect<int> nr_processors_lower_paralevels, int nr_processors_at_newlevel);
  117. void Wrapup_Parallel_Scan_Heis (char whichDSF, DP Delta, int N, int M, int iKmin, int iKmax,
  118. int paralevel, Vect<int> rank_lower_paralevels,
  119. Vect<int> nr_processors_lower_paralevels, int nr_processors_at_newlevel);
  120. void Sort_RAW_File (const char ffsq_file[], char optionchar);
  121. void Sort_RAW_File (const char ffsq_file[], char optionchar, char whichDSF);
  122. // Functions for data interpretation:
  123. DP Smoothen_RAW_into_SF (std::string prefix, int iKmin, int iKmax, int DiK,
  124. DP ommin, DP ommax, int Nom, DP gwidth, DP normalization, DP denom_sum_K);
  125. DP Smoothen_RAW_into_SF (std::string prefix, Vect<std::string> rawfilename, Vect<DP> weight, int iKmin, int iKmax, int DiK,
  126. DP ommin, DP ommax, int Nom, DP gwidth, DP normalization, DP denom_sum_K);
  127. void Write_K_File (DP Length, int iKmin, int iKmax);
  128. void Write_Omega_File (int Nout_omega, DP omegamin, DP omegamax);
  129. // Smoothen with gaussian width scaled with two-particle bandwidth
  130. DP Smoothen_RAW_into_SF_LiebLin_Scaled (std::string prefix, DP L, int N, int iKmin, int iKmax, int DiK, DP ommin, DP ommax, int Nom, DP width, DP normalization);
  131. //****************************************************************************
  132. struct Scan_Info {
  133. DP sumrule_obtained;
  134. DP Nfull; // dimensionality of (sub)Hilbert space considered
  135. long long int Ninadm;
  136. long long int Ndata;
  137. long long int Ndata_conv;
  138. long long int Ndata_conv0;
  139. double TT; // total computation time in seconds
  140. public:
  141. Scan_Info(); // constructor, puts everything to zero
  142. Scan_Info (DP sr, DP Nf, long long int Ni, long long int Nd, long long int Ndc, long long int Ndc0, double t);
  143. void Save (const char* outfile_Cstr);
  144. void Load (const char* infile_Cstr);
  145. inline Scan_Info& operator = (const Scan_Info& ref_info)
  146. {
  147. sumrule_obtained = ref_info.sumrule_obtained;
  148. Nfull = ref_info.Nfull;
  149. Ninadm = ref_info.Ninadm;
  150. Ndata = ref_info.Ndata;
  151. Ndata_conv = ref_info.Ndata_conv;
  152. Ndata_conv0 = ref_info.Ndata_conv0;
  153. TT = ref_info.TT;
  154. return(*this);
  155. }
  156. inline Scan_Info& operator+= (const Scan_Info& ref_info)
  157. {
  158. if (this != &ref_info) {
  159. sumrule_obtained += ref_info.sumrule_obtained;
  160. Nfull += ref_info.Nfull;
  161. Ninadm += ref_info.Ninadm;
  162. Ndata += ref_info.Ndata;
  163. Ndata_conv += ref_info.Ndata_conv;
  164. Ndata_conv0 += ref_info.Ndata_conv0;
  165. TT += ref_info.TT;
  166. }
  167. return(*this);
  168. }
  169. inline Scan_Info& operator-= (const Scan_Info& ref_info)
  170. {
  171. if (this != &ref_info) {
  172. sumrule_obtained -= ref_info.sumrule_obtained;
  173. Nfull -= ref_info.Nfull;
  174. Ninadm -= ref_info.Ninadm;
  175. Ndata -= ref_info.Ndata;
  176. Ndata_conv -= ref_info.Ndata_conv;
  177. Ndata_conv0 -= ref_info.Ndata_conv0;
  178. TT -= ref_info.TT;
  179. }
  180. return(*this);
  181. }
  182. };
  183. std::ostream& operator<< (std::ostream& s, const Scan_Info& info);
  184. template<class Tstate>
  185. Scan_Info General_Scan (char whichDSF, int iKmin, int iKmax, int iKmod, DP kBT, Tstate& AveragingState, Tstate& SeedScanState,
  186. std::string defaultScanStatename, int Max_Secs, DP target_sumrule, bool refine, int paralevel, Vect<int> rank, Vect<int> nr_processors);
  187. //****************************************************************************
  188. // Functions in src/SCAN/Descendents.cc:
  189. Vect<std::string> Descendents (const LiebLin_Bethe_State& ScanState, const LiebLin_Bethe_State& OriginState, int type_required);
  190. Vect<std::string> Descendents (const Heis_Bethe_State& ScanState, const Heis_Bethe_State& OriginState, int type_required);
  191. struct Scan_Thread {
  192. std::string label;
  193. int type;
  194. Scan_Thread ();
  195. Scan_Thread (std::string label_ref, int type_ref) {
  196. label = label_ref;
  197. type = type_ref;
  198. }
  199. Scan_Thread& operator= (const Scan_Thread& RefThread);
  200. };
  201. struct Scan_Thread_Data {
  202. // By convention, a Scan_Thread_Data object handles a list of threads which are yet to be descended.
  203. // Improvement on Scan_Thread_Set used up to ABACUS++G_7, saving data to disk instead of holding it in memory.
  204. int nlists = 6400; // number of threads lists, fixed to this number by convention.
  205. DP logscale = (1.0/64) * log(2.0); // each separate list contains threads differing by a scale factor of 2^{1/64} \approx 1.01.
  206. std::string thrdir_name; // directory in which threads files are saved.
  207. Vect<int> nthreads_total;
  208. Vect<int> nthreads_on_disk;
  209. int lowest_il_with_nthreads_neq_0;
  210. // In-memory storage, for adding threads efficiently without constantly writing to disk
  211. // These objects are saved to disk when Next_Scan_Threads are called.
  212. Vect<int> dim;
  213. Vect<int> nthreads_in_memory;
  214. Vect<Vect<std::string> > label;
  215. Vect<Vect<int> > type; // which type of descendent is needed
  216. Vect<std::string> filename;
  217. Scan_Thread_Data ();
  218. Scan_Thread_Data (std::string thrdir_name_ref, bool refine);
  219. ~Scan_Thread_Data ();
  220. bool Increase_Memory_Size (int il, int nr_to_add);
  221. void Include_Thread (DP abs_data_value_ref, std::string label_ref, int type_ref);
  222. void Include_Thread (int il, std::string label_ref, int type_ref);
  223. Vect<Scan_Thread> Extract_Next_Scan_Threads (); // returns a vector of the threads that are next in line. By defn, all threads with index il == lowest_il_with_nthreads_neq_0. These are removed from the object.
  224. Vect<Scan_Thread> Extract_Next_Scan_Threads (int min_nr); // as above, but returns a minimum of min_nr threads.
  225. void Flush_to_Disk (int il);
  226. void Save ();
  227. void Load ();
  228. };
  229. //****************************************************************************
  230. // To populate a list of states for scanning:
  231. inline void Scan_for_Possible_Bases (const Vect<int> SeedNrap, const Vect<int> Str_L,
  232. int Mdown_remaining, Vect<std::string>& possible_base_label, int& nfound, int nexc_max_used,
  233. int base_level_to_scan, Vect<int>& Nrapidities)
  234. {
  235. if (Mdown_remaining < 0) { ABACUSerror("Scan_for_Possible_Bases: shouldn't be here..."); } // reached inconsistent point
  236. if (base_level_to_scan == 0) {
  237. if (Str_L[0] != 1) ABACUSerror("Str_L[0] != 1 in ABACUS_Scan.h Scan_for_Possible_Bases.");
  238. Nrapidities[0] = Mdown_remaining;
  239. // Set label:
  240. std::stringstream M0out;
  241. M0out << Nrapidities[0];
  242. possible_base_label[nfound] = M0out.str();
  243. for (int itype = 1; itype < Nrapidities.size(); ++itype)
  244. if (Nrapidities[itype] > 0) {
  245. possible_base_label[nfound] += TYPESEP;
  246. std::stringstream typeout;
  247. typeout << itype;
  248. possible_base_label[nfound] += typeout.str();
  249. possible_base_label[nfound] += EXCSEP;
  250. std::stringstream Mout;
  251. Mout << Nrapidities[itype];
  252. possible_base_label[nfound] += Mout.str();
  253. }
  254. nfound++;
  255. }
  256. else {
  257. // Preserve the number of strings at this level as compared to SeedState:
  258. Nrapidities[base_level_to_scan] = SeedNrap[base_level_to_scan];
  259. if (Mdown_remaining - Str_L[base_level_to_scan] * Nrapidities[base_level_to_scan] >= 0)
  260. Scan_for_Possible_Bases (SeedNrap, Str_L, Mdown_remaining - Str_L[base_level_to_scan] * Nrapidities[base_level_to_scan],
  261. possible_base_label, nfound, nexc_max_used, base_level_to_scan - 1, Nrapidities);
  262. // Reduce number of strings at this level as compared to SeedState:
  263. for (int i = 1; i <= ABACUS::min(SeedNrap[base_level_to_scan], nexc_max_used/Str_L[base_level_to_scan]); ++i) {
  264. Nrapidities[base_level_to_scan] = SeedNrap[base_level_to_scan] - i;
  265. if (Mdown_remaining - Str_L[base_level_to_scan] * Nrapidities[base_level_to_scan] >= 0)
  266. Scan_for_Possible_Bases (SeedNrap, Str_L, Mdown_remaining - Str_L[base_level_to_scan] * Nrapidities[base_level_to_scan],
  267. possible_base_label, nfound, nexc_max_used - i*Str_L[base_level_to_scan], base_level_to_scan - 1, Nrapidities);
  268. }
  269. // Increase the number of strings at this level as compared to SeedState:
  270. for (int i = 1; i <= ABACUS::min(Mdown_remaining/Str_L[base_level_to_scan], nexc_max_used/Str_L[base_level_to_scan]); ++i) {
  271. Nrapidities[base_level_to_scan] = SeedNrap[base_level_to_scan] + i;
  272. if (Mdown_remaining - Str_L[base_level_to_scan] * Nrapidities[base_level_to_scan] >= 0)
  273. Scan_for_Possible_Bases (SeedNrap, Str_L, Mdown_remaining - Str_L[base_level_to_scan] * Nrapidities[base_level_to_scan],
  274. possible_base_label, nfound, nexc_max_used - i*Str_L[base_level_to_scan], base_level_to_scan - 1, Nrapidities);
  275. }
  276. }
  277. }
  278. inline Vect<std::string> Possible_Bases (const Vect<int> SeedNrap, const Vect<int> Str_L, int Mdown)//const Heis_Bethe_State& SeedState)
  279. {
  280. int nexc_max_used = NEXC_MAX_HEIS;
  281. Vect<std::string> possible_base_label (1000);
  282. int nfound = 0;
  283. Vect<int> Nrapidities = SeedNrap;
  284. int Mdown_remaining = Mdown;
  285. Scan_for_Possible_Bases (SeedNrap, Str_L, Mdown_remaining, possible_base_label, nfound, nexc_max_used, SeedNrap.size() - 1, Nrapidities);
  286. // Copy results into a clean vector:
  287. Vect<std::string> possible_base_label_found (nfound);
  288. for (int i = 0; i < nfound; ++i) possible_base_label_found[i] = possible_base_label[i];
  289. return(possible_base_label_found);
  290. }
  291. //****************************************************************************
  292. template<class Tstate>
  293. class Scan_State_List {
  294. public:
  295. int ndef;
  296. Vect<Tstate> State;
  297. Vect<std::string> base_label;
  298. Vect<Scan_Info> info; // info for base and type of State[n]
  299. Vect<bool> flag_for_scan; // set to true, next round of scanning will use this base/type
  300. Vect<bool> scan_attempted; // whether this has already been attempted
  301. public:
  302. inline Scan_State_List (char whichDSF, const Tstate& SeedScanState);
  303. public:
  304. inline Tstate& Return_State (std::string base_label_ref); // returns a state corresponding to same base and type
  305. inline void Populate_List (char whichDSF, const Tstate& SeedScanState); // creates all types of states containing up to nexc_max excitations
  306. inline void Include_Info (Scan_Info& info_to_add, std::string base_label_ref);
  307. inline void Raise_Scanning_Flags (DP threshold); // checks whether base/type should be scanned based on simpler base/type combinations
  308. inline void Order_in_SRC ();
  309. inline void Save_Info (const char* sumfile_Cstr);
  310. inline void Load_Info (const char* sumfile_Cstr);
  311. };
  312. // Do the explicit class specializations:
  313. template<>
  314. inline Scan_State_List<LiebLin_Bethe_State>::Scan_State_List (char whichDSF, const LiebLin_Bethe_State& SeedScanState)
  315. : ndef(0), State(Vect<LiebLin_Bethe_State>(MAX_STATE_LIST_SIZE)), base_label(Vect<std::string>(MAX_STATE_LIST_SIZE)),
  316. info(Vect<Scan_Info>(MAX_STATE_LIST_SIZE)), flag_for_scan(Vect<bool>(false, MAX_STATE_LIST_SIZE)),
  317. scan_attempted(Vect<bool>(false, MAX_STATE_LIST_SIZE))
  318. {
  319. State[0] = SeedScanState;
  320. }
  321. template<>
  322. inline Scan_State_List<XXZ_Bethe_State>::Scan_State_List (char whichDSF, const XXZ_Bethe_State& SeedScanState)
  323. : ndef(0), State(Vect<XXZ_Bethe_State>(MAX_STATE_LIST_SIZE)), base_label(Vect<std::string>(MAX_STATE_LIST_SIZE)),
  324. info(Vect<Scan_Info>(MAX_STATE_LIST_SIZE)), flag_for_scan(Vect<bool>(false, MAX_STATE_LIST_SIZE)),
  325. scan_attempted(Vect<bool>(false, MAX_STATE_LIST_SIZE))
  326. {
  327. State[0] = SeedScanState;
  328. }
  329. template<>
  330. inline Scan_State_List<XXX_Bethe_State>::Scan_State_List (char whichDSF, const XXX_Bethe_State& SeedScanState)
  331. : ndef(0), State(Vect<XXX_Bethe_State>(MAX_STATE_LIST_SIZE)), base_label(Vect<std::string>(MAX_STATE_LIST_SIZE)),
  332. info(Vect<Scan_Info>(MAX_STATE_LIST_SIZE)), flag_for_scan(Vect<bool>(false, MAX_STATE_LIST_SIZE)),
  333. scan_attempted(Vect<bool>(false, MAX_STATE_LIST_SIZE))
  334. {
  335. State[0] = SeedScanState;
  336. }
  337. template<>
  338. inline Scan_State_List<XXZ_gpd_Bethe_State>::Scan_State_List (char whichDSF, const XXZ_gpd_Bethe_State& SeedScanState)
  339. : ndef(0), State(Vect<XXZ_gpd_Bethe_State>(MAX_STATE_LIST_SIZE)), base_label(Vect<std::string>(MAX_STATE_LIST_SIZE)),
  340. info(Vect<Scan_Info>(MAX_STATE_LIST_SIZE)), flag_for_scan(Vect<bool>(false, MAX_STATE_LIST_SIZE)),
  341. scan_attempted(Vect<bool>(false, MAX_STATE_LIST_SIZE))
  342. {
  343. State[0] = SeedScanState;
  344. }
  345. /* IN_DEVELOPMENT
  346. template<>
  347. inline Scan_State_List<ODSLF_XXZ_Bethe_State>::Scan_State_List (char whichDSF, const ODSLF_XXZ_Bethe_State& RefState)
  348. : ndef(0), State(Vect<ODSLF_XXZ_Bethe_State>(MAX_STATE_LIST_SIZE)), base_label(Vect<std::string>(MAX_STATE_LIST_SIZE)),
  349. info(Vect<Scan_Info>(MAX_STATE_LIST_SIZE)), flag_for_scan(Vect<bool>(false, MAX_STATE_LIST_SIZE)),
  350. scan_attempted(Vect<bool>(false, MAX_STATE_LIST_SIZE))
  351. {
  352. if (whichDSF == 'Z' || whichDSF == 'z') State[0] = ODSLF_XXZ_Bethe_State(RefState.chain, RefState.base.Mdown);
  353. else if (whichDSF == 'm') State[0] = ODSLF_XXZ_Bethe_State(RefState.chain, RefState.base.Mdown - 1);
  354. else if (whichDSF == 'p') State[0] = ODSLF_XXZ_Bethe_State(RefState.chain, RefState.base.Mdown + 1);
  355. else ABACUSerror("Unknown whichDSF in Scan_State_List<ODSLF_XXZ... constructor.");
  356. }
  357. */
  358. template<>
  359. inline LiebLin_Bethe_State& Scan_State_List<LiebLin_Bethe_State>::Return_State (std::string base_label_ref)
  360. {
  361. int n = 0;
  362. while (n < ndef && base_label_ref.compare(base_label[n]) != 0) n++;
  363. if (n == ndef) {
  364. State[n] = State[0];
  365. base_label[n] = base_label_ref;
  366. info[n].Nfull = 1LL; // Nfull not definable for LiebLin
  367. ndef++;
  368. }
  369. return(State[n]);
  370. }
  371. template<>
  372. inline XXZ_Bethe_State& Scan_State_List<XXZ_Bethe_State>::Return_State (std::string base_label_ref)
  373. {
  374. int n = 0;
  375. while (n < ndef && base_label_ref.compare(base_label[n]) != 0) n++;
  376. if (n == ndef) {
  377. Heis_Base checkbase (State[0].chain, base_label_ref);
  378. State[n] = XXZ_Bethe_State (State[0].chain, checkbase);
  379. info[n].Nfull = checkbase.dimH;
  380. ndef++;
  381. }
  382. return(State[n]);
  383. }
  384. template<>
  385. inline XXX_Bethe_State& Scan_State_List<XXX_Bethe_State>::Return_State (std::string base_label_ref)
  386. {
  387. int n = 0;
  388. while (n < ndef && base_label_ref.compare(base_label[n]) != 0) n++;
  389. if (n == ndef) {
  390. Heis_Base checkbase (State[0].chain, base_label_ref);
  391. State[n] = XXX_Bethe_State (State[0].chain, checkbase);
  392. info[n].Nfull = checkbase.dimH;
  393. ndef++;
  394. }
  395. return(State[n]);
  396. }
  397. template<>
  398. inline XXZ_gpd_Bethe_State& Scan_State_List<XXZ_gpd_Bethe_State>::Return_State (std::string base_label_ref)
  399. {
  400. int n = 0;
  401. while (n < ndef && base_label_ref.compare(base_label[n]) != 0) n++;
  402. if (n == ndef) {
  403. Heis_Base checkbase (State[0].chain, base_label_ref);
  404. State[n] = XXZ_gpd_Bethe_State (State[0].chain, checkbase);
  405. info[n].Nfull = checkbase.dimH;
  406. ndef++;
  407. }
  408. return(State[n]);
  409. }
  410. /* IN DEVELOPMENT
  411. template<>
  412. inline ODSLF_XXZ_Bethe_State& Scan_State_List<ODSLF_XXZ_Bethe_State>::Return_State (long long int base_id_ref, long long int type_id_ref)
  413. {
  414. int n = 0;
  415. while (n < ndef && !(base_id_ref == State[n].base_id && type_id_ref == State[n].type_id)) n++;
  416. if (n == ndef) {
  417. State[n] = ODSLF_XXZ_Bethe_State (State[0].chain, base_id_ref, type_id_ref);
  418. info[n].Nfull = State[n].maxid + 1LL;
  419. ndef++;
  420. }
  421. return(State[n]);
  422. }
  423. */
  424. template<>
  425. inline void Scan_State_List<LiebLin_Bethe_State>::Populate_List (char whichDSF, const LiebLin_Bethe_State& SeedScanState)
  426. {
  427. // For LiebLin_Bethe_State: only one base is used, so there is only one state here.
  428. if (ndef != 0) ABACUSerror("Please only populate a virgin Scan_State_List.");
  429. std::stringstream baselabel;
  430. baselabel << State[0].N;
  431. base_label[0] = baselabel.str();
  432. std::stringstream label0;
  433. label0 << State[0].N << LABELSEP << ABACUScoding[0] << LABELSEP;//"_0_";
  434. State[0].Set_to_Label (label0.str(), SeedScanState.Ix2);
  435. info[0].Nfull = 1LL; // Nfull not definable for LiebLin
  436. ndef = 1;
  437. }
  438. template<>
  439. inline void Scan_State_List<XXZ_Bethe_State>::Populate_List (char whichDSF, const XXZ_Bethe_State& SeedScanState)
  440. {
  441. // creates all types of states containing up to nexc_max excitations
  442. if (ndef != 0) ABACUSerror("Please only populate a virgin Scan_State_List.");
  443. // We assume that SeedScanState has quantum numbers which are set according to the relevant AveragingState.
  444. // This function creates a list of states with other bases in the vicinity of that of SeedScanState,
  445. // matching the quantum numbers as closely as possible.
  446. Vect<int> Str_L(SeedScanState.chain.Nstrings);
  447. for (int i = 0; i < SeedScanState.chain.Nstrings; ++i) Str_L[i] = SeedScanState.chain.Str_L[i];
  448. // First of all, we create a list of the possible bases themselves.
  449. Vect<std::string> bases_label = Possible_Bases (SeedScanState.base.Nrap, Str_L, SeedScanState.base.Mdown); // returns a vector of possible bases
  450. for (int ib = 0; ib < bases_label.size(); ++ib) {
  451. Heis_Base checkbase (State[0].chain, bases_label[ib]);
  452. State[ndef] = XXZ_Bethe_State (State[0].chain, checkbase);
  453. State[ndef].Set_to_Closest_Matching_Ix2_fixed_Base (SeedScanState);
  454. State[ndef].Set_Label_from_Ix2 (State[ndef].Ix2); // sets to trivial label for this base
  455. base_label[ndef] = bases_label[ib];
  456. info[ndef].Nfull = State[ndef].base.dimH;
  457. ndef++;
  458. if (ndef >= MAX_STATE_LIST_SIZE) ABACUSerror("Increase number of elements in ScanStateList.");
  459. }
  460. }
  461. template<>
  462. inline void Scan_State_List<XXX_Bethe_State>::Populate_List (char whichDSF, const XXX_Bethe_State& SeedScanState)
  463. {
  464. // creates all types of states containing up to nexc_max excitations
  465. if (ndef != 0) ABACUSerror("Please only populate a virgin Scan_State_List.");
  466. // We assume that SeedScanState has quantum numbers which are set according to the relevant AveragingState.
  467. // This function creates a list of states with other bases in the vicinity of that of SeedScanState,
  468. // matching the quantum numbers as closely as possible.
  469. Vect<int> Str_L(SeedScanState.chain.Nstrings);
  470. for (int i = 0; i < SeedScanState.chain.Nstrings; ++i) Str_L[i] = SeedScanState.chain.Str_L[i];
  471. // To take infinite rapidities into account, we use intermediate states with up to 2 less finite rapidities (1 for Szz, 2 for Spm)
  472. int nrinfrapmax = 0;
  473. if (whichDSF == 'z') nrinfrapmax = 1;
  474. else if (whichDSF == 'p') nrinfrapmax = ABACUS::min(2, SeedScanState.base.Mdown);
  475. Vect<int> Nrapmod = SeedScanState.base.Nrap;
  476. for (int nrinfrap = 0; nrinfrap <= nrinfrapmax; ++nrinfrap) {
  477. Nrapmod[0] = SeedScanState.base.Nrap[0] - nrinfrap;
  478. if (Nrapmod[0] < 0) ABACUSerror("Putting too many rapidities at infinity in ABACUS_Scan.h: Possible_Bases.");
  479. Vect<std::string> bases_label = Possible_Bases (Nrapmod, Str_L, SeedScanState.base.Mdown-nrinfrap); // returns a vector of possible bases
  480. for (int ib = 0; ib < bases_label.size(); ++ib) {
  481. Heis_Base checkbase (State[0].chain, bases_label[ib]);
  482. State[ndef] = XXX_Bethe_State (State[0].chain, checkbase);
  483. State[ndef].Set_to_Closest_Matching_Ix2_fixed_Base (SeedScanState);
  484. base_label[ndef] = bases_label[ib];
  485. info[ndef].Nfull = State[ndef].base.dimH;
  486. ndef++;
  487. if (ndef >= MAX_STATE_LIST_SIZE) ABACUSerror("Increase number of elements in ScanStateList.");
  488. }
  489. } // for nrinfrap
  490. }
  491. template<>
  492. inline void Scan_State_List<XXZ_gpd_Bethe_State>::Populate_List (char whichDSF, const XXZ_gpd_Bethe_State& SeedScanState)
  493. {
  494. // creates all types of states containing up to nexc_max excitations
  495. if (ndef != 0) ABACUSerror("Please only populate a virgin Scan_State_List.");
  496. // We assume that SeedScanState has quantum numbers which are set according to the relevant AveragingState.
  497. // This function creates a list of states with other bases in the vicinity of that of SeedScanState,
  498. // matching the quantum numbers as closely as possible.
  499. Vect<int> Str_L(SeedScanState.chain.Nstrings);
  500. for (int i = 0; i < SeedScanState.chain.Nstrings; ++i) Str_L[i] = SeedScanState.chain.Str_L[i];
  501. // First of all, we create a list of the possible bases themselves.
  502. Vect<std::string> bases_label = Possible_Bases (SeedScanState.base.Nrap, Str_L, SeedScanState.base.Mdown); // returns a vector of possible bases
  503. for (int ib = 0; ib < bases_label.size(); ++ib) {
  504. Heis_Base checkbase (State[0].chain, bases_label[ib]);
  505. State[ndef] = XXZ_gpd_Bethe_State (State[0].chain, checkbase);
  506. State[ndef].Set_to_Closest_Matching_Ix2_fixed_Base (SeedScanState);
  507. base_label[ndef] = bases_label[ib];
  508. info[ndef].Nfull = State[ndef].base.dimH;
  509. ndef++;
  510. if (ndef >= MAX_STATE_LIST_SIZE) ABACUSerror("Increase number of elements in ScanStateList.");
  511. }
  512. }
  513. /* IN DEVELOPMENT
  514. template<>
  515. inline void Scan_State_List<ODSLF_XXZ_Bethe_State>::Populate_List ()
  516. {
  517. // creates all types of states containing up to nexc_max excitations
  518. if (ndef != 0) ABACUSerror("Please only populate a virgin Scan_State_List.");
  519. //std::cout << "In Populate_List: " << State[0] << std::endl;
  520. Vect<long long int> bases_id = State[0].chain.Possible_Bases (State[0].base.Mdown); // returns a vector of possible bases
  521. //std::cout << "Mdown = " << State[0].base.Mdown << "\tPossible bases size: " << bases_id.size() << "\tPossible bases: " << bases_id << std::endl;
  522. for (int ib = 0; ib < bases_id.size(); ++ib) {
  523. ODSLF_Base checkbase (State[0].chain, bases_id[ib]);
  524. Vect<long long int> types_id = checkbase.Possible_Types (); // returns a vector of possible types
  525. //std::cout << "For base_id " << bases_id[ib] << "\t found types " << types_id << std::endl;
  526. for (int it = 0; it < types_id.size(); ++it) {
  527. if (bases_id[ib] < 1000000) { // FUDGE: consider only one-strings
  528. //std::cout << "Populate list: constructing state: " << bases_id[ib] << "\t" << types_id[it] << std::endl;
  529. State[ndef] = ODSLF_XXZ_Bethe_State (State[0].chain, bases_id[ib], types_id[it]);
  530. //std::cout << "Populate list: before setting id: " << std::endl << State[ndef] << std::endl;
  531. State[ndef].Set_to_id(0LL);
  532. //std::cout << "Populate list: after setting id: " << std::endl << State[ndef] << std::endl;
  533. info[ndef].Nfull = State[ndef].maxid + 1LL;
  534. ndef++;
  535. if (ndef >= MAX_STATE_LIST_SIZE) ABACUSerror("Increase number of elements in ScanStateList.");
  536. }
  537. }
  538. }
  539. }
  540. */
  541. template<class Tstate>
  542. inline void Scan_State_List<Tstate>::Include_Info (Scan_Info& info_to_add, std::string base_label_ref)
  543. {
  544. int n = 0;
  545. while (n < ndef && base_label_ref.compare(base_label[n]) != 0) n++;
  546. if (n == ndef) {
  547. std::cout << "ndef = " << ndef << std::endl;
  548. for (int i = 0; i < ndef; ++i) std::cout << base_label[i] << "\t";
  549. std::cout << std::endl;
  550. std::cout << "base_label_ref " << base_label_ref << std::endl;
  551. ABACUSerror("Did not find base_label_ref in Scan_State_List::Include_Info.");
  552. }
  553. info[n] += info_to_add;
  554. return;
  555. }
  556. template<class Tstate>
  557. inline void Scan_State_List<Tstate>::Raise_Scanning_Flags (DP threshold)
  558. {
  559. flag_for_scan = true;
  560. }
  561. template<class Tstate>
  562. inline void Scan_State_List<Tstate>::Order_in_SRC ()
  563. {
  564. if (ndef > 0) {
  565. Vect_INT index(ndef);
  566. for (int i = 0; i < ndef; ++i) index[i] = i;
  567. Vect<DP> sr (ndef);
  568. for (int i = 0; i < ndef; ++i) sr[i] = info[i].sumrule_obtained;
  569. sr.QuickSort(index, 0, ndef - 1);
  570. Vect<Tstate> State_ordered(ndef);
  571. Vect<std::string> base_label_ordered(ndef);
  572. Vect<Scan_Info> info_ordered(ndef);
  573. Vect<bool> flag_for_scan_ordered(ndef);
  574. // Put data in proper order
  575. for (int i = 0; i < ndef; ++i) {
  576. State_ordered[i] = State[index[ndef - 1 - i] ];
  577. base_label_ordered[i] = base_label[index[ndef - 1 - i] ];
  578. info_ordered[i] = info[index[ndef - 1 - i] ];
  579. flag_for_scan_ordered[i] = flag_for_scan[index[ndef - 1 - i] ];
  580. }
  581. // Put back in *this object:
  582. for (int i = 0; i < ndef; ++i) {
  583. State[i] = State_ordered[i];
  584. base_label[i] = base_label_ordered[i];
  585. info[i] = info_ordered[i];
  586. flag_for_scan[i] = flag_for_scan_ordered[i];
  587. } // The rest are all simply 0.
  588. }
  589. }
  590. template<class Tstate>
  591. inline void Scan_State_List<Tstate>::Save_Info (const char* sumfile_Cstr)
  592. {
  593. std::ofstream outfile;
  594. outfile.open(sumfile_Cstr);
  595. if (outfile.fail()) ABACUSerror("Could not open outfile... ");
  596. outfile.setf(std::ios::fixed);
  597. outfile.precision(16);
  598. outfile << std::setw(20) << "base" << std::setw(25) << "sumrule_obtained" << std::setw(25) << "Nfull" << std::setw(10) << "Ninadm" << std::setw(10) << "Ndata" << std::setw(10) << "conv" << std::setw(10) << "conv0" << std::setw(10) << "TT.";
  599. for (int i = 0; i < ndef; ++i)
  600. if (info[i].Nfull > 0.0) {
  601. int TT_hr = int(info[i].TT/3600);
  602. int TT_min = int((info[i].TT - 3600.0*TT_hr)/60);
  603. outfile << std::endl << std::setw(20) << base_label[i] << std::setw(25) << std::fixed << std::setprecision(20) << info[i].sumrule_obtained;
  604. if (info[i].Nfull < 1.0e+10) outfile << std::setw(25) << std::fixed << std::setprecision(0) << info[i].Nfull;
  605. else outfile << std::setw(25) << std::scientific << std::setprecision(16) << info[i].Nfull;
  606. outfile << std::setw(10) << info[i].Ninadm << std::setw(10) << info[i].Ndata << std::setw(10) << info[i].Ndata_conv << std::setw(10) << info[i].Ndata_conv0 << std::setw(10) << TT_hr << " h " << TT_min << " m " << std::fixed << std::showpoint << std::setprecision(3) << info[i].TT - 3600.0*TT_hr - 60.0*TT_min << " s";
  607. }
  608. outfile.close();
  609. }
  610. template<class Tstate>
  611. inline void Scan_State_List<Tstate>::Load_Info (const char* sumfile_Cstr)
  612. {
  613. std::ifstream infile;
  614. infile.open(sumfile_Cstr);
  615. if(infile.fail()) {
  616. std::cout << std::endl << sumfile_Cstr << std::endl;
  617. ABACUSerror("Could not open input file in Scan_State_List::Load_Info.");
  618. }
  619. // Load first line, containing informative text:
  620. char junk[256];
  621. infile.getline(junk, 256);
  622. // Now load the previous info's:
  623. std::string base_label_ref;
  624. DP sr_ref;
  625. DP Nfull_ref;
  626. long long int Ninadm_ref, Ndata_ref, conv_ref, conv0_ref;
  627. DP TT_ref;
  628. int TT_hr, TT_min;
  629. DP TT_sec;
  630. char a;
  631. while (infile.peek() != EOF) {
  632. infile >> base_label_ref >> sr_ref >> Nfull_ref >> Ninadm_ref >> Ndata_ref >> conv_ref >> conv0_ref >> TT_hr >> a >> TT_min >> a >> TT_sec >> a;
  633. TT_ref = 3600.0 * TT_hr + 60.0* TT_min + TT_sec;
  634. Scan_Info info_ref (sr_ref, Nfull_ref, Ninadm_ref, Ndata_ref, conv_ref, conv0_ref, TT_ref);
  635. (*this).Include_Info (info_ref, base_label_ref);
  636. }
  637. infile.close();
  638. return;
  639. }
  640. } // namespace ABACUS
  641. #endif