Rework Makefile; adopt semver, starting with 1.0.0

This commit is contained in:
J.-S. Caux
2021-08-24 10:40:19 +02:00
parent f5f1a59862
commit 4e4e414b3b
18 changed files with 55 additions and 471 deletions
+275
View File
@@ -0,0 +1,275 @@
/**********************************************************
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
+29
View File
@@ -0,0 +1,29 @@
/**********************************************************
This software is part of J.-S. Caux's ABACUS library.
Copyright (c) J.-S. Caux.
-----------------------------------------------------------
File: src/BETHE/Bethe_State.cc
Purpose: defines functions in Bethe_State class,
providing a unified object for eigenstates of all
Bethe Ansatz integrable models.
IN DEVELOPMENT
***********************************************************/
#include "ABACUS.h"
using namespace std;
namespace ABACUS {
Bethe_State::Bethe_State (long long int base_id_ref, long long int type_id_ref,
long long int id_ref, long long int maxid_ref) :
base_id(base_id_ref), type_id(type_id_ref), id(id_ref), maxid(maxid_ref) {}
} // namespace ABACUS
+276
View File
@@ -0,0 +1,276 @@
/**********************************************************
This software is part of J.-S. Caux's ABACUS library.
Copyright (c) J.-S. Caux.
-----------------------------------------------------------
File: src/BETHE/Offsets.cc
Purpose: defines functions in Offsets class.
IN DEVELOPMENT
***********************************************************/
#include "ABACUS.h"
using namespace std;
namespace ABACUS {
// Function definitions: class Offsets
Offsets::Offsets () : base(), Tableau(Vect<Young_Tableau>()), type_id(0LL), id(0LL), maxid(0LL) {};
Offsets::Offsets (const Offsets& RefOffset) // copy constructor
: base(RefOffset.base), Tableau(Vect<Young_Tableau> (2 * base.Nrap.size() + 2)), type_id(RefOffset.type_id), id(RefOffset.id), maxid(RefOffset.maxid)
{
for (int i = 0; i < 2 * base.Nrap.size() + 2; ++i) Tableau[i] = RefOffset.Tableau[i];
}
Offsets::Offsets (const Heis_Base& RefBase, long long int req_type_id)
// sets all tableaux to empty ones, with nparticles(req_type_id) at each level
{
// Build nparticles vector from req_type_id
Vect<int> nparticles(0, 2* RefBase.Nrap.size() + 2);
long long int factor = pow_ulli (10LL, nparticles.size() - 1);
long long int id_eff = req_type_id;
for (int i = 0; i < nparticles.size(); ++i) {
nparticles[nparticles.size() - 1 - i] = id_eff/factor;
id_eff -= factor * nparticles[nparticles.size() - 1 - i];
factor /= 10LL;
}
// Check if we've got the right vector...
long long int idcheck = Offsets_type_id (nparticles);
if (idcheck != req_type_id) ABACUSerror("idcheck != req_type_id in Offsets constructor.");
(*this) = Offsets(RefBase, nparticles);
}
Offsets::Offsets (const Heis_Base& RefBase, Vect<int> nparticles) // sets all tableaux to empty ones, with nparticles at each level
: base(RefBase), Tableau(Vect<Young_Tableau> (2 * base.Nrap.size() + 2)), type_id(Offsets_type_id (nparticles)), id(0LL), maxid(0LL)
{
// Checks on nparticles vector:
if (nparticles.size() != 2 * base.Nrap.size() + 2) ABACUSerror("Wrong nparticles.size in Offsets constructor.");
//if (base.Nrap[0] != (nparticles[3] + nparticles[2] + base.Mdown - nparticles[0] - nparticles[1])) ABACUSerror("Wrong Nrap[0] in Offsets constructor.");
if (nparticles[3] + nparticles[2] != nparticles[0] + nparticles[1]) {
cout << nparticles[0] << "\t" << nparticles[1] << "\t" << nparticles[2] << "\t" << nparticles[3] << endl;
ABACUSerror("Wrong Npar[0-3] in Offsets constructor.");
}
for (int base_level = 1; base_level < base.Nrap.size(); ++ base_level)
if (base.Nrap[base_level] != nparticles[2*base_level + 2] + nparticles[2*base_level + 3]) {
cout << base_level << "\t" << base.Nrap[base_level] << "\t" << nparticles[2*base_level + 2] << "\t" << nparticles[2*base_level + 3] << endl;
ABACUSerror("Wrong Nrap[] in Offsets constructor.");
}
// nparticles[0,1]: number of holes on R and L side in GS interval
if (nparticles[0] > (base.Nrap[0] + 1)/2) ABACUSerror("nparticles[0] too large in Offsets constructor.");
if (nparticles[1] > base.Nrap[0]/2) ABACUSerror("nparticles[1] too large in Offsets constructor.");
// nparticles[2,3]: number of particles of type 0 on R and L side out of GS interval
if (nparticles[2] > (base.Ix2_max[0] - base.Nrap[0] + 1)/2) ABACUSerror("nparticles[2] too large in Offsets constructor.");
if (nparticles[3] > (base.Ix2_max[0] - base.Nrap[0] + 1)/2) ABACUSerror("nparticles[3] too large in Offsets constructor.");
for (int base_level = 1; base_level < base.Nrap.size(); ++ base_level)
if ((nparticles[2*base_level + 2] > 0 && nparticles[2*base_level + 2] > (base.Ix2_max[base_level] - ((base.Nrap[base_level] + 1) % 2) + 2)/2)
//|| (nparticles[2*base_level + 3] > 0 && nparticles[2*base_level + 3] > (base.Ix2_max[base_level] - (base.Nrap[base_level] % 2) - 1)/2)) {
|| (nparticles[2*base_level + 3] > 0
&& nparticles[2*base_level + 3] > base.Ix2_max[base_level] + 1 - (base.Ix2_max[base_level] - ((base.Nrap[base_level] + 1) % 2) + 2)/2)) {
cout << base_level << "\t" << nparticles[2*base_level + 2] << "\t" << (base.Ix2_max[base_level] - ((base.Nrap[base_level] + 1) % 2) + 2)/2
<< "\t" << nparticles[2*base_level + 3] << "\t" << (base.Ix2_max[base_level] - (base.Nrap[base_level] % 2) - 1)/2
<< "\t" << (nparticles[2*base_level + 2] > 0) << "\t" << (nparticles[2*base_level + 2] > (base.Ix2_max[base_level] - ((base.Nrap[base_level] + 1) % 2) + 2)/2)
//<< "\t" << (nparticles[2*base_level + 3] > 0) << "\t" << (nparticles[2*base_level + 3] > (base.Ix2_max[base_level] - (base.Nrap[base_level] % 2) - 1)/2)
<< "\t" << (nparticles[2*base_level + 3] > 0) << "\t"
<< (nparticles[2*base_level + 3] > base.Ix2_max[base_level] + 1 - (base.Ix2_max[base_level] - ((base.Nrap[base_level] + 1) % 2) + 2)/2)
<< endl;
ABACUSerror("nparticles too large in Offsets constructor.");
}
// Check sum of rapidities
// Holes in GS interval
Tableau[0] = Young_Tableau(nparticles[0], (base.Nrap[0] + 1)/2 - nparticles[0]);
Tableau[1] = Young_Tableau(nparticles[1], base.Nrap[0]/2 - nparticles[1], Tableau[0]);
// Particles of type 0 out of GS interval
Tableau[2] = Young_Tableau(nparticles[2], (base.Ix2_max[0] - base.Nrap[0] + 1)/2 - nparticles[2], Tableau[0]);
Tableau[3] = Young_Tableau(nparticles[3], (base.Ix2_max[0] - base.Nrap[0] + 1)/2 - nparticles[3], Tableau[2]);
// Tableaux of index i = 2,...: data about string type i/2-1.
for (int base_level = 1; base_level < base.Nrap.size(); ++base_level) {
Tableau[2*base_level + 2] = Young_Tableau(nparticles[2*base_level + 2],
//(base.Ix2_max[base_level] - ((base.Nrap[base_level]) % 2) + 2)/2 - nparticles[2*base_level + 2], Tableau[2]);
//(base.Ix2_max[base_level] - base.Nrap[base_level] % 2 + 2)/2 - nparticles[2*base_level + 2], Tableau[2]);
(base.Ix2_max[base_level] - ((base.Nrap[base_level] + 1) % 2))/2 + 1 - nparticles[2*base_level + 2], Tableau[2]);
Tableau[2*base_level + 3] = Young_Tableau(nparticles[2*base_level + 3],
//(base.Ix2_max[base_level] - base.Nrap[base_level] % 2)/2 - nparticles[2*base_level + 3], Tableau[3]);
(base.Ix2_max[base_level] - (base.Nrap[base_level] % 2) - 1)/2 + 1 - nparticles[2*base_level + 3], Tableau[3]);
}
maxid = 1LL;
//id = Tableau[0].id;
for (int i = 0; i < nparticles.size(); ++i) {
maxid *= Tableau[i].maxid + 1LL;
//id += maxid + Tableau[i].id;
}
maxid -= 1LL;
}
Offsets& Offsets::operator= (const Offsets& RefOffset)
{
if (this != &RefOffset) {
base = RefOffset.base;
Tableau = RefOffset.Tableau;
type_id = RefOffset.type_id;
id = RefOffset.id;
maxid = RefOffset.maxid;
}
return(*this);
}
bool Offsets::operator<= (const Offsets& RefOffsets)
{
// Check whether all nonzero tableau row lengths in RefOffsets
// are <= than those in *this
bool answer = true;
for (int level = 0; level < 4; ++level) { // check fundamental level only
//for (int level = 0; level < 2 * base.Nrap.size() + 2; ++level) {
// First check whether all rows which exist in both tableaux satisfy rule:
for (int tableau_level = 0; tableau_level < ABACUS::min(Tableau[level].Nrows, RefOffsets.Tableau[level].Nrows); ++tableau_level)
if (Tableau[level].Row_L[tableau_level] > RefOffsets.Tableau[level].Row_L[tableau_level])
answer = false;
// Now check whether there exist extra rows violating rule:
for (int tableau_level = ABACUS::min(Tableau[level].Nrows, RefOffsets.Tableau[level].Nrows); tableau_level < Tableau[level].Nrows; ++tableau_level)
if (Tableau[level].Row_L[tableau_level] > 0) answer = false;
}
return(answer);
}
bool Offsets::operator>= (const Offsets& RefOffsets)
{
// Check whether all nonzero tableau row lengths in RefOffsets
// are >= than those in *this
bool answer = true;
for (int level = 0; level < 4; ++level) { // check fundamental level only
//for (int level = 0; level < 2 * base.Nrap.size() + 2; ++level) {
// First check whether all rows which exist in both tableaux satisfy rule:
for (int tableau_level = 0; tableau_level < ABACUS::min(Tableau[level].Nrows, RefOffsets.Tableau[level].Nrows); ++tableau_level)
if (Tableau[level].Row_L[tableau_level] < RefOffsets.Tableau[level].Row_L[tableau_level])
answer = false;
// Now check whether there exist extra rows violating rule:
for (int tableau_level = ABACUS::min(Tableau[level].Nrows, RefOffsets.Tableau[level].Nrows); tableau_level < RefOffsets.Tableau[level].Nrows; ++tableau_level)
if (RefOffsets.Tableau[level].Row_L[tableau_level] > 0) answer = false;
}
return(answer);
}
void Offsets::Compute_type_id ()
{
type_id = 0LL;
for (int i = 0; i < 2*base.Nrap.size() + 2; ++i) {
Tableau[i].Compute_id();
type_id += Tableau[i].Nrows * pow_ulli(10LL, i);
}
}
void Offsets::Set_to_id (long long int idnr)
{
// The idnr of the Offset is given by
// sub_id[0] + (total number of tableaux of type 0) * (sub_id[1] + (total number of tableaux of type 1) * (sub_id[2] + ...
// + total number of tableaux of type (2*base.Nrap.size()) * sub_id[2*base.Nrap.size() + 1]
if (idnr > maxid) {
cout << idnr << "\t" << maxid << endl;
ABACUSerror("idnr too large in offsets.Set_to_id.");
}
id = idnr;
Vect<long long int> sub_id(0LL, 2*base.Nrap.size() + 2);
long long int idnr_eff = idnr;
long long int temp_prod = 1LL;
Vect<long long int> result_choose(2*base.Nrap.size() + 2);
for (int i = 0; i <= 2*base.Nrap.size(); ++i) {
//result_choose[i] = choose_lli(Tableau[i].Nrows + Tableau[i].Ncols, Tableau[i].Nrows);
result_choose[i] = Tableau[i].maxid + 1LL;
temp_prod *= result_choose[i];
}
for (int i = 2*base.Nrap.size() + 1; i > 0; --i) {
sub_id[i] = idnr_eff/temp_prod;
idnr_eff -= sub_id[i] * temp_prod;
temp_prod /= result_choose[i-1];
}
sub_id[0] = idnr_eff; // what's left goes to the bottom...
for (int i = 0; i <= 2*base.Nrap.size() + 1; ++i) {
//cout << "level = " << i << " Tableau.id = " << sub_id[i] << endl;
if ((Tableau[i].Nrows * Tableau[i].Ncols == 0) && (sub_id[i] != 0)) ABACUSerror("index too large in offset.Set_to_id.");
if (Tableau[i].id != sub_id[i]) Tableau[i].Set_to_id(sub_id[i]);
}
Compute_type_id ();
return;
}
void Offsets::Compute_id ()
{
long long int prod_maxid = 1LL;
id = 0LL;
for (int i = 0; i < 2*base.Nrap.size() + 2; ++i) {
Tableau[i].Compute_id();
id += Tableau[i].id * prod_maxid;
prod_maxid *= Tableau[i].maxid + 1LL;
}
}
Vect<long long int> Offsets::Descendents (bool fixed_iK)
{
// From a given vector of Young tableaux specifying a particular eigenstate,
// this function provides the full set of descendents (either at the same momentum if
// fixed_iK == true, or not) by returning a vector of all descendent id's (leaving the
// base and type invariant), which can then be used for further calculations.
// This set of descendents is meant to be used when calculating either partition functions
// or zero-temperature correlation functions.
// IMPORTANT ASSUMPTIONS:
// - all even sectors consistently increase/decrease momentum for increasing tableau row length
// - all odd sectors consistently decrease/increase momentum for increasing tableau row length
// FOR FIXED MOMENTUM:
// all tableau levels `above' the lowest occupied one are descended as for fixed_iK == false,
// and the lowest sector's highest tableau level's row length is modified (increased or decreased by one
// unit if possible) such that the iK of Tableau_desc == iK of Tableau_ref.
// The logic behind this is that for a state with nexc excitations, we let run nexc - 1 of the
// excitations, and the lowest one is fixed in place by the momentum constraint, if possible.
Vect<Young_Tableau> Tableau_ref = (*this).Tableau;
Vect<Young_Tableau> Tableau_desc = Tableau_ref;
}
} // namespace ABACUS