276 lines
7.3 KiB
C++
276 lines
7.3 KiB
C++
/**********************************************************
|
|
|
|
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<int>()), Nraptot(0), Ix2_infty(Vect<DP>()),
|
|
Ix2_max(Vect<int>()), id(0LL) {}
|
|
|
|
Base::Base (int N) : Charge(N), Nrap(Vect<int>(N,1)), Nraptot(N), Ix2_infty(Vect<DP>(1.0e+100,1)),
|
|
Ix2_max(Vect<int>(LONG_LONG_MAX, 1)), id(N) {}
|
|
|
|
Base::Base (const Base& RefBase) // copy constructor
|
|
: Charge(RefBase.Charge), Nrap(Vect<int>(RefBase.Nrap.size())), Nraptot(RefBase.Nraptot),
|
|
Ix2_infty(Vect<DP>(RefBase.Ix2_infty.size())),
|
|
Ix2_max(Vect<int>(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<int>& Nrapidities)
|
|
: Charge(0), Nrap(Nrapidities), Nraptot(0), Ix2_infty(Vect<DP>(RefChain.Nstrings)),
|
|
Ix2_max(Vect<int>(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<int>(RefChain.Nstrings)), Nraptot(0),
|
|
Ix2_infty(Vect<DP>(RefChain.Nstrings)), Ix2_max(Vect<int>(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
|