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.

State_Label.cc 20KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549
  1. /**********************************************************
  2. This software is part of J.-S. Caux's ABACUS library.
  3. Copyright (c) J.-S. Caux.
  4. -----------------------------------------------------------
  5. File: src/UTILS/State_Label.cc
  6. Purpose: universal implementation of state labels for ABACUS
  7. ***********************************************************/
  8. #include "ABACUS.h"
  9. using namespace std;
  10. using namespace ABACUS;
  11. namespace ABACUS {
  12. // The label of a state is built as follows:
  13. // M0[|type1:M1|type2:M2...]_nexc0[|nexc1|nexc2...]_type0Ix2old@type0Ix2new[:...][|type1Ix2old@type1Ix2new...]
  14. // A label is always relative to another label reference state, in practice
  15. // the seed state used in the scanning for correlations (or otherwise by default: the ground state).
  16. // The first part of the label (before the first _ ) labels the particle content (the "base").
  17. // The second part (between the two _ ) specifies the number of quantum numbers
  18. // excited to a position different from the configuration of the label reference state.
  19. // The third part gives, for each excitation, the moved quantum number, and
  20. // (after the @) the quantum number it has been moved to.
  21. // The second part is redundant (it could be read off the third part), but is kept since it is human-readable.
  22. // Example:
  23. // 300|2:23|5:4_3|2|1_-21@-43:11@-21:299@341|0@-24:4@12|5@35
  24. // labels a state with
  25. // 300 particles of type 0, 23 of type 2 and 4 of type 5
  26. // 3 type 0 particles displaced (Ix2 = -21 displaced to Ix2 = -43, 11 to -21 and 299 at 341)
  27. // 2 type 2 particles displaced (Ix2 = 0 to -24 and 4 to 12)
  28. // 1 type 5 particle displaced (Ix2 = 5 displaced to Ix2 = 35).
  29. string Extract_Base_Label (string label)
  30. {
  31. string::size_type i1 = label.find(LABELSEP);
  32. string baselabel = label.substr(0, i1);
  33. return(baselabel);
  34. }
  35. string Extract_nexc_Label (string label)
  36. {
  37. string::size_type i1 = label.find(LABELSEP);
  38. string::size_type i2 = label.rfind(LABELSEP);
  39. return(label.substr(i1+1, i2-i1-1));
  40. }
  41. // For compressed labels: conversions between integers and char/strings.
  42. // This is done according to the following data (in ABACUS_Scan.h): look for ABACUScoding.
  43. string Convert_POSINT_to_STR (int int_to_convert)
  44. {
  45. // Converts a positive integer into a string according to the coding defined by global constant array ABACUScoding.
  46. if (int_to_convert < 0) ABACUSerror("Trying to convert a negative integer to a string.");
  47. int remainder = int_to_convert;
  48. stringstream result_strstrm;
  49. do {
  50. result_strstrm << ABACUScoding[remainder - ABACUScodingsize * (remainder/ABACUScodingsize)];
  51. remainder /= ABACUScodingsize;
  52. } while (remainder > 0);
  53. return(result_strstrm.str());
  54. }
  55. int Convert_CHAR_to_POSINT (char char_to_convert)
  56. {
  57. // Converts a char into an int according to the coding defined by global constant array ABACUScoding.
  58. for (int i = 0; i < ABACUScodingsize; ++i)
  59. if (char_to_convert == ABACUScoding[i]) return(i);
  60. cout << "char to convert: " << char_to_convert << endl;
  61. ABACUSerror("Failed to convert char to posint: char not in ABACUScoding set.");
  62. return(-1);
  63. }
  64. int Convert_STR_to_POSINT (string str_to_convert)
  65. {
  66. // Converts a string into a positive integer according to the coding defined by global constant array ABACUScoding.
  67. int result = 0;
  68. for (unsigned int i = 0; i < str_to_convert.size(); ++i) {
  69. result = ABACUScodingsize * result + Convert_CHAR_to_POSINT(str_to_convert[str_to_convert.size() - 1 - i]);
  70. }
  71. return(result);
  72. }
  73. // For reading only the base part of a label:
  74. State_Label_Data Read_Base_Label (string label)
  75. {
  76. // Converts a given label into the appropriate State_Label_Data
  77. // Split label into base, nexc and q#exc parts:
  78. // these are divided by the two LABELSEP characters in the label.
  79. string::size_type i1 = label.find(LABELSEP);
  80. string::size_type i2 = label.rfind(LABELSEP);
  81. string baselabel = label.substr(0, i1);
  82. string nexclabel = label.substr(i1+1, i2-i1-1);
  83. string Ix2exclabel = label.substr(i2+1);
  84. // Read off the base label: count the number of TYPESEP in baselabel
  85. int nbar = 0;
  86. for (unsigned int i = 0; i < baselabel.length(); ++i) if (baselabel[i] == TYPESEP) nbar++;
  87. // There are now nbar + 1 base label data:
  88. int ntypes = nbar + 1;
  89. Vect<int> type(ntypes); // integer type labels of the types present
  90. type[0] = 0; // always the case by convention
  91. Vect<int> M(ntypes); // how many particles of each type
  92. if (ntypes == 1) { // Only one type to read off
  93. istringstream M0buffer(baselabel);
  94. M0buffer >> M[0];
  95. }
  96. else { // ntypes > 1
  97. // Read off M[0]:
  98. string::size_type i1 = baselabel.find(TYPESEP); // M0 is always present, without type specifier
  99. string M0 = baselabel.substr(0, i1);
  100. istringstream M0buffer(M0);
  101. M0buffer >> M[0];
  102. // Read off M[1 ... ntypes - 2]
  103. string baselabelremaining = baselabel;
  104. for (int itype = 1; itype < ntypes - 1; ++itype) {
  105. // Remove everything up to leftmost TYPESEP in baselabelremaining
  106. string::size_type i1 = baselabelremaining.find(TYPESEP); // M0 is always present, without type specifier
  107. baselabelremaining = baselabelremaining.substr(i1+1);
  108. string::size_type i2 = baselabelremaining.find(EXCSEP);
  109. string::size_type i3 = baselabelremaining.find(TYPESEP);
  110. string typeread = baselabelremaining.substr(0, i2);
  111. string Mread = baselabelremaining.substr(i2+1,i3-i2-1);
  112. istringstream typereadbuffer (typeread);
  113. typereadbuffer >> type[itype];
  114. istringstream Mreadbuffer (Mread);
  115. Mreadbuffer >> M[itype];
  116. }
  117. // Read off M[ntypes - 1]
  118. {
  119. string::size_type i1 = baselabelremaining.find(TYPESEP); // M0 is always present, without type specifier
  120. baselabelremaining = baselabelremaining.substr(i1+1);
  121. string::size_type i2 = baselabelremaining.find(EXCSEP);
  122. string typeread = baselabelremaining.substr(0, i2);
  123. string Mread = baselabelremaining.substr(i2+1);
  124. istringstream typereadbuffer (typeread);
  125. typereadbuffer >> type[ntypes - 1];
  126. istringstream Mreadbuffer (Mread);
  127. Mreadbuffer >> M[ntypes - 1];
  128. }
  129. } // else if ntypes > 1
  130. // baselabel is now completely read
  131. // Define some dud nex, Ix2old, Ix2exc:
  132. Vect<int> nexc(ntypes); // how many excitations as compared to the OriginState
  133. Vect<Vect<int> > Ix2old(ntypes); // which Ix2 will be excited
  134. Vect<Vect<int> > Ix2exc(ntypes); // which Ix2 the excitation has shifted to
  135. State_Label_Data labeldata (type, M, nexc, Ix2old, Ix2exc);
  136. return(labeldata);
  137. }
  138. State_Label_Data Read_State_Label (string label, const Vect<Vect<int> >& OriginIx2)
  139. {
  140. // Converts a given label into the appropriate State_Label_Data
  141. // Split label into base, nexc and q#exc parts:
  142. // these are divided by the two LABELSEP characters in the label.
  143. string::size_type i1 = label.find(LABELSEP);
  144. string::size_type i2 = label.rfind(LABELSEP);
  145. string baselabel = label.substr(0, i1);
  146. string nexclabel = label.substr(i1+1, i2-i1-1);
  147. string Ix2exclabel = label.substr(i2+1);
  148. // Read off the base label: count the number of TYPESEP in baselabel
  149. int nbar = 0;
  150. for (unsigned int i = 0; i < baselabel.length(); ++i) if (baselabel[i] == TYPESEP) nbar++;
  151. // There are now nbar + 1 base label data:
  152. int ntypes = nbar + 1;
  153. Vect<int> type(ntypes); // integer type labels of the types present
  154. type[0] = 0; // always the case by convention
  155. Vect<int> M(ntypes); // how many particles of each type
  156. if (ntypes == 1) { // Only one type to read off
  157. istringstream M0buffer(baselabel);
  158. M0buffer >> M[0];
  159. }
  160. else { // ntypes > 1
  161. // Read off M[0]:
  162. string::size_type i1 = baselabel.find(TYPESEP); // M0 is always present, without type specifier
  163. string M0 = baselabel.substr(0, i1);
  164. istringstream M0buffer(M0);
  165. M0buffer >> M[0];
  166. // Read off M[1 ... ntypes - 2]
  167. string baselabelremaining = baselabel;
  168. for (int itype = 1; itype < ntypes - 1; ++itype) {
  169. // Remove everything up to leftmost TYPESEP in baselabelremaining
  170. string::size_type i1 = baselabelremaining.find(TYPESEP); // M0 is always present, without type specifier
  171. baselabelremaining = baselabelremaining.substr(i1+1);
  172. string::size_type i2 = baselabelremaining.find(EXCSEP);
  173. string::size_type i3 = baselabelremaining.find(TYPESEP);
  174. string typeread = baselabelremaining.substr(0, i2);
  175. string Mread = baselabelremaining.substr(i2+1,i3-i2-1);
  176. istringstream typereadbuffer (typeread);
  177. typereadbuffer >> type[itype];
  178. istringstream Mreadbuffer (Mread);
  179. Mreadbuffer >> M[itype];
  180. }
  181. // Read off M[ntypes - 1]
  182. {
  183. string::size_type i1 = baselabelremaining.find(TYPESEP); // M0 is always present, without type specifier
  184. baselabelremaining = baselabelremaining.substr(i1+1);
  185. string::size_type i2 = baselabelremaining.find(EXCSEP);
  186. string typeread = baselabelremaining.substr(0, i2);
  187. string Mread = baselabelremaining.substr(i2+1);
  188. istringstream typereadbuffer (typeread);
  189. typereadbuffer >> type[ntypes - 1];
  190. istringstream Mreadbuffer (Mread);
  191. Mreadbuffer >> M[ntypes - 1];
  192. }
  193. } // else if ntypes > 1
  194. // baselabel is now completely read
  195. // Read off the nexc vector:
  196. Vect<int> nexc(ntypes); // how many excitations as compared to the OriginState
  197. if (ntypes == 1) { // Only one type to read off
  198. istringstream exc0buffer(nexclabel);
  199. exc0buffer >> nexc[0];
  200. }
  201. else { // ntypes > 1
  202. // Read off nexc[0]:
  203. string::size_type i1 = nexclabel.find(TYPESEP);
  204. string nexc0 = nexclabel.substr(0, i1);
  205. istringstream nexc0buffer(nexc0);
  206. nexc0buffer >> nexc[0];
  207. // Read off nexc[1 ... ntypes - 2]
  208. string nexclabelremaining = nexclabel;
  209. for (int itype = 1; itype < ntypes - 1; ++itype) {
  210. // Remove everything up to leftmost TYPESEP in nexclabelremaining
  211. string::size_type i1 = nexclabelremaining.find(TYPESEP);
  212. nexclabelremaining = nexclabelremaining.substr(i1+1);
  213. string::size_type i2 = nexclabelremaining.find(TYPESEP);
  214. string nexcread = nexclabelremaining.substr(0, i2);
  215. istringstream nexcreadbuffer (nexcread);
  216. nexcreadbuffer >> nexc[itype];
  217. }
  218. // Read off nexc[ntypes - 1]
  219. {
  220. string::size_type i1 = nexclabelremaining.find(TYPESEP);
  221. nexclabelremaining = nexclabelremaining.substr(i1+1);
  222. istringstream nexcreadbuffer (nexclabelremaining);
  223. nexcreadbuffer >> nexc[ntypes - 1];
  224. }
  225. } // else if ntypes > 1
  226. // nexc is now completely read
  227. // Now read off the (compressed) jexc and Ix2exc vectors of vectors:
  228. Vect<Vect<int> > Ix2old(ntypes); // which Ix2 will be excited
  229. Vect<Vect<int> > Ix2exc(ntypes); // which Ix2 the excitation has shifted to
  230. for (int itype = 0; itype < ntypes; ++itype) {
  231. Ix2old[itype] = Vect<int> (ABACUS::max(nexc[itype],1));
  232. Ix2exc[itype] = Vect<int> (ABACUS::max(nexc[itype],1));
  233. }
  234. string Ix2exclabelremaining = Ix2exclabel;
  235. for (int itype = 0; itype < ntypes - 1; ++itype) {
  236. // Read off the Ix2old, Ix2exc:
  237. if (nexc[itype] == 0) { // careful here, need to remove a TYPESEP
  238. string::size_type i2 = Ix2exclabelremaining.find(TYPESEP);
  239. Ix2exclabelremaining = Ix2exclabelremaining.substr(i2+1);
  240. }
  241. for (int iexc = 0; iexc < nexc[itype]; ++iexc) {
  242. //string::size_type i1 = Ix2exclabelremaining.find(INEXCSEP);
  243. string::size_type i2 = (iexc < nexc[itype] - 1 ? Ix2exclabelremaining.find(EXCSEP)
  244. : Ix2exclabelremaining.find(TYPESEP)); // careful here!
  245. string Ix2excIDread = Ix2exclabelremaining.substr(0,i2);
  246. int Ix2excID = Convert_STR_to_POSINT(Ix2excIDread);
  247. Ix2old[itype][iexc] = OriginIx2[type[itype] ][Ix2excID - M[itype] * (Ix2excID/M[itype])];
  248. // index is remainder w/r to nr of strings of this type
  249. // Convention: if remainder is even, moving left. If odd, moving right.
  250. // 0 means move one unit left, 1 means move one unit right, etc.
  251. Ix2exc[itype][iexc] = Ix2old[itype][iexc] + (Ix2excID/M[itype] % 2 ? 2 : -2)
  252. * (Ix2excID/(2 * M[itype]) + 1); // ABACUS++T_8 onwards
  253. // Remove everything up to index i2 in Ix2exclabelremaining
  254. Ix2exclabelremaining = Ix2exclabelremaining.substr(i2+1);
  255. }
  256. }
  257. // Now read off the Ix2old, Ix2exc of the last type: this is always done
  258. for (int iexc = 0; iexc < nexc[ntypes - 1] - 1; ++iexc) {
  259. string::size_type i2 = Ix2exclabelremaining.find(EXCSEP);
  260. string Ix2excIDread = Ix2exclabelremaining.substr(0,i2);
  261. int Ix2excID = Convert_STR_to_POSINT(Ix2excIDread);
  262. Ix2old[ntypes - 1][iexc] = OriginIx2[type[ntypes - 1] ][Ix2excID - M[ntypes - 1] * (Ix2excID/M[ntypes - 1])];
  263. // index is remainder w/r to nr of strings of this type
  264. // Convention: if remainder is even, moving left. If odd, moving right.
  265. Ix2exc[ntypes - 1][iexc] = Ix2old[ntypes - 1][iexc] + (Ix2excID/M[ntypes - 1] % 2 ? 2 : -2)
  266. * (Ix2excID/(2 * M[ntypes - 1]) + 1); // ABACUS++T_8 onwards
  267. // Remove everything up to index i2 in Ix2exclabelremaining
  268. Ix2exclabelremaining = Ix2exclabelremaining.substr(i2+1);
  269. }
  270. // Now read off the last pair:
  271. int Ix2excID = Convert_STR_to_POSINT(Ix2exclabelremaining);
  272. Ix2old[ntypes - 1][ABACUS::max(nexc[ntypes - 1] - 1,0)] =
  273. OriginIx2[type[ntypes - 1] ][Ix2excID - M[ntypes - 1] * (Ix2excID/M[ntypes - 1])];
  274. // index is remainder w/r to nr of strings of this type
  275. // Convention: if remainder is even, moving left. If odd, moving right.
  276. Ix2exc[ntypes - 1][ABACUS::max(nexc[ntypes - 1] - 1,0)] = Ix2old[ntypes - 1][nexc[ntypes - 1] - 1]
  277. + (Ix2excID/M[ntypes - 1] % 2 ? 2 : -2) * (Ix2excID/(2 * M[ntypes - 1]) + 1); // ABACUS++T_8 onwards
  278. State_Label_Data labeldata (type, M, nexc, Ix2old, Ix2exc);
  279. return(labeldata);
  280. }
  281. State_Label_Data Read_State_Label (string label, const Vect<int>& OriginIx2)
  282. {
  283. Vect<Vect<int> > OriginIx2here(1);
  284. OriginIx2here[0] = OriginIx2;
  285. return(Read_State_Label (label, OriginIx2here));
  286. }
  287. string Return_State_Label (State_Label_Data data, const Vect<Vect<int> >& OriginIx2)
  288. {
  289. // This function produces a compressed label.
  290. string label;
  291. // Write the base:
  292. // First, particles of type 0:
  293. stringstream M0out;
  294. M0out << data.M[0];
  295. label += M0out.str();
  296. for (int itype = 1; itype < data.M.size(); ++itype) {
  297. if (data.M[itype] > 0) {
  298. label += TYPESEP;
  299. stringstream typeout;
  300. typeout << data.type[itype];
  301. label += typeout.str();
  302. label += EXCSEP;
  303. stringstream Mout;
  304. Mout << data.M[itype];
  305. label += Mout.str();
  306. }
  307. }
  308. label += LABELSEP;
  309. // Now the nexc:
  310. stringstream nexc0out;
  311. nexc0out << data.nexc[0];
  312. label += nexc0out.str();
  313. for (int iexc = 1; iexc < data.nexc.size(); ++iexc) {
  314. label += TYPESEP;
  315. stringstream nexcout;
  316. nexcout << data.nexc[iexc];
  317. label += nexcout.str();
  318. }
  319. label += LABELSEP;
  320. // Now the displacements:
  321. // The conventions are as follows.
  322. // For each excitation, an integer number ID is given according to the following rules:
  323. // ID % data.M[itype] gives the index of the hole position in OriginIx2.
  324. // We now define remainder1 == ID - (ID % data.M[itype]).
  325. // remainder1 is interpreted as: remainder1 even/odd means displacement to left/right
  326. // remainder1/2 + 1 gives then the displacement in units of quantum nr.
  327. // The +1 is to start labeling displacement from 0 (so 0 means displace by one unit).
  328. for (int itype = 0; itype < data.M.size(); ++itype) {
  329. if (itype > 0) label += TYPESEP;
  330. for (int iexc = 0; iexc < data.nexc[itype]; ++iexc) {
  331. if (iexc > 0) label += EXCSEP;
  332. int excID = abs(data.Ix2exc[itype][iexc] - data.Ix2old[itype][iexc]) - 2; // necessarily even and >= 0
  333. if (data.Ix2exc[itype][iexc] > data.Ix2old[itype][iexc]) excID += 1; // make odd if displacement is to the right
  334. int holeindex = -1;
  335. do {
  336. holeindex++;
  337. } while (OriginIx2[data.type[itype] ][holeindex] != data.Ix2old[itype][iexc]
  338. && holeindex < OriginIx2[data.type[itype] ].size() - 1);
  339. if (holeindex == OriginIx2[data.type[itype] ].size())
  340. ABACUSerror("Going out of bounds in Compress_Label.");
  341. excID = excID * data.M[itype] + holeindex;
  342. label += Convert_POSINT_to_STR(excID);
  343. } // for iexc
  344. } // for itype
  345. return(label);
  346. }
  347. string Return_State_Label (State_Label_Data data, const Vect<int>& OriginIx2)
  348. {
  349. Vect<Vect<int> > OriginIx2here(1);
  350. OriginIx2here[0] = OriginIx2;
  351. return(Return_State_Label (data, OriginIx2here));
  352. }
  353. string Return_State_Label (const Vect<Vect<int> >& ScanIx2, const Vect<Vect<int> >& OriginIx2)
  354. {
  355. // This function does not assume any ordering of the Ix2.
  356. if (ScanIx2.size() != OriginIx2.size())
  357. ABACUSerror("ScanIx2.size() != OriginIx2.size() in Find_Label.");
  358. for (int i = 0; i < ScanIx2.size(); ++i)
  359. if (ScanIx2[i].size() != OriginIx2[i].size())
  360. ABACUSerror("ScanIx2[i].size() != OriginIx2[i].size() in Find_Label.");
  361. // Set the state ulabel:
  362. // Count the number of types present:
  363. int ntypespresent = 0;
  364. for (int is = 0; is < ScanIx2.size(); ++is)
  365. if (is == 0 || ScanIx2[is].size() > 0) ntypespresent++; // type 0 is by default always present
  366. Vect<int> type_ref(ntypespresent);
  367. Vect<int> M_ref(ntypespresent);
  368. Vect<int> nexc_ref(0, ntypespresent);
  369. // Define type_ref and M_ref:
  370. int ntypespresentcheck = 0;
  371. for (int is = 0; is < ScanIx2.size(); ++is) if (is == 0 || ScanIx2[is].size() > 0) { // type 0 is by default always present
  372. type_ref[ntypespresentcheck] = is;
  373. M_ref[ntypespresentcheck++] = ScanIx2[is].size();
  374. }
  375. if (ntypespresentcheck != ntypespresent) ABACUSerror("Counting types present wrong in Return_Label.");
  376. // Count nr of particle-holes:
  377. for (int it = 0; it < ntypespresent; ++it)
  378. for (int i = 0; i < M_ref[it]; ++i) if (!OriginIx2[type_ref[it] ].includes(ScanIx2[type_ref[it] ][i])) nexc_ref[it] += 1;
  379. Vect<Vect<int> > Ix2old_ref(ntypespresent);
  380. Vect<Vect<int> > Ix2exc_ref(ntypespresent);
  381. for (int it = 0; it < ntypespresent; ++it) Ix2old_ref[it] = Vect<int>(ABACUS::max(nexc_ref[it],1));
  382. for (int it = 0; it < ntypespresent; ++it) Ix2exc_ref[it] = Vect<int>(ABACUS::max(nexc_ref[it],1));
  383. for (int it = 0; it < ntypespresent; ++it) {
  384. int nexccheck = 0;
  385. for (int i = 0; i < M_ref[it]; ++i)
  386. if (!OriginIx2[type_ref[it] ].includes(ScanIx2[type_ref[it] ][i]))
  387. Ix2exc_ref[it][nexccheck++] = ScanIx2[type_ref[it] ][i];
  388. if (nexccheck != nexc_ref[it])
  389. ABACUSerror("Counting excitations wrong (1) in Return_State_Label");
  390. nexccheck = 0;
  391. for (int i = 0; i < M_ref[it]; ++i)
  392. if (!ScanIx2[type_ref[it] ].includes(OriginIx2[type_ref[it] ][i]))
  393. Ix2old_ref[it][nexccheck++] = OriginIx2[type_ref[it] ][i];
  394. if (nexccheck != nexc_ref[it]) {
  395. cout << OriginIx2 << endl;
  396. cout << ScanIx2 << endl;
  397. cout << nexc_ref[it] << endl;
  398. cout << Ix2exc_ref[it] << endl;
  399. ABACUSerror("Counting excitations wrong (2) in Return_State_Label");
  400. }
  401. // Now order the Ix2old_ref and Ix2exc_ref:
  402. Ix2old_ref[it].QuickSort();
  403. Ix2exc_ref[it].QuickSort();
  404. } // for it
  405. State_Label_Data labeldata(type_ref, M_ref, nexc_ref, Ix2old_ref, Ix2exc_ref);
  406. return(Return_State_Label (labeldata, OriginIx2));
  407. }
  408. string Return_State_Label (const Vect<int>& ScanIx2, const Vect<int>& OriginIx2)
  409. {
  410. Vect<Vect<int> > ScanIx2here(1);
  411. ScanIx2here[0] = ScanIx2;
  412. Vect<Vect<int> > OriginIx2here(1);
  413. OriginIx2here[0] = OriginIx2;
  414. return(Return_State_Label (ScanIx2here, OriginIx2here));
  415. }
  416. Vect<Vect<int> > Return_Ix2_from_Label (string label_ref, const Vect<Vect<int> >& OriginIx2)
  417. {
  418. // ASSUMPTIONS:
  419. // OriginIx2 is ordered.
  420. Vect<Vect<int> > Ix2 = OriginIx2; // this will fail if the sizes are incompatible
  421. State_Label_Data labeldata = Read_State_Label (label_ref, OriginIx2);
  422. // Now set the excitations:
  423. for (int it = 0; it < labeldata.type.size(); ++it)
  424. for (int iexc = 0; iexc < labeldata.nexc[it]; ++iexc)
  425. for (int i = 0; i < labeldata.M[it]; ++i)
  426. if (Ix2[labeldata.type[it] ][i] == labeldata.Ix2old[it][iexc]) {
  427. Ix2[labeldata.type[it] ][i] = labeldata.Ix2exc[it][iexc];
  428. }
  429. // Now reorder the Ix2 to follow convention:
  430. for (int il = 0; il < Ix2.size(); ++il) Ix2[il].QuickSort();
  431. return(Ix2);
  432. }
  433. Vect<int> Return_Ix2_from_Label (string label_ref, const Vect<int>& OriginIx2)
  434. {
  435. Vect<Vect<int> > OriginIx2here(1);
  436. OriginIx2here[0] = OriginIx2;
  437. return(Return_Ix2_from_Label(label_ref, OriginIx2here)[0]);
  438. }
  439. } // namespace ABACUS