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 37KB

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