/********************************************************** This software is part of J.-S. Caux's ABACUS library. Copyright (c) J.-S. Caux. ----------------------------------------------------------- File: src/BETHE/Base.cc Purpose: defines functions in Base class, providing a unified base object for all Bethe Ansatz integrable models. ***********************************************************/ #include "ABACUS.h" using namespace std; namespace ABACUS { // Function definitions: class Base Base::Base () : Charge(0), Nrap(Vect()), Nraptot(0), Ix2_infty(Vect()), Ix2_max(Vect()), id(0LL) {} Base::Base (int N) : Charge(N), Nrap(Vect(N,1)), Nraptot(N), Ix2_infty(Vect(1.0e+100,1)), Ix2_max(Vect(LONG_LONG_MAX, 1)), id(N) {} Base::Base (const Base& RefBase) // copy constructor : Charge(RefBase.Charge), Nrap(Vect(RefBase.Nrap.size())), Nraptot(RefBase.Nraptot), Ix2_infty(Vect(RefBase.Ix2_infty.size())), Ix2_max(Vect(RefBase.Ix2_max.size())), id(RefBase.id) { for (int i = 0; i < Nrap.size(); ++i) { Nrap[i] = RefBase.Nrap[i]; Ix2_infty[i] = RefBase.Ix2_infty[i]; Ix2_max[i] = RefBase.Ix2_max[i]; } } Base::Base (const Heis_Chain& RefChain, const Vect& Nrapidities) : Charge(0), Nrap(Nrapidities), Nraptot(0), Ix2_infty(Vect(RefChain.Nstrings)), Ix2_max(Vect(RefChain.Nstrings)), id (0LL) { // Check consistency of Nrapidities vector with RefChain if (RefChain.Nstrings != Nrapidities.size()) ABACUSerror("Incompatible Nrapidities vector used in Base constructor."); int Mcheck = 0; for (int i = 0; i < RefChain.Nstrings; ++i) Mcheck += RefChain.Str_L[i] * Nrap[i]; Charge = Mcheck; Nraptot = 0; for (int i = 0; i < RefChain.Nstrings; ++i) Nraptot += Nrap[i]; // Compute id id += Nrapidities[0]; long long int factor = 100000LL; for (int i = 1; i < RefChain.Nstrings; ++i) { id += factor * Nrapidities[i]; factor *= 100LL; } // Now compute the Ix2_infty numbers (*this).Compute_Ix2_limits(RefChain); } Base::Base (const Heis_Chain& RefChain, long long int id_ref) : Charge(0), Nrap(Vect(RefChain.Nstrings)), Nraptot(0), Ix2_infty(Vect(RefChain.Nstrings)), Ix2_max(Vect(RefChain.Nstrings)), id (id_ref) { // Build Nrapidities vector from id_ref long long int factor = pow_ulli (10LL, 2* RefChain.Nstrings + 1); long long int id_eff = id_ref; for (int i = 0; i < RefChain.Nstrings - 1; ++i) { Nrap[RefChain.Nstrings - 1 - i] = id_eff/factor; id_eff -= factor * Nrap[RefChain.Nstrings - 1 - i]; factor /= 100LL; } Nrap[0] = id_eff; int Mcheck = 0; for (int i = 0; i < RefChain.Nstrings; ++i) Mcheck += RefChain.Str_L[i] * Nrap[i]; Charge = Mcheck; Nraptot = 0; for (int i = 0; i < RefChain.Nstrings; ++i) Nraptot += Nrap[i]; // Now compute the Ix2_infty numbers (*this).Compute_Ix2_limits(RefChain); } Base& Base::operator= (const Base& RefBase) { if (this != & RefBase) { Charge = RefBase.Charge; Nrap = RefBase.Nrap; Nraptot = RefBase.Nraptot; Ix2_infty = RefBase.Ix2_infty; Ix2_max = RefBase.Ix2_max; id = RefBase.id; } return(*this); } bool Base::operator== (const Base& RefBase) { bool answer = (Nrap == RefBase.Nrap); return (answer); } bool Base::operator!= (const Base& RefBase) { bool answer = (Nrap != RefBase.Nrap); return (answer); } void Base::Compute_Ix2_limits (const Heis_Chain& RefChain) { if ((RefChain.Delta > 0.0) && (RefChain.Delta < 1.0)) { // Compute the Ix2_infty numbers DP sum1 = 0.0; DP sum2 = 0.0; for (int j = 0; j < RefChain.Nstrings; ++j) { sum1 = 0.0; for (int k = 0; k < RefChain.Nstrings; ++k) { sum2 = 0.0; sum2 += (RefChain.Str_L[j] == RefChain.Str_L[k]) ? 0.0 : 2.0 * atan(tan(0.25 * PI * (1.0 + RefChain.par[j] * RefChain.par[k]) - 0.5 * fabs(RefChain.Str_L[j] - RefChain.Str_L[k]) * RefChain.anis)); sum2 += 2.0 * atan(tan(0.25 * PI * (1.0 + RefChain.par[j] * RefChain.par[k]) - 0.5 * (RefChain.Str_L[j] + RefChain.Str_L[k]) * RefChain.anis)); for (int a = 1; a < ABACUS::min(RefChain.Str_L[j], RefChain.Str_L[k]); ++a) sum2 += 2.0 * 2.0 * atan(tan(0.25 * PI * (1.0 + RefChain.par[j] * RefChain.par[k]) - 0.5 * (fabs(RefChain.Str_L[j] - RefChain.Str_L[k]) + 2.0*a) * RefChain.anis)); sum1 += (Nrap[k] - ((j == k) ? 1 : 0)) * sum2; } Ix2_infty[j] = (1.0/PI) * fabs(RefChain.Nsites * 2.0 * atan(tan(0.25 * PI * (1.0 + RefChain.par[j]) - 0.5 * RefChain.Str_L[j] * RefChain.anis)) - sum1); } // The Ix2_infty are now set. // Now compute the Ix2_max limits for (int j = 0; j < RefChain.Nstrings; ++j) { Ix2_max[j] = int(floor(Ix2_infty[j])); // sets basic integer // Reject formally infinite rapidities (i.e. if Delta is root of unity) //cout << "Ix2_infty - Ix2_max = " << Ix2_infty[j] - Ix2_max[j] << endl; //if (Ix2_infty[j] == Ix2_max[j]) { //Ix2_max[j] -= 2; //} // If Nrap is even, Ix2_max must be odd. If odd, then even. if (!((Nrap[j] + Ix2_max[j]) % 2)) Ix2_max[j] -= 1; while (Ix2_max[j] > RefChain.Nsites) { Ix2_max[j] -= 2; } } } // if XXZ gapless else if (RefChain.Delta == 1.0) { // Compute the Ix2_infty numbers int sum1 = 0; for (int j = 0; j < RefChain.Nstrings; ++j) { sum1 = 0; for (int k = 0; k < RefChain.Nstrings; ++k) { sum1 += Nrap[k] * (2 * ABACUS::min(RefChain.Str_L[j], RefChain.Str_L[k]) - ((j == k) ? 1 : 0)); } //Ix2_infty[j] = (RefChain.Nsites - 1.0 + 2.0 * RefChain.Str_L[j] - sum1); Ix2_infty[j] = (RefChain.Nsites + 1.0 - sum1); // to get counting right... } // The Ix2_infty are now set. // Now compute the Ix2_max limits for (int j = 0; j < RefChain.Nstrings; ++j) { Ix2_max[j] = int(floor(Ix2_infty[j])); // sets basic integer // Give the correct parity to Ix2_max // If Nrap is even, Ix2_max must be odd. If odd, then even. if (!((Nrap[j] + Ix2_max[j]) % 2)) Ix2_max[j] -= 1; // If Ix2_max equals Ix2_infty, we reduce it by 2: if (Ix2_max[j] == int(Ix2_infty[j])) Ix2_max[j] -= 2; while (Ix2_max[j] > RefChain.Nsites) { Ix2_max[j] -= 2; } } } // if XXX AFM else if (RefChain.Delta > 1.0) { // Compute the Ix2_infty numbers int sum1 = 0; for (int j = 0; j < RefChain.Nstrings; ++j) { sum1 = 0; for (int k = 0; k < RefChain.Nstrings; ++k) { sum1 += Nrap[k] * (2 * ABACUS::min(RefChain.Str_L[j], RefChain.Str_L[k]) - ((j == k) ? 1 : 0)); } Ix2_infty[j] = (RefChain.Nsites - 1 + 2 * RefChain.Str_L[j] - sum1); } // The Ix2_infty are now set. // Now compute the Ix2_max limits for (int j = 0; j < RefChain.Nstrings; ++j) { Ix2_max[j] = int(floor(Ix2_infty[j])); // sets basic integer // Give the correct parity to Ix2_max // If Nrap is even, Ix2_max must be odd. If odd, then even. if (!((Nrap[j] + Ix2_max[j]) % 2)) Ix2_max[j] -= 1; // If Ix2_max equals Ix2_infty, we reduce it by 2: //if (Ix2_max[j] == Ix2_infty[j]) Ix2_max[j] -= 2; while (Ix2_max[j] > RefChain.Nsites) { Ix2_max[j] -= 2; } } } // if XXZ_gpd } } // namespace ABACUS